diff --git a/c_src/sqlite3.c b/c_src/sqlite3.c index 9443127..ab7af8e 100644 --- a/c_src/sqlite3.c +++ b/c_src/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.44.2. By combining all the individual C code files into this +** version 3.43.0. 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 -** ebead0e7230cd33bcec9f95d2183069565b9. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -53,11 +50,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. ** @@ -402,6 +399,9 @@ extern "C" { #ifndef SQLITE_SYSAPI # define SQLITE_SYSAPI #endif +#ifndef LIBSQL_API +# define LIBSQL_API +#endif /* ** These no-op macros are used in front of interfaces to mark those @@ -459,9 +459,11 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.44.2" -#define SQLITE_VERSION_NUMBER 3044002 -#define SQLITE_SOURCE_ID "2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f" +#define SQLITE_VERSION "3.43.0" +#define SQLITE_VERSION_NUMBER 3043000 +#define SQLITE_SOURCE_ID "2023-05-23 11:47:56 cec49c7d93362f527f0b4744cd1ae95d44a79671d49d69baa77fda70be29alt1" + +#define LIBSQL_VERSION "0.2.2" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -500,6 +502,8 @@ SQLITE_API const char *sqlite3_libversion(void); SQLITE_API const char *sqlite3_sourceid(void); SQLITE_API int sqlite3_libversion_number(void); +SQLITE_API const char *libsql_libversion(void); + /* ** CAPI3REF: Run-Time Library Compilation Options Diagnostics ** @@ -841,7 +845,6 @@ SQLITE_API int sqlite3_exec( #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) #define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) -#define SQLITE_IOERR_IN_PAGE (SQLITE_IOERR | (34<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) @@ -1320,6 +1323,13 @@ struct sqlite3_io_methods { ** ^When there are multiple VFS shims in the stack, this opcode finds the ** upper-most shim only. ** +**
  • [[SQLITE_FCNTL_WAL_METHODS_POINTER]] +** ^The [SQLITE_FCNTL_WAL_METHODS_POINTER] opcode finds a pointer to the top-level +** WAL methods currently in use. ^(The argument X in +** sqlite3_file_control(db,SQLITE_FCNTL_WAL_METHODS_POINTER,X) must be +** of type "[libsql_wal_methods] **". This opcodes will set *X +** to a pointer to the top-level WAL methods.)^ +** **
  • [[SQLITE_FCNTL_PRAGMA]] ** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] ** file control is sent to the open [sqlite3_file] object corresponding @@ -1504,7 +1514,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]] @@ -1556,6 +1566,9 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 +// libSQL extension +#define SQLITE_FCNTL_WAL_METHODS_POINTER 129 + /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE @@ -1584,6 +1597,16 @@ typedef struct sqlite3_mutex sqlite3_mutex; */ typedef struct sqlite3_api_routines sqlite3_api_routines; +/* +** CAPI3REF: Loadable Extension Thunk +** +** A pointer to the opaque libsql_api_routines structure is passed as +** the fourth parameter to entry points of [loadable extensions]. This +** structure must be typedefed in order to work around compiler warnings +** on some platforms. +*/ +typedef struct libsql_api_routines libsql_api_routines; + /* ** CAPI3REF: File Name ** @@ -2440,7 +2463,7 @@ struct sqlite3_mem_methods { ** is stored in each sorted record and the required column values loaded ** from the database as records are returned in sorted order. The default ** value for this option is to never use this optimization. Specifying a -** negative value for this option restores the default behavior. +** negative value for this option restores the default behaviour. ** This option is only available if SQLite is compiled with the ** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. ** @@ -2615,7 +2638,7 @@ struct sqlite3_mem_methods { ** database handle, SQLite checks if this will mean that there are now no ** connections at all to the database. If so, it performs a checkpoint ** operation before closing the connection. This option may be used to -** override this behavior. The first parameter passed to this operation +** override this behaviour. The first parameter passed to this operation ** is an integer - positive to disable checkpoints-on-close, or zero (the ** default) to enable them, and negative to leave the setting unchanged. ** The second parameter is a pointer to an integer @@ -2768,7 +2791,7 @@ 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]] @@ -3049,7 +3072,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 +3725,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 @@ -4063,6 +4083,24 @@ SQLITE_API int sqlite3_open_v2( int flags, /* Flags */ const char *zVfs /* Name of VFS module to use */ ); +SQLITE_API int libsql_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs, /* Name of VFS module to use, NULL for default */ + const char *zWal /* Name of WAL module to use */ +); + +SQLITE_API int libsql_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs, /* Name of VFS module to use, NULL for default */ + const char *zWal, /* Name of WAL module to use */ + void* pWalMethodsData /* User data, passed to the libsql_wal struct*/ +); + +SQLITE_API LIBSQL_API int libsql_try_initialize_wasm_func_table(sqlite3 *db); /* ** CAPI3REF: Obtain Values For URI Parameters @@ -4075,7 +4113,7 @@ SQLITE_API int sqlite3_open_v2( ** as F) must be one of: ** @@ -4188,7 +4226,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 @@ -4268,7 +4306,6 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language ** text that describes the error, as either UTF-8 or UTF-16 respectively. -** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by @@ -4736,41 +4773,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 [sqlite3_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 @@ -4934,7 +4936,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 @@ -5639,7 +5641,6 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); */ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); - /* ** CAPI3REF: Create Or Redefine SQL Functions ** KEYWORDS: {function creation routines} @@ -5850,7 +5851,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. **

    @@ -5886,27 +5887,13 @@ SQLITE_API int sqlite3_create_window_function( ** ** ** [[SQLITE_SUBTYPE]]

    SQLITE_SUBTYPE
    -** The SQLITE_SUBTYPE flag indicates to SQLite that a function might call +** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. -** This flag instructs SQLite to omit some corner-case optimizations that -** might disrupt the operation of the [sqlite3_value_subtype()] function, -** causing it to return zero rather than the correct subtype(). -** SQL functions that invokes [sqlite3_value_subtype()] should have this -** property. If the SQLITE_SUBTYPE property is omitted, then the return -** value from [sqlite3_value_subtype()] might sometimes be zero even though -** a non-zero subtype was specified by the function argument expression. -** -** [[SQLITE_RESULT_SUBTYPE]]
    SQLITE_RESULT_SUBTYPE
    -** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call -** [sqlite3_result_subtype()] to cause a sub-type to be associated with its -** result. -** Every function that invokes [sqlite3_result_subtype()] should have this -** property. If it does not, then the call to [sqlite3_result_subtype()] -** might become a no-op if the function is used as term in an -** [expression index]. On the other hand, SQL functions that never invoke -** [sqlite3_result_subtype()] should avoid setting this property, as the -** purpose of this property is to disable certain optimizations that are -** incompatible with subtypes. +** Specifying this flag makes no difference for scalar or aggregate user +** functions. However, if it is not specified for a user-defined window +** function, then any sub-types belonging to arguments passed to the window +** function may be discarded before the window function is called (i.e. +** sqlite3_value_subtype() will always return 0). **
    ** */ @@ -5914,7 +5901,6 @@ SQLITE_API int sqlite3_create_window_function( #define SQLITE_DIRECTONLY 0x000080000 #define SQLITE_SUBTYPE 0x000100000 #define SQLITE_INNOCUOUS 0x000200000 -#define SQLITE_RESULT_SUBTYPE 0x001000000 /* ** CAPI3REF: Deprecated Functions @@ -6111,12 +6097,6 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*); ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. -** -** Every [application-defined SQL function] that invoke this interface -** should include the [SQLITE_SUBTYPE] property in the text -** encoding argument when the function is [sqlite3_create_function|registered]. -** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() -** might return zero instead of the upstream subtype in some corner cases. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); @@ -6215,56 +6195,48 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** METHOD: sqlite3_context ** ** These functions may be used by (non-aggregate) SQL functions to -** associate auxiliary data with argument values. If the same argument -** value is passed to multiple invocations of the same SQL function during -** query execution, under some circumstances the associated auxiliary data -** might be preserved. An example of where this might be useful is in a -** regular-expression matching function. The compiled version of the regular -** expression can be stored as auxiliary data associated with the pattern string. +** associate metadata with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated metadata may be preserved. An example +** of where this might be useful is in a regular-expression matching +** function. The compiled version of the regular expression can be stored as +** metadata associated with the pattern string. ** Then as long as the pattern string remains the same, ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** -** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata ** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument ** value to the application-defined function. ^N is zero for the left-most -** function argument. ^If there is no auxiliary data +** function argument. ^If there is no metadata ** associated with the function argument, the sqlite3_get_auxdata(C,N) interface ** returns a NULL pointer. ** -** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the -** N-th argument of the application-defined function. ^Subsequent +** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th +** argument of the application-defined function. ^Subsequent ** calls to sqlite3_get_auxdata(C,N) return P from the most recent -** sqlite3_set_auxdata(C,N,P,X) call if the auxiliary data is still valid or -** NULL if the auxiliary data has been discarded. +** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or +** NULL if the metadata has been discarded. ** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, ** SQLite will invoke the destructor function X with parameter P exactly -** once, when the auxiliary data is discarded. -** SQLite is free to discard the auxiliary data at any time, including: ** -** Note the last two bullets in particular. The destructor X in +** Note the last bullet in particular. The destructor X in ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() ** should be called near the end of the function implementation and the ** function implementation should not make any use of P after -** sqlite3_set_auxdata() has been called. Furthermore, a call to -** sqlite3_get_auxdata() that occurs immediately after a corresponding call -** to sqlite3_set_auxdata() might still return NULL if an out-of-memory -** condition occurred during the sqlite3_set_auxdata() call or if the -** function is being evaluated during query planning rather than during -** query execution. -** -** ^(In practice, auxiliary data is preserved between function calls for +** sqlite3_set_auxdata() has been called. +** +** ^(In practice, metadata is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** @@ -6274,67 +6246,10 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** ** These routines must be called from the same thread in which ** the SQL function is running. -** -** See also: [sqlite3_get_clientdata()] and [sqlite3_set_clientdata()]. */ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); -/* -** CAPI3REF: Database Connection Client Data -** METHOD: sqlite3 -** -** These functions are used to associate one or more named pointers -** with a [database connection]. -** A call to sqlite3_set_clientdata(D,N,P,X) causes the pointer P -** to be attached to [database connection] D using name N. Subsequent -** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P -** or a NULL pointer if there were no prior calls to -** sqlite3_set_clientdata() with the same values of D and N. -** Names are compared using strcmp() and are thus case sensitive. -** -** If P and X are both non-NULL, then the destructor X is invoked with -** argument P on the first of the following occurrences: -** -** -** SQLite does not do anything with client data other than invoke -** destructors on the client data at the appropriate time. The intended -** use for client data is to provide a mechanism for wrapper libraries -** to store additional information about an SQLite database connection. -** -** There is no limit (other than available memory) on the number of different -** client data pointers (with different names) that can be attached to a -** single database connection. However, the implementation is optimized -** for the case of having only one or two different client data names. -** Applications and wrapper libraries are discouraged from using more than -** one client data name each. -** -** There is no way to enumerate the client data pointers -** associated with a database connection. The N parameter can be thought -** of as a secret key such that only code that knows the secret key is able -** to access the associated data. -** -** Security Warning: These interfaces should not be exposed in scripting -** languages or in other circumstances where it might be possible for an -** an attacker to invoke them. Any agent that can invoke these interfaces -** can probably also take control of the process. -** -** Database connection client data is only available for SQLite -** version 3.44.0 ([dateof:3.44.0]) and later. -** -** See also: [sqlite3_set_auxdata()] and [sqlite3_get_auxdata()]. -*/ -SQLITE_API void *sqlite3_get_clientdata(sqlite3*,const char*); -SQLITE_API int sqlite3_set_clientdata(sqlite3*, const char*, void*, void(*)(void*)); /* ** CAPI3REF: Constants Defining Special Destructor Behavior @@ -6536,20 +6451,6 @@ SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); ** higher order bits are discarded. ** The number of subtype bytes preserved by SQLite might increase ** in future releases of SQLite. -** -** Every [application-defined SQL function] that invokes this interface -** should include the [SQLITE_RESULT_SUBTYPE] property in its -** text encoding argument when the SQL function is -** [sqlite3_create_function|registered]. If the [SQLITE_RESULT_SUBTYPE] -** property is omitted from the function that invokes sqlite3_result_subtype(), -** then in some cases the sqlite3_result_subtype() might fail to set -** the result subtype. -** -** If SQLite is compiled with -DSQLITE_STRICT_SUBTYPE=1, then any -** SQL function that invokes the sqlite3_result_subtype() interface -** and that does not have the SQLITE_RESULT_SUBTYPE property will raise -** an error. Future versions of SQLite might enable -DSQLITE_STRICT_SUBTYPE=1 -** by default. */ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); @@ -6981,7 +6882,7 @@ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); /* -** CAPI3REF: Allowed return values from sqlite3_txn_state() +** CAPI3REF: Allowed return values from [sqlite3_txn_state()] ** KEYWORDS: {transaction state} ** ** These constants define the current transaction state of a database file. @@ -7113,7 +7014,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** ^Each call to the sqlite3_autovacuum_pages() interface overrides all ** previous invocations for that database connection. ^If the callback ** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer, -** then the autovacuum steps callback is canceled. The return value +** then the autovacuum steps callback is cancelled. The return value ** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might ** be some other error code if something goes wrong. The current ** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other @@ -7632,10 +7533,9 @@ struct sqlite3_module { /* The methods above are in versions 1 and 2 of the sqlite_module object. ** Those below are for version 3 and greater. */ int (*xShadowName)(const char*); - /* The methods above are in versions 1 through 3 of the sqlite_module object. - ** Those below are for version 4 and greater. */ - int (*xIntegrity)(sqlite3_vtab *pVTab, const char *zSchema, - const char *zTabName, int mFlags, char **pzErr); + /* The methods below relate to features contributed by the community and + ** are available for version 700 and greater. */ + int (*xPreparedSql)(sqlite3_vtab_cursor*, const char*); }; /* @@ -8123,7 +8023,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); ** code is returned and the transaction rolled back. ** ** Calling this function with an argument that is not a NULL pointer or an -** open blob handle results in undefined behavior. ^Calling this routine +** open blob handle results in undefined behaviour. ^Calling this routine ** with a null pointer (such as would be returned by a failed call to ** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function ** is passed a valid open blob handle, the values returned by the @@ -8251,6 +8151,34 @@ SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); +/* +** CAPI3REF: Virtual WAL Methods +** +** Virtual WAL methods can be redefined in order to change the default +** behavior of the write-ahead log. +** Methods can be registered and unregistered. +** The following interfaces are provided. +** +** ^The libsql_wal_methods_find() interface returns a pointer +** to the methods given their identifier. +** ^Names are case sensitive. +** ^Names are zero-terminated UTF-8 strings. +** ^If there is no match, a NULL pointer is returned. +** ^If zName is NULL then the default implementation is returned. +** +** ^New WAL methods are registered with libsql_wal_methods_register(). +** ^Same methods can be registered multiple times without injury. +** +** ^Unregister WAL methods with the libsql_wal_methods_unregister() interface. +*/ +typedef struct libsql_wal_methods libsql_wal_methods; +SQLITE_API libsql_wal_methods *libsql_wal_methods_find(const char *zName); +SQLITE_API int libsql_wal_methods_register(libsql_wal_methods*); +SQLITE_API int libsql_wal_methods_unregister(libsql_wal_methods*); + +SQLITE_API libsql_wal_methods *libsql_wal_methods_next(libsql_wal_methods *w); +SQLITE_API const char *libsql_wal_methods_name(libsql_wal_methods *w); + /* ** CAPI3REF: Mutexes ** @@ -8603,7 +8531,6 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SAVE 5 #define SQLITE_TESTCTRL_PRNG_RESTORE 6 #define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */ -#define SQLITE_TESTCTRL_FK_NO_ACTION 7 #define SQLITE_TESTCTRL_BITVEC_TEST 8 #define SQLITE_TESTCTRL_FAULT_INSTALL 9 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 @@ -8632,8 +8559,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 @@ -9173,6 +9099,14 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED. ** ** +** +** [[LIBSQL_STMTSTATUS_ROWS_READ]] +** [[LIBSQL_STMTSTATUS_ROWS_WRITTEN]] +**
    LIBSQL_STMTSTATUS_ROWS_READ
    +** LIBSQL_STMTSTATUS_ROWS_WRITTEN
    +**
    ^LIBSQL_STMTSTATUS_ROWS_READ is the number of rows read when executing +** this statement. LIBSQL_STMTSTATUS_ROWS_WRITTEN value is the number of +** rows written. */ #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 #define SQLITE_STMTSTATUS_SORT 2 @@ -9184,6 +9118,10 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); #define SQLITE_STMTSTATUS_FILTER_HIT 8 #define SQLITE_STMTSTATUS_MEMUSED 99 +#define LIBSQL_STMTSTATUS_BASE 1024 +#define LIBSQL_STMTSTATUS_ROWS_READ LIBSQL_STMTSTATUS_BASE + 1 +#define LIBSQL_STMTSTATUS_ROWS_WRITTEN LIBSQL_STMTSTATUS_BASE + 2 + /* ** CAPI3REF: Custom Page Cache Object ** @@ -10089,7 +10027,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. **
    @@ -10279,7 +10217,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 @@ -10708,7 +10646,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 @@ -10737,6 +10675,22 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *); #endif +/* +** CAPI3REF: The close hook. +** METHOD: sqlite3 +** +** ^The [libsql_close_hook()] interface registers a callback function +** that is invoked prior to closing the database connection. +** ^At most one close hook may be registered at a time on a single +** [database connection]; each call to [libsql_close_hook()] overrides +** the previous setting. +** ^The close hook is disabled by invoking [libsql_close_hook()] +** with a NULL pointer as the second parameter. +** ^The third parameter to [libsql_close_hook()] is passed through as +** the first parameter to callbacks. +*/ +SQLITE_API void *libsql_close_hook(sqlite3 *db, void (*xClose)(void *pCtx, sqlite3 *db), void *arg); + /* ** CAPI3REF: Low-level system error code ** METHOD: sqlite3 @@ -10969,13 +10923,6 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c ** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy ** of the database exists. ** -** After the call, if the SQLITE_SERIALIZE_NOCOPY bit had been set, -** the returned buffer content will remain accessible and unchanged -** until either the next write operation on the connection or when -** the connection is closed, and applications must not modify the -** buffer. If the bit had been clear, the returned buffer will not -** be accessed by SQLite after the call. -** ** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the ** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory ** allocation error occurs. @@ -11024,9 +10971,6 @@ SQLITE_API unsigned char *sqlite3_serialize( ** SQLite will try to increase the buffer size using sqlite3_realloc64() ** if writes on the database cause it to grow larger than M bytes. ** -** Applications must not modify the buffer P or invalidate it before -** the database connection D is closed. -** ** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the ** database is currently in a read transaction or is involved in a backup ** operation. @@ -11035,13 +10979,6 @@ SQLITE_API unsigned char *sqlite3_serialize( ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the ** function returns SQLITE_ERROR. ** -** The deserialized database should not be in [WAL mode]. If the database -** is in WAL mode, then any attempt to use the database file will result -** in an [SQLITE_CANTOPEN] error. The application can set the -** [file format version numbers] (bytes 18 and 19) of the input database P -** to 0x01 prior to invoking sqlite3_deserialize(D,S,P,N,M,F) to force the -** database file into rollback mode and work around this limitation. -** ** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the ** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then ** [sqlite3_free()] is invoked on argument P prior to returning. @@ -12114,18 +12051,6 @@ SQLITE_API int sqlite3changeset_concat( ); -/* -** CAPI3REF: Upgrade the Schema of a Changeset/Patchset -*/ -SQLITE_API int sqlite3changeset_upgrade( - sqlite3 *db, - const char *zDb, - int nIn, const void *pIn, /* Input changeset */ - int *pnOut, void **ppOut /* OUT: Inverse of input */ -); - - - /* ** CAPI3REF: Changegroup Handle ** @@ -12172,38 +12097,6 @@ typedef struct sqlite3_changegroup sqlite3_changegroup; */ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp); -/* -** CAPI3REF: Add a Schema to a Changegroup -** METHOD: sqlite3_changegroup_schema -** -** This method may be used to optionally enforce the rule that the changesets -** added to the changegroup handle must match the schema of database zDb -** ("main", "temp", or the name of an attached database). If -** sqlite3changegroup_add() is called to add a changeset that is not compatible -** with the configured schema, SQLITE_SCHEMA is returned and the changegroup -** object is left in an undefined state. -** -** A changeset schema is considered compatible with the database schema in -** the same way as for sqlite3changeset_apply(). Specifically, for each -** table in the changeset, there exists a database table with: -** -** -** -** The output of the changegroup object always has the same schema as the -** database nominated using this function. In cases where changesets passed -** to sqlite3changegroup_add() have fewer columns than the corresponding table -** in the database schema, these are filled in using the default column -** values from the database schema. This makes it possible to combined -** changesets that have different numbers of columns for a single table -** within a changegroup, provided that they are otherwise compatible. -*/ -SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const char *zDb); - /* ** CAPI3REF: Add A Changeset To A Changegroup ** METHOD: sqlite3_changegroup @@ -12272,18 +12165,13 @@ SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const c ** If the new changeset contains changes to a table that is already present ** in the changegroup, then the number of columns and the position of the ** primary key columns for the table must be consistent. If this is not the -** case, this function fails with SQLITE_SCHEMA. Except, if the changegroup -** object has been configured with a database schema using the -** sqlite3changegroup_schema() API, then it is possible to combine changesets -** with different numbers of columns for a single table, provided that -** they are otherwise compatible. -** -** If the input changeset appears to be corrupt and the corruption is -** detected, SQLITE_CORRUPT is returned. Or, if an out-of-memory condition -** occurs during processing, this function returns SQLITE_NOMEM. +** case, this function fails with SQLITE_SCHEMA. If the input changeset +** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is +** returned. Or, if an out-of-memory condition occurs during processing, this +** function returns SQLITE_NOMEM. In all cases, if an error occurs the state +** of the final contents of the changegroup is undefined. ** -** In all cases, if an error occurs the state of the final contents of the -** changegroup is undefined. If no error occurs, SQLITE_OK is returned. +** If no error occurs, SQLITE_OK is returned. */ SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); @@ -12548,17 +12436,10 @@ SQLITE_API int sqlite3changeset_apply_v2( **
  • an insert change if all fields of the conflicting row match ** the row being inserted. ** -** -**
    SQLITE_CHANGESETAPPLY_FKNOACTION
    -** If this flag it set, then all foreign key constraints in the target -** database behave as if they were declared with "ON UPDATE NO ACTION ON -** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL -** or SET DEFAULT. */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 #define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 -#define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008 /* ** CAPI3REF: Constants Passed To The Conflict Handler @@ -13299,7 +13180,7 @@ struct Fts5PhraseIter { ** See xPhraseFirstColumn above. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ void *(*xUserData)(Fts5Context*); @@ -13528,8 +13409,8 @@ struct Fts5ExtensionApi { ** as separate queries of the FTS index are required for each synonym. ** ** When using methods (2) or (3), it is important that the tokenizer only -** provide synonyms when tokenizing document text (method (3)) or query -** text (method (2)), not both. Doing so will not cause any errors, but is +** provide synonyms when tokenizing document text (method (2)) or query +** text (method (3)), not both. Doing so will not cause any errors, but is ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; @@ -13577,7 +13458,7 @@ struct fts5_api { int (*xCreateTokenizer)( fts5_api *pApi, const char *zName, - void *pUserData, + void *pContext, fts5_tokenizer *pTokenizer, void (*xDestroy)(void*) ); @@ -13586,7 +13467,7 @@ struct fts5_api { int (*xFindTokenizer)( fts5_api *pApi, const char *zName, - void **ppUserData, + void **ppContext, fts5_tokenizer *pTokenizer ); @@ -13594,7 +13475,7 @@ struct fts5_api { int (*xCreateFunction)( fts5_api *pApi, const char *zName, - void *pUserData, + void *pContext, fts5_extension_function xFunction, void (*xDestroy)(void*) ); @@ -13611,6 +13492,338 @@ struct fts5_api { #endif /* _FTS5_H */ /******** End of fts5.h *********/ +/******** Begin file page_header.h *********/ +// SPDX-License-Identifier: MIT + +#ifndef LIBSQL_PAGE_HEADER_H +#define LIBSQL_PAGE_HEADER_H + +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +typedef struct Pager Pager; +typedef struct libsql_pghdr PgHdr; +typedef struct PCache PCache; + +/* +** Every page in the cache is controlled by an instance of the following +** structure. +*/ +struct libsql_pghdr { + sqlite3_pcache_page *pPage; /* Pcache object page handle */ + void *pData; /* Page data */ + void *pExtra; /* Extra content */ + PCache *pCache; /* PRIVATE: Cache that owns this page */ + PgHdr *pDirty; /* Transient list of dirty sorted by pgno */ + Pager *pPager; /* The pager this page is part of */ + unsigned int pgno; /* Page number for this page */ + unsigned int pageHash; /* Hash of page content */ + unsigned short flags; /* PGHDR flags defined below */ + + /********************************************************************** + ** Elements above, except pCache, are public. All that follow are + ** private to pcache.c and should not be accessed by other modules. + ** pCache is grouped with the public elements for efficiency. + */ + unsigned long long nRef; /* Number of users of this page */ + PgHdr *pDirtyNext; /* Next element in list of dirty pages */ + PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ + /* NB: pDirtyNext and pDirtyPrev are undefined if the + ** PgHdr object is not dirty */ +}; + +typedef struct libsql_pghdr libsql_pghdr; + +#endif // LIBSQL_PAGE_HEADER_H + +/******** End of page_header.h *********/ +/******** Begin file wal.h *********/ +/* +** 2010 February 1 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface to the write-ahead logging +** system. Refer to the comments below and the header comment attached to +** the implementation of each function in log.c for further details. +*/ + +#ifndef SQLITE_WAL_H +#define SQLITE_WAL_H + + +/* Macros for extracting appropriate sync flags for either transaction +** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)): +*/ +#define WAL_SYNC_FLAGS(X) ((X)&0x03) +#define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03) + +#define WAL_SAVEPOINT_NDATA 4 + +/* Connection to a write-ahead log (WAL) file. +** There is one object of this type for each pager. +*/ +typedef struct libsql_wal libsql_wal; + +typedef struct libsql_wal_methods { + int iVersion; /* Current version is 1, versioning is here for backward compatibility */ + /* Open and close a connection to a write-ahead log. */ + int (*xOpen)(sqlite3_vfs*, sqlite3_file* , const char*, int no_shm_mode, long long max_size, struct libsql_wal_methods*, libsql_wal**); + int (*xClose)(libsql_wal*, sqlite3* db, int sync_flags, int nBuf, unsigned char *zBuf); + + /* Set the limiting size of a WAL file. */ + void (*xLimit)(libsql_wal*, long long limit); + + /* Used by readers to open (lock) and close (unlock) a snapshot. A + ** snapshot is like a read-transaction. It is the state of the database + ** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and + ** preserves the current state even if the other threads or processes + ** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the + ** transaction and releases the lock. + */ + int (*xBeginReadTransaction)(libsql_wal *, int *); + void (*xEndReadTransaction)(libsql_wal *); + + /* Read a page from the write-ahead log, if it is present. */ + int (*xFindFrame)(libsql_wal *, unsigned int, unsigned int *); + int (*xReadFrame)(libsql_wal *, unsigned int, int, unsigned char *); + + /* If the WAL is not empty, return the size of the database. */ + unsigned int (*xDbsize)(libsql_wal *pWal); + + /* Obtain or release the WRITER lock. */ + int (*xBeginWriteTransaction)(libsql_wal *pWal); + int (*xEndWriteTransaction)(libsql_wal *pWal); + + /* Undo any frames written (but not committed) to the log */ + int (*xUndo)(libsql_wal *pWal, int (*xUndo)(void *, unsigned int), void *pUndoCtx); + + /* Return an integer that records the current (uncommitted) write + ** position in the WAL */ + void (*xSavepoint)(libsql_wal *pWal, unsigned int *aWalData); + + /* Move the write position of the WAL back to iFrame. Called in + ** response to a ROLLBACK TO command. */ + int (*xSavepointUndo)(libsql_wal *pWal, unsigned int *aWalData); + + /* Write a frame or frames to the log. */ + int (*xFrames)(libsql_wal *pWal, int, libsql_pghdr *, unsigned int, int, int); + + /* Copy pages from the log to the database file */ + int (*xCheckpoint)( + libsql_wal *pWal, /* Write-ahead log connection */ + sqlite3 *db, /* Check this handle's interrupt flag */ + int eMode, /* One of PASSIVE, FULL and RESTART */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags to sync db file with (or 0) */ + int nBuf, /* Size of buffer nBuf */ + unsigned char *zBuf, /* Temporary buffer to use */ + int *pnLog, /* OUT: Number of frames in WAL */ + int *pnCkpt /* OUT: Number of backfilled frames in WAL */ + ); + + /* Return the value to pass to a sqlite3_wal_hook callback, the + ** number of frames in the WAL at the point of the last commit since + ** sqlite3WalCallback() was called. If no commits have occurred since + ** the last call, then return 0. + */ + int (*xCallback)(libsql_wal *pWal); + + /* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released) + ** by the pager layer on the database file. + */ + int (*xExclusiveMode)(libsql_wal *pWal, int op); + + /* Return true if the argument is non-NULL and the WAL module is using + ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the + ** WAL module is using shared-memory, return false. + */ + int (*xHeapMemory)(libsql_wal *pWal); + + // Only needed with SQLITE_ENABLE_SNAPSHOT, but part of the ABI + int (*xSnapshotGet)(libsql_wal *pWal, sqlite3_snapshot **ppSnapshot); + void (*xSnapshotOpen)(libsql_wal *pWal, sqlite3_snapshot *pSnapshot); + int (*xSnapshotRecover)(libsql_wal *pWal); + int (*xSnapshotCheck)(libsql_wal *pWal, sqlite3_snapshot *pSnapshot); + void (*xSnapshotUnlock)(libsql_wal *pWal); + + // Only needed with SQLITE_ENABLE_ZIPVFS, but part of the ABI + /* If the WAL file is not empty, return the number of bytes of content + ** stored in each frame (i.e. the db page-size when the WAL was created). + */ + int (*xFramesize)(libsql_wal *pWal); + + + /* Return the sqlite3_file object for the WAL file */ + sqlite3_file *(*xFile)(libsql_wal *pWal); + + // Only needed with SQLITE_ENABLE_SETLK_TIMEOUT + int (*xWriteLock)(libsql_wal *pWal, int bLock); + + void (*xDb)(libsql_wal *pWal, sqlite3 *db); + + /* Return the WAL pathname length based on the owning pager's pathname len. + ** For WAL implementations not based on a single file, 0 should be returned. */ + int (*xPathnameLen)(int origPathname); + + /* Get the WAL pathname to given buffer. Assumes that the buffer can hold + ** at least xPathnameLen bytes. For WAL implementations not based on a single file, + ** this operation can safely be a no-op. + ** */ + void (*xGetWalPathname)(char *buf, const char *orig, int orig_len); + + /* + ** This optional callback gets called before the main database file which owns + ** the WAL file is open. It is a good place for initialization routines, as WAL + ** is otherwise open lazily. + */ + int (*xPreMainDbOpen)(libsql_wal_methods *methods, const char *main_db_path); + + /* True if the implementation relies on shared memory routines (e.g. locks) */ + int bUsesShm; + + const char *zName; + struct libsql_wal_methods *pNext; +} libsql_wal_methods; + +libsql_wal_methods* libsql_wal_methods_find(const char *zName); + +/* Object declarations */ +typedef struct WalIndexHdr WalIndexHdr; +typedef struct WalIterator WalIterator; +typedef struct WalCkptInfo WalCkptInfo; + + +/* +** The following object holds a copy of the wal-index header content. +** +** The actual header in the wal-index consists of two copies of this +** object followed by one instance of the WalCkptInfo object. +** For all versions of SQLite through 3.10.0 and probably beyond, +** the locking bytes (WalCkptInfo.aLock) start at offset 120 and +** the total header size is 136 bytes. +** +** The szPage value can be any power of 2 between 512 and 32768, inclusive. +** Or it can be 1 to represent a 65536-byte page. The latter case was +** added in 3.7.1 when support for 64K pages was added. +*/ +struct WalIndexHdr { + unsigned int iVersion; /* Wal-index version */ + unsigned int unused; /* Unused (padding) field */ + unsigned int iChange; /* Counter incremented each transaction */ + unsigned char isInit; /* 1 when initialized */ + unsigned char bigEndCksum; /* True if checksums in WAL are big-endian */ + unsigned short szPage; /* Database page size in bytes. 1==64K */ + unsigned int mxFrame; /* Index of last valid frame in the WAL */ + unsigned int nPage; /* Size of database in pages */ + unsigned int aFrameCksum[2]; /* Checksum of last frame in log */ + unsigned int aSalt[2]; /* Two salt values copied from WAL header */ + unsigned int aCksum[2]; /* Checksum over all prior fields */ +}; + +/* +** An open write-ahead log file is represented by an instance of the +** following object. +*/ +struct libsql_wal { + sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ + sqlite3_file *pDbFd; /* File handle for the database file */ + sqlite3_file *pWalFd; /* File handle for WAL file */ + unsigned int iCallback; /* Value to pass to log callback (or 0) */ + long long mxWalSize; /* Truncate WAL to this size upon reset */ + int nWiData; /* Size of array apWiData */ + int szFirstBlock; /* Size of first block written to WAL file */ + volatile unsigned int **apWiData; /* Pointer to wal-index content in memory */ + unsigned int szPage; /* Database page size */ + short readLock; /* Which read lock is being held. -1 for none */ + unsigned char syncFlags; /* Flags to use to sync header writes */ + unsigned char exclusiveMode; /* Non-zero if connection is in exclusive mode */ + unsigned char writeLock; /* True if in a write transaction */ + unsigned char ckptLock; /* True if holding a checkpoint lock */ + unsigned char readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ + unsigned char truncateOnCommit; /* True to truncate WAL file on commit */ + unsigned char syncHeader; /* Fsync the WAL header if true */ + unsigned char padToSectorBoundary; /* Pad transactions out to the next sector */ + unsigned char bShmUnreliable; /* SHM content is read-only and unreliable */ + WalIndexHdr hdr; /* Wal-index header for current transaction */ + unsigned int minFrame; /* Ignore wal frames before this one */ + unsigned int iReCksum; /* On commit, recalculate checksums from here */ + const char *zWalName; /* Name of WAL file */ + unsigned int nCkpt; /* Checkpoint sequence counter in the wal-header */ + unsigned char lockError; /* True if a locking error has occurred */ + WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ + sqlite3 *db; + libsql_wal_methods *pMethods; /* Virtual methods for interacting with WAL */ + void *pMethodsData; /* Optional context for private use of libsql_wal_methods */ +}; + +typedef struct libsql_wal libsql_wal; + +#endif /* SQLITE_WAL_H */ + +/******** End of wal.h *********/ +/******** Begin file wasm_bindings.h *********/ +/* SPDX-License-Identifier: MIT */ +#ifdef LIBSQL_ENABLE_WASM_RUNTIME + +#ifndef LIBSQL_WASM_BINDINGS_H +#define LIBSQL_WASM_BINDINGS_H + +typedef struct libsql_wasm_engine_t libsql_wasm_engine_t; +typedef struct libsql_wasm_module_t libsql_wasm_module_t; + +typedef struct libsql_wasm_udf_api { + int (*libsql_value_type)(sqlite3_value*); + int (*libsql_value_int)(sqlite3_value*); + double (*libsql_value_double)(sqlite3_value*); + const unsigned char *(*libsql_value_text)(sqlite3_value*); + const void *(*libsql_value_blob)(sqlite3_value*); + int (*libsql_value_bytes)(sqlite3_value*); + void (*libsql_result_error)(sqlite3_context*, const char*, int); + void (*libsql_result_error_nomem)(sqlite3_context*); + void (*libsql_result_int)(sqlite3_context*, int); + void (*libsql_result_double)(sqlite3_context*, double); + void (*libsql_result_text)(sqlite3_context*, const char*, int, void(*)(void*)); + void (*libsql_result_blob)(sqlite3_context*, const void*, int, void(*)(void*)); + void (*libsql_result_null)(sqlite3_context*); + void *(*libsql_malloc)(int); + void (*libsql_free)(void *); +} libsql_wasm_udf_api; + +/* +** Runs a WebAssembly user-defined function. +** Additional data can be accessed via sqlite3_user_data(context) +*/ +SQLITE_API void libsql_run_wasm(struct libsql_wasm_udf_api *api, sqlite3_context *context, + libsql_wasm_engine_t *engine, libsql_wasm_module_t *module, const char *func_name, int argc, sqlite3_value **argv); + +/* +** Compiles a WebAssembly module. Can accept both .wat and binary Wasm format, depending on the implementation. +** err_msg_buf needs to be deallocated with libsql_free_wasm_module. +*/ +SQLITE_API libsql_wasm_module_t *libsql_compile_wasm_module(libsql_wasm_engine_t* engine, const char *pSrcBody, int nBody, + void *(*alloc_err_buf)(unsigned long long), char **err_msg_buf); + +/* +** Frees a module allocated with libsql_compile_wasm_module +*/ +SQLITE_API void libsql_free_wasm_module(void *module); + +/* +** Creates a new wasm engine +*/ +SQLITE_API libsql_wasm_engine_t *libsql_wasm_engine_new(); +SQLITE_API void libsql_wasm_engine_free(libsql_wasm_engine_t *); + +#endif //LIBSQL_WASM_BINDINGS_H +#endif //LIBSQL_ENABLE_WASM_RUNTIME + +/******** End of wasm_bindings.h *********/ /************** End of sqlite3.h *********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -13705,7 +13918,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 @@ -13949,16 +14162,6 @@ struct fts5_api { # endif #endif -/* -** Enable SQLITE_USE_SEH by default on MSVC builds. Only omit -** SEH support if the -DSQLITE_OMIT_SEH option is given. -*/ -#if defined(_MSC_VER) && !defined(SQLITE_OMIT_SEH) -# define SQLITE_USE_SEH 1 -#else -# undef SQLITE_USE_SEH -#endif - /* ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. ** 0 means mutexes are permanently disable and the library is never @@ -14373,164 +14576,166 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_AS 24 #define TK_COMMA 25 #define TK_WITHOUT 26 -#define TK_ABORT 27 -#define TK_ACTION 28 -#define TK_AFTER 29 -#define TK_ANALYZE 30 -#define TK_ASC 31 -#define TK_ATTACH 32 -#define TK_BEFORE 33 -#define TK_BY 34 -#define TK_CASCADE 35 -#define TK_CAST 36 -#define TK_CONFLICT 37 -#define TK_DATABASE 38 -#define TK_DESC 39 -#define TK_DETACH 40 -#define TK_EACH 41 -#define TK_FAIL 42 -#define TK_OR 43 -#define TK_AND 44 -#define TK_IS 45 -#define TK_MATCH 46 -#define TK_LIKE_KW 47 -#define TK_BETWEEN 48 -#define TK_IN 49 -#define TK_ISNULL 50 -#define TK_NOTNULL 51 -#define TK_NE 52 -#define TK_EQ 53 -#define TK_GT 54 -#define TK_LE 55 -#define TK_LT 56 -#define TK_GE 57 -#define TK_ESCAPE 58 -#define TK_ID 59 -#define TK_COLUMNKW 60 -#define TK_DO 61 -#define TK_FOR 62 -#define TK_IGNORE 63 -#define TK_INITIALLY 64 -#define TK_INSTEAD 65 -#define TK_NO 66 -#define TK_KEY 67 -#define TK_OF 68 -#define TK_OFFSET 69 -#define TK_PRAGMA 70 -#define TK_RAISE 71 -#define TK_RECURSIVE 72 -#define TK_REPLACE 73 -#define TK_RESTRICT 74 -#define TK_ROW 75 -#define TK_ROWS 76 -#define TK_TRIGGER 77 -#define TK_VACUUM 78 -#define TK_VIEW 79 -#define TK_VIRTUAL 80 -#define TK_WITH 81 -#define TK_NULLS 82 -#define TK_FIRST 83 -#define TK_LAST 84 -#define TK_CURRENT 85 -#define TK_FOLLOWING 86 -#define TK_PARTITION 87 -#define TK_PRECEDING 88 -#define TK_RANGE 89 -#define TK_UNBOUNDED 90 -#define TK_EXCLUDE 91 -#define TK_GROUPS 92 -#define TK_OTHERS 93 -#define TK_TIES 94 -#define TK_GENERATED 95 -#define TK_ALWAYS 96 -#define TK_MATERIALIZED 97 -#define TK_REINDEX 98 -#define TK_RENAME 99 -#define TK_CTIME_KW 100 -#define TK_ANY 101 -#define TK_BITAND 102 -#define TK_BITOR 103 -#define TK_LSHIFT 104 -#define TK_RSHIFT 105 -#define TK_PLUS 106 -#define TK_MINUS 107 -#define TK_STAR 108 -#define TK_SLASH 109 -#define TK_REM 110 -#define TK_CONCAT 111 -#define TK_PTR 112 -#define TK_COLLATE 113 -#define TK_BITNOT 114 -#define TK_ON 115 -#define TK_INDEXED 116 -#define TK_STRING 117 -#define TK_JOIN_KW 118 -#define TK_CONSTRAINT 119 -#define TK_DEFAULT 120 -#define TK_NULL 121 -#define TK_PRIMARY 122 -#define TK_UNIQUE 123 -#define TK_CHECK 124 -#define TK_REFERENCES 125 -#define TK_AUTOINCR 126 -#define TK_INSERT 127 -#define TK_DELETE 128 -#define TK_UPDATE 129 -#define TK_SET 130 -#define TK_DEFERRABLE 131 -#define TK_FOREIGN 132 -#define TK_DROP 133 -#define TK_UNION 134 -#define TK_ALL 135 -#define TK_EXCEPT 136 -#define TK_INTERSECT 137 -#define TK_SELECT 138 -#define TK_VALUES 139 -#define TK_DISTINCT 140 -#define TK_DOT 141 -#define TK_FROM 142 -#define TK_JOIN 143 -#define TK_USING 144 -#define TK_ORDER 145 -#define TK_GROUP 146 -#define TK_HAVING 147 -#define TK_LIMIT 148 -#define TK_WHERE 149 -#define TK_RETURNING 150 -#define TK_INTO 151 -#define TK_NOTHING 152 -#define TK_FLOAT 153 -#define TK_BLOB 154 -#define TK_INTEGER 155 -#define TK_VARIABLE 156 -#define TK_CASE 157 -#define TK_WHEN 158 -#define TK_THEN 159 -#define TK_ELSE 160 -#define TK_INDEX 161 -#define TK_ALTER 162 -#define TK_ADD 163 -#define TK_WINDOW 164 -#define TK_OVER 165 -#define TK_FILTER 166 -#define TK_COLUMN 167 -#define TK_AGG_FUNCTION 168 -#define TK_AGG_COLUMN 169 -#define TK_TRUEFALSE 170 -#define TK_ISNOT 171 -#define TK_FUNCTION 172 -#define TK_UMINUS 173 -#define TK_UPLUS 174 -#define TK_TRUTH 175 -#define TK_REGISTER 176 -#define TK_VECTOR 177 -#define TK_SELECT_COLUMN 178 -#define TK_IF_NULL_ROW 179 -#define TK_ASTERISK 180 -#define TK_SPAN 181 -#define TK_ERROR 182 -#define TK_SPACE 183 -#define TK_ILLEGAL 184 +#define TK_RANDOM 27 +#define TK_ABORT 28 +#define TK_ACTION 29 +#define TK_AFTER 30 +#define TK_ANALYZE 31 +#define TK_ASC 32 +#define TK_ATTACH 33 +#define TK_BEFORE 34 +#define TK_BY 35 +#define TK_CASCADE 36 +#define TK_CAST 37 +#define TK_CONFLICT 38 +#define TK_DATABASE 39 +#define TK_DESC 40 +#define TK_DETACH 41 +#define TK_EACH 42 +#define TK_FAIL 43 +#define TK_FUNCTION 44 +#define TK_LANGUAGE 45 +#define TK_OR 46 +#define TK_AND 47 +#define TK_IS 48 +#define TK_MATCH 49 +#define TK_LIKE_KW 50 +#define TK_BETWEEN 51 +#define TK_IN 52 +#define TK_ISNULL 53 +#define TK_NOTNULL 54 +#define TK_NE 55 +#define TK_EQ 56 +#define TK_GT 57 +#define TK_LE 58 +#define TK_LT 59 +#define TK_GE 60 +#define TK_ESCAPE 61 +#define TK_ID 62 +#define TK_COLUMNKW 63 +#define TK_DO 64 +#define TK_FOR 65 +#define TK_IGNORE 66 +#define TK_INITIALLY 67 +#define TK_INSTEAD 68 +#define TK_NO 69 +#define TK_KEY 70 +#define TK_OF 71 +#define TK_OFFSET 72 +#define TK_PRAGMA 73 +#define TK_RAISE 74 +#define TK_RECURSIVE 75 +#define TK_REPLACE 76 +#define TK_RESTRICT 77 +#define TK_ROW 78 +#define TK_ROWS 79 +#define TK_TRIGGER 80 +#define TK_VACUUM 81 +#define TK_VIEW 82 +#define TK_VIRTUAL 83 +#define TK_WITH 84 +#define TK_NULLS 85 +#define TK_FIRST 86 +#define TK_LAST 87 +#define TK_CURRENT 88 +#define TK_FOLLOWING 89 +#define TK_PARTITION 90 +#define TK_PRECEDING 91 +#define TK_RANGE 92 +#define TK_UNBOUNDED 93 +#define TK_EXCLUDE 94 +#define TK_GROUPS 95 +#define TK_OTHERS 96 +#define TK_TIES 97 +#define TK_GENERATED 98 +#define TK_ALWAYS 99 +#define TK_MATERIALIZED 100 +#define TK_REINDEX 101 +#define TK_RENAME 102 +#define TK_CTIME_KW 103 +#define TK_ANY 104 +#define TK_BITAND 105 +#define TK_BITOR 106 +#define TK_LSHIFT 107 +#define TK_RSHIFT 108 +#define TK_PLUS 109 +#define TK_MINUS 110 +#define TK_STAR 111 +#define TK_SLASH 112 +#define TK_REM 113 +#define TK_CONCAT 114 +#define TK_PTR 115 +#define TK_COLLATE 116 +#define TK_BITNOT 117 +#define TK_ON 118 +#define TK_INDEXED 119 +#define TK_STRING 120 +#define TK_JOIN_KW 121 +#define TK_CONSTRAINT 122 +#define TK_DEFAULT 123 +#define TK_NULL 124 +#define TK_PRIMARY 125 +#define TK_UNIQUE 126 +#define TK_CHECK 127 +#define TK_REFERENCES 128 +#define TK_AUTOINCR 129 +#define TK_INSERT 130 +#define TK_DELETE 131 +#define TK_UPDATE 132 +#define TK_SET 133 +#define TK_DEFERRABLE 134 +#define TK_FOREIGN 135 +#define TK_DROP 136 +#define TK_BLOB 137 +#define TK_UNION 138 +#define TK_ALL 139 +#define TK_EXCEPT 140 +#define TK_INTERSECT 141 +#define TK_SELECT 142 +#define TK_VALUES 143 +#define TK_DISTINCT 144 +#define TK_DOT 145 +#define TK_FROM 146 +#define TK_JOIN 147 +#define TK_USING 148 +#define TK_ORDER 149 +#define TK_GROUP 150 +#define TK_HAVING 151 +#define TK_LIMIT 152 +#define TK_WHERE 153 +#define TK_RETURNING 154 +#define TK_INTO 155 +#define TK_NOTHING 156 +#define TK_FLOAT 157 +#define TK_INTEGER 158 +#define TK_VARIABLE 159 +#define TK_CASE 160 +#define TK_WHEN 161 +#define TK_THEN 162 +#define TK_ELSE 163 +#define TK_INDEX 164 +#define TK_ALTER 165 +#define TK_ADD 166 +#define TK_WINDOW 167 +#define TK_OVER 168 +#define TK_FILTER 169 +#define TK_COLUMN 170 +#define TK_AGG_FUNCTION 171 +#define TK_AGG_COLUMN 172 +#define TK_TRUEFALSE 173 +#define TK_ISNOT 174 +#define TK_UMINUS 175 +#define TK_UPLUS 176 +#define TK_TRUTH 177 +#define TK_REGISTER 178 +#define TK_VECTOR 179 +#define TK_SELECT_COLUMN 180 +#define TK_IF_NULL_ROW 181 +#define TK_ASTERISK 182 +#define TK_SPAN 183 +#define TK_ERROR 184 +#define TK_SPACE 185 +#define TK_ILLEGAL 186 /************** End of parse.h ***********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -14818,31 +15023,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 whose 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, @@ -14852,33 +15034,16 @@ typedef INT16_TYPE LogEst; ** using C-preprocessor macros. If that is unsuccessful, or if ** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined ** at run-time. -** -** If you are building SQLite on some obscure platform for which the -** following ifdef magic does not work, you can always include either: -** -** -DSQLITE_BYTEORDER=1234 -** -** or -** -** -DSQLITE_BYTEORDER=4321 -** -** to cause the build to work for little-endian or big-endian processors, -** respectively. */ -#ifndef SQLITE_BYTEORDER /* Replicate changes at tag-20230904a */ -# if defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ -# define SQLITE_BYTEORDER 4321 -# elif defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ -# define SQLITE_BYTEORDER 1234 -# elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 -# define SQLITE_BYTEORDER 4321 -# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ +#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(__ARMEB__) || defined(__AARCH64EB__) -# define SQLITE_BYTEORDER 4321 +# define SQLITE_BYTEORDER 1234 +# elif defined(sparc) || defined(__ppc__) || \ + defined(__ARMEB__) || defined(__AARCH64EB__) +# define SQLITE_BYTEORDER 4321 # else # define SQLITE_BYTEORDER 0 # endif @@ -15093,7 +15258,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 @@ -15202,13 +15367,11 @@ typedef struct Column Column; typedef struct Cte Cte; typedef struct CteUse CteUse; typedef struct Db Db; -typedef struct DbClientData DbClientData; typedef struct DbFixer DbFixer; typedef struct Schema Schema; typedef struct Expr Expr; typedef struct ExprList ExprList; typedef struct FKey FKey; -typedef struct FpDecode FpDecode; typedef struct FuncDestructor FuncDestructor; typedef struct FuncDef FuncDef; typedef struct FuncDefHash FuncDefHash; @@ -15227,7 +15390,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; @@ -15665,7 +15827,7 @@ typedef struct Pager Pager; /* ** Handle type for pages. */ -typedef struct PgHdr DbPage; +typedef struct libsql_pghdr DbPage; /* ** Page number PAGER_SJ_PGNO is never used in an SQLite database (it is @@ -15738,9 +15900,13 @@ typedef struct PgHdr DbPage; ** a detailed description of each routine. */ +typedef struct libsql_wal_methods libsql_wal_methods; + /* Open and close a Pager connection. */ SQLITE_PRIVATE int sqlite3PagerOpen( sqlite3_vfs*, + libsql_wal_methods*, + void* pWalMethodsData, Pager **ppPager, const char*, int, @@ -15836,6 +16002,9 @@ SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*); SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*); SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager*, int); SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager*); +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE libsql_wal_methods *sqlite3PagerWalMethods(Pager*); +#endif SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*); SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); @@ -15865,10 +16034,6 @@ SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*); # define enable_simulated_io_errors() #endif -#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) -SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager*); -#endif - #endif /* SQLITE_PAGER_H */ /************** End of pager.h ***********************************************/ @@ -15918,9 +16083,11 @@ typedef struct BtCursor BtCursor; typedef struct BtShared BtShared; typedef struct BtreePayload BtreePayload; +typedef struct libsql_wal_methods libsql_wal_methods; SQLITE_PRIVATE int sqlite3BtreeOpen( sqlite3_vfs *pVfs, /* VFS to use with this b-tree */ + libsql_wal_methods *pWal,/* WAL methods to use with this b-tree */ const char *zFilename, /* Name of database file to open */ sqlite3 *db, /* Associated database connection */ Btree **ppBtree, /* Return open Btree* here */ @@ -16198,7 +16365,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*); @@ -16512,25 +16681,25 @@ typedef struct VdbeOpList VdbeOpList; #define OP_IdxLE 40 /* jump, synopsis: key=r[P3@P4] */ #define OP_IdxGT 41 /* jump, synopsis: key=r[P3@P4] */ #define OP_IdxLT 42 /* jump, synopsis: key=r[P3@P4] */ -#define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ -#define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ -#define OP_IdxGE 45 /* jump, synopsis: key=r[P3@P4] */ -#define OP_RowSetRead 46 /* jump, synopsis: r[P3]=rowset(P1) */ -#define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ +#define OP_IdxGE 43 /* jump, synopsis: key=r[P3@P4] */ +#define OP_RowSetRead 44 /* jump, synopsis: r[P3]=rowset(P1) */ +#define OP_RowSetTest 45 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ +#define OP_Or 46 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ +#define OP_And 47 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ #define OP_Program 48 /* jump */ #define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ -#define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ -#define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ -#define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ -#define OP_Eq 53 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ -#define OP_Gt 54 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ -#define OP_Le 55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ -#define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */ -#define OP_ElseEq 58 /* jump, same as TK_ESCAPE */ -#define OP_IfPos 59 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ -#define OP_IfNotZero 60 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ -#define OP_DecrJumpZero 61 /* jump, synopsis: if (--r[P1])==0 goto P2 */ +#define OP_IfPos 50 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ +#define OP_IfNotZero 51 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ +#define OP_DecrJumpZero 52 /* jump, synopsis: if (--r[P1])==0 goto P2 */ +#define OP_IsNull 53 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ +#define OP_NotNull 54 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ +#define OP_Ne 55 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ +#define OP_Eq 56 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ +#define OP_Gt 57 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ +#define OP_Le 58 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ +#define OP_Lt 59 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */ +#define OP_ElseEq 61 /* jump, same as TK_ESCAPE */ #define OP_IncrVacuum 62 /* jump */ #define OP_VNext 63 /* jump */ #define OP_Filter 64 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ @@ -16571,92 +16740,94 @@ typedef struct VdbeOpList VdbeOpList; #define OP_ReadCookie 99 #define OP_SetCookie 100 #define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */ -#define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ -#define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ -#define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ -#define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ -#define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ -#define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ -#define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ -#define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ -#define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ -#define OP_OpenRead 112 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */ -#define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ -#define OP_OpenDup 115 -#define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */ -#define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */ -#define OP_OpenEphemeral 118 /* synopsis: nColumn=P2 */ -#define OP_SorterOpen 119 -#define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ +#define OP_OpenRead 102 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenWrite 103 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenDup 104 +#define OP_BitAnd 105 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ +#define OP_BitOr 106 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ +#define OP_ShiftLeft 107 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ +#define OP_Add 109 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ +#define OP_Subtract 110 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ +#define OP_Multiply 111 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ +#define OP_Divide 112 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ +#define OP_Remainder 113 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ +#define OP_Concat 114 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ +#define OP_OpenAutoindex 115 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 116 /* synopsis: nColumn=P2 */ +#define OP_BitNot 117 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ +#define OP_SorterOpen 118 +#define OP_SequenceTest 119 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ +#define OP_String8 120 /* same as TK_STRING, synopsis: r[P2]='P4' */ #define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */ #define OP_Close 122 #define OP_ColumnsUsed 123 #define OP_SeekScan 124 /* synopsis: Scan-ahead up to P1 rows */ #define OP_SeekHit 125 /* synopsis: set P2<=seekHit<=P3 */ #define OP_Sequence 126 /* synopsis: r[P2]=cursor[P1].ctr++ */ -#define OP_NewRowid 127 /* synopsis: r[P2]=rowid */ -#define OP_Insert 128 /* synopsis: intkey=r[P3] data=r[P2] */ -#define OP_RowCell 129 -#define OP_Delete 130 -#define OP_ResetCount 131 -#define OP_SorterCompare 132 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ -#define OP_SorterData 133 /* synopsis: r[P2]=data */ -#define OP_RowData 134 /* synopsis: r[P2]=data */ -#define OP_Rowid 135 /* synopsis: r[P2]=PX rowid of P1 */ -#define OP_NullRow 136 -#define OP_SeekEnd 137 -#define OP_IdxInsert 138 /* synopsis: key=r[P2] */ -#define OP_SorterInsert 139 /* synopsis: key=r[P2] */ -#define OP_IdxDelete 140 /* synopsis: key=r[P2@P3] */ -#define OP_DeferredSeek 141 /* synopsis: Move P3 to P1.rowid if needed */ -#define OP_IdxRowid 142 /* synopsis: r[P2]=rowid */ -#define OP_FinishSeek 143 -#define OP_Destroy 144 -#define OP_Clear 145 -#define OP_ResetSorter 146 -#define OP_CreateBtree 147 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ -#define OP_SqlExec 148 -#define OP_ParseSchema 149 -#define OP_LoadAnalysis 150 -#define OP_DropTable 151 -#define OP_DropIndex 152 -#define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_DropTrigger 154 -#define OP_IntegrityCk 155 -#define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */ -#define OP_Param 157 -#define OP_FkCounter 158 /* synopsis: fkctr[P1]+=P2 */ -#define OP_MemMax 159 /* synopsis: r[P1]=max(r[P1],r[P2]) */ -#define OP_OffsetLimit 160 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -#define OP_AggInverse 161 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ -#define OP_AggStep 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggStep1 163 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggValue 164 /* synopsis: r[P3]=value N=P2 */ -#define OP_AggFinal 165 /* synopsis: accum=r[P1] N=P2 */ -#define OP_Expire 166 -#define OP_CursorLock 167 -#define OP_CursorUnlock 168 -#define OP_TableLock 169 /* synopsis: iDb=P1 root=P2 write=P3 */ -#define OP_VBegin 170 -#define OP_VCreate 171 -#define OP_VDestroy 172 -#define OP_VOpen 173 -#define OP_VCheck 174 -#define OP_VInitIn 175 /* synopsis: r[P2]=ValueList(P1,P3) */ -#define OP_VColumn 176 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VRename 177 -#define OP_Pagecount 178 -#define OP_MaxPgcnt 179 -#define OP_ClrSubtype 180 /* synopsis: r[P1].subtype = 0 */ -#define OP_FilterAdd 181 /* synopsis: filter(P1) += key(P3@P4) */ -#define OP_Trace 182 -#define OP_CursorHint 183 -#define OP_ReleaseReg 184 /* synopsis: release r[P1@P2] mask P3 */ -#define OP_Noop 185 -#define OP_Explain 186 -#define OP_Abortable 187 +#define OP_CreateWasmFunc 127 /* synopsis: addWasmFunc[P4] */ +#define OP_DropWasmFunc 128 /* synopsis: dropWasmFunc[P4] */ +#define OP_NewRowid 129 /* synopsis: r[P2]=rowid */ +#define OP_Insert 130 /* synopsis: intkey=r[P3] data=r[P2] */ +#define OP_RowCell 131 +#define OP_Delete 132 +#define OP_ResetCount 133 +#define OP_SorterCompare 134 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ +#define OP_SorterData 135 /* synopsis: r[P2]=data */ +#define OP_RowData 136 /* synopsis: r[P2]=data */ +#define OP_Rowid 137 /* synopsis: r[P2]=PX rowid of P1 */ +#define OP_NullRow 138 +#define OP_SeekEnd 139 +#define OP_IdxInsert 140 /* synopsis: key=r[P2] */ +#define OP_SorterInsert 141 /* synopsis: key=r[P2] */ +#define OP_IdxDelete 142 /* synopsis: key=r[P2@P3] */ +#define OP_DeferredSeek 143 /* synopsis: Move P3 to P1.rowid if needed */ +#define OP_IdxRowid 144 /* synopsis: r[P2]=rowid */ +#define OP_FinishSeek 145 +#define OP_Destroy 146 +#define OP_Clear 147 +#define OP_ResetSorter 148 +#define OP_CreateBtree 149 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ +#define OP_SqlExec 150 +#define OP_ParseSchema 151 +#define OP_LoadAnalysis 152 +#define OP_DropTable 153 +#define OP_DropIndex 154 +#define OP_DropTrigger 155 +#define OP_IntegrityCk 156 +#define OP_Real 157 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ +#define OP_RowSetAdd 158 /* synopsis: rowset(P1)=r[P2] */ +#define OP_Param 159 +#define OP_FkCounter 160 /* synopsis: fkctr[P1]+=P2 */ +#define OP_MemMax 161 /* synopsis: r[P1]=max(r[P1],r[P2]) */ +#define OP_OffsetLimit 162 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ +#define OP_AggInverse 163 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ +#define OP_AggStep 164 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggStep1 165 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggValue 166 /* synopsis: r[P3]=value N=P2 */ +#define OP_AggFinal 167 /* synopsis: accum=r[P1] N=P2 */ +#define OP_Expire 168 +#define OP_CursorLock 169 +#define OP_CursorUnlock 170 +#define OP_TableLock 171 /* synopsis: iDb=P1 root=P2 write=P3 */ +#define OP_VBegin 172 +#define OP_VCreate 173 +#define OP_VDestroy 174 +#define OP_VOpen 175 +#define OP_VInitIn 176 /* synopsis: r[P2]=ValueList(P1,P3) */ +#define OP_VPreparedSql 177 +#define OP_VColumn 178 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VRename 179 +#define OP_Pagecount 180 +#define OP_MaxPgcnt 181 +#define OP_ClrSubtype 182 /* synopsis: r[P1].subtype = 0 */ +#define OP_FilterAdd 183 /* synopsis: filter(P1) += key(P3@P4) */ +#define OP_Trace 184 +#define OP_CursorHint 185 +#define OP_ReleaseReg 186 /* synopsis: release r[P1@P2] mask P3 */ +#define OP_Noop 187 +#define OP_Explain 188 +#define OP_Abortable 189 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c @@ -16674,26 +16845,26 @@ 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,\ -/* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\ -/* 48 */ 0x01, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ -/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01, 0x41,\ +/* 32 */ 0x41, 0x01, 0x01, 0x01, 0x41, 0x01, 0x41, 0x41,\ +/* 40 */ 0x41, 0x41, 0x41, 0x41, 0x23, 0x0b, 0x26, 0x26,\ +/* 48 */ 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x0b,\ +/* 56 */ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x01, 0x01, 0x41,\ /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\ /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40, 0x00,\ -/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x26, 0x26,\ -/* 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,\ -/* 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,\ -/* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\ -/* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00,\ -/* 184 */ 0x00, 0x00, 0x00, 0x00,} +/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x40, 0x00,\ +/* 104 */ 0x40, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ +/* 112 */ 0x26, 0x26, 0x26, 0x40, 0x40, 0x12, 0x00, 0x00,\ +/* 120 */ 0x10, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10, 0x00,\ +/* 128 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 136 */ 0x00, 0x50, 0x00, 0x40, 0x04, 0x04, 0x00, 0x40,\ +/* 144 */ 0x50, 0x40, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00,\ +/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x06, 0x10,\ +/* 160 */ 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,\ +/* 176 */ 0x50, 0x00, 0x40, 0x00, 0x10, 0x10, 0x02, 0x00,\ +/* 184 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} /* The resolve3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum @@ -16868,7 +17039,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. ** @@ -16886,7 +17057,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 @@ -16896,7 +17067,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. @@ -16971,38 +17142,52 @@ SQLITE_PRIVATE int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr) #ifndef _PCACHE_H_ -typedef struct PgHdr PgHdr; +/************** Include page_header.h in the middle of pcache.h **************/ +/************** Begin file page_header.h *************************************/ +// SPDX-License-Identifier: MIT + +#ifndef LIBSQL_PAGE_HEADER_H +#define LIBSQL_PAGE_HEADER_H + +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +typedef struct Pager Pager; +typedef struct libsql_pghdr PgHdr; typedef struct PCache PCache; /* ** Every page in the cache is controlled by an instance of the following ** structure. */ -struct PgHdr { +struct libsql_pghdr { sqlite3_pcache_page *pPage; /* Pcache object page handle */ void *pData; /* Page data */ void *pExtra; /* Extra content */ PCache *pCache; /* PRIVATE: Cache that owns this page */ PgHdr *pDirty; /* Transient list of dirty sorted by pgno */ Pager *pPager; /* The pager this page is part of */ - Pgno pgno; /* Page number for this page */ -#ifdef SQLITE_CHECK_PAGES - u32 pageHash; /* Hash of page content */ -#endif - u16 flags; /* PGHDR flags defined below */ + unsigned int pgno; /* Page number for this page */ + unsigned int pageHash; /* Hash of page content */ + unsigned short flags; /* PGHDR flags defined below */ /********************************************************************** ** Elements above, except pCache, are public. All that follow are ** private to pcache.c and should not be accessed by other modules. ** pCache is grouped with the public elements for efficiency. */ - i64 nRef; /* Number of users of this page */ + unsigned long long nRef; /* Number of users of this page */ PgHdr *pDirtyNext; /* Next element in list of dirty pages */ PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ /* NB: pDirtyNext and pDirtyPrev are undefined if the ** PgHdr object is not dirty */ }; +typedef struct libsql_pghdr libsql_pghdr; + +#endif // LIBSQL_PAGE_HEADER_H + +/************** End of page_header.h *****************************************/ +/************** Continuing where we left off in pcache.h *********************/ + /* Bit values for PgHdr.flags */ #define PGHDR_CLEAN 0x001 /* Page not on the PCache.pDirty list */ #define PGHDR_DIRTY 0x002 /* Page is on the PCache.pDirty list */ @@ -17224,6 +17409,10 @@ SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); /************** End of mutex.h ***********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ +#if defined(LIBSQL_ENABLE_WASM_RUNTIME) && !defined(SQLITE_AMALGAMATION) +#include "ext/udf/wasm_bindings.h" +#endif + /* The SQLITE_EXTRA_DURABLE compile-time option used to set the default ** synchronous setting to EXTRA. It is no longer supported. */ @@ -17235,7 +17424,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 @@ -17274,7 +17463,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. ** @@ -17385,7 +17574,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 */ @@ -17402,7 +17591,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 @@ -17479,6 +17668,14 @@ SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); */ #define SQLITE_MAX_DB (SQLITE_MAX_ATTACHED+2) +#ifdef LIBSQL_ENABLE_WASM_RUNTIME +typedef struct libsql_wasm_ctx { + libsql_wasm_engine_t *engine; +} libsql_wasm_ctx; +#endif + +typedef struct libsql_wal_methods libsql_wal_methods; + /* ** Each database connection is an instance of the following structure. */ @@ -17602,7 +17799,6 @@ struct sqlite3 { i64 nDeferredCons; /* Net deferred constraints this transaction. */ i64 nDeferredImmCons; /* Net deferred immediate constraints */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ - DbClientData *pDbData; /* sqlite3_set_clientdata() content */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY /* The following variables are all protected by the STATIC_MAIN ** mutex, not by sqlite3.mutex. They are used by code in notify.c. @@ -17623,6 +17819,15 @@ struct sqlite3 { #ifdef SQLITE_USER_AUTHENTICATION sqlite3_userauth auth; /* User authentication information */ #endif +#ifdef LIBSQL_ENABLE_WASM_RUNTIME + libsql_wasm_ctx wasm; /* WebAssembly runtime context */ +#endif + libsql_wal_methods* pWalMethods; /* Custom WAL methods */ + void* pWalMethodsData; /* optional data for WAL methods */ + void *pCloseArg; /* First argument to xCloseCallback */ + void (*xCloseCallback)( /* Registered using sqlite3_close_hook() */ + void*, sqlite3* + ); }; /* @@ -17685,7 +17890,6 @@ struct sqlite3 { /* 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_FkNoAction HI(0x00008) /* Treat all FK as NO ACTION */ /* Flags used only if debugging */ #ifdef SQLITE_DEBUG @@ -17743,7 +17947,6 @@ struct sqlite3 { #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_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* @@ -17826,7 +18029,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!!! @@ -17834,7 +18036,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. */ @@ -17845,7 +18047,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 */ @@ -17854,15 +18055,14 @@ struct FuncDestructor { #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a ** single query - might change over time */ #define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */ -#define SQLITE_FUNC_RUNONLY 0x8000 /* Cannot be used by valueFromFunction */ +/* 0x8000 -- available for reuse */ #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ -/* SQLITE_SUBTYPE 0x00100000 // Consumer of subtypes */ +#define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */ #define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */ #define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */ #define SQLITE_FUNC_BUILTIN 0x00800000 /* This is a built-in function */ -/* SQLITE_RESULT_SUBTYPE 0x01000000 // Generator of subtypes */ #define SQLITE_FUNC_ANYORDER 0x08000000 /* count/min/max aggregate */ /* Identifier numbers for each in-line function */ @@ -17954,10 +18154,9 @@ struct FuncDestructor { #define MFUNCTION(zName, nArg, xPtr, xFunc) \ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } -#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, iArg, xFunc) \ - {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_FUNC_CONSTANT|\ - SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|\ - ((bRS)*SQLITE_SUBTYPE)|((bWS)*SQLITE_RESULT_SUBTYPE), \ +#define JFUNCTION(zName, nArg, iArg, xFunc) \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|\ + SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_FUNC_BUILTIN|\ @@ -18309,6 +18508,10 @@ struct Table { #define TF_Ephemeral 0x00004000 /* An ephemeral table */ #define TF_Eponymous 0x00008000 /* An eponymous virtual table */ #define TF_Strict 0x00010000 /* STRICT mode */ +/* libSQL extension */ +#define TF_RandomRowid 0x01000000 /* Random rowid */ + +#define LIBSQL_RANDOM_ROWID_MARKER 0xffffffff /* ** Allowed values for Table.eTabType @@ -18427,7 +18630,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. @@ -18703,9 +18906,6 @@ struct AggInfo { FuncDef *pFunc; /* The aggregate function implementation */ int iDistinct; /* Ephemeral table used to enforce DISTINCT */ int iDistAddr; /* Address of OP_OpenEphemeral */ - int iOBTab; /* Ephemeral table to implement ORDER BY */ - u8 bOBPayload; /* iOBTab has payload columns separate from key */ - u8 bOBUnique; /* Enforce uniqueness on iOBTab keys */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ @@ -18844,7 +19044,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. @@ -18890,7 +19090,7 @@ struct Expr { #define EP_Reduced 0x004000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ #define EP_Win 0x008000 /* Contains window functions */ #define EP_TokenOnly 0x010000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ -#define EP_FullSize 0x020000 /* Expr structure must remain full sized */ + /* 0x020000 // Available for reuse */ #define EP_IfNullRow 0x040000 /* The TK_IF_NULL_ROW opcode */ #define EP_Unlikely 0x080000 /* unlikely() or likelihood() function */ #define EP_ConstFunc 0x100000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ @@ -18920,15 +19120,12 @@ struct Expr { #define ExprClearProperty(E,P) (E)->flags&=~(P) #define ExprAlwaysTrue(E) (((E)->flags&(EP_OuterON|EP_IsTrue))==EP_IsTrue) #define ExprAlwaysFalse(E) (((E)->flags&(EP_OuterON|EP_IsFalse))==EP_IsFalse) -#define ExprIsFullSize(E) (((E)->flags&(EP_Reduced|EP_TokenOnly))==0) /* Macros used to ensure that the correct members of unions are accessed ** in 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) @@ -19038,7 +19235,6 @@ struct ExprList { #define ENAME_NAME 0 /* The AS clause of a result set */ #define ENAME_SPAN 1 /* Complete text of the result set expression */ #define ENAME_TAB 2 /* "DB.TABLE.NAME" for the result set */ -#define ENAME_ROWID 3 /* "DB.TABLE._rowid_" for * expansion of rowid */ /* ** An instance of this structure can hold a simple list of identifiers, @@ -19118,7 +19314,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 */ @@ -19647,7 +19843,6 @@ struct Parse { int *aLabel; /* Space to hold the labels */ ExprList *pConstExpr;/* Constant expressions */ IndexedExpr *pIdxEpr;/* List of expressions used by active indexes */ - IndexedExpr *pIdxPartExpr; /* Exprs constrained by index WHERE clauses */ Token constraintName;/* Name of the constraint currently being parsed */ yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ @@ -19655,9 +19850,6 @@ struct Parse { int regRoot; /* Register holding root page number for new objects */ int nMaxArg; /* Max args passed to user function by sub-program */ int nSelect; /* Number of SELECT stmts. Counter for Select.selId */ -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */ -#endif #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ @@ -19671,9 +19863,12 @@ struct Parse { int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ Returning *pReturning; /* The RETURNING clause */ } u1; + u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ u32 oldmask; /* Mask of old.* columns referenced */ u32 newmask; /* Mask of new.* columns referenced */ - LogEst nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */ +#endif u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ u8 bReturning; /* Coding a RETURNING trigger */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ @@ -19797,7 +19992,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 */ @@ -19919,7 +20113,6 @@ struct Returning { int iRetCur; /* Transient table holding RETURNING results */ int nRetCol; /* Number of in pReturnEL after expansion */ int iRetReg; /* Register array for holding a row of RETURNING */ - char zName[40]; /* Name of trigger: "sqlite_returning_%p" */ }; /* @@ -19941,25 +20134,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 @@ -19986,7 +20160,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. ** @@ -20012,7 +20186,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 */ @@ -20099,7 +20272,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 */ @@ -20139,7 +20311,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*); @@ -20220,16 +20391,6 @@ struct CteUse { }; -/* Client data associated with sqlite3_set_clientdata() and -** sqlite3_get_clientdata(). -*/ -struct DbClientData { - DbClientData *pNext; /* Next in a linked list */ - void *pData; /* The data */ - void (*xDestructor)(void*); /* Destructor. Might be NULL */ - char zName[1]; /* Name of this client data. MUST BE LAST */ -}; - #ifdef SQLITE_DEBUG /* ** An instance of the TreeView object is used for printing the content of @@ -20531,20 +20692,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) @@ -20634,8 +20781,6 @@ SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*); SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*); SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr*); SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, const Token*, int); -SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy(Parse*,Expr*,ExprList*); -SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse*,Expr*); SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); @@ -20695,8 +20840,8 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); SQLITE_PRIVATE void sqlite3AddGenerated(Parse*,Expr*,Token*); SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u32,Select*); SQLITE_PRIVATE void sqlite3AddReturning(Parse*,ExprList*); -SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, - sqlite3_vfs**,char**,char **); +SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,const char*,unsigned int*, + sqlite3_vfs**,libsql_wal_methods**,char**,char **); #define sqlite3CodecQueryParameters(A,B,C) 0 SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*); @@ -20837,7 +20982,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*); @@ -20872,7 +21017,6 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*); SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); SQLITE_PRIVATE int sqlite3IsRowid(const char*); -SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab); SQLITE_PRIVATE void sqlite3GenerateRowDelete( Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); @@ -20987,7 +21131,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*); @@ -21092,7 +21235,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*)); @@ -21132,6 +21274,7 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*); SQLITE_PRIVATE void sqlite3AlterFunctions(void); SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); +void libsqlAlterAlterColumn(Parse*, SrcList*, Token*, Token*); SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *); SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int); @@ -21144,8 +21287,7 @@ SQLITE_PRIVATE int sqlite3MatchEName( const struct ExprList_item*, const char*, const char*, - const char*, - int* + const char* ); SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr*); SQLITE_PRIVATE u8 sqlite3StrIHash(const char*); @@ -21201,11 +21343,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(void*); -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*); @@ -21457,7 +21594,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); @@ -21743,6 +21879,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC "4_BYTE_ALIGNED_MALLOC", #endif +#ifdef SQLITE_64BIT_STATS + "64BIT_STATS", +#endif #ifdef SQLITE_ALLOW_COVERING_INDEX_SCAN # if SQLITE_ALLOW_COVERING_INDEX_SCAN != 1 "ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN), @@ -22038,9 +22177,6 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS "EXPLAIN_ESTIMATED_ROWS", #endif -#ifdef SQLITE_EXTRA_AUTOEXT - "EXTRA_AUTOEXT=" CTIMEOPT_VAL(SQLITE_EXTRA_AUTOEXT), -#endif #ifdef SQLITE_EXTRA_IFNULLROW "EXTRA_IFNULLROW", #endif @@ -22082,9 +22218,6 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_INTEGRITY_CHECK_ERROR_MAX "INTEGRITY_CHECK_ERROR_MAX=" CTIMEOPT_VAL(SQLITE_INTEGRITY_CHECK_ERROR_MAX), #endif -#ifdef SQLITE_LEGACY_JSON_VALID - "LEGACY_JSON_VALID", -#endif #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS "LIKE_DOESNT_MATCH_BLOBS", #endif @@ -22322,9 +22455,6 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS "OMIT_SCHEMA_VERSION_PRAGMAS", #endif -#ifdef SQLITE_OMIT_SEH - "OMIT_SEH", -#endif #ifdef SQLITE_OMIT_SHARED_CACHE "OMIT_SHARED_CACHE", #endif @@ -22722,7 +22852,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 */ @@ -22952,9 +23081,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 @@ -22986,7 +23112,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 */ @@ -23027,7 +23152,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 @@ -23040,25 +23164,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 */ - u32 cacheStatus; /* Vdbe.cacheCtr value */ - u32 colCacheCtr; /* Column cache counter */ -}; - /* ** 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 @@ -23379,21 +23490,20 @@ 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() */ + u32 aLibsqlCounter[3]; /* libSQL extension: Counters used by sqlite3_stmt_status()*/ char *zSql; /* Text of the SQL statement that generated this */ #ifdef SQLITE_ENABLE_NORMALIZE char *zNormSql; /* Normalization of the associated SQL statement */ @@ -23437,7 +23547,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 */ }; @@ -23527,7 +23637,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); @@ -24124,8 +24233,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; @@ -24466,14 +24575,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; } @@ -24652,25 +24764,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: @@ -24714,8 +24807,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; } @@ -24881,73 +24985,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++; @@ -24957,7 +25006,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; @@ -24973,7 +25022,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; @@ -25140,7 +25190,7 @@ static void datetimeFunc( zBuf[16] = '0' + (x.m)%10; zBuf[17] = ':'; if( x.useSubsec ){ - s = (int)(1000.0*x.s + 0.5); + s = (int)1000.0*x.s; zBuf[18] = '0' + (s/10000)%10; zBuf[19] = '0' + (s/1000)%10; zBuf[20] = '.'; @@ -25187,7 +25237,7 @@ static void timeFunc( zBuf[4] = '0' + (x.m)%10; zBuf[5] = ':'; if( x.useSubsec ){ - s = (int)(1000.0*x.s + 0.5); + s = (int)1000.0*x.s; zBuf[6] = '0' + (s/10000)%10; zBuf[7] = '0' + (s/1000)%10; zBuf[8] = '.'; @@ -25258,7 +25308,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 ** %% % @@ -25284,16 +25334,13 @@ static void strftimeFunc( computeJD(&x); computeYMD_HMS(&x); for(i=j=0; zFmt[i]; i++){ - char cf; if( zFmt[i]!='%' ) continue; if( j12 ) h -= 12; - if( h==0 ) h = 12; - sqlite3_str_appendf(&sRes, cf=='I' ? "%02d" : "%2d", h); + case 'H': { + sqlite3_str_appendf(&sRes, "%02d", x.h); break; } case 'W': /* Fall thru */ @@ -25328,7 +25362,7 @@ static void strftimeFunc( y.D = 1; computeJD(&y); nDay = (int)((x.iJD-y.iJD+43200000)/86400000); - if( cf=='W' ){ + if( zFmt[i]=='W' ){ int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ wd = (int)(((x.iJD+43200000)/86400000)%7); sqlite3_str_appendf(&sRes,"%02d",(nDay+7-wd)/7); @@ -25349,19 +25383,6 @@ static void strftimeFunc( sqlite3_str_appendf(&sRes,"%02d",x.m); break; } - case 'p': /* Fall thru */ - case 'P': { - if( x.h>=12 ){ - sqlite3_str_append(&sRes, cf=='p' ? "PM" : "pm", 2); - }else{ - sqlite3_str_append(&sRes, cf=='p' ? "AM" : "am", 2); - } - break; - } - case 'R': { - sqlite3_str_appendf(&sRes, "%02d:%02d", x.h, x.m); - break; - } case 's': { if( x.useSubsec ){ sqlite3_str_appendf(&sRes,"%.3f", @@ -25376,15 +25397,9 @@ static void strftimeFunc( sqlite3_str_appendf(&sRes,"%02d",(int)x.s); break; } - case 'T': { - sqlite3_str_appendf(&sRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s); - break; - } - case 'u': /* Fall thru */ case 'w': { - char c = (char)(((x.iJD+129600000)/86400000) % 7) + '0'; - if( c=='0' && cf=='u' ) c = '7'; - sqlite3_str_appendchar(&sRes, 1, c); + sqlite3_str_appendchar(&sRes, 1, + (char)(((x.iJD+129600000)/86400000) % 7) + '0'); break; } case 'Y': { @@ -25433,117 +25448,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() ** @@ -25618,7 +25522,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 ), @@ -25772,7 +25675,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(), @@ -26393,7 +26296,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){ @@ -26481,7 +26384,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 */ @@ -28473,7 +28376,7 @@ static void checkMutexFree(sqlite3_mutex *p){ assert( SQLITE_MUTEX_FAST<2 ); assert( SQLITE_MUTEX_WARNONCONTENTION<2 ); -#ifdef SQLITE_ENABLE_API_ARMOR +#if SQLITE_ENABLE_API_ARMOR if( ((CheckMutex*)p)->iType<2 ) #endif { @@ -28948,7 +28851,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) @@ -29145,7 +29048,7 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){ */ static void pthreadMutexFree(sqlite3_mutex *p){ assert( p->nRef==0 ); -#ifdef SQLITE_ENABLE_API_ARMOR +#if SQLITE_ENABLE_API_ARMOR if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ) #endif { @@ -29449,7 +29352,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 @@ -29498,7 +29401,7 @@ SQLITE_PRIVATE void sqlite3MemoryBarrier(void){ SQLITE_MEMORY_BARRIER; #elif defined(__GNUC__) __sync_synchronize(); -#elif MSVC_VERSION>=1400 +#elif MSVC_VERSION>=1300 _ReadWriteBarrier(); #elif defined(MemoryBarrier) MemoryBarrier(); @@ -30709,7 +30612,7 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ if( db->mallocFailed || rc ){ return apiHandleError(db, rc); } - return 0; + return rc & db->errMask; } /************** End of malloc.c **********************************************/ @@ -30821,6 +30724,57 @@ 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 */ + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** "*val" is a u64. *msd is a divisor used to extract the +** most significant digit of *val. Extract that most significant +** digit and return it. +*/ +static char et_getdigit_int(u64 *val, u64 *msd){ + u64 x = (*val)/(*msd); + *val -= x*(*msd); + if( *msd>=10 ) *msd /= 10; + return '0' + (char)(x & 15); +} +#endif /* SQLITE_OMIT_FLOATING_POINT */ + /* ** Set the StrAccum object to an error mode. */ @@ -30912,15 +30866,20 @@ 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 */ + sqlite_uint64 msd; /* Divisor to get most-significant-digit + ** of longvalue */ 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 */ @@ -31195,61 +31154,94 @@ 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); - bufpt = buf; - if( s.sign=='-' ){ - /* no-op */ - }else if( flag_prefix ){ - buf[0] = flag_prefix; + exp = 0; + if( xtype==etGENERIC && precision>0 ) precision--; + testcase( precision>0xfff ); + if( realvalue<1.0e+16 + && realvalue==(LONGDOUBLE_TYPE)(longvalue = (u64)realvalue) + ){ + /* Number is a pure integer that can be represented as u64 */ + for(msd=1; msd*10<=longvalue; msd *= 10, exp++){} + if( exp>precision && xtype!=etFLOAT ){ + u64 rnd = msd/2; + int kk = precision; + while( kk-- > 0 ){ rnd /= 10; } + longvalue += rnd; + } + }else{ + msd = 0; + longvalue = 0; /* To prevent a compiler warning */ + 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; + } + if( sqlite3IsNaN((double)realvalue) ){ + if( flag_zeropad ){ + bufpt = "null"; + length = 4; }else{ - bufpt++; + bufpt = "NaN"; + length = 3; } - length = sqlite3Strlen30(bufpt); break; } - } - if( s.sign=='-' ){ - prefix = '-'; - }else{ - prefix = flag_prefix; - } - exp = s.iDP-1; - if( xtype==etGENERIC && precision>0 ) precision--; + /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ + if( ALWAYS(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 ){ + if( flag_zeropad ){ + realvalue = 9.0; + exp = 999; + }else{ + bufpt = buf; + buf[0] = prefix; + memcpy(buf+(prefix!=0),"Inf",4); + length = 3+(prefix!=0); + break; + } + } + if( xtype!=etFLOAT ){ + realvalue += rounder; + if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } + } + } + } /* ** If the field type is etGENERIC, then convert to either etEXP @@ -31269,8 +31261,9 @@ SQLITE_API void sqlite3_str_vappendf( if( xtype==etEXP ){ e2 = 0; }else{ - e2 = s.iDP - 1; + e2 = exp; } + nsd = 16 + flag_altform2*10; bufpt = buf; { i64 szBufNeeded; /* Size of a temporary buffer needed */ @@ -31288,12 +31281,16 @@ SQLITE_API void sqlite3_str_vappendf( *(bufpt++) = prefix; } /* Digits prior to the decimal point */ - j = 0; if( e2<0 ){ *(bufpt++) = '0'; + }else if( msd>0 ){ + for(; e2>=0; e2--){ + *(bufpt++) = et_getdigit_int(&longvalue,&msd); + if( cThousand && (e2%3)==0 && e2>1 ) *(bufpt++) = ','; + } }else{ for(; e2>=0; e2--){ - *(bufpt++) = j1 ) *(bufpt++) = ','; } } @@ -31303,12 +31300,19 @@ 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++) = j0 ){ + while( (precision--)>0 ){ + *(bufpt++) = et_getdigit_int(&longvalue,&msd); + } + }else{ + while( (precision--)>0 ){ + *(bufpt++) = et_getdigit(&realvalue,&nsd); + } } /* Remove trailing zeros and the "." if no digits follow the "." */ if( flag_rtz && flag_dp ){ @@ -31324,7 +31328,6 @@ SQLITE_API void sqlite3_str_vappendf( } /* Add the "eNNN" suffix */ if( xtype==etEXP ){ - exp = s.iDP - 1; *(bufpt++) = aDigits[infop->charset]; if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; @@ -31358,8 +31361,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; @@ -32083,75 +32086,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(void *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 ****************************************/ /* @@ -32568,7 +32502,6 @@ SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u sqlite3TreeViewItem(pView, "FILTER", 1); sqlite3TreeViewExpr(pView, pWin->pFilter, 0); sqlite3TreeViewPop(&pView); - if( pWin->eFrmType==TK_FILTER ) return; } sqlite3TreeViewPush(&pView, more); if( pWin->zName ){ @@ -32578,7 +32511,7 @@ SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u } if( pWin->zBase ) nElement++; if( pWin->pOrderBy ) nElement++; - if( pWin->eFrmType!=0 && pWin->eFrmType!=TK_FILTER ) nElement++; + if( pWin->eFrmType ) nElement++; if( pWin->eExclude ) nElement++; if( pWin->zBase ){ sqlite3TreeViewPush(&pView, (--nElement)>0); @@ -32591,7 +32524,7 @@ SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u if( pWin->pOrderBy ){ sqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY"); } - if( pWin->eFrmType!=0 && pWin->eFrmType!=TK_FILTER ){ + if( pWin->eFrmType ){ char zBuf[30]; const char *zFrmType = "ROWS"; if( pWin->eFrmType==TK_RANGE ) zFrmType = "RANGE"; @@ -32839,7 +32772,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m assert( ExprUseXList(pExpr) ); pFarg = pExpr->x.pList; #ifndef SQLITE_OMIT_WINDOWFUNC - pWin = IsWindowFunc(pExpr) ? pExpr->y.pWin : 0; + pWin = ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0; #else pWin = 0; #endif @@ -32865,13 +32798,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs); } if( pFarg ){ - sqlite3TreeViewExprList(pView, pFarg, pWin!=0 || pExpr->pLeft, 0); - if( pExpr->pLeft ){ - Expr *pOB = pExpr->pLeft; - assert( pOB->op==TK_ORDER ); - assert( ExprUseXList(pOB) ); - sqlite3TreeViewExprList(pView, pOB->x.pList, pWin!=0, "ORDERBY"); - } + sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0); } #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ @@ -32880,10 +32807,6 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m #endif break; } - case TK_ORDER: { - sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, "ORDERBY"); - break; - } #ifndef SQLITE_OMIT_SUBQUERY case TK_EXISTS: { assert( ExprUseXSelect(pExpr) ); @@ -34470,7 +34393,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. @@ -34587,23 +34510,6 @@ SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3 *db){ */ SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ if( rc==SQLITE_IOERR_NOMEM ) return; -#ifdef SQLITE_USE_SEH - if( rc==SQLITE_IOERR_IN_PAGE ){ - int ii; - int iErr; - sqlite3BtreeEnterAll(db); - for(ii=0; iinDb; ii++){ - if( db->aDb[ii].pBt ){ - iErr = sqlite3PagerWalSystemErrno(sqlite3BtreePager(db->aDb[ii].pBt)); - if( iErr ){ - db->iSysErrno = iErr; - } - } - } - sqlite3BtreeLeaveAll(db); - return; - } -#endif rc &= 0xff; if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){ db->iSysErrno = sqlite3OsGetLastError(db->pVfs); @@ -34648,16 +34554,12 @@ SQLITE_PRIVATE void sqlite3ProgressCheck(Parse *p){ p->rc = SQLITE_INTERRUPT; } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK - if( db->xProgress ){ - if( p->rc==SQLITE_INTERRUPT ){ - p->nProgressSteps = 0; - }else if( (++p->nProgressSteps)>=db->nProgressOps ){ - if( db->xProgress(db->pProgressArg) ){ - p->nErr++; - p->rc = SQLITE_INTERRUPT; - } - p->nProgressSteps = 0; + if( db->xProgress && (++p->nProgressSteps)>=db->nProgressOps ){ + if( db->xProgress(db->pProgressArg) ){ + p->nErr++; + p->rc = SQLITE_INTERRUPT; } + p->nProgressSteps = 0; } #endif } @@ -34853,40 +34755,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 } /* @@ -34927,11 +34832,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 */ @@ -34971,7 +34877,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; } + 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--; } - assert( r>=0.0 ); - if( r>+1.7976931348623157081452742373e+308L ){ + + /* adjust the sign of significand */ + s = sign<0 ? -s : s; + + if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/ + result = (double)s; + }else{ + /* 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 - *pResult = +INFINITY; + result = INFINITY*s; #else - *pResult = 1.0e308*10.0; + result = 1e308*1e308*s; /* Infinity */ #endif - }else{ - *pResult = (double)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); - } - }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); + } + } + }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 ){ @@ -35244,7 +35140,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; @@ -35322,9 +35218,7 @@ SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ }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); } } @@ -35403,153 +35297,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_exp(decimal_sub('1.0e+100',decimal(1.0e+100))); - */ - double rr[2]; - rr[0] = r; - rr[1] = 0.0; - if( rr[0]>9.223372036854774784e+18 ){ - while( rr[0]>9.223372036854774784e+118 ){ - exp += 100; - dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); - } - while( rr[0]>9.223372036854774784e+28 ){ - exp += 10; - dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); - } - while( rr[0]>9.223372036854774784e+18 ){ - exp += 1; - dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); - } - }else{ - while( rr[0]<9.223372036854774784e-83 ){ - exp -= 100; - dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); - } - while( rr[0]<9.223372036854774784e+07 ){ - exp -= 10; - dekkerMul2(rr, 1.0e+10, 0.0); - } - while( rr[0]<9.22337203685477478e+17 ){ - exp -= 1; - dekkerMul2(rr, 1.0e+01, 0.0); - } - } - v = 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. @@ -35813,32 +35560,121 @@ SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ ** this function assumes the single-byte case has already been handled. */ SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){ - u64 v64; - u8 n; + u32 a,b; - /* Assume that the single-byte case has already been handled by - ** the getVarint32() macro */ - assert( (p[0] & 0x80)!=0 ); + /* The 1-byte case. Overwhelmingly the most common. Handled inline + ** by the getVarin32() macro */ + a = *p; + /* a: p0 (unmasked) */ +#ifndef getVarint32 + if (!(a&0x80)) + { + /* Values between 0 and 127 */ + *v = a; + return 1; + } +#endif - if( (p[1] & 0x80)==0 ){ - /* This is the two-byte case */ - *v = ((p[0]&0x7f)<<7) | p[1]; + /* The 2-byte case */ + p++; + b = *p; + /* b: p1 (unmasked) */ + if (!(b&0x80)) + { + /* Values between 128 and 16383 */ + a &= 0x7f; + a = a<<7; + *v = a | b; return 2; } - if( (p[2] & 0x80)==0 ){ - /* This is the three-byte case */ - *v = ((p[0]&0x7f)<<14) | ((p[1]&0x7f)<<7) | p[2]; + + /* The 3-byte case */ + p++; + a = a<<14; + a |= *p; + /* a: p0<<14 | p2 (unmasked) */ + if (!(a&0x80)) + { + /* Values between 16384 and 2097151 */ + a &= (0x7f<<14)|(0x7f); + b &= 0x7f; + b = b<<7; + *v = a | b; return 3; } - /* four or more bytes */ - n = sqlite3GetVarint(p, &v64); - assert( n>3 && n<=9 ); - if( (v64 & SQLITE_MAX_U32)!=v64 ){ - *v = 0xffffffff; - }else{ + + /* A 32-bit varint is used to store size information in btrees. + ** Objects are rarely larger than 2MiB limit of a 3-byte varint. + ** A 3-byte varint is sufficient, for example, to record the size + ** of a 1048569-byte BLOB or string. + ** + ** We only unroll the first 1-, 2-, and 3- byte cases. The very + ** rare larger cases can be handled by the slower 64-bit varint + ** routine. + */ +#if 1 + { + u64 v64; + u8 n; + + n = sqlite3GetVarint(p-2, &v64); + assert( n>3 && n<=9 ); + if( (v64 & SQLITE_MAX_U32)!=v64 ){ + *v = 0xffffffff; + }else{ + *v = (u32)v64; + } + return n; + } + +#else + /* For following code (kept for historical record only) shows an + ** unrolling for the 3- and 4-byte varint cases. This code is + ** slightly faster, but it is also larger and much harder to test. + */ + p++; + b = b<<14; + b |= *p; + /* b: p1<<14 | p3 (unmasked) */ + if (!(b&0x80)) + { + /* Values between 2097152 and 268435455 */ + b &= (0x7f<<14)|(0x7f); + a &= (0x7f<<14)|(0x7f); + a = a<<7; + *v = a | b; + return 4; + } + + p++; + a = a<<14; + a |= *p; + /* a: p0<<28 | p2<<14 | p4 (unmasked) */ + if (!(a&0x80)) + { + /* Values between 268435456 and 34359738367 */ + a &= SLOT_4_2_0; + b &= SLOT_4_2_0; + b = b<<7; + *v = a | b; + return 5; + } + + /* We can only reach this point when reading a corrupt database + ** file. In that case we are not in any hurry. Use the (relatively + ** slow) general-purpose sqlite3GetVarint() routine to extract the + ** value. */ + { + u64 v64; + u8 n; + + p -= 4; + n = sqlite3GetVarint(p, &v64); + assert( n>5 && n<=9 ); *v = (u32)v64; + return n; } - return n; +#endif } /* @@ -35989,7 +35825,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 +36138,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 +36310,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. @@ -36703,25 +36539,25 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 40 */ "IdxLE" OpHelp("key=r[P3@P4]"), /* 41 */ "IdxGT" OpHelp("key=r[P3@P4]"), /* 42 */ "IdxLT" OpHelp("key=r[P3@P4]"), - /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), - /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), - /* 45 */ "IdxGE" OpHelp("key=r[P3@P4]"), - /* 46 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), - /* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), + /* 43 */ "IdxGE" OpHelp("key=r[P3@P4]"), + /* 44 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), + /* 45 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), + /* 46 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), + /* 47 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), /* 48 */ "Program" OpHelp(""), /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), - /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), - /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), - /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), - /* 53 */ "Eq" OpHelp("IF r[P3]==r[P1]"), - /* 54 */ "Gt" OpHelp("IF r[P3]>r[P1]"), - /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"), - /* 56 */ "Lt" OpHelp("IF r[P3]=r[P1]"), - /* 58 */ "ElseEq" OpHelp(""), - /* 59 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), - /* 60 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), - /* 61 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), + /* 50 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), + /* 51 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), + /* 52 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), + /* 53 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), + /* 54 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), + /* 55 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), + /* 56 */ "Eq" OpHelp("IF r[P3]==r[P1]"), + /* 57 */ "Gt" OpHelp("IF r[P3]>r[P1]"), + /* 58 */ "Le" OpHelp("IF r[P3]<=r[P1]"), + /* 59 */ "Lt" OpHelp("IF r[P3]=r[P1]"), + /* 61 */ "ElseEq" OpHelp(""), /* 62 */ "IncrVacuum" OpHelp(""), /* 63 */ "VNext" OpHelp(""), /* 64 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), @@ -36762,92 +36598,94 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 99 */ "ReadCookie" OpHelp(""), /* 100 */ "SetCookie" OpHelp(""), /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), - /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), - /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), - /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), - /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), - /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), - /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), - /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), - /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), - /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), - /* 112 */ "OpenRead" OpHelp("root=P2 iDb=P3"), - /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), - /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), - /* 115 */ "OpenDup" OpHelp(""), - /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"), - /* 117 */ "String8" OpHelp("r[P2]='P4'"), - /* 118 */ "OpenEphemeral" OpHelp("nColumn=P2"), - /* 119 */ "SorterOpen" OpHelp(""), - /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), + /* 102 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 103 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 104 */ "OpenDup" OpHelp(""), + /* 105 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), + /* 106 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), + /* 107 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), + /* 109 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), + /* 110 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), + /* 111 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), + /* 112 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), + /* 113 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), + /* 114 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), + /* 115 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 116 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 117 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), + /* 118 */ "SorterOpen" OpHelp(""), + /* 119 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), + /* 120 */ "String8" OpHelp("r[P2]='P4'"), /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), /* 122 */ "Close" OpHelp(""), /* 123 */ "ColumnsUsed" OpHelp(""), /* 124 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), /* 125 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), /* 126 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), - /* 127 */ "NewRowid" OpHelp("r[P2]=rowid"), - /* 128 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), - /* 129 */ "RowCell" OpHelp(""), - /* 130 */ "Delete" OpHelp(""), - /* 131 */ "ResetCount" OpHelp(""), - /* 132 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), - /* 133 */ "SorterData" OpHelp("r[P2]=data"), - /* 134 */ "RowData" OpHelp("r[P2]=data"), - /* 135 */ "Rowid" OpHelp("r[P2]=PX rowid of P1"), - /* 136 */ "NullRow" OpHelp(""), - /* 137 */ "SeekEnd" OpHelp(""), - /* 138 */ "IdxInsert" OpHelp("key=r[P2]"), - /* 139 */ "SorterInsert" OpHelp("key=r[P2]"), - /* 140 */ "IdxDelete" OpHelp("key=r[P2@P3]"), - /* 141 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), - /* 142 */ "IdxRowid" OpHelp("r[P2]=rowid"), - /* 143 */ "FinishSeek" OpHelp(""), - /* 144 */ "Destroy" OpHelp(""), - /* 145 */ "Clear" OpHelp(""), - /* 146 */ "ResetSorter" OpHelp(""), - /* 147 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), - /* 148 */ "SqlExec" OpHelp(""), - /* 149 */ "ParseSchema" OpHelp(""), - /* 150 */ "LoadAnalysis" OpHelp(""), - /* 151 */ "DropTable" OpHelp(""), - /* 152 */ "DropIndex" OpHelp(""), - /* 153 */ "Real" OpHelp("r[P2]=P4"), - /* 154 */ "DropTrigger" OpHelp(""), - /* 155 */ "IntegrityCk" OpHelp(""), - /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), - /* 157 */ "Param" OpHelp(""), - /* 158 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), - /* 159 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), - /* 160 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), - /* 161 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), - /* 162 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 163 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 164 */ "AggValue" OpHelp("r[P3]=value N=P2"), - /* 165 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 166 */ "Expire" OpHelp(""), - /* 167 */ "CursorLock" OpHelp(""), - /* 168 */ "CursorUnlock" OpHelp(""), - /* 169 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), - /* 170 */ "VBegin" OpHelp(""), - /* 171 */ "VCreate" OpHelp(""), - /* 172 */ "VDestroy" OpHelp(""), - /* 173 */ "VOpen" OpHelp(""), - /* 174 */ "VCheck" OpHelp(""), - /* 175 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), - /* 176 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 177 */ "VRename" OpHelp(""), - /* 178 */ "Pagecount" OpHelp(""), - /* 179 */ "MaxPgcnt" OpHelp(""), - /* 180 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), - /* 181 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), - /* 182 */ "Trace" OpHelp(""), - /* 183 */ "CursorHint" OpHelp(""), - /* 184 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), - /* 185 */ "Noop" OpHelp(""), - /* 186 */ "Explain" OpHelp(""), - /* 187 */ "Abortable" OpHelp(""), + /* 127 */ "CreateWasmFunc" OpHelp("addWasmFunc[P4]"), + /* 128 */ "DropWasmFunc" OpHelp("dropWasmFunc[P4]"), + /* 129 */ "NewRowid" OpHelp("r[P2]=rowid"), + /* 130 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), + /* 131 */ "RowCell" OpHelp(""), + /* 132 */ "Delete" OpHelp(""), + /* 133 */ "ResetCount" OpHelp(""), + /* 134 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), + /* 135 */ "SorterData" OpHelp("r[P2]=data"), + /* 136 */ "RowData" OpHelp("r[P2]=data"), + /* 137 */ "Rowid" OpHelp("r[P2]=PX rowid of P1"), + /* 138 */ "NullRow" OpHelp(""), + /* 139 */ "SeekEnd" OpHelp(""), + /* 140 */ "IdxInsert" OpHelp("key=r[P2]"), + /* 141 */ "SorterInsert" OpHelp("key=r[P2]"), + /* 142 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 143 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), + /* 144 */ "IdxRowid" OpHelp("r[P2]=rowid"), + /* 145 */ "FinishSeek" OpHelp(""), + /* 146 */ "Destroy" OpHelp(""), + /* 147 */ "Clear" OpHelp(""), + /* 148 */ "ResetSorter" OpHelp(""), + /* 149 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), + /* 150 */ "SqlExec" OpHelp(""), + /* 151 */ "ParseSchema" OpHelp(""), + /* 152 */ "LoadAnalysis" OpHelp(""), + /* 153 */ "DropTable" OpHelp(""), + /* 154 */ "DropIndex" OpHelp(""), + /* 155 */ "DropTrigger" OpHelp(""), + /* 156 */ "IntegrityCk" OpHelp(""), + /* 157 */ "Real" OpHelp("r[P2]=P4"), + /* 158 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), + /* 159 */ "Param" OpHelp(""), + /* 160 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 161 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), + /* 162 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), + /* 163 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), + /* 164 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 165 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 166 */ "AggValue" OpHelp("r[P3]=value N=P2"), + /* 167 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 168 */ "Expire" OpHelp(""), + /* 169 */ "CursorLock" OpHelp(""), + /* 170 */ "CursorUnlock" OpHelp(""), + /* 171 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 172 */ "VBegin" OpHelp(""), + /* 173 */ "VCreate" OpHelp(""), + /* 174 */ "VDestroy" OpHelp(""), + /* 175 */ "VOpen" OpHelp(""), + /* 176 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), + /* 177 */ "VPreparedSql" OpHelp(""), + /* 178 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 179 */ "VRename" OpHelp(""), + /* 180 */ "Pagecount" OpHelp(""), + /* 181 */ "MaxPgcnt" OpHelp(""), + /* 182 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), + /* 183 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), + /* 184 */ "Trace" OpHelp(""), + /* 185 */ "CursorHint" OpHelp(""), + /* 186 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), + /* 187 */ "Noop" OpHelp(""), + /* 188 */ "Explain" OpHelp(""), + /* 189 */ "Abortable" OpHelp(""), }; return azName[i]; } @@ -37861,7 +37699,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: ** @@ -38448,7 +38286,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. */ @@ -38970,7 +38808,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. @@ -38984,7 +38822,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 @@ -39186,7 +39024,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; @@ -39549,7 +39387,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. ** @@ -39557,7 +39395,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 @@ -39578,7 +39416,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. */ @@ -39606,7 +39444,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 ); @@ -40824,7 +40662,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 ); @@ -40940,7 +40778,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, @@ -40989,6 +40827,9 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { unixInodeInfo *pInode; afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; int skipShared = 0; +#ifdef SQLITE_TEST + int h = pFile->h; +#endif assert( pFile ); OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock, @@ -41004,6 +40845,9 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){ assert( pInode->eFileLock==pFile->eFileLock ); + SimulateIOErrorBenign(1); + SimulateIOError( h=(-1) ) + SimulateIOErrorBenign(0); #ifdef SQLITE_DEBUG /* When reducing a lock such that other processes can start @@ -41052,6 +40896,9 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { unsigned long long sharedLockByte = SHARED_FIRST+pInode->sharedByte; pInode->nShared--; if( pInode->nShared==0 ){ + SimulateIOErrorBenign(1); + SimulateIOError( h=(-1) ) + SimulateIOErrorBenign(0); if( !skipShared ){ rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0); } @@ -41226,7 +41073,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 ){ @@ -41378,7 +41225,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 ){ @@ -41500,7 +41347,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 { @@ -44545,17 +44392,12 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ ** than the argument. */ static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ -#if !defined(HAVE_NANOSLEEP) || HAVE_NANOSLEEP+0 +#if OS_VXWORKS || _POSIX_C_SOURCE >= 199309L struct timespec sp; + sp.tv_sec = microseconds / 1000000; sp.tv_nsec = (microseconds % 1000000) * 1000; - - /* Almost all modern unix systems support nanosleep(). But if you are - ** compiling for one of the rare exceptions, you can use - ** -DHAVE_NANOSLEEP=0 (perhaps in conjuction with -DHAVE_USLEEP if - ** usleep() is available) in order to bypass the use of nanosleep() */ nanosleep(&sp, NULL); - UNUSED_PARAMETER(NotUsed); return microseconds; #elif defined(HAVE_USLEEP) && HAVE_USLEEP @@ -47145,7 +46987,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. */ @@ -48725,7 +48567,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 ){ @@ -48803,7 +48645,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 ){ @@ -48913,7 +48755,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; @@ -48972,7 +48814,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; @@ -49329,7 +49171,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 ){ @@ -50733,7 +50575,6 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; size_t i, j; - DWORD pid; int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX); int nMax, nBuf, nDir, nLen; char *zBuf; @@ -50946,10 +50787,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ j = sqlite3Strlen30(zBuf); sqlite3_randomness(15, &zBuf[j]); - pid = osGetCurrentProcessId(); for(i=0; i<15; i++, j++){ - zBuf[j] += pid & 0xff; - pid >>= 8; zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; @@ -53215,7 +53053,7 @@ SQLITE_PRIVATE int sqlite3MemdbInit(void){ ** values between 1 and iDivisor. apSub[1] holds values between ** iDivisor+1 and 2*iDivisor. apSub[N] holds values between ** N*iDivisor+1 and (N+1)*iDivisor. Each subbitmap is normalized -** to hold deal with values between 1 and iDivisor. +** to deal with values between 1 and iDivisor. */ struct Bitvec { u32 iSize; /* Maximum bit index. Max iSize is 4,294,967,296. */ @@ -53314,7 +53152,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; @@ -53647,7 +53485,7 @@ struct PCache { ** Return 1 if pPg is on the dirty list for pCache. Return 0 if not. ** This routine runs inside of assert() statements only. */ -#if defined(SQLITE_ENABLE_EXPENSIVE_ASSERT) +#ifdef SQLITE_DEBUG static int pageOnDirtyList(PCache *pCache, PgHdr *pPg){ PgHdr *p; for(p=pCache->pDirty; p; p=p->pDirtyNext){ @@ -53655,16 +53493,6 @@ static int pageOnDirtyList(PCache *pCache, PgHdr *pPg){ } return 0; } -static int pageNotOnDirtyList(PCache *pCache, PgHdr *pPg){ - PgHdr *p; - for(p=pCache->pDirty; p; p=p->pDirtyNext){ - if( p==pPg ) return 0; - } - return 1; -} -#else -# define pageOnDirtyList(A,B) 1 -# define pageNotOnDirtyList(A,B) 1 #endif /* @@ -53685,7 +53513,7 @@ SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){ assert( pCache!=0 ); /* Every page has an associated PCache */ if( pPg->flags & PGHDR_CLEAN ){ assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */ - assert( pageNotOnDirtyList(pCache, pPg) );/* CLEAN pages not on dirtylist */ + assert( !pageOnDirtyList(pCache, pPg) );/* CLEAN pages not on dirty list */ }else{ assert( (pPg->flags & PGHDR_DIRTY)!=0 );/* If not CLEAN must be DIRTY */ assert( pPg->pDirtyNext==0 || pPg->pDirtyNext->pDirtyPrev==pPg ); @@ -53821,7 +53649,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. */ @@ -54309,7 +54137,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. ** @@ -54549,7 +54377,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 @@ -54583,7 +54411,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. ** @@ -55803,7 +55631,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. @@ -56307,7 +56135,8 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 #ifndef SQLITE_WAL_H #define SQLITE_WAL_H -/* #include "sqliteInt.h" */ +/* #include "sqlite3.h" */ +/* #include "page_header.h" */ /* Macros for extracting appropriate sync flags for either transaction ** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)): @@ -56315,138 +56144,208 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 #define WAL_SYNC_FLAGS(X) ((X)&0x03) #define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03) -#ifdef SQLITE_OMIT_WAL -# define sqlite3WalOpen(x,y,z) 0 -# define sqlite3WalLimit(x,y) -# define sqlite3WalClose(v,w,x,y,z) 0 -# define sqlite3WalBeginReadTransaction(y,z) 0 -# define sqlite3WalEndReadTransaction(z) -# define sqlite3WalDbsize(y) 0 -# define sqlite3WalBeginWriteTransaction(y) 0 -# define sqlite3WalEndWriteTransaction(x) 0 -# define sqlite3WalUndo(x,y,z) 0 -# define sqlite3WalSavepoint(y,z) -# define sqlite3WalSavepointUndo(y,z) 0 -# define sqlite3WalFrames(u,v,w,x,y,z) 0 -# define sqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0 -# define sqlite3WalCallback(z) 0 -# define sqlite3WalExclusiveMode(y,z) 0 -# define sqlite3WalHeapMemory(z) 0 -# define sqlite3WalFramesize(z) 0 -# define sqlite3WalFindFrame(x,y,z) 0 -# define sqlite3WalFile(x) 0 -# undef SQLITE_USE_SEH -#else - #define WAL_SAVEPOINT_NDATA 4 /* Connection to a write-ahead log (WAL) file. ** There is one object of this type for each pager. */ -typedef struct Wal Wal; +typedef struct libsql_wal libsql_wal; + +typedef struct libsql_wal_methods { + int iVersion; /* Current version is 1, versioning is here for backward compatibility */ + /* Open and close a connection to a write-ahead log. */ + int (*xOpen)(sqlite3_vfs*, sqlite3_file* , const char*, int no_shm_mode, long long max_size, struct libsql_wal_methods*, libsql_wal**); + int (*xClose)(libsql_wal*, sqlite3* db, int sync_flags, int nBuf, unsigned char *zBuf); + + /* Set the limiting size of a WAL file. */ + void (*xLimit)(libsql_wal*, long long limit); + + /* Used by readers to open (lock) and close (unlock) a snapshot. A + ** snapshot is like a read-transaction. It is the state of the database + ** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and + ** preserves the current state even if the other threads or processes + ** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the + ** transaction and releases the lock. + */ + int (*xBeginReadTransaction)(libsql_wal *, int *); + void (*xEndReadTransaction)(libsql_wal *); + + /* Read a page from the write-ahead log, if it is present. */ + int (*xFindFrame)(libsql_wal *, unsigned int, unsigned int *); + int (*xReadFrame)(libsql_wal *, unsigned int, int, unsigned char *); + + /* If the WAL is not empty, return the size of the database. */ + unsigned int (*xDbsize)(libsql_wal *pWal); + + /* Obtain or release the WRITER lock. */ + int (*xBeginWriteTransaction)(libsql_wal *pWal); + int (*xEndWriteTransaction)(libsql_wal *pWal); + + /* Undo any frames written (but not committed) to the log */ + int (*xUndo)(libsql_wal *pWal, int (*xUndo)(void *, unsigned int), void *pUndoCtx); + + /* Return an integer that records the current (uncommitted) write + ** position in the WAL */ + void (*xSavepoint)(libsql_wal *pWal, unsigned int *aWalData); + + /* Move the write position of the WAL back to iFrame. Called in + ** response to a ROLLBACK TO command. */ + int (*xSavepointUndo)(libsql_wal *pWal, unsigned int *aWalData); + + /* Write a frame or frames to the log. */ + int (*xFrames)(libsql_wal *pWal, int, libsql_pghdr *, unsigned int, int, int); + + /* Copy pages from the log to the database file */ + int (*xCheckpoint)( + libsql_wal *pWal, /* Write-ahead log connection */ + sqlite3 *db, /* Check this handle's interrupt flag */ + int eMode, /* One of PASSIVE, FULL and RESTART */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags to sync db file with (or 0) */ + int nBuf, /* Size of buffer nBuf */ + unsigned char *zBuf, /* Temporary buffer to use */ + int *pnLog, /* OUT: Number of frames in WAL */ + int *pnCkpt /* OUT: Number of backfilled frames in WAL */ + ); -/* Open and close a connection to a write-ahead log. */ -SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**); -SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *); + /* Return the value to pass to a sqlite3_wal_hook callback, the + ** number of frames in the WAL at the point of the last commit since + ** sqlite3WalCallback() was called. If no commits have occurred since + ** the last call, then return 0. + */ + int (*xCallback)(libsql_wal *pWal); -/* Set the limiting size of a WAL file. */ -SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64); + /* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released) + ** by the pager layer on the database file. + */ + int (*xExclusiveMode)(libsql_wal *pWal, int op); -/* Used by readers to open (lock) and close (unlock) a snapshot. A -** snapshot is like a read-transaction. It is the state of the database -** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and -** preserves the current state even if the other threads or processes -** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the -** transaction and releases the lock. -*/ -SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *); -SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal); + /* Return true if the argument is non-NULL and the WAL module is using + ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the + ** WAL module is using shared-memory, return false. + */ + int (*xHeapMemory)(libsql_wal *pWal); -/* Read a page from the write-ahead log, if it is present. */ -SQLITE_PRIVATE int sqlite3WalFindFrame(Wal *, Pgno, u32 *); -SQLITE_PRIVATE int sqlite3WalReadFrame(Wal *, u32, int, u8 *); + // Only needed with SQLITE_ENABLE_SNAPSHOT, but part of the ABI + int (*xSnapshotGet)(libsql_wal *pWal, sqlite3_snapshot **ppSnapshot); + void (*xSnapshotOpen)(libsql_wal *pWal, sqlite3_snapshot *pSnapshot); + int (*xSnapshotRecover)(libsql_wal *pWal); + int (*xSnapshotCheck)(libsql_wal *pWal, sqlite3_snapshot *pSnapshot); + void (*xSnapshotUnlock)(libsql_wal *pWal); -/* If the WAL is not empty, return the size of the database. */ -SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal); + // Only needed with SQLITE_ENABLE_ZIPVFS, but part of the ABI + /* If the WAL file is not empty, return the number of bytes of content + ** stored in each frame (i.e. the db page-size when the WAL was created). + */ + int (*xFramesize)(libsql_wal *pWal); -/* Obtain or release the WRITER lock. */ -SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal); -SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal); -/* Undo any frames written (but not committed) to the log */ -SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx); + /* Return the sqlite3_file object for the WAL file */ + sqlite3_file *(*xFile)(libsql_wal *pWal); -/* Return an integer that records the current (uncommitted) write -** position in the WAL */ -SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData); + // Only needed with SQLITE_ENABLE_SETLK_TIMEOUT + int (*xWriteLock)(libsql_wal *pWal, int bLock); -/* Move the write position of the WAL back to iFrame. Called in -** response to a ROLLBACK TO command. */ -SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData); + void (*xDb)(libsql_wal *pWal, sqlite3 *db); -/* Write a frame or frames to the log. */ -SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int); + /* Return the WAL pathname length based on the owning pager's pathname len. + ** For WAL implementations not based on a single file, 0 should be returned. */ + int (*xPathnameLen)(int origPathname); -/* Copy pages from the log to the database file */ -SQLITE_PRIVATE int sqlite3WalCheckpoint( - Wal *pWal, /* Write-ahead log connection */ - sqlite3 *db, /* Check this handle's interrupt flag */ - int eMode, /* One of PASSIVE, FULL and RESTART */ - int (*xBusy)(void*), /* Function to call when busy */ - void *pBusyArg, /* Context argument for xBusyHandler */ - int sync_flags, /* Flags to sync db file with (or 0) */ - int nBuf, /* Size of buffer nBuf */ - u8 *zBuf, /* Temporary buffer to use */ - int *pnLog, /* OUT: Number of frames in WAL */ - int *pnCkpt /* OUT: Number of backfilled frames in WAL */ -); + /* Get the WAL pathname to given buffer. Assumes that the buffer can hold + ** at least xPathnameLen bytes. For WAL implementations not based on a single file, + ** this operation can safely be a no-op. + ** */ + void (*xGetWalPathname)(char *buf, const char *orig, int orig_len); -/* Return the value to pass to a sqlite3_wal_hook callback, the -** number of frames in the WAL at the point of the last commit since -** sqlite3WalCallback() was called. If no commits have occurred since -** the last call, then return 0. -*/ -SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal); + /* + ** This optional callback gets called before the main database file which owns + ** the WAL file is open. It is a good place for initialization routines, as WAL + ** is otherwise open lazily. + */ + int (*xPreMainDbOpen)(libsql_wal_methods *methods, const char *main_db_path); -/* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released) -** by the pager layer on the database file. -*/ -SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op); + /* True if the implementation relies on shared memory routines (e.g. locks) */ + int bUsesShm; -/* Return true if the argument is non-NULL and the WAL module is using -** heap-memory for the wal-index. Otherwise, if the argument is NULL or the -** WAL module is using shared-memory, return false. -*/ -SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal); + const char *zName; + struct libsql_wal_methods *pNext; +} libsql_wal_methods; -#ifdef SQLITE_ENABLE_SNAPSHOT -SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot); -SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot); -SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal); -SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot); -SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal); -#endif +libsql_wal_methods* libsql_wal_methods_find(const char *zName); -#ifdef SQLITE_ENABLE_ZIPVFS -/* If the WAL file is not empty, return the number of bytes of content -** stored in each frame (i.e. the db page-size when the WAL was created). -*/ -SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal); -#endif +/* Object declarations */ +typedef struct WalIndexHdr WalIndexHdr; +typedef struct WalIterator WalIterator; +typedef struct WalCkptInfo WalCkptInfo; -/* Return the sqlite3_file object for the WAL file */ -SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal); -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock); -SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db); -#endif +/* +** The following object holds a copy of the wal-index header content. +** +** The actual header in the wal-index consists of two copies of this +** object followed by one instance of the WalCkptInfo object. +** For all versions of SQLite through 3.10.0 and probably beyond, +** the locking bytes (WalCkptInfo.aLock) start at offset 120 and +** the total header size is 136 bytes. +** +** The szPage value can be any power of 2 between 512 and 32768, inclusive. +** Or it can be 1 to represent a 65536-byte page. The latter case was +** added in 3.7.1 when support for 64K pages was added. +*/ +struct WalIndexHdr { + unsigned int iVersion; /* Wal-index version */ + unsigned int unused; /* Unused (padding) field */ + unsigned int iChange; /* Counter incremented each transaction */ + unsigned char isInit; /* 1 when initialized */ + unsigned char bigEndCksum; /* True if checksums in WAL are big-endian */ + unsigned short szPage; /* Database page size in bytes. 1==64K */ + unsigned int mxFrame; /* Index of last valid frame in the WAL */ + unsigned int nPage; /* Size of database in pages */ + unsigned int aFrameCksum[2]; /* Checksum of last frame in log */ + unsigned int aSalt[2]; /* Two salt values copied from WAL header */ + unsigned int aCksum[2]; /* Checksum over all prior fields */ +}; -#ifdef SQLITE_USE_SEH -SQLITE_PRIVATE int sqlite3WalSystemErrno(Wal*); -#endif +/* +** An open write-ahead log file is represented by an instance of the +** following object. +*/ +struct libsql_wal { + sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ + sqlite3_file *pDbFd; /* File handle for the database file */ + sqlite3_file *pWalFd; /* File handle for WAL file */ + unsigned int iCallback; /* Value to pass to log callback (or 0) */ + long long mxWalSize; /* Truncate WAL to this size upon reset */ + int nWiData; /* Size of array apWiData */ + int szFirstBlock; /* Size of first block written to WAL file */ + volatile unsigned int **apWiData; /* Pointer to wal-index content in memory */ + unsigned int szPage; /* Database page size */ + short readLock; /* Which read lock is being held. -1 for none */ + unsigned char syncFlags; /* Flags to use to sync header writes */ + unsigned char exclusiveMode; /* Non-zero if connection is in exclusive mode */ + unsigned char writeLock; /* True if in a write transaction */ + unsigned char ckptLock; /* True if holding a checkpoint lock */ + unsigned char readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ + unsigned char truncateOnCommit; /* True to truncate WAL file on commit */ + unsigned char syncHeader; /* Fsync the WAL header if true */ + unsigned char padToSectorBoundary; /* Pad transactions out to the next sector */ + unsigned char bShmUnreliable; /* SHM content is read-only and unreliable */ + WalIndexHdr hdr; /* Wal-index header for current transaction */ + unsigned int minFrame; /* Ignore wal frames before this one */ + unsigned int iReCksum; /* On commit, recalculate checksums from here */ + const char *zWalName; /* Name of WAL file */ + unsigned int nCkpt; /* Checkpoint sequence counter in the wal-header */ + unsigned char lockError; /* True if a locking error has occurred */ + WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ + sqlite3 *db; + libsql_wal_methods *pMethods; /* Virtual methods for interacting with WAL */ + void *pMethodsData; /* Optional context for private use of libsql_wal_methods */ +}; + +typedef struct libsql_wal libsql_wal; -#endif /* ifndef SQLITE_OMIT_WAL */ #endif /* SQLITE_WAL_H */ /************** End of wal.h *************************************************/ @@ -56655,7 +56554,7 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ ** * If the connection is open in rollback-mode, a RESERVED or greater ** lock is held on the database file. ** * If the connection is open in WAL-mode, a WAL write transaction -** is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully +** is open (i.e. pPager->pWalMethods->xBeginWriteTransaction() has been successfully ** called). ** * The dbSize, dbOrigSize and dbFileSize variables are all valid. ** * The contents of the pager cache have not been modified. @@ -56731,7 +56630,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. @@ -57127,8 +57026,10 @@ struct Pager { char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ PCache *pPCache; /* Pointer to page cache object */ #ifndef SQLITE_OMIT_WAL - Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ - char *zWal; /* File name for write-ahead log */ + libsql_wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ + libsql_wal_methods *pWalMethods; /* Virtual methods for interacting with WAL */ + char *zWal; /* File name for write-ahead log */ + void *pWalMethodsData; /* WA: methods context data */ #endif }; @@ -57249,7 +57150,7 @@ SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ if( pPager->pWal ){ u32 iRead = 0; int rc; - rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); + rc = pPager->pWalMethods->xFindFrame(pPager->pWal, pgno, &iRead); return (rc==SQLITE_OK && iRead==0); } #endif @@ -57922,32 +57823,9 @@ static int writeJournalHdr(Pager *pPager){ memset(zHeader, 0, sizeof(aJournalMagic)+4); } - - /* The random check-hash initializer */ - if( pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ - sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); - } -#ifdef SQLITE_DEBUG - else{ - /* The Pager.cksumInit variable is usually randomized above to protect - ** against there being existing records in the journal file. This is - ** dangerous, as following a crash they may be mistaken for records - ** written by the current transaction and rolled back into the database - ** file, causing corruption. The following assert statements verify - ** that this is not required in "journal_mode=memory" mode, as in that - ** case the journal file is always 0 bytes in size at this point. - ** It is advantageous to avoid the sqlite3_randomness() call if possible - ** as it takes the global PRNG mutex. */ - i64 sz = 0; - sqlite3OsFileSize(pPager->jfd, &sz); - assert( sz==0 ); - assert( pPager->journalOff==journalHdrOffset(pPager) ); - assert( sqlite3JournalIsInMemory(pPager->jfd) ); - } -#endif + sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); - /* The initial database size */ put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize); /* The assumed sector size for this process */ @@ -58127,7 +58005,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), @@ -58180,7 +58058,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 @@ -58283,7 +58161,9 @@ static void pager_unlock(Pager *pPager){ if( pagerUseWal(pPager) ){ assert( !isOpen(pPager->jfd) ); - sqlite3WalEndReadTransaction(pPager->pWal); +#ifndef SQLITE_OMIT_WAL + pPager->pWalMethods->xEndReadTransaction(pPager->pWal); +#endif pPager->eState = PAGER_OPEN; }else if( !pPager->exclusiveMode ){ int rc; /* Error code returned by pagerUnlockDb() */ @@ -58350,7 +58230,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. @@ -58562,7 +58442,9 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE ** lock held on the database file. */ - rc2 = sqlite3WalEndWriteTransaction(pPager->pWal); +#ifndef SQLITE_OMIT_WAL + rc2 = pPager->pWalMethods->xEndWriteTransaction(pPager->pWal); +#endif assert( rc2==SQLITE_OK ); }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){ /* This branch is taken when committing a transaction in rollback-journal @@ -58580,9 +58462,13 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; } - if( !pPager->exclusiveMode - && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) - ){ + int should_unlock = !pPager->exclusiveMode; +#ifndef SQLITE_OMIT_WAL + if (should_unlock && pagerUseWal(pPager)) { + should_unlock &= pPager->pWalMethods->xExclusiveMode(pPager->pWal, 0); + } +#endif + if( should_unlock ){ rc2 = pagerUnlockDb(pPager, SHARED_LOCK); } pPager->eState = PAGER_READER; @@ -58591,9 +58477,6 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ return (rc==SQLITE_OK?rc2:rc); } -/* Forward reference */ -static int pager_playback(Pager *pPager, int isHot); - /* ** Execute a rollback if a transaction is active and unlock the ** database file. @@ -58622,28 +58505,13 @@ static void pagerUnlockAndRollback(Pager *pPager){ assert( pPager->eState==PAGER_READER ); pager_end_transaction(pPager, 0, 0); } - }else if( pPager->eState==PAGER_ERROR - && pPager->journalMode==PAGER_JOURNALMODE_MEMORY - && isOpen(pPager->jfd) - ){ - /* Special case for a ROLLBACK due to I/O error with an in-memory - ** journal: We have to rollback immediately, before the journal is - ** closed, because once it is closed, all content is forgotten. */ - int errCode = pPager->errCode; - u8 eLock = pPager->eLock; - pPager->eState = PAGER_OPEN; - pPager->errCode = SQLITE_OK; - pPager->eLock = EXCLUSIVE_LOCK; - pager_playback(pPager, 1); - pPager->errCode = errCode; - pPager->eLock = eLock; } pager_unlock(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 @@ -59449,11 +59317,11 @@ static int readDbPage(PgHdr *pPg){ assert( isOpen(pPager->fd) ); if( pagerUseWal(pPager) ){ - rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); + rc = pPager->pWalMethods->xFindFrame(pPager->pWal, pPg->pgno, &iFrame); if( rc ) return rc; } if( iFrame ){ - rc = sqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData); + rc = pPager->pWalMethods->xReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData); }else #endif { @@ -59576,7 +59444,7 @@ static int pagerRollbackWal(Pager *pPager){ ** + Reload page content from the database (if refcount>0). */ pPager->dbSize = pPager->dbOrigSize; - rc = sqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager); + rc = pPager->pWalMethods->xUndo(pPager->pWal, pagerUndoCallback, (void *)pPager); pList = sqlite3PcacheDirtyList(pPager->pPCache); while( pList && rc==SQLITE_OK ){ PgHdr *pNext = pList->pDirty; @@ -59588,7 +59456,7 @@ static int pagerRollbackWal(Pager *pPager){ } /* -** This function is a wrapper around sqlite3WalFrames(). As well as logging +** This function is a wrapper around pPager->pWalMethods->xFrames(). As well as logging ** the contents of the list of pages headed by pList (connected by pDirty), ** this function notifies any active backup processes that the pages have ** changed. @@ -59609,7 +59477,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 ); } @@ -59636,7 +59504,7 @@ static int pagerWalFrames( pPager->aStat[PAGER_STAT_WRITE] += nList; if( pList->pgno==1 ) pager_write_changecounter(pList); - rc = sqlite3WalFrames(pPager->pWal, + rc = pPager->pWalMethods->xFrames(pPager->pWal, pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags ); if( rc==SQLITE_OK && pPager->pBackup ){ @@ -59670,14 +59538,14 @@ static int pagerBeginReadTransaction(Pager *pPager){ assert( pagerUseWal(pPager) ); assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); - /* sqlite3WalEndReadTransaction() was not called for the previous + /* pPager->pWalMethods->xEndReadTransaction() was not called for the previous ** transaction in locking_mode=EXCLUSIVE. So call it now. If we ** are in locking_mode=NORMAL and EndRead() was previously called, ** the duplicate call is harmless. */ - sqlite3WalEndReadTransaction(pPager->pWal); + pPager->pWalMethods->xEndReadTransaction(pPager->pWal); - rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); + rc = pPager->pWalMethods->xBeginReadTransaction(pPager->pWal, &changed); if( rc!=SQLITE_OK || changed ){ pager_reset(pPager); if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); @@ -59709,7 +59577,11 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){ assert( pPager->eLock>=SHARED_LOCK ); assert( isOpen(pPager->fd) ); assert( pPager->tempFile==0 ); - nPage = sqlite3WalDbsize(pPager->pWal); +#ifndef SQLITE_OMIT_WAL + nPage = pagerUseWal(pPager) ? pPager->pWalMethods->xDbsize(pPager->pWal) : 0; +#else + nPage = 0; +#endif /* If the number of pages in the database is not available from the ** WAL sub-system, determine the page count based on the size of @@ -59740,7 +59612,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 @@ -59913,9 +59785,11 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ u32 ii; /* Loop counter */ i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize); +#ifndef SQLITE_OMIT_WAL if( pagerUseWal(pPager) ){ - rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData); + rc = pPager->pWalMethods->xSavepointUndo(pPager->pWal, pSavepoint->aWalData); } +#endif for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && iinSubRec; ii++){ assert( offset==(i64)ii*(4+pPager->pageSize) ); rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1); @@ -60597,7 +60471,9 @@ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ ){ a = pTmp; } - sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a); + if (pagerUseWal(pPager)) { + pPager->pWalMethods->xClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a); + } pPager->pWal = 0; } #endif @@ -61138,6 +61014,8 @@ SQLITE_PRIVATE int sqlite3PagerFlush(Pager *pPager){ */ SQLITE_PRIVATE int sqlite3PagerOpen( sqlite3_vfs *pVfs, /* The virtual file system to use */ + libsql_wal_methods *pWalMethods, /* WAL methods to use */ + void *pWalMethodsData, /* WAL methods context data */ Pager **ppPager, /* OUT: Return the Pager structure here */ const char *zFilename, /* Name of the database file to open */ int nExtra, /* Extra bytes append to each in-memory page */ @@ -61150,7 +61028,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 */ @@ -61225,6 +61107,10 @@ SQLITE_PRIVATE int sqlite3PagerOpen( } } +#ifndef SQLITE_OMIT_WAL + int nWalPathname = pWalMethods->xPathnameLen(nPathname); +#endif + /* Allocate memory for the Pager structure, PCache object, the ** three file descriptors, the database file name and the journal ** file name. The layout in memory is as follows: @@ -61269,19 +61155,18 @@ 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 */ nPathname + 8 + 1 + /* Journal filename */ #ifndef SQLITE_OMIT_WAL - nPathname + 4 + 1 + /* WAL filename */ + nWalPathname + 1 + /* WAL filename */ #endif 3 /* Terminator */ ); @@ -61295,8 +61180,9 @@ SQLITE_PRIVATE int sqlite3PagerOpen( pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile); pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; + pPager->pWalMethodsData = pWalMethodsData; 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 */ @@ -61325,11 +61211,14 @@ SQLITE_PRIVATE int sqlite3PagerOpen( } #ifndef SQLITE_OMIT_WAL + pPager->pWalMethods = pWalMethods; /* Fill in Pager.zWal */ - if( nPathname>0 ){ + if( nWalPathname>0 ){ pPager->zWal = (char*)pPtr; - memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; - memcpy(pPtr, "-wal", 4); pPtr += 4 + 1; + pWalMethods->xGetWalPathname((char *)pPtr, zPathname, nPathname); + pPtr += nWalPathname; + pPtr[0] = '\0'; + pPtr++; #ifdef SQLITE_ENABLE_8_3_NAMES sqlite3FileSuffix3(zFilename, pPager->zWal); pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1); @@ -61337,6 +61226,13 @@ SQLITE_PRIVATE int sqlite3PagerOpen( }else{ pPager->zWal = 0; } + + if (pWalMethods->xPreMainDbOpen) { + int rc = pWalMethods->xPreMainDbOpen(pWalMethods, zPathname); + if (rc != SQLITE_OK) { + return rc; + } + } #endif (void)pPtr; /* Suppress warning about unused pPtr value */ @@ -61350,7 +61246,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, @@ -61487,18 +61385,15 @@ 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){ Pager *pPager; - const char *p; while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){ zName--; } - p = zName - 4 - sizeof(Pager*); - assert( EIGHT_BYTE_ALIGNMENT(p) ); - pPager = *(Pager**)p; + pPager = *(Pager**)(zName - 4 - sizeof(Pager*)); return pPager->fd; } @@ -62074,11 +61969,13 @@ static int getPageMMap( assert( pPager->errCode==SQLITE_OK ); if( bMmapOk && pagerUseWal(pPager) ){ - rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); +#ifndef SQLITE_OMIT_WAL + rc = pPager->pWalMethods->xFindFrame(pPager->pWal, pgno, &iFrame); if( rc!=SQLITE_OK ){ *ppPage = 0; return rc; } +#endif } if( bMmapOk && iFrame==0 ){ void *pData = 0; @@ -62132,20 +62029,8 @@ SQLITE_PRIVATE int sqlite3PagerGet( DbPage **ppPage, /* Write a pointer to the page here */ int flags /* PAGER_GET_XXX flags */ ){ -#if 0 /* Trace page fetch by setting to 1 */ - int rc; - printf("PAGE %u\n", pgno); - fflush(stdout); - rc = pPager->xGet(pPager, pgno, ppPage, flags); - if( rc ){ - printf("PAGE %u failed with 0x%02x\n", pgno, rc); - fflush(stdout); - } - return rc; -#else - /* Normal, high-speed version of sqlite3PagerGet() */ + /* printf("PAGE %u\n", pgno); fflush(stdout); */ return pPager->xGet(pPager, pgno, ppPage, flags); -#endif } /* @@ -62333,15 +62218,16 @@ SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory assert( pPager->pInJournal==0 ); if( pagerUseWal(pPager) ){ +#ifndef SQLITE_OMIT_WAL /* If the pager is configured to use locking_mode=exclusive, and an ** exclusive lock on the database is not already held, obtain it now. */ - if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){ + if( pPager->exclusiveMode && pPager->pWalMethods->xExclusiveMode(pPager->pWal, -1) ){ rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); if( rc!=SQLITE_OK ){ return rc; } - (void)sqlite3WalExclusiveMode(pPager->pWal, 1); + (void)pPager->pWalMethods->xExclusiveMode(pPager->pWal, 1); } /* Grab the write lock on the log file. If successful, upgrade to @@ -62349,7 +62235,8 @@ SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory ** The busy-handler is not invoked if another connection already ** holds the write-lock. If possible, the upper layer will call it. */ - rc = sqlite3WalBeginWriteTransaction(pPager->pWal); + rc = pPager->pWalMethods->xBeginWriteTransaction(pPager->pWal); +#endif }else{ /* Obtain a RESERVED lock on the database file. If the exFlag parameter ** is true, then immediately upgrade this to an EXCLUSIVE lock. The @@ -63021,13 +62908,6 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0); if( rc==SQLITE_OK ){ rc = pager_write_pagelist(pPager, pList); - if( rc==SQLITE_OK && pPager->dbSize>pPager->dbFileSize ){ - char *pTmp = pPager->pTmpSpace; - int szPage = (int)pPager->pageSize; - memset(pTmp, 0, szPage); - rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, - ((i64)pPager->dbSize*pPager->pageSize)-szPage); - } if( rc==SQLITE_OK ){ rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0); } @@ -63357,7 +63237,9 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){ return SQLITE_NOMEM_BKPT; } if( pagerUseWal(pPager) ){ - sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData); +#ifndef SQLITE_OMIT_WAL + pPager->pWalMethods->xSavepoint(pPager->pWal, aNew[ii].aWalData); +#endif } pPager->nSavepoint = ii+1; } @@ -63504,6 +63386,15 @@ SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){ return pPager->pVfs; } +#ifndef SQLITE_OMIT_WAL +/* +** Return the WAL methods structure for the pager. +*/ +SQLITE_PRIVATE libsql_wal_methods *sqlite3PagerWalMethods(Pager *pPager){ + return pPager->pWalMethods; +} +#endif + /* ** Return the file handle for the database file associated ** with the pager. This might return NULL if the file has @@ -63521,7 +63412,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){ #if SQLITE_OMIT_WAL return pPager->jfd; #else - return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd; + return pPager->pWal ? pPager->pWalMethods->xFile(pPager->pWal) : pPager->jfd; #endif } @@ -63718,6 +63609,15 @@ SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){ return pPg->pExtra; } +static int pagerWalHeapMemory(Pager *pPager) { +#ifndef SQLITE_OMIT_WAL + if (pagerUseWal(pPager)) { + return pPager->pWalMethods->xHeapMemory(pPager->pWal); + } +#endif + return 0; +} + /* ** Get/set the locking-mode for this pager. Parameter eMode must be one ** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or @@ -63734,8 +63634,8 @@ SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){ || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); assert( PAGER_LOCKINGMODE_QUERY<0 ); assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 ); - assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) ); - if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){ + assert( pPager->exclusiveMode || 0==pagerWalHeapMemory(pPager) ); + if( eMode>=0 && !pPager->tempFile && !pagerWalHeapMemory(pPager) ){ pPager->exclusiveMode = (u8)eMode; } return (int)pPager->exclusiveMode; @@ -63794,7 +63694,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. */ @@ -63839,7 +63739,7 @@ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ } assert( state==pPager->eState ); } - }else if( eMode==PAGER_JOURNALMODE_OFF || eMode==PAGER_JOURNALMODE_MEMORY ){ + }else if( eMode==PAGER_JOURNALMODE_OFF ){ sqlite3OsClose(pPager->jfd); } } @@ -63876,7 +63776,9 @@ SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){ if( iLimit>=-1 ){ pPager->journalSizeLimit = iLimit; - sqlite3WalLimit(pPager->pWal, iLimit); +#ifndef SQLITE_OMIT_WAL + pPager->pWalMethods->xLimit(pPager->pWal, iLimit); +#endif } return pPager->journalSizeLimit; } @@ -63931,7 +63833,7 @@ SQLITE_PRIVATE int sqlite3PagerCheckpoint( sqlite3_exec(db, "PRAGMA table_list",0,0,0); } if( pPager->pWal ){ - rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode, + rc = pPager->pWalMethods->xCheckpoint(pPager->pWal, db, eMode, (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), pPager->pBusyHandlerArg, pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, @@ -63942,7 +63844,10 @@ SQLITE_PRIVATE int sqlite3PagerCheckpoint( } SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){ - return sqlite3WalCallback(pPager->pWal); + if (pagerUseWal(pPager)) { + return pPager->pWalMethods->xCallback(pPager->pWal); + } + return SQLITE_OK; } /* @@ -63952,7 +63857,7 @@ SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){ SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){ const sqlite3_io_methods *pMethods = pPager->fd->pMethods; if( pPager->noLock ) return 0; - return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap); + return pPager->exclusiveMode || (pPager->pWalMethods->bUsesShm == 0) || (pMethods->iVersion>=2 && pMethods->xShmMap); } /* @@ -63976,7 +63881,7 @@ static int pagerExclusiveLock(Pager *pPager){ } /* -** Call sqlite3WalOpen() to open the WAL handle. If the pager is in +** Call pPager->pWalMethods->xOpen() to open the WAL handle. If the pager is in ** exclusive-locking mode when this function is called, take an EXCLUSIVE ** lock on the database file and use heap-memory to store the wal-index ** in. Otherwise, use the normal shared-memory. @@ -64000,10 +63905,14 @@ static int pagerOpenWal(Pager *pPager){ ** (e.g. due to malloc() failure), return an error code. */ if( rc==SQLITE_OK ){ - rc = sqlite3WalOpen(pPager->pVfs, + rc = pPager->pWalMethods->xOpen(pPager->pVfs, pPager->fd, pPager->zWal, pPager->exclusiveMode, - pPager->journalSizeLimit, &pPager->pWal + pPager->journalSizeLimit, pPager->pWalMethods, &pPager->pWal ); + + if (rc == SQLITE_OK && pPager->pWal) { + pPager->pWal->pMethodsData = pPager->pWalMethodsData; + } } pagerFixMaplimit(pPager); @@ -64093,7 +64002,7 @@ SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){ if( rc==SQLITE_OK && pPager->pWal ){ rc = pagerExclusiveLock(pPager); if( rc==SQLITE_OK ){ - rc = sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, + rc = pPager->pWalMethods->xClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize, (u8*)pPager->pTmpSpace); pPager->pWal = 0; pagerFixMaplimit(pPager); @@ -64106,14 +64015,14 @@ SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT /* ** If pager pPager is a wal-mode database not in exclusive locking mode, -** invoke the sqlite3WalWriteLock() function on the associated Wal object +** invoke the pPager->pWalMethods->xWriteLock() function on the associated Wal object ** with the same db and bLock parameters as were passed to this function. ** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise. */ SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){ int rc = SQLITE_OK; if( pagerUseWal(pPager) && pPager->exclusiveMode==0 ){ - rc = sqlite3WalWriteLock(pPager->pWal, bLock); + rc = pPager->pWalMethods->xWriteLock(pPager->pWal, bLock); } return rc; } @@ -64124,7 +64033,7 @@ SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){ */ SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ if( pagerUseWal(pPager) ){ - sqlite3WalDb(pPager->pWal, db); + pPager->pWalMethods->xDb(pPager->pWal, db); } } #endif @@ -64137,7 +64046,7 @@ SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){ int rc = SQLITE_ERROR; if( pPager->pWal ){ - rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot); + rc = pPager->pWalMethods->xSnapshotGet(pPager->pWal, ppSnapshot); } return rc; } @@ -64153,7 +64062,7 @@ SQLITE_PRIVATE int sqlite3PagerSnapshotOpen( ){ int rc = SQLITE_OK; if( pPager->pWal ){ - sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot); + pPager->pWalMethods->xSnapshotOpen(pPager->pWal, pSnapshot); }else{ rc = SQLITE_ERROR; } @@ -64161,13 +64070,13 @@ SQLITE_PRIVATE int sqlite3PagerSnapshotOpen( } /* -** If this is a WAL database, call sqlite3WalSnapshotRecover(). If this +** If this is a WAL database, call pPager->pWalMethods->xSnapshotRecover(). If this ** is not a WAL database, return an error. */ SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager){ int rc; if( pPager->pWal ){ - rc = sqlite3WalSnapshotRecover(pPager->pWal); + rc = pPager->pWalMethods->xSnapshotRecover(pPager->pWal); }else{ rc = SQLITE_ERROR; } @@ -64189,7 +64098,7 @@ SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager){ SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot){ int rc; if( pPager->pWal ){ - rc = sqlite3WalSnapshotCheck(pPager->pWal, pSnapshot); + rc = pPager->pWalMethods->xSnapshotCheck(pPager->pWal, pSnapshot); }else{ rc = SQLITE_ERROR; } @@ -64202,7 +64111,7 @@ SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pS */ SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){ assert( pPager->pWal ); - sqlite3WalSnapshotUnlock(pPager->pWal); + pPager->pWalMethods->xSnapshotUnlock(pPager->pWal); } #endif /* SQLITE_ENABLE_SNAPSHOT */ @@ -64218,13 +64127,7 @@ SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){ */ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){ assert( pPager->eState>=PAGER_READER ); - return sqlite3WalFramesize(pPager->pWal); -} -#endif - -#ifdef SQLITE_USE_SEH -SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ - return sqlite3WalSystemErrno(pPager->pWal); + return pPager->pWalMethods->xFramesize(pPager->pWal); } #endif @@ -64481,10 +64384,14 @@ SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ ** that correspond to frames greater than the new K value are removed ** from the hash table at this point. */ +/* #include "sqliteInt.h" */ #ifndef SQLITE_OMIT_WAL /* #include "wal.h" */ +typedef libsql_pghdr PgHdr; +typedef libsql_wal Wal; + /* ** Trace output macros */ @@ -64518,7 +64425,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 @@ -64532,40 +64439,6 @@ SQLITE_PRIVATE int sqlite3WalTrace = 0; #define WAL_READ_LOCK(I) (3+(I)) #define WAL_NREADER (SQLITE_SHM_NLOCK-3) - -/* Object declarations */ -typedef struct WalIndexHdr WalIndexHdr; -typedef struct WalIterator WalIterator; -typedef struct WalCkptInfo WalCkptInfo; - - -/* -** The following object holds a copy of the wal-index header content. -** -** The actual header in the wal-index consists of two copies of this -** object followed by one instance of the WalCkptInfo object. -** For all versions of SQLite through 3.10.0 and probably beyond, -** the locking bytes (WalCkptInfo.aLock) start at offset 120 and -** the total header size is 136 bytes. -** -** The szPage value can be any power of 2 between 512 and 32768, inclusive. -** Or it can be 1 to represent a 65536-byte page. The latter case was -** added in 3.7.1 when support for 64K pages was added. -*/ -struct WalIndexHdr { - u32 iVersion; /* Wal-index version */ - u32 unused; /* Unused (padding) field */ - u32 iChange; /* Counter incremented each transaction */ - u8 isInit; /* 1 when initialized */ - u8 bigEndCksum; /* True if checksums in WAL are big-endian */ - u16 szPage; /* Database page size in bytes. 1==64K */ - u32 mxFrame; /* Index of last valid frame in the WAL */ - u32 nPage; /* Size of database in pages */ - u32 aFrameCksum[2]; /* Checksum of last frame in log */ - u32 aSalt[2]; /* Two salt values copied from WAL header */ - u32 aCksum[2]; /* Checksum over all prior fields */ -}; - /* ** A copy of the following object occurs in the wal-index immediately ** following the second copy of the WalIndexHdr. This object stores @@ -64594,7 +64467,7 @@ struct WalIndexHdr { ** 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. ** @@ -64733,54 +64606,6 @@ struct WalCkptInfo { WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE) \ ) -/* -** An open write-ahead log file is represented by an instance of the -** following object. -*/ -struct Wal { - sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ - sqlite3_file *pDbFd; /* File handle for the database file */ - sqlite3_file *pWalFd; /* File handle for WAL file */ - u32 iCallback; /* Value to pass to log callback (or 0) */ - i64 mxWalSize; /* Truncate WAL to this size upon reset */ - int nWiData; /* Size of array apWiData */ - int szFirstBlock; /* Size of first block written to WAL file */ - volatile u32 **apWiData; /* Pointer to wal-index content in memory */ - u32 szPage; /* Database page size */ - i16 readLock; /* Which read lock is being held. -1 for none */ - u8 syncFlags; /* Flags to use to sync header writes */ - u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ - u8 writeLock; /* True if in a write transaction */ - u8 ckptLock; /* True if holding a checkpoint lock */ - u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ - u8 truncateOnCommit; /* True to truncate WAL file on commit */ - u8 syncHeader; /* Fsync the WAL header if true */ - u8 padToSectorBoundary; /* Pad transactions out to the next sector */ - u8 bShmUnreliable; /* SHM content is read-only and unreliable */ - WalIndexHdr hdr; /* Wal-index header for current transaction */ - u32 minFrame; /* Ignore wal frames before this one */ - u32 iReCksum; /* On commit, recalculate checksums from here */ - const char *zWalName; /* Name of WAL file */ - u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ -#ifdef SQLITE_USE_SEH - u32 lockMask; /* Mask of locks held */ - void *pFree; /* Pointer to sqlite3_free() if exception thrown */ - u32 *pWiValue; /* Value to write into apWiData[iWiPg] */ - int iWiPg; /* Write pWiValue into apWiData[iWiPg] */ - int iSysErrno; /* System error code following exception */ -#endif -#ifdef SQLITE_DEBUG - int nSehTry; /* Number of nested SEH_TRY{} blocks */ - u8 lockError; /* True if a locking error has occurred */ -#endif -#ifdef SQLITE_ENABLE_SNAPSHOT - WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ -#endif -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - sqlite3 *db; -#endif -}; - /* ** Candidate values for Wal.exclusiveMode. */ @@ -64852,113 +64677,6 @@ struct WalIterator { sizeof(ht_slot)*HASHTABLE_NSLOT + HASHTABLE_NPAGE*sizeof(u32) \ ) -/* -** Structured Exception Handling (SEH) is a Windows-specific technique -** for catching exceptions raised while accessing memory-mapped files. -** -** The -DSQLITE_USE_SEH compile-time option means to use SEH to catch and -** deal with system-level errors that arise during WAL -shm file processing. -** Without this compile-time option, any system-level faults that appear -** while accessing the memory-mapped -shm file will cause a process-wide -** signal to be deliver, which will more than likely cause the entire -** process to exit. -*/ -#ifdef SQLITE_USE_SEH -#include - -/* Beginning of a block of code in which an exception might occur */ -# define SEH_TRY __try { \ - assert( walAssertLockmask(pWal) && pWal->nSehTry==0 ); \ - VVA_ONLY(pWal->nSehTry++); - -/* The end of a block of code in which an exception might occur */ -# define SEH_EXCEPT(X) \ - VVA_ONLY(pWal->nSehTry--); \ - assert( pWal->nSehTry==0 ); \ - } __except( sehExceptionFilter(pWal, GetExceptionCode(), GetExceptionInformation() ) ){ X } - -/* Simulate a memory-mapping fault in the -shm file for testing purposes */ -# define SEH_INJECT_FAULT sehInjectFault(pWal) - -/* -** The second argument is the return value of GetExceptionCode() for the -** current exception. Return EXCEPTION_EXECUTE_HANDLER if the exception code -** indicates that the exception may have been caused by accessing the *-shm -** file mapping. Or EXCEPTION_CONTINUE_SEARCH otherwise. -*/ -static int sehExceptionFilter(Wal *pWal, int eCode, EXCEPTION_POINTERS *p){ - VVA_ONLY(pWal->nSehTry--); - if( eCode==EXCEPTION_IN_PAGE_ERROR ){ - if( p && p->ExceptionRecord && p->ExceptionRecord->NumberParameters>=3 ){ - /* From MSDN: For this type of exception, the first element of the - ** ExceptionInformation[] array is a read-write flag - 0 if the exception - ** was thrown while reading, 1 if while writing. The second element is - ** the virtual address being accessed. The "third array element specifies - ** the underlying NTSTATUS code that resulted in the exception". */ - pWal->iSysErrno = (int)p->ExceptionRecord->ExceptionInformation[2]; - } - return EXCEPTION_EXECUTE_HANDLER; - } - return EXCEPTION_CONTINUE_SEARCH; -} - -/* -** If one is configured, invoke the xTestCallback callback with 650 as -** the argument. If it returns true, throw the same exception that is -** thrown by the system if the *-shm file mapping is accessed after it -** has been invalidated. -*/ -static void sehInjectFault(Wal *pWal){ - int res; - assert( pWal->nSehTry>0 ); - - res = sqlite3FaultSim(650); - if( res!=0 ){ - ULONG_PTR aArg[3]; - aArg[0] = 0; - aArg[1] = 0; - aArg[2] = (ULONG_PTR)res; - RaiseException(EXCEPTION_IN_PAGE_ERROR, 0, 3, (const ULONG_PTR*)aArg); - } -} - -/* -** There are two ways to use this macro. To set a pointer to be freed -** if an exception is thrown: -** -** SEH_FREE_ON_ERROR(0, pPtr); -** -** and to cancel the same: -** -** SEH_FREE_ON_ERROR(pPtr, 0); -** -** In the first case, there must not already be a pointer registered to -** be freed. In the second case, pPtr must be the registered pointer. -*/ -#define SEH_FREE_ON_ERROR(X,Y) \ - assert( (X==0 || Y==0) && pWal->pFree==X ); pWal->pFree = Y - -/* -** There are two ways to use this macro. To arrange for pWal->apWiData[iPg] -** to be set to pValue if an exception is thrown: -** -** SEH_SET_ON_ERROR(iPg, pValue); -** -** and to cancel the same: -** -** SEH_SET_ON_ERROR(0, 0); -*/ -#define SEH_SET_ON_ERROR(X,Y) pWal->iWiPg = X; pWal->pWiValue = Y - -#else -# define SEH_TRY VVA_ONLY(pWal->nSehTry++); -# define SEH_EXCEPT(X) VVA_ONLY(pWal->nSehTry--); assert( pWal->nSehTry==0 ); -# define SEH_INJECT_FAULT assert( pWal->nSehTry>0 ); -# define SEH_FREE_ON_ERROR(X,Y) -# define SEH_SET_ON_ERROR(X,Y) -#endif /* ifdef SQLITE_USE_SEH */ - - /* ** Obtain a pointer to the iPage'th page of the wal-index. The wal-index ** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are @@ -65031,7 +64749,6 @@ static int walIndexPage( int iPage, /* The page we seek */ volatile u32 **ppPage /* Write the page pointer here */ ){ - SEH_INJECT_FAULT; if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){ return walIndexPageRealloc(pWal, iPage, ppPage); } @@ -65043,7 +64760,6 @@ static int walIndexPage( */ static volatile WalCkptInfo *walCkptInfo(Wal *pWal){ assert( pWal->nWiData>0 && pWal->apWiData[0] ); - SEH_INJECT_FAULT; return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]); } @@ -65052,7 +64768,6 @@ static volatile WalCkptInfo *walCkptInfo(Wal *pWal){ */ static volatile WalIndexHdr *walIndexHdr(Wal *pWal){ assert( pWal->nWiData>0 && pWal->apWiData[0] ); - SEH_INJECT_FAULT; return (volatile WalIndexHdr*)pWal->apWiData[0]; } @@ -65242,7 +64957,7 @@ static int walDecodeFrame( return 0; } - /* A frame is only valid if the page number is greater than zero. + /* A frame is only valid if the page number is creater than zero. */ pgno = sqlite3Get4byte(&aFrame[0]); if( pgno==0 ){ @@ -65250,7 +64965,7 @@ static int walDecodeFrame( } /* A frame is only valid if a checksum of the WAL header, - ** all prior frames, the first 16 bytes of this frame-header, + ** all prior frams, the first 16 bytes of this frame-header, ** and the frame-data matches the checksum in the last 8 ** bytes of this frame-header. */ @@ -65310,18 +65025,12 @@ static int walLockShared(Wal *pWal, int lockIdx){ WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, walLockName(lockIdx), rc ? "failed" : "ok")); VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); ) -#ifdef SQLITE_USE_SEH - if( rc==SQLITE_OK ) pWal->lockMask |= (1 << lockIdx); -#endif return rc; } static void walUnlockShared(Wal *pWal, int lockIdx){ if( pWal->exclusiveMode ) return; (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); -#ifdef SQLITE_USE_SEH - pWal->lockMask &= ~(1 << lockIdx); -#endif WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); } static int walLockExclusive(Wal *pWal, int lockIdx, int n){ @@ -65332,20 +65041,12 @@ static int walLockExclusive(Wal *pWal, int lockIdx, int n){ WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, walLockName(lockIdx), n, rc ? "failed" : "ok")); VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); ) -#ifdef SQLITE_USE_SEH - if( rc==SQLITE_OK ){ - pWal->lockMask |= (((1<exclusiveMode ) return; (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); -#ifdef SQLITE_USE_SEH - pWal->lockMask &= ~(((1<apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1]; } @@ -65697,7 +65397,6 @@ static int walIndexRecover(Wal *pWal){ /* Malloc a buffer to read frames into. */ szFrame = szPage + WAL_FRAME_HDRSIZE; aFrame = (u8 *)sqlite3_malloc64(szFrame + WALINDEX_PGSZ); - SEH_FREE_ON_ERROR(0, aFrame); if( !aFrame ){ rc = SQLITE_NOMEM_BKPT; goto recovery_error; @@ -65716,7 +65415,6 @@ static int walIndexRecover(Wal *pWal){ rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare); assert( aShare!=0 || rc!=SQLITE_OK ); if( aShare==0 ) break; - SEH_SET_ON_ERROR(iPg, aShare); pWal->apWiData[iPg] = aPrivate; for(iFrame=iFirst; iFrame<=iLast; iFrame++){ @@ -65744,7 +65442,6 @@ static int walIndexRecover(Wal *pWal){ } } pWal->apWiData[iPg] = aShare; - SEH_SET_ON_ERROR(0,0); nHdr = (iPg==0 ? WALINDEX_HDR_SIZE : 0); nHdr32 = nHdr / sizeof(u32); #ifndef SQLITE_SAFER_WALINDEX_RECOVERY @@ -65775,11 +65472,9 @@ static int walIndexRecover(Wal *pWal){ } } #endif - SEH_INJECT_FAULT; if( iFrame<=iLast ) break; } - SEH_FREE_ON_ERROR(aFrame, 0); sqlite3_free(aFrame); } @@ -65807,7 +65502,6 @@ static int walIndexRecover(Wal *pWal){ }else{ pInfo->aReadMark[i] = READMARK_NOT_USED; } - SEH_INJECT_FAULT; walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); }else if( rc!=SQLITE_BUSY ){ goto recovery_error; @@ -65854,6 +65548,8 @@ static void walIndexClose(Wal *pWal, int isDelete){ ** already be opened on connection pDbFd. The buffer that zWalName points ** to must remain valid for the lifetime of the returned Wal* handle. ** +** Custom virtual methods may be provided via the pMethods parameter. +** ** A SHARED lock should be held on the database file when this function ** is called. The purpose of this SHARED lock is to prevent any other ** client from unlinking the WAL or wal-index file. If another process @@ -65864,12 +65560,13 @@ static void walIndexClose(Wal *pWal, int isDelete){ ** *ppWal is set to point to a new WAL handle. If an error occurs, ** an SQLite error code is returned and *ppWal is left unmodified. */ -SQLITE_PRIVATE int sqlite3WalOpen( +static int sqlite3WalOpen( sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */ sqlite3_file *pDbFd, /* The open database file */ const char *zWalName, /* Name of the WAL file */ int bNoShm, /* True to run in heap-memory mode */ i64 mxWalSize, /* Truncate WAL to this size on reset */ + libsql_wal_methods* pMethods, /* Virtual methods for interacting with WAL */ Wal **ppWal /* OUT: Allocated Wal handle */ ){ int rc; /* Return Code */ @@ -65960,14 +65657,15 @@ SQLITE_PRIVATE int sqlite3WalOpen( } *ppWal = pRet; WALTRACE(("WAL%d: opened\n", pRet)); + pRet->pMethods = pMethods; } return rc; } /* -** 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){ +static void sqlite3WalLimit(Wal *pWal, i64 iLimit){ if( pWal ) pWal->mxWalSize = iLimit; } @@ -66191,16 +65889,23 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ 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]); - SEH_FREE_ON_ERROR(0, p); + + /* 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; + } + for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && iaSegment[i].aPgno = (u32 *)sLoc.aPgno; } } + sqlite3_free(aTmp); + if( rc!=SQLITE_OK ){ - SEH_FREE_ON_ERROR(p, 0); walIteratorFree(p); p = 0; } @@ -66276,7 +65982,7 @@ static void walDisableBlocking(Wal *pWal){ ** ** If the bLock parameter is false and the WRITER lock is held, release it. */ -SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock){ +static int sqlite3WalWriteLock(Wal *pWal, int bLock){ int rc = SQLITE_OK; assert( pWal->readLock<0 || bLock==0 ); if( bLock ){ @@ -66295,13 +66001,6 @@ SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock){ return rc; } -/* -** Set the database handle used to determine if blocking locks are required. -*/ -SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){ - pWal->db = db; -} - /* ** Take an exclusive WRITE lock. Blocking if so configured. */ @@ -66316,9 +66015,16 @@ static int walLockWriter(Wal *pWal){ # define walEnableBlocking(x) 0 # define walDisableBlocking(x) # define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1) -# define sqlite3WalDb(pWal, db) #endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */ +/* +** Set the database handle used to determine if blocking locks are required. +*/ +static void sqlite3WalDb(Wal *pWal, sqlite3 *db){ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + pWal->db = db; +#endif +} /* ** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and @@ -66455,13 +66161,13 @@ static int walCheckpoint( mxSafeFrame = pWal->hdr.mxFrame; mxPage = pWal->hdr.nPage; for(i=1; iaReadMark+i); SEH_INJECT_FAULT; + u32 y = AtomicLoad(pInfo->aReadMark+i); if( mxSafeFrame>y ){ assert( y<=pWal->hdr.mxFrame ); rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); if( rc==SQLITE_OK ){ u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED); - AtomicStore(pInfo->aReadMark+i, iMark); SEH_INJECT_FAULT; + AtomicStore(pInfo->aReadMark+i, iMark); walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); }else if( rc==SQLITE_BUSY ){ mxSafeFrame = y; @@ -66482,7 +66188,8 @@ static int walCheckpoint( && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK ){ u32 nBackfill = pInfo->nBackfill; - pInfo->nBackfillAttempted = mxSafeFrame; SEH_INJECT_FAULT; + + pInfo->nBackfillAttempted = mxSafeFrame; /* Sync the WAL to disk */ rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); @@ -66513,7 +66220,6 @@ static int walCheckpoint( while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ i64 iOffset; assert( walFramePgno(pWal, iFrame)==iDbpage ); - SEH_INJECT_FAULT; if( AtomicLoad(&db->u1.isInterrupted) ){ rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; break; @@ -66543,7 +66249,7 @@ static int walCheckpoint( } } if( rc==SQLITE_OK ){ - AtomicStore(&pInfo->nBackfill, mxSafeFrame); SEH_INJECT_FAULT; + AtomicStore(&pInfo->nBackfill, mxSafeFrame); } } @@ -66565,7 +66271,6 @@ static int walCheckpoint( */ if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ assert( pWal->writeLock ); - SEH_INJECT_FAULT; if( pInfo->nBackfillhdr.mxFrame ){ rc = SQLITE_BUSY; }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ @@ -66597,7 +66302,6 @@ static int walCheckpoint( } walcheckpoint_out: - SEH_FREE_ON_ERROR(pIter, 0); walIteratorFree(pIter); return rc; } @@ -66620,97 +66324,10 @@ static void walLimitSize(Wal *pWal, i64 nMax){ } } -#ifdef SQLITE_USE_SEH -/* -** This is the "standard" exception handler used in a few places to handle -** an exception thrown by reading from the *-shm mapping after it has become -** invalid in SQLITE_USE_SEH builds. It is used as follows: -** -** SEH_TRY { ... } -** SEH_EXCEPT( rc = walHandleException(pWal); ) -** -** This function does three things: -** -** 1) Determines the locks that should be held, based on the contents of -** the Wal.readLock, Wal.writeLock and Wal.ckptLock variables. All other -** held locks are assumed to be transient locks that would have been -** released had the exception not been thrown and are dropped. -** -** 2) Frees the pointer at Wal.pFree, if any, using sqlite3_free(). -** -** 3) Set pWal->apWiData[pWal->iWiPg] to pWal->pWiValue if not NULL -** -** 4) Returns SQLITE_IOERR. -*/ -static int walHandleException(Wal *pWal){ - if( pWal->exclusiveMode==0 ){ - static const int S = 1; - static const int E = (1<lockMask & ~( - (pWal->readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) - | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) - | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) - ); - for(ii=0; iipFree); - pWal->pFree = 0; - if( pWal->pWiValue ){ - pWal->apWiData[pWal->iWiPg] = pWal->pWiValue; - pWal->pWiValue = 0; - } - return SQLITE_IOERR_IN_PAGE; -} - -/* -** Assert that the Wal.lockMask mask, which indicates the locks held -** by the connenction, is consistent with the Wal.readLock, Wal.writeLock -** and Wal.ckptLock variables. To be used as: -** -** assert( walAssertLockmask(pWal) ); -*/ -static int walAssertLockmask(Wal *pWal){ - if( pWal->exclusiveMode==0 ){ - static const int S = 1; - static const int E = (1<readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) - | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) - | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) -#ifdef SQLITE_ENABLE_SNAPSHOT - | (pWal->pSnapshot ? (pWal->lockMask & (1 << WAL_CKPT_LOCK)) : 0) -#endif - ); - assert( mExpect==pWal->lockMask ); - } - return 1; -} - -/* -** Return and zero the "system error" field set when an -** EXCEPTION_IN_PAGE_ERROR exception is caught. -*/ -SQLITE_PRIVATE int sqlite3WalSystemErrno(Wal *pWal){ - int iRet = 0; - if( pWal ){ - iRet = pWal->iSysErrno; - pWal->iSysErrno = 0; - } - return iRet; -} - -#else -# define walAssertLockmask(x) 1 -#endif /* ifdef SQLITE_USE_SEH */ - /* ** Close a connection to a log file. */ -SQLITE_PRIVATE int sqlite3WalClose( +static int sqlite3WalClose( Wal *pWal, /* Wal to close */ sqlite3 *db, /* For interrupt flag */ int sync_flags, /* Flags to pass to OsSync() (or 0) */ @@ -66721,8 +66338,6 @@ SQLITE_PRIVATE int sqlite3WalClose( if( pWal ){ int isDelete = 0; /* True to unlink wal and wal-index files */ - assert( walAssertLockmask(pWal) ); - /* If an EXCLUSIVE lock can be obtained on the database file (using the ** ordinary, rollback-mode locking methods, this guarantees that the ** connection associated with this log file is the only connection to @@ -66737,7 +66352,7 @@ SQLITE_PRIVATE int sqlite3WalClose( if( pWal->exclusiveMode==WAL_NORMAL_MODE ){ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; } - rc = sqlite3WalCheckpoint(pWal, db, + rc = pWal->pMethods->xCheckpoint(pWal, db, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0 ); if( rc==SQLITE_OK ){ @@ -66747,7 +66362,7 @@ SQLITE_PRIVATE int sqlite3WalClose( ); if( bPersist!=1 ){ /* Try to delete the WAL file if the checkpoint completed and - ** fsynced (rc==SQLITE_OK) and if we are not in persistent-wal + ** fsyned (rc==SQLITE_OK) and if we are not in persistent-wal ** mode (!bPersist) */ isDelete = 1; }else if( pWal->mxWalSize>=0 ){ @@ -66814,7 +66429,7 @@ static SQLITE_NO_TSAN int walIndexTryHdr(Wal *pWal, int *pChanged){ ** give false-positive warnings about these accesses because the tools do not ** account for the double-read and the memory barrier. The use of mutexes ** here would be problematic as the memory being accessed is potentially - ** shared among multiple processes and not all mutex implementations work + ** shared among multiple processes and not all mutex implementions work ** reliably in that environment. */ aHdr = walIndexHdr(pWal); @@ -67128,7 +66743,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ pWal->apWiData[i] = 0; } pWal->bShmUnreliable = 0; - sqlite3WalEndReadTransaction(pWal); + pWal->pMethods->xEndReadTransaction(pWal); *pChanged = 1; } return rc; @@ -67265,7 +66880,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ assert( pWal->nWiData>0 ); assert( pWal->apWiData[0]!=0 ); pInfo = walCkptInfo(pWal); - SEH_INJECT_FAULT; if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame #ifdef SQLITE_ENABLE_SNAPSHOT && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0) @@ -67315,7 +66929,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ } #endif for(i=1; iaReadMark+i); SEH_INJECT_FAULT; + u32 thisMark = AtomicLoad(pInfo->aReadMark+i); if( mxReadMark<=thisMark && thisMark<=mxFrame ){ assert( thisMark!=READMARK_NOT_USED ); mxReadMark = thisMark; @@ -67381,7 +66995,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ ** we can guarantee that the checkpointer that set nBackfill could not ** see any pages past pWal->hdr.mxFrame, this problem does not come up. */ - pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT; + pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; walShmBarrier(pWal); if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) @@ -67396,54 +67010,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ } #ifdef SQLITE_ENABLE_SNAPSHOT -/* -** This function does the work of sqlite3WalSnapshotRecover(). -*/ -static int walSnapshotRecover( - Wal *pWal, /* WAL handle */ - void *pBuf1, /* Temp buffer pWal->szPage bytes in size */ - void *pBuf2 /* Temp buffer pWal->szPage bytes in size */ -){ - int szPage = (int)pWal->szPage; - int rc; - i64 szDb; /* Size of db file in bytes */ - - rc = sqlite3OsFileSize(pWal->pDbFd, &szDb); - if( rc==SQLITE_OK ){ - volatile WalCkptInfo *pInfo = walCkptInfo(pWal); - u32 i = pInfo->nBackfillAttempted; - for(i=pInfo->nBackfillAttempted; i>AtomicLoad(&pInfo->nBackfill); i--){ - WalHashLoc sLoc; /* Hash table location */ - u32 pgno; /* Page number in db file */ - i64 iDbOff; /* Offset of db file entry */ - i64 iWalOff; /* Offset of wal file entry */ - - rc = walHashGet(pWal, walFramePage(i), &sLoc); - if( rc!=SQLITE_OK ) break; - assert( i - sLoc.iZero - 1 >=0 ); - pgno = sLoc.aPgno[i-sLoc.iZero-1]; - iDbOff = (i64)(pgno-1) * szPage; - - if( iDbOff+szPage<=szDb ){ - iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; - rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); - - if( rc==SQLITE_OK ){ - rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); - } - - if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ - break; - } - } - - pInfo->nBackfillAttempted = i-1; - } - } - - return rc; -} - /* ** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted ** variable so that older snapshots can be accessed. To do this, loop @@ -67463,27 +67029,56 @@ static int walSnapshotRecover( ** error occurs. It is not an error if nBackfillAttempted cannot be ** decreased at all. */ -SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){ +static int sqlite3WalSnapshotRecover(Wal *pWal){ int rc; assert( pWal->readLock>=0 ); rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); if( rc==SQLITE_OK ){ - void *pBuf1 = sqlite3_malloc(pWal->szPage); - void *pBuf2 = sqlite3_malloc(pWal->szPage); - if( pBuf1==0 || pBuf2==0 ){ - rc = SQLITE_NOMEM; - }else{ - pWal->ckptLock = 1; - SEH_TRY { - rc = walSnapshotRecover(pWal, pBuf1, pBuf2); + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + int szPage = (int)pWal->szPage; + i64 szDb; /* Size of db file in bytes */ + + rc = sqlite3OsFileSize(pWal->pDbFd, &szDb); + if( rc==SQLITE_OK ){ + void *pBuf1 = sqlite3_malloc(szPage); + void *pBuf2 = sqlite3_malloc(szPage); + if( pBuf1==0 || pBuf2==0 ){ + rc = SQLITE_NOMEM; + }else{ + u32 i = pInfo->nBackfillAttempted; + for(i=pInfo->nBackfillAttempted; i>AtomicLoad(&pInfo->nBackfill); i--){ + WalHashLoc sLoc; /* Hash table location */ + u32 pgno; /* Page number in db file */ + i64 iDbOff; /* Offset of db file entry */ + i64 iWalOff; /* Offset of wal file entry */ + + rc = walHashGet(pWal, walFramePage(i), &sLoc); + if( rc!=SQLITE_OK ) break; + assert( i - sLoc.iZero - 1 >=0 ); + pgno = sLoc.aPgno[i-sLoc.iZero-1]; + iDbOff = (i64)(pgno-1) * szPage; + + if( iDbOff+szPage<=szDb ){ + iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; + rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); + + if( rc==SQLITE_OK ){ + rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); + } + + if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ + break; + } + } + + pInfo->nBackfillAttempted = i-1; + } } - SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) - pWal->ckptLock = 0; - } - sqlite3_free(pBuf1); - sqlite3_free(pBuf2); + sqlite3_free(pBuf1); + sqlite3_free(pBuf2); + } walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); } @@ -67492,20 +67087,28 @@ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){ #endif /* SQLITE_ENABLE_SNAPSHOT */ /* -** This function does the work of sqlite3WalBeginReadTransaction() (see -** below). That function simply calls this one inside an SEH_TRY{...} block. +** Begin a read transaction on the database. +** +** This routine used to be called sqlite3OpenSnapshot() and with good reason: +** it takes a snapshot of the state of the WAL and wal-index for the current +** instant in time. The current thread will continue to use this snapshot. +** Other threads might append new content to the WAL and wal-index but +** that extra content is ignored by the current thread. +** +** If the database contents have changes since the previous read +** transaction, then *pChanged is set to 1 before returning. The +** Pager layer will use this to know that its cache is stale and +** needs to be flushed. */ -static int walBeginReadTransaction(Wal *pWal, int *pChanged){ +static int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ int rc; /* Return code */ int cnt = 0; /* Number of TryBeginRead attempts */ #ifdef SQLITE_ENABLE_SNAPSHOT - int ckptLock = 0; int bChanged = 0; WalIndexHdr *pSnapshot = pWal->pSnapshot; #endif assert( pWal->ckptLock==0 ); - assert( pWal->nSehTry>0 ); #ifdef SQLITE_ENABLE_SNAPSHOT if( pSnapshot ){ @@ -67528,7 +67131,7 @@ static int walBeginReadTransaction(Wal *pWal, int *pChanged){ if( rc!=SQLITE_OK ){ return rc; } - ckptLock = 1; + pWal->ckptLock = 1; } #endif @@ -67586,49 +67189,27 @@ static int walBeginReadTransaction(Wal *pWal, int *pChanged){ pWal->minFrame = 1; if( rc!=SQLITE_OK ){ - sqlite3WalEndReadTransaction(pWal); + pWal->pMethods->xEndReadTransaction(pWal); } } } /* Release the shared CKPT lock obtained above. */ - if( ckptLock ){ + if( pWal->ckptLock ){ assert( pSnapshot ); walUnlockShared(pWal, WAL_CKPT_LOCK); + pWal->ckptLock = 0; } #endif return rc; } -/* -** Begin a read transaction on the database. -** -** This routine used to be called sqlite3OpenSnapshot() and with good reason: -** it takes a snapshot of the state of the WAL and wal-index for the current -** instant in time. The current thread will continue to use this snapshot. -** Other threads might append new content to the WAL and wal-index but -** that extra content is ignored by the current thread. -** -** If the database contents have changes since the previous read -** transaction, then *pChanged is set to 1 before returning. The -** Pager layer will use this to know that its cache is stale and -** needs to be flushed. -*/ -SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ - int rc; - SEH_TRY { - rc = walBeginReadTransaction(pWal, pChanged); - } - SEH_EXCEPT( rc = walHandleException(pWal); ) - return rc; -} - /* ** Finish with a read transaction. All this does is release the ** read-lock. */ -SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){ - sqlite3WalEndWriteTransaction(pWal); +static void sqlite3WalEndReadTransaction(Wal *pWal){ + pWal->pMethods->xEndWriteTransaction(pWal); if( pWal->readLock>=0 ){ walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); pWal->readLock = -1; @@ -67643,7 +67224,7 @@ SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){ ** Return SQLITE_OK if successful, or an error code if an error occurs. If an ** error does occur, the final value of *piRead is undefined. */ -static int walFindFrame( +static int sqlite3WalFindFrame( Wal *pWal, /* WAL handle */ Pgno pgno, /* Database page number to read data for */ u32 *piRead /* OUT: Frame number (or zero) */ @@ -67706,7 +67287,6 @@ static int walFindFrame( } nCollide = HASHTABLE_NSLOT; iKey = walHash(pgno); - SEH_INJECT_FAULT; while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){ u32 iFrame = iH + sLoc.iZero; if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH-1]==pgno ){ @@ -67743,36 +67323,12 @@ static int walFindFrame( return SQLITE_OK; } -/* -** Search the wal file for page pgno. If found, set *piRead to the frame that -** contains the page. Otherwise, if pgno is not in the wal file, set *piRead -** to zero. -** -** Return SQLITE_OK if successful, or an error code if an error occurs. If an -** error does occur, the final value of *piRead is undefined. -** -** The difference between this function and walFindFrame() is that this -** function wraps walFindFrame() in an SEH_TRY{...} block. -*/ -SQLITE_PRIVATE int sqlite3WalFindFrame( - Wal *pWal, /* WAL handle */ - Pgno pgno, /* Database page number to read data for */ - u32 *piRead /* OUT: Frame number (or zero) */ -){ - int rc; - SEH_TRY { - rc = walFindFrame(pWal, pgno, piRead); - } - SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) - return rc; -} - /* ** Read the contents of frame iRead from the wal file into buffer pOut ** (which is nOut bytes in size). Return SQLITE_OK if successful, or an ** error code otherwise. */ -SQLITE_PRIVATE int sqlite3WalReadFrame( +static int sqlite3WalReadFrame( Wal *pWal, /* WAL handle */ u32 iRead, /* Frame to read */ int nOut, /* Size of buffer pOut in bytes */ @@ -67792,7 +67348,7 @@ SQLITE_PRIVATE int sqlite3WalReadFrame( /* ** Return the size of the database in pages (or zero, if unknown). */ -SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){ +static Pgno sqlite3WalDbsize(Wal *pWal){ if( pWal && ALWAYS(pWal->readLock>=0) ){ return pWal->hdr.nPage; } @@ -67813,7 +67369,7 @@ SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){ ** ** There can only be a single writer active at a time. */ -SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){ +static int sqlite3WalBeginWriteTransaction(Wal *pWal){ int rc; #ifdef SQLITE_ENABLE_SETLK_TIMEOUT @@ -67848,17 +67404,12 @@ SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){ ** time the read transaction on this connection was started, then ** the write is disallowed. */ - SEH_TRY { - if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){ - rc = SQLITE_BUSY_SNAPSHOT; - } - } - SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) - - if( rc!=SQLITE_OK ){ + if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){ walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); pWal->writeLock = 0; + rc = SQLITE_BUSY_SNAPSHOT; } + return rc; } @@ -67866,7 +67417,7 @@ SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){ ** End a write transaction. The commit has already been done. This ** routine merely releases the lock. */ -SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){ +static int sqlite3WalEndWriteTransaction(Wal *pWal){ if( pWal->writeLock ){ walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); pWal->writeLock = 0; @@ -67888,39 +67439,36 @@ SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){ ** Otherwise, if the callback function does not return an error, this ** function returns SQLITE_OK. */ -SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){ +static int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){ int rc = SQLITE_OK; if( ALWAYS(pWal->writeLock) ){ Pgno iMax = pWal->hdr.mxFrame; Pgno iFrame; - SEH_TRY { - /* Restore the clients cache of the wal-index header to the state it - ** was in before the client began writing to the database. - */ - memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr)); + /* Restore the clients cache of the wal-index header to the state it + ** was in before the client began writing to the database. + */ + memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr)); - for(iFrame=pWal->hdr.mxFrame+1; - ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; - iFrame++ - ){ - /* This call cannot fail. Unless the page for which the page number - ** is passed as the second argument is (a) in the cache and - ** (b) has an outstanding reference, then xUndo is either a no-op - ** (if (a) is false) or simply expels the page from the cache (if (b) - ** is false). - ** - ** If the upper layer is doing a rollback, it is guaranteed that there - ** are no outstanding references to any page other than page 1. And - ** page 1 is never written to the log until the transaction is - ** committed. As a result, the call to xUndo may not fail. - */ - assert( walFramePgno(pWal, iFrame)!=1 ); - rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); - } - if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); + for(iFrame=pWal->hdr.mxFrame+1; + ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; + iFrame++ + ){ + /* This call cannot fail. Unless the page for which the page number + ** is passed as the second argument is (a) in the cache and + ** (b) has an outstanding reference, then xUndo is either a no-op + ** (if (a) is false) or simply expels the page from the cache (if (b) + ** is false). + ** + ** If the upper layer is doing a rollback, it is guaranteed that there + ** are no outstanding references to any page other than page 1. And + ** page 1 is never written to the log until the transaction is + ** committed. As a result, the call to xUndo may not fail. + */ + assert( walFramePgno(pWal, iFrame)!=1 ); + rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); } - SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); } return rc; } @@ -67931,7 +67479,7 @@ SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *p ** "rollback" the write position of the WAL handle back to the current ** point in the event of a savepoint rollback (via WalSavepointUndo()). */ -SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ +static void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ assert( pWal->writeLock ); aWalData[0] = pWal->hdr.mxFrame; aWalData[1] = pWal->hdr.aFrameCksum[0]; @@ -67945,7 +67493,7 @@ SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ ** of WAL_SAVEPOINT_NDATA u32 values that has been previously populated ** by a call to WalSavepoint(). */ -SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ +static int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ int rc = SQLITE_OK; assert( pWal->writeLock ); @@ -67964,10 +67512,7 @@ SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ pWal->hdr.mxFrame = aWalData[0]; pWal->hdr.aFrameCksum[0] = aWalData[1]; pWal->hdr.aFrameCksum[1] = aWalData[2]; - SEH_TRY { - walCleanupHash(pWal); - } - SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + walCleanupHash(pWal); } return rc; @@ -68148,7 +67693,7 @@ static int walRewriteChecksums(Wal *pWal, u32 iLast){ ** Write a set of frames to the log. The caller must hold the write-lock ** on the log file (obtained using sqlite3WalBeginWriteTransaction()). */ -static int walFrames( +static int sqlite3WalFrames( Wal *pWal, /* Wal handle to write to */ int szPage, /* Database page-size in bytes */ PgHdr *pList, /* List of dirty pages to write */ @@ -68259,7 +67804,7 @@ static int walFrames( ** checksums must be recomputed when the transaction is committed. */ if( iFirst && (p->pDirty || isCommit==0) ){ u32 iWrite = 0; - VVA_ONLY(rc =) walFindFrame(pWal, p->pgno, &iWrite); + VVA_ONLY(rc =) pWal->pMethods->xFindFrame(pWal, p->pgno, &iWrite); assert( rc==SQLITE_OK || iWrite==0 ); if( iWrite>=iFirst ){ i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE; @@ -68378,29 +67923,6 @@ static int walFrames( return rc; } -/* -** Write a set of frames to the log. The caller must hold the write-lock -** on the log file (obtained using sqlite3WalBeginWriteTransaction()). -** -** The difference between this function and walFrames() is that this -** function wraps walFrames() in an SEH_TRY{...} block. -*/ -SQLITE_PRIVATE int sqlite3WalFrames( - Wal *pWal, /* Wal handle to write to */ - int szPage, /* Database page-size in bytes */ - PgHdr *pList, /* List of dirty pages to write */ - Pgno nTruncate, /* Database size after this commit */ - int isCommit, /* True if this is a commit */ - int sync_flags /* Flags to pass to OsSync() (or 0) */ -){ - int rc; - SEH_TRY { - rc = walFrames(pWal, szPage, pList, nTruncate, isCommit, sync_flags); - } - SEH_EXCEPT( rc = walHandleException(pWal); ) - return rc; -} - /* ** This routine is called to implement sqlite3_wal_checkpoint() and ** related interfaces. @@ -68411,7 +67933,7 @@ SQLITE_PRIVATE int sqlite3WalFrames( ** If parameter xBusy is not NULL, it is a pointer to a busy-handler ** callback. In this case this function runs a blocking checkpoint. */ -SQLITE_PRIVATE int sqlite3WalCheckpoint( +static int sqlite3WalCheckpoint( Wal *pWal, /* Wal connection */ sqlite3 *db, /* Check this handle's interrupt flag */ int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */ @@ -68440,7 +67962,7 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( /* Enable blocking locks, if possible. If blocking locks are successfully ** enabled, set xBusy2=0 so that the busy-handler is never invoked. */ - sqlite3WalDb(pWal, db); + pWal->pMethods->xDb(pWal, db); (void)walEnableBlocking(pWal); /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive @@ -68480,33 +68002,30 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( /* Read the wal-index header. */ - SEH_TRY { - if( rc==SQLITE_OK ){ - walDisableBlocking(pWal); - rc = walIndexReadHdr(pWal, &isChanged); - (void)walEnableBlocking(pWal); - if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ - sqlite3OsUnfetch(pWal->pDbFd, 0, 0); - } + if( rc==SQLITE_OK ){ + walDisableBlocking(pWal); + rc = walIndexReadHdr(pWal, &isChanged); + (void)walEnableBlocking(pWal); + if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ + sqlite3OsUnfetch(pWal->pDbFd, 0, 0); } + } - /* Copy data from the log to the database file. */ - if( rc==SQLITE_OK ){ - if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ - rc = SQLITE_CORRUPT_BKPT; - }else{ - rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags,zBuf); - } + /* Copy data from the log to the database file. */ + if( rc==SQLITE_OK ){ - /* If no error occurred, set the output variables. */ - if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ - if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; - SEH_INJECT_FAULT; - if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill); - } + if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags, zBuf); + } + + /* If no error occurred, set the output variables. */ + if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ + if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; + if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill); } } - SEH_EXCEPT( rc = walHandleException(pWal); ) if( isChanged ){ /* If a new wal-index header was loaded before the checkpoint was @@ -68519,10 +68038,10 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( } walDisableBlocking(pWal); - sqlite3WalDb(pWal, 0); + pWal->pMethods->xDb(pWal, 0); /* Release the locks. */ - sqlite3WalEndWriteTransaction(pWal); + pWal->pMethods->xEndWriteTransaction(pWal); if( pWal->ckptLock ){ walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); pWal->ckptLock = 0; @@ -68539,7 +68058,7 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( ** sqlite3WalCallback() was called. If no commits have occurred since ** the last call, then return 0. */ -SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal){ +static int sqlite3WalCallback(Wal *pWal){ u32 ret = 0; if( pWal ){ ret = pWal->iCallback; @@ -68572,7 +68091,7 @@ SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal){ ** should acquire the database exclusive lock prior to invoking ** the op==1 case. */ -SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){ +static int sqlite3WalExclusiveMode(Wal *pWal, int op){ int rc; assert( pWal->writeLock==0 ); assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 ); @@ -68583,9 +68102,7 @@ SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){ ** locks are taken in this case). Nor should the pager attempt to ** upgrade to exclusive-mode following such an error. */ -#ifndef SQLITE_USE_SEH assert( pWal->readLock>=0 || pWal->lockError ); -#endif assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) ); if( op==0 ){ @@ -68616,7 +68133,7 @@ SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){ ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the ** WAL module is using shared-memory, return false. */ -SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){ +static int sqlite3WalHeapMemory(Wal *pWal){ return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ); } @@ -68625,7 +68142,7 @@ SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){ ** every other subsystem, so the WAL module can put whatever it needs ** in the object. */ -SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){ +static int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){ int rc = SQLITE_OK; WalIndexHdr *pRet; static const u32 aZero[4] = { 0, 0, 0, 0 }; @@ -68649,7 +68166,7 @@ SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapsho /* Try to open on pSnapshot when the next read-transaction starts */ -SQLITE_PRIVATE void sqlite3WalSnapshotOpen( +static void sqlite3WalSnapshotOpen( Wal *pWal, sqlite3_snapshot *pSnapshot ){ @@ -68684,21 +68201,18 @@ SQLITE_API int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){ ** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER ** lock is released before returning. */ -SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){ +static int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){ int rc; - SEH_TRY { - rc = walLockShared(pWal, WAL_CKPT_LOCK); - if( rc==SQLITE_OK ){ - WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot; - if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) - || pNew->mxFramenBackfillAttempted - ){ - rc = SQLITE_ERROR_SNAPSHOT; - walUnlockShared(pWal, WAL_CKPT_LOCK); - } + rc = walLockShared(pWal, WAL_CKPT_LOCK); + if( rc==SQLITE_OK ){ + WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot; + if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) + || pNew->mxFramenBackfillAttempted + ){ + rc = SQLITE_ERROR_SNAPSHOT; + walUnlockShared(pWal, WAL_CKPT_LOCK); } } - SEH_EXCEPT( rc = walHandleException(pWal); ) return rc; } @@ -68706,7 +68220,7 @@ SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapsho ** Release a lock obtained by an earlier successful call to ** sqlite3WalSnapshotCheck(). */ -SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal){ +static void sqlite3WalSnapshotUnlock(Wal *pWal){ assert( pWal ); walUnlockShared(pWal, WAL_CKPT_LOCK); } @@ -68720,7 +68234,7 @@ SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal){ ** read-lock. This function returns the database page-size if it is known, ** or zero if it is not (or if pWal is NULL). */ -SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){ +static int sqlite3WalFramesize(Wal *pWal){ assert( pWal==0 || pWal->readLock>=0 ); return (pWal ? pWal->szPage : 0); } @@ -68728,10 +68242,165 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){ /* Return the sqlite3_file object for the WAL file */ -SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ +static sqlite3_file *sqlite3WalFile(Wal *pWal){ return pWal->pWalFd; } +static int libsqlWalPathnameLen(int n) { + return n ? n + 4 : 0; +} + +static void libsqlGetWalPathname(char *buf, const char *orig, int orig_len) { + memcpy(buf, orig, orig_len); + memcpy(buf + orig_len, "-wal", 4); +} + +static int libsqlPreMainDbOpen(struct libsql_wal_methods *methods, const char *main_db_path) { + return SQLITE_OK; +} + +libsql_wal_methods *libsql_wal_methods_find(const char *zName) { + static libsql_wal_methods methods; + static libsql_wal_methods *methods_head = NULL; + +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if (rc != SQLITE_OK) { + return NULL; + } +#endif + + if (!zName || *zName == '\0') { + zName = "default"; + } + if (methods_head == NULL && strncmp(zName, "default", 7) == 0) { + methods.iVersion = 1; + methods.xOpen = sqlite3WalOpen; + methods.xClose = sqlite3WalClose; + methods.xLimit = sqlite3WalLimit; + methods.xBeginReadTransaction = sqlite3WalBeginReadTransaction; + methods.xEndReadTransaction = sqlite3WalEndReadTransaction; + methods.xFindFrame = sqlite3WalFindFrame; + methods.xReadFrame = sqlite3WalReadFrame; + methods.xDbsize = sqlite3WalDbsize; + methods.xBeginWriteTransaction = sqlite3WalBeginWriteTransaction; + methods.xEndWriteTransaction = sqlite3WalEndWriteTransaction; + methods.xUndo = sqlite3WalUndo; + methods.xSavepoint = sqlite3WalSavepoint; + methods.xSavepointUndo = sqlite3WalSavepointUndo; + methods.xFrames = sqlite3WalFrames; + methods.xCheckpoint = sqlite3WalCheckpoint; + methods.xCallback = sqlite3WalCallback; + methods.xExclusiveMode = sqlite3WalExclusiveMode; + methods.xHeapMemory = sqlite3WalHeapMemory; + +#ifdef SQLITE_ENABLE_SNAPSHOT + methods.xSnapshotGet = sqlite3WalSnapshotGet; + methods.xSnapshotOpen = sqlite3WalSnapshotOpen; + methods.xSnapshotRecover = sqlite3WalSnapshotRecover; + methods.xSnapshotCheck = sqlite3WalSnapshotCheck; + methods.xSnapshotUnlock = sqlite3WalSnapshotUnlock; +#endif + +#ifdef SQLITE_ENABLE_ZIPVFS + methods.xFramesize = sqlite3WalFramesize; +#endif + + methods.xFile = sqlite3WalFile; + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + methods.xWriteLock = sqlite3WalWriteLock; +#endif + methods.xDb = sqlite3WalDb; + methods.xPathnameLen = libsqlWalPathnameLen; + methods.xGetWalPathname = libsqlGetWalPathname; + methods.xPreMainDbOpen = libsqlPreMainDbOpen; + + methods.bUsesShm = 1; + methods.zName = "default"; + methods.pNext = NULL; + methods_head = &methods; + + return methods_head; + } + + // Look up in the methods table + for (libsql_wal_methods *m = methods_head; m != NULL; m = m->pNext) { + if (m && strcmp(zName, m->zName) == 0) { + return m; + } + } + + return NULL; +} + +int libsql_wal_methods_register(libsql_wal_methods* pWalMethods) { +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if (rc != SQLITE_OK) { + return rc; + } +#endif + + if (strncmp(pWalMethods->zName, "default", 7) == 0) { + return SQLITE_MISUSE; + } + MUTEX_LOGIC(sqlite3_mutex *mutex;) + MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); ) + sqlite3_mutex_enter(mutex); + + libsql_wal_methods *prev = libsql_wal_methods_find("default"); + libsql_wal_methods *m = prev->pNext; + + while (1) { + if (m == NULL) { + prev->pNext = pWalMethods; + pWalMethods->pNext = NULL; + break; + } + if (strcmp(m->zName, pWalMethods->zName) == 0) { + prev->pNext = pWalMethods; + pWalMethods->pNext = m->pNext; + break; + } + prev = m; + m = m->pNext; + } + sqlite3_mutex_leave(mutex); + return SQLITE_OK; +} + +int libsql_wal_methods_unregister(libsql_wal_methods *pWalMethods) { + if (strncmp(pWalMethods->zName, "default", 7) == 0) { + return SQLITE_MISUSE; + } + MUTEX_LOGIC(sqlite3_mutex *mutex;) + MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); ) + sqlite3_mutex_enter(mutex); + + libsql_wal_methods *prev = libsql_wal_methods_find("default"); + libsql_wal_methods *m = prev->pNext; + + while (m != NULL) { + if (strcmp(m->zName, pWalMethods->zName) == 0) { + prev->pNext = m->pNext; + break; + } + prev = m; + m = m->pNext; + } + sqlite3_mutex_leave(mutex); + return SQLITE_OK; +} + +libsql_wal_methods *libsql_wal_methods_next(libsql_wal_methods *w) { + return w->pNext; +} + +const char *libsql_wal_methods_name(libsql_wal_methods *w) { + return w->zName; +} + #endif /* #ifndef SQLITE_OMIT_WAL */ /************** End of wal.c *************************************************/ @@ -68937,7 +68606,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ ** 0x81 0x00 becomes 0x00000080 ** 0x82 0x00 becomes 0x00000100 ** 0x80 0x7f becomes 0x0000007f -** 0x81 0x91 0xd1 0xac 0x78 becomes 0x12345678 +** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678 ** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081 ** ** Variable length integers are used for rowids and to hold the number of @@ -69020,7 +68689,7 @@ typedef struct CellInfo CellInfo; ** 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.) ** @@ -69452,7 +69121,7 @@ struct IntegrityCk { BtShared *pBt; /* The tree being checked out */ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ u8 *aPgRef; /* 1 bit per page in the db (see above) */ - Pgno nCkPage; /* Pages in the database. 0 for partial check */ + Pgno nPage; /* Number of pages in the database */ int mxErr; /* Stop accumulating errors when this reaches zero */ int nErr; /* Number of messages written to zErrMsg so far */ int rc; /* SQLITE_OK, SQLITE_NOMEM, or SQLITE_INTERRUPT */ @@ -69476,7 +69145,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 @@ -69653,7 +69322,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. @@ -71320,7 +70989,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; @@ -71421,7 +71090,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; iiPage. +** +** 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; } /* @@ -72221,7 +71917,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); } } @@ -72259,12 +71955,13 @@ static int btreeInvokeBusyHandler(void *pArg){ ** to problems with locking. */ SQLITE_PRIVATE int sqlite3BtreeOpen( - sqlite3_vfs *pVfs, /* VFS to use for this b-tree */ - const char *zFilename, /* Name of the file containing the BTree database */ - sqlite3 *db, /* Associated database handle */ - Btree **ppBtree, /* Pointer to new Btree object written here */ - int flags, /* Options */ - int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */ + sqlite3_vfs *pVfs, /* VFS to use for this b-tree */ + libsql_wal_methods *pWal,/* WAL methods to use for this b-tree */ + const char *zFilename, /* Name of the file containing the BTree database */ + sqlite3 *db, /* Associated database handle */ + Btree **ppBtree, /* Pointer to new Btree object written here */ + int flags, /* Options */ + int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */ ){ BtShared *pBt = 0; /* Shared part of btree structure */ Btree *p; /* Handle to return */ @@ -72400,15 +72097,14 @@ 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; goto btree_open_out; } - rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, + void* pWalMethodsData = NULL; + if (db) pWalMethodsData= db->pWalMethodsData; + rc = sqlite3PagerOpen(pVfs, pWal, pWalMethodsData, &pBt->pPager, zFilename, sizeof(MemPage), flags, vfsFlags, pageReinit); if( rc==SQLITE_OK ){ sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap); @@ -72619,7 +72315,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. ** @@ -72854,7 +72550,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 @@ -73101,6 +72797,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 @@ -73120,7 +72817,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); @@ -73140,7 +72836,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 @@ -73320,7 +73015,7 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){ ** proceed. */ static SQLITE_NOINLINE int btreeBeginTrans( - Btree *p, /* The btree in which to start the transaction */ + Btree *p, /* The btree in which to start the transactino */ int wrflag, /* True to start a write transaction */ int *pSchemaVersion /* Put schema version number here, if not NULL */ ){ @@ -74612,6 +74307,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. @@ -74623,6 +74319,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 @@ -74648,7 +74345,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. @@ -75110,7 +74807,6 @@ SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){ ** vice-versa). */ static int moveToChild(BtCursor *pCur, u32 newPgno){ - int rc; assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPageapPage[pCur->iPage] = pCur->pPage; pCur->ix = 0; pCur->iPage++; - rc = getAndInitPage(pCur->pBt, newPgno, &pCur->pPage, pCur->curPagerFlags); - assert( pCur->pPage!=0 || rc!=SQLITE_OK ); - if( rc==SQLITE_OK - && (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; + return getAndInitPage(pCur->pBt, newPgno, &pCur->pPage, pCur, + pCur->curPagerFlags); } #ifdef SQLITE_DEBUG @@ -75242,7 +74928,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; @@ -75354,7 +75040,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; } @@ -75459,7 +75145,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); @@ -75855,36 +75541,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 ); @@ -76668,7 +76328,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. */ @@ -77279,13 +76939,12 @@ static int rebuildPage( int k; /* Current slot in pCArray->apEnd[] */ u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */ - assert( nCell>0 ); assert( i(u32)usableSize ){ j = 0; } + if( NEVER(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; @@ -77348,7 +77007,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( @@ -77368,7 +77027,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; @@ -77586,7 +77245,6 @@ static int editPage( return SQLITE_OK; editpage_fail: /* Unable to edit this page. Rebuild it from scratch instead. */ - if( nNew<1 ) return SQLITE_CORRUPT_BKPT; populateCellCache(pCArray, iNew, nNew); return rebuildPage(pCArray, iNew, nNew, pPg); } @@ -77664,7 +77322,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ ** with entries for the new page, and any pointer from the ** cell on the page to an overflow page. If either of these ** operations fails, the return code is set, but the contents - ** of the parent page are still manipulated by the code below. + ** of the parent page are still manipulated by thh code below. ** That is Ok, at this point the parent page is guaranteed to ** be marked as dirty. Returning an error code will cause a ** rollback, undoing any changes made to the parent page. @@ -77940,7 +77598,7 @@ static int balance_nonroot( pgno = get4byte(pRight); while( 1 ){ if( rc==SQLITE_OK ){ - rc = getAndInitPage(pBt, pgno, &apOld[i], 0); + rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0); } if( rc ){ memset(apOld, 0, (i+1)*sizeof(MemPage*)); @@ -78254,7 +77912,7 @@ static int balance_nonroot( } } - /* Sanity check: For a non-corrupt database file one of the following + /* Sanity check: For a non-corrupt database file one of the follwing ** must be true: ** (1) We found one or more cells (cntNew[0])>0), or ** (2) pPage is a virtual root page. A virtual root page is when @@ -78479,9 +78137,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 */ @@ -78873,7 +78529,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 */ @@ -79656,7 +79312,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 ); @@ -79825,7 +79481,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; if( (pBt->openFlags & BTREE_SINGLE)==0 && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1)) @@ -80246,8 +79902,7 @@ static void checkAppendMsg( ** corresponds to page iPg is already set. */ static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ - assert( pCheck->aPgRef!=0 ); - assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 ); + assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07))); } @@ -80255,8 +79910,7 @@ static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ ** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg. */ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ - assert( pCheck->aPgRef!=0 ); - assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 ); + assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07)); } @@ -80270,7 +79924,7 @@ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ ** Also check that the page number is in bounds. */ static int checkRef(IntegrityCk *pCheck, Pgno iPage){ - if( iPage>pCheck->nCkPage || iPage==0 ){ + if( iPage>pCheck->nPage || iPage==0 ){ checkAppendMsg(pCheck, "invalid page number %u", iPage); return 1; } @@ -80497,7 +80151,6 @@ static int checkTreePage( if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){ checkAppendMsg(pCheck, "unable to get the page. error code=%d", rc); - if( rc==SQLITE_IOERR_NOMEM ) pCheck->rc = SQLITE_NOMEM; goto end_of_check; } @@ -80768,15 +80421,15 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( sCheck.db = db; sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; - sCheck.nCkPage = btreePagecount(sCheck.pBt); + sCheck.nPage = btreePagecount(sCheck.pBt); sCheck.mxErr = mxErr; sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; - if( sCheck.nCkPage==0 ){ + if( sCheck.nPage==0 ){ goto integrity_ck_cleanup; } - sCheck.aPgRef = sqlite3MallocZero((sCheck.nCkPage / 8)+ 1); + sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); if( !sCheck.aPgRef ){ checkOom(&sCheck); goto integrity_ck_cleanup; @@ -80788,7 +80441,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( } i = PENDING_BYTE_PAGE(pBt); - if( i<=sCheck.nCkPage ) setPageReferenced(&sCheck, i); + if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i); /* Check the integrity of the freelist */ @@ -80839,7 +80492,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( /* Make sure every page in the file is referenced */ if( !bPartial ){ - for(i=1; i<=sCheck.nCkPage && sCheck.mxErr; i++){ + for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ #ifdef SQLITE_OMIT_AUTOVACUUM if( getPageReferenced(&sCheck, i)==0 ){ checkAppendMsg(&sCheck, "Page %u: never used", i); @@ -82258,40 +81911,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_Ephem|MEM_Static))!=MEM_Str ){ - /* pMem must be a string, and it cannot be an ephemeral or static string */ - 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==sqlite3RCStrUnref ){ - /* Blindly assume that all RCStr objects are zero-terminated */ - pMem->flags |= MEM_Term; - return; - } - }else if( 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. @@ -82553,6 +82172,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. @@ -82579,7 +82228,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{ @@ -82641,7 +82290,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 ** @@ -82709,8 +82358,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; } @@ -82781,7 +82430,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; @@ -82789,9 +82437,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; @@ -83315,24 +82961,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. */ @@ -83400,7 +83028,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 @@ -83459,7 +83086,7 @@ static int valueFromFunction( #endif assert( pFunc ); if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 - || (pFunc->funcFlags & (SQLITE_FUNC_NEEDCOLL|SQLITE_FUNC_RUNONLY))!=0 + || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) ){ return SQLITE_OK; } @@ -83660,7 +83287,6 @@ static int valueFromExpr( if( pVal ){ pVal->flags = MEM_Int; pVal->u.i = pExpr->u.zToken[4]==0; - sqlite3ValueApplyAffinity(pVal, affinity, enc); } } @@ -84183,43 +83809,13 @@ static int growOpArray(Vdbe *v, int nOp){ ** sqlite3CantopenError(lineno) */ static void test_addop_breakpoint(int pc, Op *pOp){ - static u64 n = 0; + static int n = 0; (void)pc; (void)pOp; n++; - if( n==LARGEST_UINT64 ) abort(); /* so that n is used, preventing a warning */ } #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. @@ -84230,16 +83826,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; @@ -84262,9 +83859,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 @@ -84281,59 +83875,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 @@ -84511,7 +84062,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; } @@ -84541,6 +84092,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){ @@ -84853,7 +84424,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ 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 @@ -84975,10 +84546,6 @@ SQLITE_PRIVATE void sqlite3VdbeNoJumpsOutsideSubrtn( int iDest = pOp->p2; /* Jump destination */ if( iDest==0 ) continue; if( pOp->opcode==OP_Gosub ) continue; - if( pOp->p3==20230325 && pOp->opcode==OP_NotNull ){ - /* This is a deliberately taken illegal branch. tag-20230325-2 */ - continue; - } if( iDest<0 ){ int j = ADDR(iDest); assert( j>=0 ); @@ -85227,8 +84794,8 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters( pScan = 0; } if( pScan ){ - if( addrLoop>0 ) pScan->addrLoop = addrLoop; - if( addrVisit>0 ) pScan->addrVisit = addrVisit; + pScan->addrLoop = addrLoop; + pScan->addrVisit = addrVisit; } } } @@ -85311,7 +84878,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 ); @@ -85475,6 +85042,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 @@ -86395,7 +85963,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), @@ -86414,7 +85982,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 ){ @@ -86628,9 +86196,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; @@ -86682,23 +86267,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); @@ -86799,12 +86368,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); @@ -86829,14 +86398,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; @@ -87349,7 +86918,6 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ sqlite3VdbeLeave(p); return SQLITE_BUSY; }else if( rc!=SQLITE_OK ){ - sqlite3SystemError(db, rc); p->rc = rc; sqlite3RollbackAll(db, SQLITE_OK); p->nChange = 0; @@ -87661,7 +87229,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){ @@ -88261,15 +87829,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; } @@ -88438,33 +87997,20 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem return n1 - n2; } -/* The following two functions are used only within testcase() to prove -** test coverage. These functions do no exist for production builds. -** We must use separate SQLITE_NOINLINE functions here, since otherwise -** optimizer code movement causes gcov to become very confused. -*/ -#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) -static int SQLITE_NOINLINE doubleLt(double a, double b){ return a8 ){ LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i; testcase( xr ); testcase( x==r ); - return (xr); + if( xr ) return +1; /*NO_TEST*/ /* work around bugs in gcov */ + return 0; /*NO_TEST*/ /* work around bugs in gcov */ }else{ i64 y; double s; @@ -88474,10 +88020,9 @@ SQLITE_PRIVATE int sqlite3IntFloatCompare(i64 i, double r){ if( iy ) return +1; s = (double)i; - testcase( doubleLt(s,r) ); - testcase( doubleLt(r,s) ); - testcase( doubleEq(r,s) ); - return (sr); + if( sr ) return +1; + return 0; } } @@ -88727,7 +88272,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; @@ -89845,7 +89390,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value *pOld){ ** is too big or if an OOM occurs. ** ** The invokeValueDestructor(P,X) routine invokes destructor function X() -** on value P if P is not going to be used and need to be destroyed. +** on value P is not going to be used and need to be destroyed. */ static void setResultStrOrError( sqlite3_context *pCtx, /* Function context */ @@ -89875,7 +89420,7 @@ static void setResultStrOrError( static int invokeValueDestructor( const void *p, /* Value to destroy */ void (*xDel)(void*), /* The destructor */ - sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if not NULL */ + sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if no NULL */ ){ assert( xDel!=SQLITE_DYNAMIC ); if( xDel==0 ){ @@ -89885,14 +89430,7 @@ static int invokeValueDestructor( }else{ xDel((void*)p); } -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx!=0 ){ - sqlite3_result_error_toobig(pCtx); - } -#else - assert( pCtx!=0 ); sqlite3_result_error_toobig(pCtx); -#endif return SQLITE_TOOBIG; } SQLITE_API void sqlite3_result_blob( @@ -89901,12 +89439,6 @@ SQLITE_API void sqlite3_result_blob( int n, void (*xDel)(void *) ){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 || n<0 ){ - invokeValueDestructor(z, xDel, pCtx); - return; - } -#endif assert( n>=0 ); assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, 0, xDel); @@ -89917,14 +89449,8 @@ SQLITE_API void sqlite3_result_blob64( sqlite3_uint64 n, void (*xDel)(void *) ){ - assert( xDel!=SQLITE_DYNAMIC ); -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ){ - invokeValueDestructor(z, xDel, 0); - return; - } -#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( xDel!=SQLITE_DYNAMIC ); if( n>0x7fffffff ){ (void)invokeValueDestructor(z, xDel, pCtx); }else{ @@ -89932,48 +89458,30 @@ SQLITE_API void sqlite3_result_blob64( } } SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return; -#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetDouble(pCtx->pOut, rVal); } SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return; -#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); } #ifndef SQLITE_OMIT_UTF16 SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return; -#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); } #endif SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return; -#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal); } SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return; -#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); } SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return; -#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); } @@ -89983,37 +89491,14 @@ SQLITE_API void sqlite3_result_pointer( const char *zPType, void (*xDestructor)(void*) ){ - Mem *pOut; -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ){ - invokeValueDestructor(pPtr, xDestructor, 0); - return; - } -#endif - pOut = pCtx->pOut; + Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); sqlite3VdbeMemRelease(pOut); pOut->flags = MEM_Null; sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor); } SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ - Mem *pOut; -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return; -#endif -#if defined(SQLITE_STRICT_SUBTYPE) && SQLITE_STRICT_SUBTYPE+0!=0 - if( pCtx->pFunc!=0 - && (pCtx->pFunc->funcFlags & SQLITE_RESULT_SUBTYPE)==0 - ){ - char zErr[200]; - sqlite3_snprintf(sizeof(zErr), zErr, - "misuse of sqlite3_result_subtype() by %s()", - pCtx->pFunc->zName); - sqlite3_result_error(pCtx, zErr, -1); - return; - } -#endif /* SQLITE_STRICT_SUBTYPE */ - pOut = pCtx->pOut; + Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); pOut->eSubtype = eSubtype & 0xff; pOut->flags |= MEM_Subtype; @@ -90024,12 +89509,6 @@ SQLITE_API void sqlite3_result_text( int n, void (*xDel)(void *) ){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ){ - invokeValueDestructor(z, xDel, 0); - return; - } -#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); } @@ -90040,12 +89519,6 @@ SQLITE_API void sqlite3_result_text64( void (*xDel)(void *), unsigned char enc ){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ){ - invokeValueDestructor(z, xDel, 0); - return; - } -#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); assert( xDel!=SQLITE_DYNAMIC ); if( enc!=SQLITE_UTF8 ){ @@ -90056,7 +89529,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 @@ -90089,16 +89561,7 @@ SQLITE_API void sqlite3_result_text16le( } #endif /* SQLITE_OMIT_UTF16 */ SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ - Mem *pOut; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return; - if( pValue==0 ){ - sqlite3_result_null(pCtx); - return; - } -#endif - pOut = pCtx->pOut; + Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemCopy(pOut, pValue); sqlite3VdbeChangeEncoding(pOut, pCtx->enc); @@ -90110,12 +89573,7 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ sqlite3_result_zeroblob64(pCtx, n>0 ? n : 0); } SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ - Mem *pOut; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return SQLITE_MISUSE_BKPT; -#endif - pOut = pCtx->pOut; + Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){ sqlite3_result_error_toobig(pCtx); @@ -90129,9 +89587,6 @@ SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ #endif } SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return; -#endif pCtx->isError = errCode ? errCode : -1; #ifdef SQLITE_DEBUG if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; @@ -90144,9 +89599,6 @@ SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ /* Force an SQLITE_TOOBIG error. */ SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return; -#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_TOOBIG; sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, @@ -90155,9 +89607,6 @@ SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ /* An SQLITE_NOMEM error. */ SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return; -#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); pCtx->isError = SQLITE_NOMEM_BKPT; @@ -90410,11 +89859,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ ** pointer to it. */ SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( p==0 ) return 0; -#else assert( p && p->pFunc ); -#endif return p->pFunc->pUserData; } @@ -90429,11 +89874,7 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ ** application defined function. */ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( p==0 ) return 0; -#else assert( p && p->pOut ); -#endif return p->pOut->db; } @@ -90452,11 +89893,7 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ ** value, as a signal to the xUpdate routine that the column is unchanged. */ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( p==0 ) return 0; -#else assert( p ); -#endif return sqlite3_value_nochange(p->pOut); } @@ -90464,7 +89901,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){ @@ -90484,7 +89921,7 @@ static int valueFromValueList( ValueList *pRhs; *ppOut = 0; - if( pVal==0 ) return SQLITE_MISUSE_BKPT; + if( pVal==0 ) return SQLITE_MISUSE; if( (pVal->flags & MEM_Dyn)==0 || pVal->xDel!=sqlite3VdbeValueListFree ){ return SQLITE_ERROR; }else{ @@ -90615,9 +90052,6 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ AuxData *pAuxData; -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return 0; -#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); #if SQLITE_ENABLE_STAT4 if( pCtx->pVdbe==0 ) return 0; @@ -90650,12 +90084,8 @@ SQLITE_API void sqlite3_set_auxdata( void (*xDelete)(void*) ){ AuxData *pAuxData; - Vdbe *pVdbe; + Vdbe *pVdbe = pCtx->pVdbe; -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCtx==0 ) return; -#endif - pVdbe= pCtx->pVdbe; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); #ifdef SQLITE_ENABLE_STAT4 if( pVdbe==0 ) goto failed; @@ -90711,8 +90141,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; } /* @@ -90801,7 +90230,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) { @@ -90885,32 +90314,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. @@ -90943,29 +90346,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( N=0 ){ u8 prior_mallocFailed = db->mallocFailed; N += useType*n; + sqlite3_mutex_enter(db->mutex); #ifndef SQLITE_OMIT_UTF16 if( useUtf16 ){ ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]); @@ -90982,9 +90371,8 @@ static const void *columnName( sqlite3OomClear(db); ret = 0; } + sqlite3_mutex_leave(db->mutex); } -columnName_end: - sqlite3_mutex_leave(db->mutex); return ret; } @@ -91077,7 +90465,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. @@ -91092,7 +90480,7 @@ static int vdbeUnbind(Vdbe *p, unsigned int i){ } sqlite3_mutex_enter(p->db->mutex); if( p->eVdbeState!=VDBE_READY_STATE ){ - sqlite3Error(p->db, SQLITE_MISUSE_BKPT); + sqlite3Error(p->db, SQLITE_MISUSE); sqlite3_mutex_leave(p->db->mutex); sqlite3_log(SQLITE_MISUSE, "bind on a busy prepared statement: [%s]", p->zSql); @@ -91321,9 +90709,6 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){ int rc; Vdbe *p = (Vdbe *)pStmt; -#ifdef SQLITE_ENABLE_API_ARMOR - if( p==0 ) return SQLITE_MISUSE_BKPT; -#endif sqlite3_mutex_enter(p->db->mutex); if( n>(u64)p->db->aLimit[SQLITE_LIMIT_LENGTH] ){ rc = SQLITE_TOOBIG; @@ -91444,42 +90829,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; -#ifdef SQLITE_ENABLE_API_ARMOR - if( pStmt==0 ) return SQLITE_MISUSE_BKPT; -#endif - sqlite3_mutex_enter(v->db->mutex); - if( ((int)v->explain)==eMode ){ - rc = SQLITE_OK; - }else if( eMode<0 || eMode>2 ){ - rc = SQLITE_ERROR; - }else if( (v->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){ - rc = SQLITE_ERROR; - }else if( v->eVdbeState!=VDBE_READY_STATE ){ - rc = SQLITE_BUSY; - }else if( v->nMem>=10 && (eMode!=2 || v->haveEqpOps) ){ - /* No reprepare necessary */ - v->explain = eMode; - rc = SQLITE_OK; - }else{ - v->explain = eMode; - rc = sqlite3Reprepare(v); - v->haveEqpOps = eMode==2; - } - 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. */ @@ -91520,7 +90869,7 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ u32 v; #ifdef SQLITE_ENABLE_API_ARMOR if( !pStmt - || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter))) + || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||(op>=ArraySize(pVdbe->aCounter)&&oppnBytesFreed = 0; db->lookaside.pEnd = db->lookaside.pTrueEnd; sqlite3_mutex_leave(db->mutex); + }else if( op>=LIBSQL_STMTSTATUS_BASE ){ + v = pVdbe->aLibsqlCounter[op - LIBSQL_STMTSTATUS_BASE]; + if( resetFlag ) pVdbe->aLibsqlCounter[op - LIBSQL_STMTSTATUS_BASE] = 0; }else{ v = pVdbe->aCounter[op]; if( resetFlag ) pVdbe->aCounter[op] = 0; @@ -91619,16 +90971,10 @@ static UnpackedRecord *vdbeUnpackRecord( ** a field of the row currently being updated or deleted. */ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ - PreUpdate *p; + PreUpdate *p = db->pPreUpdate; Mem *pMem; int rc = SQLITE_OK; -#ifdef SQLITE_ENABLE_API_ARMOR - if( db==0 || ppValue==0 ){ - return SQLITE_MISUSE_BKPT; - } -#endif - p = db->pPreUpdate; /* Test that this call is being made from within an SQLITE_DELETE or ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */ if( !p || p->op==SQLITE_INSERT ){ @@ -91689,12 +91035,7 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa ** the number of columns in the row being updated, deleted or inserted. */ SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){ - PreUpdate *p; -#ifdef SQLITE_ENABLE_API_ARMOR - p = db!=0 ? db->pPreUpdate : 0; -#else - p = db->pPreUpdate; -#endif + PreUpdate *p = db->pPreUpdate; return (p ? p->keyinfo.nKeyField : 0); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -91712,12 +91053,7 @@ SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){ ** or SET DEFAULT action is considered a trigger. */ SQLITE_API int sqlite3_preupdate_depth(sqlite3 *db){ - PreUpdate *p; -#ifdef SQLITE_ENABLE_API_ARMOR - p = db!=0 ? db->pPreUpdate : 0; -#else - p = db->pPreUpdate; -#endif + PreUpdate *p = db->pPreUpdate; return (p ? p->v->nFrame : 0); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -91728,12 +91064,7 @@ SQLITE_API int sqlite3_preupdate_depth(sqlite3 *db){ ** only. */ SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *db){ - PreUpdate *p; -#ifdef SQLITE_ENABLE_API_ARMOR - p = db!=0 ? db->pPreUpdate : 0; -#else - p = db->pPreUpdate; -#endif + PreUpdate *p = db->pPreUpdate; return (p ? p->iBlobWrite : -1); } #endif @@ -91744,16 +91075,10 @@ SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *db){ ** a field of the row currently being updated or inserted. */ SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ - PreUpdate *p; + PreUpdate *p = db->pPreUpdate; int rc = SQLITE_OK; Mem *pMem; -#ifdef SQLITE_ENABLE_API_ARMOR - if( db==0 || ppValue==0 ){ - return SQLITE_MISUSE_BKPT; - } -#endif - p = db->pPreUpdate; if( !p || p->op==SQLITE_DELETE ){ rc = SQLITE_MISUSE_BKPT; goto preupdate_new_out; @@ -91832,20 +91157,11 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2( void *pOut /* OUT: Write the answer here */ ){ Vdbe *p = (Vdbe*)pStmt; - VdbeOp *aOp; - int nOp; + VdbeOp *aOp = p->aOp; + int nOp = p->nOp; ScanStatus *pScan = 0; int idx; -#ifdef SQLITE_ENABLE_API_ARMOR - if( p==0 || pOut==0 - || iScanStatusOpSQLITE_SCANSTAT_NCYCLE ){ - return 1; - } -#endif - aOp = p->aOp; - nOp = p->nOp; if( p->pFrame ){ VdbeFrame *pFrame; for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); @@ -91992,7 +91308,7 @@ SQLITE_API int sqlite3_stmt_scanstatus( SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; int ii; - for(ii=0; p!=0 && iinOp; ii++){ + for(ii=0; iinOp; ii++){ Op *pOp = &p->aOp[ii]; pOp->nExec = 0; pOp->nCycle = 0; @@ -92219,6 +91535,9 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ +#ifdef LIBSQL_ENABLE_WASM_RUNTIME +/* #include "ext/udf/wasm_bindings.h" */ +#endif /* ** Invoke this macro on memory cells just prior to changing the @@ -92331,12 +91650,11 @@ SQLITE_API int sqlite3_found_count = 0; ** sqlite3CantopenError(lineno) */ static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ - static u64 n = 0; + static int n = 0; (void)pc; (void)pOp; (void)v; n++; - if( n==LARGEST_UINT64 ) abort(); /* So that n is used, preventing a warning */ } #endif @@ -92756,9 +92074,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 @@ -92895,93 +92210,6 @@ static u64 filterHash(const Mem *aMem, const Op *pOp){ 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 */ - u32 cacheStatus, /* Current Vdbe.cacheCtr value */ - u32 colCacheCtr, /* Current value of the column cache counter */ - 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 && pC->pKeyInfo==0 ){ - /* 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. - ** - ** Only do this on table-btrees so that writes to index-btrees do not - ** need to clear the cache. This buys performance in the common case - ** in exchange for generality. - */ - 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->cacheStatus!=cacheStatus - || pCache->colCacheCtr!=colCacheCtr - || 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->cacheStatus = cacheStatus; - pCache->colCacheCtr = colCacheCtr; - pCache->iOffset = sqlite3BtreeOffset(pC->uc.pCursor); - }else{ - pBuf = pCache->pCValue; - } - assert( t>=12 ); - sqlite3RCStrRef(pBuf); - if( t&1 ){ - rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, encoding, - sqlite3RCStrUnref); - pDest->flags |= MEM_Term; - }else{ - rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, 0, - 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 */ @@ -92996,6 +92224,11 @@ static const char *vdbeMemTypeName(Mem *pMem){ return azTypes[sqlite3_value_type(pMem)-1]; } +#ifdef LIBSQL_ENABLE_WASM_RUNTIME +FuncDef *try_instantiate_wasm_function(sqlite3 *db, const char *pName, int nName, const char *pSrcBody, int nBody, int nArg, char **err_msg_buf); +int deregister_wasm_function(sqlite3 *db, const char *zName); +#endif + /* ** Execute as much of a VDBE program as we can. ** This is the core of sqlite3_step(). @@ -93024,7 +92257,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec( Mem *pIn2 = 0; /* 2nd input operand */ Mem *pIn3 = 0; /* 3rd input operand */ Mem *pOut = 0; /* Output operand */ - u32 colCacheCtr = 0; /* Column cache counter */ #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) u64 *pnCycle = 0; int bStmtScanStatus = IS_STMT_SCANSTATUS(db)!=0; @@ -93220,8 +92452,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) ); @@ -93429,7 +92661,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 @@ -94560,10 +93792,10 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ ** opcodes are allowed to occur between this instruction and the previous ** OP_Lt or OP_Gt. ** -** If the result of an OP_Eq comparison on the same two operands as -** the prior OP_Lt or OP_Gt would have been true, then jump to P2. If -** the result of an OP_Eq comparison on the two previous operands -** would have been false or NULL, then fall through. +** If result of an OP_Eq comparison on the same two operands as the +** prior OP_Lt or OP_Gt would have been true, then jump to P2. +** If the result of an OP_Eq comparison on the two previous +** operands would have been false or NULL, then fall through. */ case OP_ElseEq: { /* same as TK_ESCAPE, jump */ @@ -94993,7 +94225,7 @@ case OP_IsType: { /* jump */ /* Opcode: ZeroOrNull P1 P2 P3 * * ** Synopsis: r[P2] = 0 OR NULL ** -** If both registers P1 and P3 are NOT NULL, then store a zero in +** If all both registers P1 and P3 are NOT NULL, then store a zero in ** register P2. If either registers P1 or P3 are NULL then put ** a NULL in register P2. */ @@ -95347,16 +94579,11 @@ 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)) - ) - ) - || sqlite3VdbeSerialTypeLen(t)==0 + 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 ** 1. the typeof() function, @@ -95373,13 +94600,11 @@ case OP_Column: { /* ncycle */ */ sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest); }else{ - rc = vdbeColumnFromOverflow(pC, p2, t, aOffset[p2], - p->cacheCtr, colCacheCtr, 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; } } @@ -95841,6 +95066,7 @@ case OP_MakeRecord: { /* NULL value. No change in zPayload */ }else{ u64 v; + u32 i; if( serial_type==7 ){ assert( sizeof(v)==sizeof(pRec->u.r) ); memcpy(&v, &pRec->u.r, sizeof(v)); @@ -95848,17 +95074,12 @@ case OP_MakeRecord: { }else{ v = pRec->u.i; } - len = sqlite3SmallTypeSizes[serial_type]; - assert( len>=1 && len<=8 && len!=5 && len!=7 ); - switch( len ){ - default: zPayload[7] = (u8)(v&0xff); v >>= 8; - zPayload[6] = (u8)(v&0xff); v >>= 8; - case 6: zPayload[5] = (u8)(v&0xff); v >>= 8; - zPayload[4] = (u8)(v&0xff); v >>= 8; - case 4: zPayload[3] = (u8)(v&0xff); v >>= 8; - case 3: zPayload[2] = (u8)(v&0xff); v >>= 8; - case 2: zPayload[1] = (u8)(v&0xff); v >>= 8; - case 1: zPayload[0] = (u8)(v&0xff); + len = i = sqlite3SmallTypeSizes[serial_type]; + assert( i>0 ); + while( 1 /*exit-by-break*/ ){ + zPayload[--i] = (u8)(v&0xFF); + if( i==0 ) break; + v >>= 8; } zPayload += len; } @@ -95910,6 +95131,7 @@ case OP_Count: { /* out2 */ }else{ nEntry = 0; /* Not needed. Only used to silence a warning. */ rc = sqlite3BtreeCount(db, pCrsr, &nEntry); + p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE] += nEntry; if( rc ) goto abort_due_to_error; } pOut = out2Prerelease(p, pOp); @@ -96667,7 +95889,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 ); @@ -96678,7 +95900,7 @@ case OP_OpenEphemeral: { /* ncycle */ pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_BTREE); if( pCx==0 ) goto no_mem; pCx->isEphemeral = 1; - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->ub.pBtx, + rc = sqlite3BtreeOpen(db->pVfs, db->pWalMethods, 0, db, &pCx->ub.pBtx, BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); if( rc==SQLITE_OK ){ @@ -97069,6 +96291,7 @@ case OP_SeekGT: { /* jump, in3, group, ncycle */ goto seek_not_found; } } + p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++; #ifdef SQLITE_TEST sqlite3_search_count++; #endif @@ -97158,7 +96381,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 @@ -97166,7 +96389,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 @@ -97398,13 +96621,13 @@ case OP_IfNotOpen: { /* jump */ ** operands to OP_NotFound and OP_IdxGT. ** ** This opcode is an optimization attempt only. If this opcode always -** falls through, the correct answer is still obtained, but extra work +** falls through, the correct answer is still obtained, but extra works ** is performed. ** ** A value of N in the seekHit flag of cursor P1 means that there exists ** a key P3:N that will match some record in the index. We want to know ** if it is possible for a record P3:P4 to match some record in the -** index. If it is not possible, we can skip some work. So if seekHit +** index. If it is not possible, we can skips some work. So if seekHit ** is less than P4, attempt to find out if a match is possible by running ** OP_NotFound. ** @@ -97638,6 +96861,7 @@ case OP_NotExists: /* jump, in3, ncycle */ pC->deferredMoveto = 0; VdbeBranchTaken(res!=0,2); pC->seekResult = res; + p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++; if( res!=0 ){ assert( rc==SQLITE_OK ); if( pOp->p2==0 ){ @@ -97667,6 +96891,45 @@ case OP_Sequence: { /* out2 */ break; } +#ifdef LIBSQL_ENABLE_WASM_RUNTIME +/* Opcode: CreateWasmFunc P1 P2 P3 P4 * +** Synopsis: addWasmFunc[P4] +** +** Registers a user-defined WebAssembly function created with name stored in P4. +** Name size is stored in P2, and body size in P3. Body can be found right after +** the name's null terminator. P1 means that IF NOT EXISTS was passed. +*/ +case OP_CreateWasmFunc: { + char *err_buf; + FuncDef *def = try_instantiate_wasm_function(db, pOp->p4.z, pOp->p2, pOp->p4.z + pOp->p2 + 1, pOp->p3, -1, &err_buf); + if( pOp->p1 == 0 && !def ) { + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3MPrintf(db, "Registering Wasm function %s failed: %s", pOp->p4.z, err_buf); + sqlite3_free(err_buf); + rc = SQLITE_ERROR; + goto abort_due_to_error; + } + break; +} + +/* Opcode: DropWasmFunc P1 * * P4 * +** Synopsis: dropWasmFunc[P4] +** +** Drops a user-defined WebAssembly function created with name stored in P4. +** P1 means that IF EXISTS was passed +*/ +case OP_DropWasmFunc: { + int dropped = deregister_wasm_function(db, pOp->p4.z); + if( pOp->p1 == 0 && !dropped ) { + rc = SQLITE_CONSTRAINT; + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3MPrintf(db, "Function %s was not registered", pOp->p4.z); + goto abort_due_to_error; + } + break; +} + +#endif /* Opcode: NewRowid P1 P2 P3 * * ** Synopsis: r[P2]=rowid @@ -97746,6 +97009,11 @@ case OP_NewRowid: { /* out2 */ } } + if ( pOp->p3 == LIBSQL_RANDOM_ROWID_MARKER) { + pC->useRandomRowid = 1; + pOp->p3 = 0; + } + #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p3 ){ /* Assert that P3 is a valid memory cell. */ @@ -97895,6 +97163,7 @@ case OP_Insert: { #endif assert( (pOp->p5 & OPFLAG_LASTROWID)==0 || (pOp->p5 & OPFLAG_NCHANGE)!=0 ); + p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE]++; if( pOp->p5 & OPFLAG_NCHANGE ){ p->nChange++; if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; @@ -97916,7 +97185,6 @@ case OP_Insert: { ); pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; - colCacheCtr++; /* Invoke the update-hook if required. */ if( rc ) goto abort_due_to_error; @@ -97970,18 +97238,13 @@ case OP_RowCell: { ** left in an undefined state. ** ** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this -** delete is one of several associated with deleting a table row and -** all its associated index entries. Exactly one of those deletes is -** the "primary" delete. The others are all on OPFLAG_FORDELETE -** cursors or else are marked with the AUXDELETE flag. +** delete one of several associated with deleting a table row and all its +** associated index entries. Exactly one of those deletes is the "primary" +** delete. The others are all on OPFLAG_FORDELETE cursors or else are +** marked with the AUXDELETE flag. ** -** If the OPFLAG_NCHANGE (0x01) flag of P2 (NB: P2 not P5) is set, then -** the row change count is incremented (otherwise not). -** -** If the OPFLAG_ISNOOP (0x40) flag of P2 (not P5!) is set, then the -** pre-update-hook for deletes is run, but the btree is otherwise unchanged. -** This happens when the OP_Delete is to be shortly followed by an OP_Insert -** with the same key, causing the btree entry to be overwritten. +** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row +** change count is incremented (otherwise not). ** ** P1 must not be pseudo-table. It has to be a real table with ** multiple rows. @@ -98082,12 +97345,12 @@ case OP_Delete: { rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); pC->cacheStatus = CACHE_STALE; - colCacheCtr++; pC->seekResult = 0; if( rc ) goto abort_due_to_error; /* Invoke the update-hook if required. */ if( opflags & OPFLAG_NCHANGE ){ + p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE]++; p->nChange++; if( db->xUpdateCallback && ALWAYS(pTab!=0) && HasRowid(pTab) ){ db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName, @@ -98150,13 +97413,13 @@ case OP_SorterCompare: { ** Write into register P2 the current sorter data for sorter cursor P1. ** Then clear the column header cache on cursor P3. ** -** This opcode is normally used to move a record out of the sorter and into +** This opcode is normally use to move a record out of the sorter and into ** a register that is the source for a pseudo-table cursor created using ** OpenPseudo. That pseudo-table cursor is the one that is identified by ** 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]; @@ -98375,6 +97638,7 @@ case OP_Last: { /* jump, ncycle */ pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; if( rc ) goto abort_due_to_error; + p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++; if( pOp->p2>0 ){ VdbeBranchTaken(res!=0,2); if( res ) goto jump_to_p2; @@ -98431,8 +97695,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--; @@ -98484,6 +97748,7 @@ case OP_Rewind: { /* jump, ncycle */ } if( rc ) goto abort_due_to_error; pC->nullRow = (u8)res; + p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++; if( pOp->p2>0 ){ VdbeBranchTaken(res!=0,2); if( res ) goto jump_to_p2; @@ -98589,6 +97854,7 @@ case OP_Next: /* jump, ncycle */ if( rc==SQLITE_OK ){ pC->nullRow = 0; p->aCounter[pOp->p5]++; + p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++; #ifdef SQLITE_TEST sqlite3_search_count++; #endif @@ -98640,6 +97906,7 @@ case OP_IdxInsert: { /* in2 */ pIn2 = &aMem[pOp->p2]; assert( (pIn2->flags & MEM_Blob) || (pOp->p5 & OPFLAG_PREFORMAT) ); if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; + p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE]++; assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->isTable==0 ); rc = ExpandBlob(pIn2); @@ -98959,7 +98226,7 @@ case OP_IdxGE: { /* jump, ncycle */ ** file is given by P1. ** ** The table being destroyed is in the main database file if P3==0. If -** P3==1 then the table to be destroyed is in the auxiliary database file +** P3==1 then the table to be clear is in the auxiliary database file ** that is used to store tables create using CREATE TEMPORARY TABLE. ** ** If AUTOVACUUM is enabled then it is possible that another root page @@ -99019,8 +98286,8 @@ case OP_Destroy: { /* out2 */ ** in the database file is given by P1. But, unlike Destroy, do not ** remove the table or index from the database file. ** -** The table being cleared is in the main database file if P2==0. If -** P2==1 then the table to be cleared is in the auxiliary database file +** The table being clear is in the main database file if P2==0. If +** P2==1 then the table to be clear is in the auxiliary database file ** that is used to store tables create using CREATE TEMPORARY TABLE. ** ** If the P3 value is non-zero, then the row change count is incremented @@ -99040,6 +98307,7 @@ case OP_Clear: { rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, (u32)pOp->p1, &nChange); if( pOp->p3 ){ p->nChange += nChange; + p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE] += nChange; if( pOp->p3>0 ){ assert( memIsValid(&aMem[pOp->p3]) ); memAboutToChange(p, &aMem[pOp->p3]); @@ -99106,41 +98374,13 @@ case OP_CreateBtree: { /* out2 */ /* Opcode: SqlExec * * * P4 * ** ** Run the SQL statement or statements specified in the P4 string. -** Disable Auth and Trace callbacks while those statements are running if -** P1 is true. */ case OP_SqlExec: { - char *zErr; -#ifndef SQLITE_OMIT_AUTHORIZATION - sqlite3_xauth xAuth; -#endif - u8 mTrace; - sqlite3VdbeIncrWriteCounter(p, 0); db->nSqlExec++; - zErr = 0; -#ifndef SQLITE_OMIT_AUTHORIZATION - xAuth = db->xAuth; -#endif - mTrace = db->mTrace; - if( pOp->p1 ){ -#ifndef SQLITE_OMIT_AUTHORIZATION - db->xAuth = 0; -#endif - db->mTrace = 0; - } - rc = sqlite3_exec(db, pOp->p4.z, 0, 0, &zErr); + rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0); db->nSqlExec--; -#ifndef SQLITE_OMIT_AUTHORIZATION - db->xAuth = xAuth; -#endif - db->mTrace = mTrace; - if( zErr || rc ){ - sqlite3VdbeError(p, "%s", zErr); - sqlite3_free(zErr); - if( rc==SQLITE_NOMEM ) goto no_mem; - goto abort_due_to_error; - } + if( rc ) goto abort_due_to_error; break; } @@ -99874,7 +99114,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]; @@ -100361,53 +99601,6 @@ case OP_VOpen: { /* ncycle */ } #endif /* SQLITE_OMIT_VIRTUALTABLE */ -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VCheck P1 P2 P3 P4 * -** -** P4 is a pointer to a Table object that is a virtual table in schema P1 -** that supports the xIntegrity() method. This opcode runs the xIntegrity() -** method for that virtual table, using P3 as the integer argument. If -** an error is reported back, the table name is prepended to the error -** message and that message is stored in P2. If no errors are seen, -** register P2 is set to NULL. -*/ -case OP_VCheck: { /* out2 */ - Table *pTab; - sqlite3_vtab *pVtab; - const sqlite3_module *pModule; - char *zErr = 0; - - pOut = &aMem[pOp->p2]; - sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */ - assert( pOp->p4type==P4_TABLE ); - pTab = pOp->p4.pTab; - assert( pTab!=0 ); - assert( IsVirtual(pTab) ); - if( pTab->u.vtab.p==0 ) break; - pVtab = pTab->u.vtab.p->pVtab; - assert( pVtab!=0 ); - pModule = pVtab->pModule; - assert( pModule!=0 ); - assert( pModule->iVersion>=4 ); - assert( pModule->xIntegrity!=0 ); - pTab->nTabRef++; - sqlite3VtabLock(pTab->u.vtab.p); - assert( pOp->p1>=0 && pOp->p1nDb ); - rc = pModule->xIntegrity(pVtab, db->aDb[pOp->p1].zDbSName, pTab->zName, - pOp->p3, &zErr); - sqlite3VtabUnlock(pTab->u.vtab.p); - sqlite3DeleteTable(db, pTab); - if( rc ){ - sqlite3_free(zErr); - goto abort_due_to_error; - } - if( zErr ){ - sqlite3VdbeMemSetStr(pOut, zErr, -1, SQLITE_UTF8, sqlite3_free); - } - break; -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VInitIn P1 P2 P3 * * ** Synopsis: r[P2]=ValueList(P1,P3) @@ -100435,6 +99628,39 @@ case OP_VInitIn: { /* out2, ncycle */ } #endif /* SQLITE_OMIT_VIRTUALTABLE */ +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VPreparedSql P1 * * * * +** +** P1 is a cursor opened using VOpen. +** +** This opcode invokes the xPreparedSql method on the virtual table specified +** by P1. The SQL text parameter to xPreparedSql is obtained from Vdbe* `p`. +** +*/ +case OP_VPreparedSql: { + const sqlite3_module *pModule; + sqlite3_vtab_cursor *pVCur; + sqlite3_vtab *pVtab; + VdbeCursor *pCur; + + pCur = p->apCsr[pOp->p1]; + assert( pCur!=0 ); + assert( pCur->eCurType==CURTYPE_VTAB ); + pVCur = pCur->uc.pVCur; + pVtab = pVCur->pVtab; + pModule = pVtab->pModule; + + /* Invoke the xPreparedSql method */ + if( pModule->iVersion>=700 ){ + if( pModule->xPreparedSql && p->zSql ){ + rc = pModule->xPreparedSql(pVCur, p->zSql); + if( rc ) goto abort_due_to_error; + } + } + + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VFilter P1 P2 P3 P4 * @@ -100593,6 +99819,7 @@ case OP_VNext: { /* jump, ncycle */ rc = pModule->xNext(pCur->uc.pVCur); sqlite3VtabImportErrmsg(p, pVtab); if( rc ) goto abort_due_to_error; + p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++; res = pModule->xEof(pCur->uc.pVCur); VdbeBranchTaken(!res,2); if( !res ){ @@ -100714,6 +99941,7 @@ case OP_VUpdate: { p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5); } }else{ + p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE]++; p->nChange++; } if( rc ) goto abort_due_to_error; @@ -100799,7 +100027,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. @@ -100817,7 +100045,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; @@ -100893,7 +100121,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; } @@ -100929,7 +100157,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]++; @@ -101181,7 +100409,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); } @@ -101354,7 +100582,8 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ /* Set the value of register r[1] in the SQL statement to integer iRow. ** This is done directly as a performance optimization */ - sqlite3VdbeMemSetInt64(&v->aMem[1], iRow); + v->aMem[1].flags = MEM_Int; + v->aMem[1].u.i = iRow; /* If the statement has been run before (and is paused at the OP_ResultRow) ** then back it up to the point where it does the OP_NotExists. This could @@ -101437,7 +100666,7 @@ SQLITE_API int sqlite3_blob_open( #endif *ppBlob = 0; #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zTable==0 || zColumn==0 ){ + if( !sqlite3SafetyCheckOk(db) || zTable==0 ){ return SQLITE_MISUSE_BKPT; } #endif @@ -101898,7 +101127,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 @@ -101921,7 +101150,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. ** @@ -101999,7 +101228,7 @@ struct SorterFile { struct SorterList { SorterRecord *pList; /* Linked list of records */ u8 *aMemory; /* If non-NULL, bulk memory to hold pList */ - i64 szPMA; /* Size of pList as PMA in bytes */ + int szPMA; /* Size of pList as PMA in bytes */ }; /* @@ -102084,7 +101313,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, @@ -102108,10 +101337,10 @@ typedef int (*SorterCompare)(SortSubtask*,int*,const void*,int,const void*,int); struct SortSubtask { SQLiteThread *pThread; /* Background thread, if any */ int bDone; /* Set if thread is finished but not joined */ - int nPMA; /* Number of PMAs currently in file */ VdbeSorter *pSorter; /* Sorter that owns this sub-task */ UnpackedRecord *pUnpacked; /* Space to unpack a record */ SorterList list; /* List for thread to write to a PMA */ + int nPMA; /* Number of PMAs currently in file */ SorterCompare xCompare; /* Compare function to use */ SorterFile file; /* Temp file for level-0 PMAs */ SorterFile file2; /* Space for other PMAs */ @@ -102156,7 +101385,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. */ @@ -103527,7 +102756,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; @@ -103585,8 +102814,8 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite( int rc = SQLITE_OK; /* Return Code */ SorterRecord *pNew; /* New list element */ int bFlush; /* True to flush contents of memory to PMA */ - i64 nReq; /* Bytes of memory required */ - i64 nPMA; /* Bytes of PMA space required */ + int nReq; /* Bytes of memory required */ + int nPMA; /* Bytes of PMA space required */ int t; /* serial type of first record field */ assert( pCsr->eCurType==CURTYPE_SORTER ); @@ -104011,7 +103240,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 ){ @@ -104651,8 +103880,6 @@ static int bytecodevtabConnect( "p5 INT," "comment TEXT," "subprog TEXT," - "nexec INT," - "ncycle INT," "stmt HIDDEN" ");", @@ -104815,7 +104042,7 @@ static int bytecodevtabColumn( } } } - i += 20; + i += 10; } } switch( i ){ @@ -104865,31 +104092,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; } @@ -104963,7 +104175,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; @@ -105010,8 +104222,7 @@ static sqlite3_module bytecodevtabModule = { /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0, - /* xIntegrity */ 0 + /* xShadowName */ 0 }; @@ -105535,7 +104746,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) ); @@ -105544,9 +104755,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; @@ -105570,7 +104779,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; } /* @@ -105696,7 +104905,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); @@ -105840,36 +105049,21 @@ static void resolveAlias( } /* -** Subqueries store the original database, table and column names for their -** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN", -** and mark the expression-list item by setting ExprList.a[].fg.eEName -** to ENAME_TAB. -** -** Check to see if the zSpan/eEName of the expression-list item passed to this -** routine matches the zDb, zTab, and zCol. If any of zDb, zTab, and zCol are -** NULL then those fields will match anything. Return true if there is a match, -** or false otherwise. -** -** SF_NestedFrom subqueries also store an entry for the implicit rowid (or -** _rowid_, or oid) column by setting ExprList.a[].fg.eEName to ENAME_ROWID, -** and setting zSpan to "DATABASE.TABLE.". This type of pItem -** argument matches if zCol is a rowid alias. If it is not NULL, (*pbRowid) -** is set to 1 if there is this kind of match. +** Subqueries stores the original database, table and column names for their +** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN". +** Check to see if the zSpan given to this routine matches the zDb, zTab, +** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will +** match anything. */ SQLITE_PRIVATE int sqlite3MatchEName( const struct ExprList_item *pItem, const char *zCol, const char *zTab, - const char *zDb, - int *pbRowid + const char *zDb ){ int n; const char *zSpan; - int eEName = pItem->fg.eEName; - if( eEName!=ENAME_TAB && (eEName!=ENAME_ROWID || NEVER(pbRowid==0)) ){ - return 0; - } - assert( pbRowid==0 || *pbRowid==0 ); + if( pItem->fg.eEName!=ENAME_TAB ) return 0; zSpan = pItem->zEName; for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ @@ -105881,11 +105075,9 @@ SQLITE_PRIVATE int sqlite3MatchEName( return 0; } zSpan += n+1; - if( zCol ){ - if( eEName==ENAME_TAB && sqlite3StrICmp(zSpan, zCol)!=0 ) return 0; - if( eEName==ENAME_ROWID && sqlite3IsRowid(zCol)==0 ) return 0; + if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){ + return 0; } - if( eEName==ENAME_ROWID ) *pbRowid = 1; return 1; } @@ -106018,7 +105210,7 @@ static int lookupName( ){ int i, j; /* Loop counters */ int cnt = 0; /* Number of matching column names */ - int cntTab = 0; /* Number of potential "rowid" matches */ + int cntTab = 0; /* Number of matching table names */ int nSubquery = 0; /* How many levels of subquery */ sqlite3 *db = pParse->db; /* The database connection */ SrcItem *pItem; /* Use for looping over pSrcList items */ @@ -106095,49 +105287,39 @@ static int lookupName( assert( pEList!=0 ); assert( pEList->nExpr==pTab->nCol ); for(j=0; jnExpr; j++){ - int bRowid = 0; /* True if possible rowid match */ - if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, &bRowid) ){ + if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ continue; } - if( bRowid==0 ){ - if( cnt>0 ){ - if( pItem->fg.isUsing==0 - || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 - ){ - /* Two or more tables have the same column name which is - ** not joined by USING. This is an error. Signal as much - ** by clearing pFJMatch and letting cnt go above 1. */ - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else - if( (pItem->fg.jointype & JT_RIGHT)==0 ){ - /* An INNER or LEFT JOIN. Use the left-most table */ - continue; - }else - if( (pItem->fg.jointype & JT_LEFT)==0 ){ - /* A RIGHT JOIN. Use the right-most table */ - cnt = 0; - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else{ - /* For a FULL JOIN, we must construct a coalesce() func */ - extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); - } + if( cnt>0 ){ + if( pItem->fg.isUsing==0 + || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 + ){ + /* Two or more tables have the same column name which is + ** not joined by USING. This is an error. Signal as much + ** by clearing pFJMatch and letting cnt go above 1. */ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else + if( (pItem->fg.jointype & JT_RIGHT)==0 ){ + /* An INNER or LEFT JOIN. Use the left-most table */ + continue; + }else + if( (pItem->fg.jointype & JT_LEFT)==0 ){ + /* A RIGHT JOIN. Use the right-most table */ + cnt = 0; + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else{ + /* For a FULL JOIN, we must construct a coalesce() func */ + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); } - cnt++; - hit = 1; - }else if( cnt>0 ){ - /* This is a potential rowid match, but there has already been - ** a real match found. So this can be ignored. */ - continue; } - cntTab++; + cnt++; + cntTab = 2; pMatch = pItem; pExpr->iColumn = j; pEList->a[j].fg.bUsed = 1; - - /* rowid cannot be part of a USING clause - assert() this. */ - assert( bRowid==0 || pEList->a[j].fg.bUsingTerm==0 ); + hit = 1; if( pEList->a[j].fg.bUsingTerm ) break; } if( hit || zTab==0 ) continue; @@ -106332,10 +105514,10 @@ static int lookupName( && pMatch && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 && sqlite3IsRowid(zCol) - && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom) + && ALWAYS(VisibleRowid(pMatch->pTab)) ){ cnt = 1; - if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1; + pExpr->iColumn = -1; pExpr->affExpr = SQLITE_AFF_INTEGER; } @@ -106788,7 +105970,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0); #endif assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); - assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER ); zId = pExpr->u.zToken; pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); if( pDef==0 ){ @@ -106930,10 +106111,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pNC->nNcErr++; } #endif - else if( is_agg==0 && pExpr->pLeft ){ - sqlite3ExprOrderByAggregateError(pParse, pExpr); - pNC->nNcErr++; - } if( is_agg ){ /* Window functions may not be arguments of aggregate functions. ** Or arguments of other window functions. But aggregate functions @@ -106952,11 +106129,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #endif sqlite3WalkExprList(pWalker, pList); if( is_agg ){ - if( pExpr->pLeft ){ - assert( pExpr->pLeft->op==TK_ORDER ); - assert( ExprUseXList(pExpr->pLeft) ); - sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList); - } #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ Select *pSel = pNC->pWinSelect; @@ -107467,7 +106639,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); @@ -107520,8 +106692,10 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ while( p ){ assert( (p->selFlags & SF_Expanded)!=0 ); assert( (p->selFlags & SF_Resolved)==0 ); + assert( db->suppressErr==0 ); /* SF_Resolved not set if errors suppressed */ p->selFlags |= SF_Resolved; + /* Resolve the expressions in the LIMIT and OFFSET clauses. These ** are not allowed to refer to any names, so pass an empty NameContext. */ @@ -107788,8 +106962,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 @@ -107831,7 +107004,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 @@ -107853,7 +107026,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. ** @@ -108240,7 +107413,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() ** @@ -108370,7 +107543,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(). @@ -108527,7 +107700,6 @@ SQLITE_PRIVATE Expr *sqlite3ExprForVectorField( */ pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0); if( pRet ){ - ExprSetProperty(pRet, EP_FullSize); pRet->iTable = nField; pRet->iColumn = iField; pRet->pLeft = pVector; @@ -108827,15 +107999,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. ** @@ -109118,69 +108281,6 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction( return pNew; } -/* -** Report an error when attempting to use an ORDER BY clause within -** the arguments of a non-aggregate function. -*/ -SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse *pParse, Expr *p){ - sqlite3ErrorMsg(pParse, - "ORDER BY may not be used with non-aggregate %#T()", p - ); -} - -/* -** Attach an ORDER BY clause to a function call. -** -** functionname( arguments ORDER BY sortlist ) -** \_____________________/ \______/ -** pExpr pOrderBy -** -** The ORDER BY clause is inserted into a new Expr node of type TK_ORDER -** and added to the Expr.pLeft field of the parent TK_FUNCTION node. -*/ -SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy( - Parse *pParse, /* Parsing context */ - Expr *pExpr, /* The function call to which ORDER BY is to be added */ - ExprList *pOrderBy /* The ORDER BY clause to add */ -){ - Expr *pOB; - sqlite3 *db = pParse->db; - if( NEVER(pOrderBy==0) ){ - assert( db->mallocFailed ); - return; - } - if( pExpr==0 ){ - assert( db->mallocFailed ); - sqlite3ExprListDelete(db, pOrderBy); - return; - } - assert( pExpr->op==TK_FUNCTION ); - assert( pExpr->pLeft==0 ); - assert( ExprUseXList(pExpr) ); - if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){ - /* Ignore ORDER BY on zero-argument aggregates */ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprListDelete, - pOrderBy); - return; - } - if( IsWindowFunc(pExpr) ){ - sqlite3ExprOrderByAggregateError(pParse, pExpr); - sqlite3ExprListDelete(db, pOrderBy); - return; - } - - pOB = sqlite3ExprAlloc(db, TK_ORDER, 0, 0); - if( pOB==0 ){ - sqlite3ExprListDelete(db, pOrderBy); - return; - } - pOB->x.pList = pOrderBy; - assert( ExprUseXList(pOB) ); - pExpr->pLeft = pOB; - ExprSetProperty(pOB, EP_FullSize); -} - /* ** Check to see if a function is usable according to current access ** rules: @@ -109359,7 +108459,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. ** @@ -109434,7 +108534,11 @@ static int dupedExprStructSize(const Expr *p, int flags){ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ assert( EXPR_FULLSIZE<=0xfff ); assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); - if( 0==flags || ExprHasProperty(p, EP_FullSize) ){ + if( 0==flags || p->op==TK_SELECT_COLUMN +#ifndef SQLITE_OMIT_WINDOWFUNC + || ExprHasProperty(p, EP_WinFunc) +#endif + ){ nSize = EXPR_FULLSIZE; }else{ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); @@ -109465,93 +108569,56 @@ static int dupedExprNodeSize(const Expr *p, int flags){ /* ** Return the number of bytes required to create a duplicate of the -** expression passed as the first argument. +** expression passed as the first argument. The second argument is a +** mask containing EXPRDUP_XXX flags. ** ** The value returned includes space to create a copy of the Expr struct ** itself and the buffer referred to by Expr.u.zToken, if any. ** -** The return value includes space to duplicate all Expr nodes in the -** tree formed by Expr.pLeft and Expr.pRight, but not any other -** substructure such as Expr.x.pList, Expr.x.pSelect, and Expr.y.pWin. +** If the EXPRDUP_REDUCE flag is set, then the return value includes +** space to duplicate all Expr nodes in the tree formed by Expr.pLeft +** and Expr.pRight variables (but not for any structures pointed to or +** descended from the Expr.x.pList or Expr.x.pSelect variables). */ -static int dupedExprSize(const Expr *p){ - int nByte; - assert( p!=0 ); - nByte = dupedExprNodeSize(p, EXPRDUP_REDUCE); - if( p->pLeft ) nByte += dupedExprSize(p->pLeft); - if( p->pRight ) nByte += dupedExprSize(p->pRight); - assert( nByte==ROUND8(nByte) ); +static int dupedExprSize(const Expr *p, int flags){ + int nByte = 0; + if( p ){ + nByte = dupedExprNodeSize(p, flags); + if( flags&EXPRDUP_REDUCE ){ + nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags); + } + } return nByte; } /* -** An EdupBuf is a memory allocation used to stored multiple Expr objects -** together with their Expr.zToken content. This is used to help implement -** compression while doing sqlite3ExprDup(). The top-level Expr does the -** allocation for itself and many of its decendents, then passes an instance -** of the structure down into exprDup() so that they decendents can have -** access to that memory. -*/ -typedef struct EdupBuf EdupBuf; -struct EdupBuf { - u8 *zAlloc; /* Memory space available for storage */ -#ifdef SQLITE_DEBUG - u8 *zEnd; /* First byte past the end of memory */ -#endif -}; - -/* -** This function is similar to sqlite3ExprDup(), except that if pEdupBuf -** is not NULL then it points to memory that can be used to store a copy -** of the input Expr p together with its p->u.zToken (if any). pEdupBuf -** is updated with the new buffer tail prior to returning. +** This function is similar to sqlite3ExprDup(), except that if pzBuffer +** is not NULL then *pzBuffer is assumed to point to a buffer large enough +** to store the copy of expression p, the copies of p->u.zToken +** (if applicable), and the copies of the p->pLeft and p->pRight expressions, +** if any. Before returning, *pzBuffer is set to the first byte past the +** portion of the buffer copied into by this function. */ -static Expr *exprDup( - sqlite3 *db, /* Database connection (for memory allocation) */ - const Expr *p, /* Expr tree to be duplicated */ - int dupFlags, /* EXPRDUP_REDUCE for compression. 0 if not */ - EdupBuf *pEdupBuf /* Preallocated storage space, or NULL */ -){ +static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){ Expr *pNew; /* Value to return */ - EdupBuf sEdupBuf; /* Memory space from which to build Expr object */ + u8 *zAlloc; /* Memory space from which to build Expr object */ u32 staticFlag; /* EP_Static if space not obtained from malloc */ - int nToken = -1; /* Space needed for p->u.zToken. -1 means unknown */ assert( db!=0 ); assert( p ); assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE ); - assert( pEdupBuf==0 || dupFlags==EXPRDUP_REDUCE ); + assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE ); /* Figure out where to write the new Expr structure. */ - if( pEdupBuf ){ - sEdupBuf.zAlloc = pEdupBuf->zAlloc; -#ifdef SQLITE_DEBUG - sEdupBuf.zEnd = pEdupBuf->zEnd; -#endif + if( pzBuffer ){ + zAlloc = *pzBuffer; staticFlag = EP_Static; - assert( sEdupBuf.zAlloc!=0 ); - assert( dupFlags==EXPRDUP_REDUCE ); + assert( zAlloc!=0 ); }else{ - int nAlloc; - if( dupFlags ){ - nAlloc = dupedExprSize(p); - }else if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - nToken = sqlite3Strlen30NN(p->u.zToken)+1; - nAlloc = ROUND8(EXPR_FULLSIZE + nToken); - }else{ - nToken = 0; - nAlloc = ROUND8(EXPR_FULLSIZE); - } - assert( nAlloc==ROUND8(nAlloc) ); - sEdupBuf.zAlloc = sqlite3DbMallocRawNN(db, nAlloc); -#ifdef SQLITE_DEBUG - sEdupBuf.zEnd = sEdupBuf.zAlloc ? sEdupBuf.zAlloc+nAlloc : 0; -#endif - + zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags)); staticFlag = 0; } - pNew = (Expr *)sEdupBuf.zAlloc; - assert( EIGHT_BYTE_ALIGNMENT(pNew) ); + pNew = (Expr *)zAlloc; if( pNew ){ /* Set nNewSize to the size allocated for the structure pointed to @@ -109560,27 +108627,22 @@ static Expr *exprDup( ** by the copy of the p->u.zToken string (if any). */ const unsigned nStructSize = dupedExprStructSize(p, dupFlags); - int nNewSize = nStructSize & 0xfff; - if( nToken<0 ){ - if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - nToken = sqlite3Strlen30(p->u.zToken) + 1; - }else{ - nToken = 0; - } + const int nNewSize = nStructSize & 0xfff; + int nToken; + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30(p->u.zToken) + 1; + }else{ + nToken = 0; } if( dupFlags ){ - assert( (int)(sEdupBuf.zEnd - sEdupBuf.zAlloc) >= nNewSize+nToken ); assert( ExprHasProperty(p, EP_Reduced)==0 ); - memcpy(sEdupBuf.zAlloc, p, nNewSize); + memcpy(zAlloc, p, nNewSize); }else{ u32 nSize = (u32)exprStructSize(p); - assert( (int)(sEdupBuf.zEnd - sEdupBuf.zAlloc) >= - (int)EXPR_FULLSIZE+nToken ); - memcpy(sEdupBuf.zAlloc, p, nSize); + memcpy(zAlloc, p, nSize); if( nSizeu.zToken string, if any. */ - assert( nToken>=0 ); - if( nToken>0 ){ - char *zToken = pNew->u.zToken = (char*)&sEdupBuf.zAlloc[nNewSize]; + if( nToken ){ + char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize]; memcpy(zToken, p->u.zToken, nToken); - nNewSize += nToken; } - sEdupBuf.zAlloc += ROUND8(nNewSize); - - if( ((p->flags|pNew->flags)&(EP_TokenOnly|EP_Leaf))==0 ){ + if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){ /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ if( ExprUseXSelect(p) ){ pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags); }else{ - pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, - p->op!=TK_ORDER ? dupFlags : 0); + pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags); } + } + /* Fill in pNew->pLeft and pNew->pRight. */ + if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){ + zAlloc += dupedExprNodeSize(p, dupFlags); + if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){ + pNew->pLeft = p->pLeft ? + exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0; + pNew->pRight = p->pRight ? + exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0; + } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(p, EP_WinFunc) ){ pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin); assert( ExprHasProperty(pNew, EP_WinFunc) ); } #endif /* SQLITE_OMIT_WINDOWFUNC */ - - /* Fill in pNew->pLeft and pNew->pRight. */ - if( dupFlags ){ - if( p->op==TK_SELECT_COLUMN ){ - pNew->pLeft = p->pLeft; - assert( p->pRight==0 - || p->pRight==p->pLeft - || ExprHasProperty(p->pLeft, EP_Subquery) ); - }else{ - pNew->pLeft = p->pLeft ? - exprDup(db, p->pLeft, EXPRDUP_REDUCE, &sEdupBuf) : 0; - } - pNew->pRight = p->pRight ? - exprDup(db, p->pRight, EXPRDUP_REDUCE, &sEdupBuf) : 0; - }else{ - if( p->op==TK_SELECT_COLUMN ){ + if( pzBuffer ){ + *pzBuffer = zAlloc; + } + }else{ + if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ + if( pNew->op==TK_SELECT_COLUMN ){ pNew->pLeft = p->pLeft; - assert( p->pRight==0 - || p->pRight==p->pLeft - || ExprHasProperty(p->pLeft, EP_Subquery) ); + assert( p->pRight==0 || p->pRight==p->pLeft + || ExprHasProperty(p->pLeft, EP_Subquery) ); }else{ pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); } @@ -109644,8 +108700,6 @@ static Expr *exprDup( } } } - if( pEdupBuf ) memcpy(pEdupBuf, &sEdupBuf, sizeof(sEdupBuf)); - assert( sEdupBuf.zAlloc <= sEdupBuf.zEnd ); return pNew; } @@ -109910,7 +108964,11 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags) ** initially NULL, then create a new expression list. ** ** The pList argument must be either NULL or a pointer to an ExprList -** obtained from a prior call to sqlite3ExprListAppend(). +** obtained from a prior call to sqlite3ExprListAppend(). This routine +** may not be used with an ExprList obtained from sqlite3ExprListDup(). +** Reason: This routine assumes that the number of slots in pList->a[] +** is a power of two. That is true for sqlite3ExprListAppend() returns +** but is not necessarily true from the return value of sqlite3ExprListDup(). ** ** If a memory allocation error occurs, the entire list is freed and ** NULL is returned. If non-NULL is returned, then it is guaranteed @@ -110736,27 +109794,6 @@ SQLITE_PRIVATE int sqlite3IsRowid(const char *z){ return 0; } -/* -** Return a pointer to a buffer containing a usable rowid alias for table -** pTab. An alias is usable if there is not an explicit user-defined column -** of the same name. -*/ -SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab){ - const char *azOpt[] = {"_ROWID_", "ROWID", "OID"}; - int ii; - assert( VisibleRowid(pTab) ); - for(ii=0; iinCol; iCol++){ - if( sqlite3_stricmp(azOpt[ii], pTab->aCol[iCol].zCnName)==0 ) break; - } - if( iCol==pTab->nCol ){ - return azOpt[ii]; - } - } - return 0; -} - /* ** 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 @@ -110857,7 +109894,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. ** @@ -110870,7 +109907,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. ** @@ -110882,12 +109919,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. ** @@ -111220,7 +110257,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. @@ -112035,13 +111072,10 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn( u8 p5 /* P5 value for OP_Column + FLAGS */ ){ assert( pParse->pVdbe!=0 ); - assert( (p5 & (OPFLAG_NOCHNG|OPFLAG_TYPEOFARG|OPFLAG_LENGTHARG))==p5 ); - assert( IsVirtual(pTab) || (p5 & OPFLAG_NOCHNG)==0 ); sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg); if( p5 ){ VdbeOp *pOp = sqlite3VdbeGetLastOp(pParse->pVdbe); if( pOp->opcode==OP_Column ) pOp->p5 = p5; - if( pOp->opcode==OP_VColumn ) pOp->p5 = (p5 & OPFLAG_NOCHNG); } return iReg; } @@ -112070,7 +111104,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 @@ -112110,7 +111144,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 */ } } @@ -112200,13 +111234,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); @@ -112294,41 +111328,6 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup( } -/* -** Expresion pExpr is guaranteed to be a TK_COLUMN or equivalent. This -** function checks the Parse.pIdxPartExpr list to see if this column -** can be replaced with a constant value. If so, it generates code to -** put the constant value in a register (ideally, but not necessarily, -** register iTarget) and returns the register number. -** -** Or, if the TK_COLUMN cannot be replaced by a constant, zero is -** returned. -*/ -static int exprPartidxExprLookup(Parse *pParse, Expr *pExpr, int iTarget){ - IndexedExpr *p; - for(p=pParse->pIdxPartExpr; p; p=p->pIENext){ - if( pExpr->iColumn==p->iIdxCol && pExpr->iTable==p->iDataCur ){ - Vdbe *v = pParse->pVdbe; - int addr = 0; - int ret; - - if( p->bMaybeNullRow ){ - addr = sqlite3VdbeAddOp1(v, OP_IfNullRow, p->iIdxCur); - } - ret = sqlite3ExprCodeTarget(pParse, p->pExpr, iTarget); - sqlite3VdbeAddOp4(pParse->pVdbe, OP_Affinity, ret, 1, 0, - (const char*)&p->aff, 1); - if( addr ){ - sqlite3VdbeJumpHere(v, addr); - sqlite3VdbeChangeP3(v, addr, ret); - } - return ret; - } - } - return 0; -} - - /* ** Generate code into the current Vdbe to evaluate the given ** expression. Attempt to store the results in register "target". @@ -112365,7 +111364,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); op = pExpr->op; } - assert( op!=TK_ORDER ); switch( op ){ case TK_AGG_COLUMN: { AggInfo *pAggInfo = pExpr->pAggInfo; @@ -112379,7 +111377,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) #ifdef SQLITE_VDBE_COVERAGE /* Verify that the OP_Null above is exercised by tests ** tag-20230325-2 */ - sqlite3VdbeAddOp3(v, OP_NotNull, target, 1, 20230325); + sqlite3VdbeAddOp2(v, OP_NotNull, target, 1); VdbeCoverageNeverTaken(v); #endif break; @@ -112418,7 +111416,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. */ @@ -112487,11 +111485,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) iTab = pParse->iSelfTab - 1; } } - else if( pParse->pIdxPartExpr - && 0!=(r1 = exprPartidxExprLookup(pParse, pExpr, target)) - ){ - return r1; - } assert( ExprUseYTab(pExpr) ); assert( pExpr->y.pTab!=0 ); iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, @@ -112749,7 +111742,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, @@ -112775,10 +111768,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; @@ -112788,16 +111781,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; } @@ -113152,9 +112143,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) ** once. If no functions are involved, then factor the code out and put it at ** the end of the prepared statement in the initialization section. ** -** If regDest>0 then the result is always stored in that register and the +** 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 @@ -113167,7 +112158,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce( ){ ExprList *p; assert( ConstFactorOk(pParse) ); - assert( regDest!=0 ); p = pParse->pConstExpr; if( regDest<0 && p ){ struct ExprList_item *pItem; @@ -113979,8 +112969,8 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(const ExprList *pA, const ExprList *pB */ SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA,Expr *pB, int iTab){ return sqlite3ExprCompare(0, - sqlite3ExprSkipCollate(pA), - sqlite3ExprSkipCollate(pB), + sqlite3ExprSkipCollateAndLikely(pA), + sqlite3ExprSkipCollateAndLikely(pB), iTab); } @@ -114073,7 +113063,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. @@ -114110,29 +113100,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. @@ -114141,33 +113113,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; @@ -114175,38 +113142,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 @@ -114268,7 +113218,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; @@ -114276,7 +113226,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; } } @@ -114284,7 +113234,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; @@ -114345,7 +113294,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 { @@ -114452,12 +113401,6 @@ SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList assert( pExpr->op==TK_AGG_FUNCTION ); assert( ExprUseXList(pExpr) ); sqlite3WalkExprList(&w, pExpr->x.pList); - if( pExpr->pLeft ){ - assert( pExpr->pLeft->op==TK_ORDER ); - assert( ExprUseXList(pExpr->pLeft) ); - assert( pExpr->pLeft->x.pList!=0 ); - sqlite3WalkExprList(&w, pExpr->pLeft->x.pList); - } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); @@ -114567,7 +113510,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 */ @@ -114580,7 +113523,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 @@ -114722,42 +113664,14 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ u8 enc = ENC(pParse->db); i = addAggInfoFunc(pParse->db, pAggInfo); if( i>=0 ){ - int nArg; assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); pItem = &pAggInfo->aFunc[i]; pItem->pFExpr = pExpr; assert( ExprUseUToken(pExpr) ); - nArg = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; pItem->pFunc = sqlite3FindFunction(pParse->db, - pExpr->u.zToken, nArg, enc, 0); - assert( pItem->bOBUnique==0 ); - if( pExpr->pLeft - && (pItem->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)==0 - ){ - /* The NEEDCOLL test above causes any ORDER BY clause on - ** aggregate min() or max() to be ignored. */ - ExprList *pOBList; - assert( nArg>0 ); - assert( pExpr->pLeft->op==TK_ORDER ); - assert( ExprUseXList(pExpr->pLeft) ); - pItem->iOBTab = pParse->nTab++; - pOBList = pExpr->pLeft->x.pList; - assert( pOBList->nExpr>0 ); - assert( pItem->bOBUnique==0 ); - if( pOBList->nExpr==1 - && nArg==1 - && sqlite3ExprCompare(0,pOBList->a[0].pExpr, - pExpr->x.pList->a[0].pExpr,0)==0 - ){ - pItem->bOBPayload = 0; - pItem->bOBUnique = ExprHasProperty(pExpr, EP_Distinct); - }else{ - pItem->bOBPayload = 1; - } - }else{ - pItem->iOBTab = -1; - } - if( ExprHasProperty(pExpr, EP_Distinct) && !pItem->bOBUnique ){ + pExpr->u.zToken, + pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0); + if( pExpr->flags & EP_Distinct ){ pItem->iDistinct = pParse->nTab++; }else{ pItem->iDistinct = -1; @@ -115393,19 +114307,14 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ /* Verify that constraints are still satisfied */ if( pNew->pCheck!=0 || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0) - || (pTab->tabFlags & TF_Strict)!=0 ){ sqlite3NestedParse(pParse, "SELECT CASE WHEN quick_check GLOB 'CHECK*'" " THEN raise(ABORT,'CHECK constraint failed')" - " WHEN quick_check GLOB 'non-* value in*'" - " THEN raise(ABORT,'type mismatch on DEFAULT')" " ELSE raise(ABORT,'NOT NULL constraint failed')" " END" " FROM pragma_quick_check(%Q,%Q)" - " WHERE quick_check GLOB 'CHECK*'" - " OR quick_check GLOB 'NULL*'" - " OR quick_check GLOB 'non-* value in*'", + " WHERE quick_check GLOB 'CHECK*' OR quick_check GLOB 'NULL*'", zTab, zDb ); } @@ -115494,7 +114403,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); @@ -115628,6 +114537,101 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( return; } +/* +** Handles the following parser reduction: +** +** cmd ::= ALTER TABLE pSrc ALTER COLUMN pOld TO pNew +*/ +void libsqlAlterAlterColumn( + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* Table being altered. pSrc->nSrc==1 */ + Token *pOld, /* Name of column being changed */ + Token *pNew /* New column declaration */ +){ + sqlite3 *db = pParse->db; /* Database connection */ + Table *pTab; /* Table being updated */ + int iCol; /* Index of column being updated */ + char *zOld = 0; /* Old column name */ + char *zNew = 0; /* New column declaration */ + const char *zDb; /* Name of schema containing the table */ + int iSchema; /* Index of the schema */ + int bQuote; /* True to quote the new name */ + + /* Locate the table to be altered */ + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_update_column; + + /* Cannot alter a system table */ + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_update_column; + if( SQLITE_OK!=isRealTable(pParse, pTab, 0) ) goto exit_update_column; + + /* Which schema holds the table to be altered */ + iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iSchema>=0 ); + zDb = db->aDb[iSchema].zDbSName; + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + goto exit_update_column; + } +#endif + + /* Make sure the old name really is a column name in the table to be + ** altered. Set iCol to be the index of the column being updated */ + zOld = sqlite3NameFromToken(db, pOld); + if( !zOld ) goto exit_update_column; + for(iCol=0; iColnCol; iCol++){ + if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break; + } + if( iCol==pTab->nCol ){ + sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld); + goto exit_update_column; + } + + /* Ensure the schema contains no double-quoted strings */ + renameTestSchema(pParse, zDb, iSchema==1, "", 0); + renameFixQuotes(pParse, zDb, iSchema==1); + + /* Do the update operation using a recursive UPDATE statement that + ** uses the sqlite_update_column() SQL function to compute the new + ** CREATE statement text for the sqlite_schema table. + */ + sqlite3MayAbort(pParse); + if(pOld->n != pNew->n || sqlite3StrNICmp(pOld->z, pNew->z, pOld->n) != 0) { + sqlite3ErrorMsg(pParse, "UPDATE cannot also rename column: \"%T\" to \"%T\". Use ALTER TABLE RENAME instead", pOld, pNew); + goto exit_update_column; + } + // NOTICE: this is the main difference in ALTER COLUMN compared to RENAME COLUMN, + // we just take the whole new column declaration as it is. + // FIXME: the semicolon can also appear in the middle of the declaration when it's quoted, + // so we should check from the end. + pNew->n = sqlite3Strlen30(pNew->z); + while (pNew->n > 0 && pNew->z[pNew->n - 1] == ';') pNew->n--; + zNew = sqlite3DbStrNDup(db, pNew->z, pNew->n); + if( !zNew ) goto exit_update_column; + assert( pNew->n>0 ); + bQuote = -1; // Contrary to RENAME, we leave quotes as is and not dequote them + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = libsql_alter_column(sql, %Q, %Q, %d, %Q, %d, %d, %d) " + "WHERE tbl_name = %Q", + zDb, + zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1, pTab->aCol[iCol].colFlags, + pTab->zName + ); + + /* Drop and reload the database schema. */ + renameReloadSchema(pParse, iSchema, INITFLAG_AlterRename); + renameTestSchema(pParse, zDb, iSchema==1, "after update", 1); + + exit_update_column: + sqlite3SrcListDelete(db, pSrc); + sqlite3DbFree(db, zOld); + sqlite3DbFree(db, zNew); + return; +} + /* ** Each RenameToken object maps an element of the parse tree into ** the token that generated that element. The parse tree element @@ -115999,7 +115003,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 @@ -116135,7 +115139,7 @@ static int renameEditSql( RenameCtx *pRename, /* Rename context */ const char *zSql, /* SQL statement to edit */ const char *zNew, /* New token text */ - int bQuote /* True to always quote token */ + int bQuote /* 1 to always quote token, -1 to never quote */ ){ i64 nNew = sqlite3Strlen30(zNew); i64 nSql = sqlite3Strlen30(zSql); @@ -116184,7 +115188,7 @@ static int renameEditSql( RenameToken *pBest = renameColumnTokenNext(pRename); if( zNew ){ - if( bQuote==0 && sqlite3IsIdChar(*pBest->t.z) ){ + if( bQuote==-1 || (bQuote==0 && sqlite3IsIdChar(*pBest->t.z)) ){ nReplace = nNew; zReplace = zNew; }else{ @@ -116598,6 +115602,180 @@ static void renameColumnFunc( sqlite3BtreeLeaveAll(db); } +/* +** SQL function: +** +** libsql_alter_column(SQL,TYPE,OBJ,DB,TABLE,COL,NEWNAME,QUOTE,TEMP) +** +** 0. zSql: SQL statement to rewrite +** 1. Database: Database name (e.g. "main") +** 2. Table: Table name +** 3. iCol: Index of column to rename +** 4. zNew: New column clause to add, e.g. "x REFERENCES other_table(y)" +** 5. bQuote: Non-zero if the new column name should be quoted. +** 6. bTemp: True if zSql comes from temp schema +** +** Do a ALTER TABLE ALTER COLUMN operation on the CREATE statement given in zSql. +** The iCol-th column (left-most is 0) of table zTable is translated from zCol +** into zNew definition, which the new constraints. +** The name should be quoted if bQuote is true. +** +** This function is used internally by the ALTER TABLE ALTER COLUMN command. +** It is only accessible to SQL created using sqlite3NestedParse(). It is +** not reachable from ordinary SQL passed into sqlite3_prepare() unless the +** SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test setting is enabled. +*/ +static void alterColumnFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + RenameCtx sCtx; + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + const char *zDb = (const char*)sqlite3_value_text(argv[1]); + const char *zTable = (const char*)sqlite3_value_text(argv[2]); + int iCol = sqlite3_value_int(argv[3]); + const char *zNew = (const char*)sqlite3_value_text(argv[4]); + int bQuote = sqlite3_value_int(argv[5]); + int bTemp = sqlite3_value_int(argv[6]); + u16 iColFlags = sqlite3_value_int(argv[7]); + + const char *zOld; + int rc; + Parse sParse; + Parse sPostAlterParse; + Index *pIdx; + int i; + Table *pTab; +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; +#endif + + UNUSED_PARAMETER(NotUsed); + if( zSql==0 ) return; + if( zTable==0 ) return; + if( zNew==0 ) return; + if( iCol<0 ) return; + sqlite3BtreeEnterAll(db); + pTab = sqlite3FindTable(db, zTable, zDb); + if( pTab==0 || iCol>=pTab->nCol ){ + sqlite3BtreeLeaveAll(db); + return; + } + zOld = pTab->aCol[iCol].zCnName; + memset(&sCtx, 0, sizeof(sCtx)); + sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol); + +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = 0; +#endif + rc = renameParseSql(&sParse, zDb, db, zSql, bTemp); + + sCtx.pTab = pTab; + if( rc!=SQLITE_OK ) goto alterColumnFunc_done; + if( sParse.pNewTable ){ + if( IsOrdinaryTable(sParse.pNewTable) ){ + int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName); + FKey *pFKey; + sCtx.pTab = sParse.pNewTable; + if( bFKOnly==0 ){ + if (iColnCol) { + Column *col = &sParse.pNewTable->aCol[iCol]; + RenameToken *pCol = renameTokenFind( + &sParse, &sCtx, (void*)col->zCnName + ); + // Expand the token until we find the end of the column definition + // FIXME: corner cases we don't cover are expected here, like quoted identifiers + // and other kinds of parentheses, and they would result in an incorrect SQL statement being generated. + // What we want here is to expand to the whole definition, including constraints, types, etc. + int open_parens = 0; + while (pCol->t.z[pCol->t.n] != 0 && pCol->t.z[pCol->t.n] != ',') { + if (pCol->t.z[pCol->t.n] == '(') open_parens++; + if (pCol->t.z[pCol->t.n] == ')') open_parens--; + if (open_parens < 0) { + break; + } + pCol->t.n++; + } + } + if( sCtx.iCol<0 ){ + renameTokenFind(&sParse, &sCtx, (void*)&sParse.pNewTable->iPKey); + } + } + } else { + rc = SQLITE_ERROR; + sParse.zErrMsg = sqlite3MPrintf(sParse.db, "Only ordinary tables can be altered, not ", IsView(sParse.pNewTable) ? "views" : "virtual tables"); + goto alterColumnFunc_done; } + } else if (sParse.pNewIndex) { + rc = SQLITE_ERROR; + sParse.zErrMsg = sqlite3MPrintf(sParse.db, "Only ordinary tables can be altered, not indexes"); + goto alterColumnFunc_done; + } else { + rc = SQLITE_ERROR; + sParse.zErrMsg = sqlite3MPrintf(sParse.db, "Only ordinary tables can be altered"); + goto alterColumnFunc_done; + } + + assert( rc==SQLITE_OK ); + rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote); + + // Validate flags - PRIMARY KEY, UNIQUE and GENERATED constrains are not allowed to be altered + // TODO: figure out more illegal combinations to validate + rc = renameParseSql(&sPostAlterParse, zDb, db, (const char *)sqlite3_value_text((sqlite3_value *)context->pOut), bTemp); + Table *pNewTab = sPostAlterParse.pNewTable; + int iNewCol; + for (iNewCol = 0; iNewCol < pNewTab->nCol; iNewCol++) { + if (sqlite3StrICmp(pNewTab->aCol[iNewCol].zCnName, zOld) == 0) break; + } + if (iNewCol == pNewTab->nCol) { + sParse.zErrMsg = sqlite3MPrintf(sParse.db, "no such column: \"%T\"", zOld); + goto alterColumnFunc_done; + } + u16 primkey_differs = (iColFlags & COLFLAG_PRIMKEY) != (pNewTab->aCol[iNewCol].colFlags & COLFLAG_PRIMKEY); + u16 unique_differs = (iColFlags & COLFLAG_UNIQUE) != (pNewTab->aCol[iNewCol].colFlags & COLFLAG_UNIQUE); + u16 generated_differs = (iColFlags & COLFLAG_GENERATED) != (pNewTab->aCol[iNewCol].colFlags & COLFLAG_GENERATED); + renameParseCleanup(&sPostAlterParse); + + if (primkey_differs) { + rc = SQLITE_ERROR; + sParse.zErrMsg = sqlite3MPrintf(sParse.db, "PRIMARY KEY constraint cannot be altered"); + goto alterColumnFunc_done; + } else if (unique_differs) { + rc = SQLITE_ERROR; + sParse.zErrMsg = sqlite3MPrintf(sParse.db, "UNIQUE constraint cannot be altered"); + goto alterColumnFunc_done; + } else if (generated_differs) { + rc = SQLITE_ERROR; + sParse.zErrMsg = sqlite3MPrintf(sParse.db, "GENERATED constraint cannot be altered"); + goto alterColumnFunc_done; + } + +alterColumnFunc_done: + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){ + sqlite3_result_value(context, argv[0]); + }else if( sParse.zErrMsg ){ + char *zErr = sqlite3MPrintf(sParse.db, "error in adding %s to %s: %s", + zNew, + zTable, + sParse.zErrMsg + ); + sqlite3_result_error(context, zErr, -1); + sqlite3DbFree(sParse.db, zErr); + }else{ + sqlite3_result_error_code(context, rc); + } + } + + renameParseCleanup(&sParse); + renameTokenFree(db, sCtx.pList); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + sqlite3BtreeLeaveAll(db); +} + /* ** Walker expression callback used by "RENAME TABLE". */ @@ -117247,6 +116425,8 @@ SQLITE_PRIVATE void sqlite3AlterFunctions(void){ INTERNAL_FUNCTION(sqlite_rename_test, 7, renameTableTest), INTERNAL_FUNCTION(sqlite_drop_column, 3, dropColumnFunc), INTERNAL_FUNCTION(sqlite_rename_quotefix,2, renameQuotefixFunc), + // libSQL extensions + INTERNAL_FUNCTION(libsql_alter_column, 8, alterColumnFunc), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); } @@ -119105,15 +118285,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; @@ -119259,6 +118438,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ ** This file contains code used to implement the ATTACH and DETACH commands. */ /* #include "sqliteInt.h" */ +/* #include "wal.h" */ #ifndef SQLITE_OMIT_ATTACH /* @@ -119335,6 +118515,7 @@ static void attachFunc( Db *pNew = 0; /* Db object for the newly attached database */ char *zErrDyn = 0; sqlite3_vfs *pVfs; + libsql_wal_methods *pWal; UNUSED_PARAMETER(NotUsed); zFile = (const char *)sqlite3_value_text(argv[0]); @@ -119354,8 +118535,9 @@ static void attachFunc( ** reopen it as a MemDB */ Btree *pNewBt = 0; pVfs = sqlite3_vfs_find("memdb"); + pWal = libsql_wal_methods_find(NULL); if( pVfs==0 ) return; - rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB); + rc = sqlite3BtreeOpen(pVfs, pWal, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB); if( rc==SQLITE_OK ){ Schema *pNewSchema = sqlite3SchemaGet(db, pNewBt); if( pNewSchema ){ @@ -119415,7 +118597,7 @@ static void attachFunc( ** or may not be initialized. */ flags = db->openFlags; - rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); + rc = sqlite3ParseUri(db->pVfs->zName, db->pWalMethods->zName, zFile, &flags, &pVfs, &pWal, &zPath, &zErr); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); sqlite3_result_error(context, zErr, -1); @@ -119424,7 +118606,7 @@ static void attachFunc( } assert( pVfs ); flags |= SQLITE_OPEN_MAIN_DB; - rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags); + rc = sqlite3BtreeOpen(pVfs, pWal, zPath, db, &pNew->pBt, 0, flags); db->nDb++; pNew->zDbSName = sqlite3DbStrDup(db, zName); } @@ -120071,7 +119253,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 ); @@ -120372,26 +119554,29 @@ 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 were factored out of inner loops. + /* Code constant expressions that where factored out of inner loops. + ** + ** The pConstExpr list might also contain expressions that we simply + ** want to keep around until the Parse object is deleted. Such + ** expressions have iConstExprReg==0. Do not generate code for + ** those expressions, of course. */ if( pParse->pConstExpr ){ ExprList *pEL = pParse->pConstExpr; pParse->okConstFactor = 0; for(i=0; inExpr; i++){ - assert( pEL->a[i].u.iConstExprReg>0 ); - sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg); + int iReg = pEL->a[i].u.iConstExprReg; + sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg); } } @@ -120890,7 +120075,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; @@ -121545,13 +120730,20 @@ SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ } #endif +/* +** Name of the special TEMP trigger used to implement RETURNING. The +** name begins with "sqlite_" so that it is guaranteed not to collide +** with any application-generated triggers. +*/ +#define RETURNING_TRIGGER_NAME "sqlite_returning" + /* ** Clean up the data structures associated with the RETURNING clause. */ static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){ Hash *pHash; pHash = &(db->aDb[1].pSchema->trigHash); - sqlite3HashInsert(pHash, pRet->zName, 0); + sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, 0); sqlite3ExprListDelete(db, pRet->pReturnEL); sqlite3DbFree(db, pRet); } @@ -121594,9 +120786,7 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet); testcase( pParse->earlyCleanup ); if( db->mallocFailed ) return; - sqlite3_snprintf(sizeof(pRet->zName), pRet->zName, - "sqlite_returning_%p", pParse); - pRet->retTrig.zName = pRet->zName; + pRet->retTrig.zName = RETURNING_TRIGGER_NAME; pRet->retTrig.op = TK_RETURNING; pRet->retTrig.tr_tm = TRIGGER_AFTER; pRet->retTrig.bReturning = 1; @@ -121607,9 +120797,9 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ pRet->retTStep.pTrig = &pRet->retTrig; pRet->retTStep.pExprList = pList; pHash = &(db->aDb[1].pSchema->trigHash); - assert( sqlite3HashFind(pHash, pRet->zName)==0 + assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 || pParse->nErr || pParse->ifNotExists ); - if( sqlite3HashInsert(pHash, pRet->zName, &pRet->retTrig) + if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig) ==&pRet->retTrig ){ sqlite3OomFault(db); } @@ -121643,7 +120833,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. */ @@ -121864,7 +121054,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; @@ -122212,7 +121402,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. @@ -122853,6 +122043,15 @@ SQLITE_PRIVATE void sqlite3EndTable( p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid; convertToWithoutRowidTable(pParse, p); } + if( tabOpts & TF_RandomRowid ){ + assert( (p->tabFlags & TF_WithoutRowid) == 0 ); + if( (p->tabFlags & TF_Autoincrement) ){ + sqlite3ErrorMsg(pParse, + "AUTOINCREMENT not allowed on RANDOM ROWID tables"); + return; + } + p->tabFlags |= TF_RandomRowid; + } iDb = sqlite3SchemaToIndex(db, p->pSchema); #ifndef SQLITE_OMIT_CHECK @@ -123053,17 +122252,6 @@ SQLITE_PRIVATE void sqlite3EndTable( /* Reparse everything to update our internal data structures */ sqlite3VdbeAddParseSchemaOp(v, iDb, sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName),0); - - /* Test for cycles in generated columns and illegal expressions - ** in CHECK constraints and in DEFAULT clauses. */ - if( p->tabFlags & TF_HasGenerated ){ - sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, - sqlite3MPrintf(db, "SELECT*FROM\"%w\".\"%w\"", - db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); - } - sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, - sqlite3MPrintf(db, "PRAGMA \"%w\".integrity_check(%Q)", - db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); } /* Add the table to the in-memory representation of the database. @@ -124113,7 +123301,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); @@ -125352,7 +124540,7 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TEMP_DB; - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags); + rc = sqlite3BtreeOpen(db->pVfs, db->pWalMethods, 0, db, &pBt, 0, flags); if( rc!=SQLITE_OK ){ sqlite3ErrorMsg(pParse, "unable to open a temporary database " "file for storing temporary tables"); @@ -125770,7 +124958,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. */ @@ -125832,6 +125020,140 @@ SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ } #endif /* !defined(SQLITE_OMIT_CTE) */ +#ifdef LIBSQL_ENABLE_WASM_RUNTIME + +void libsql_create_function( + Parse *pParse, /* The parsing context */ + Token *pName, /* Function name */ + Token *pLang, /* Language of the function */ + Token *pBody, /* Body of the function */ + int isBlob, /* If the input token is blob */ + int noErr /* Suppress error messages if FUNCTION already exists */ +) { + if (pLang->n != 4 && sqlite3_strnicmp("wasm", pLang->z, 4) != 0) { + sqlite3ErrorMsg(pParse, "The only supported language for user-defined functions is 'wasm'"); + return; + } + + libsql_try_initialize_wasm_func_table(pParse->db); + + Token table = {"libsql_wasm_func_table", 22}; + Token name = {"name", 4}; + Token body = {"body", 4}; + + const void *pParsedBody = NULL; + int src_size = 0; + if (isBlob) { + pParsedBody = sqlite3HexToBlob(pParse->db, pBody->z + 2, pBody->n - 2); + src_size = (pBody->n - 3)/2; + } else { + pParsedBody = sqlite3NameFromToken(pParse->db, pBody); + src_size = sqlite3Strlen30(pParsedBody); + } + + SrcList* tab_list = sqlite3SrcListAppend(pParse, NULL, &table, NULL); + if (!tab_list) { + sqlite3ErrorMsg(pParse, "Failed to allocate tab list"); + sqlite3DbFree(pParse->db, (void*)pParsedBody); + return; + } + IdList* id_list = sqlite3IdListAppend(pParse, NULL, &name); + if (!id_list) { + sqlite3ErrorMsg(pParse, "Failed to allocate id list"); + sqlite3SrcListDelete(pParse->db, tab_list); + sqlite3DbFree(pParse->db, (void*)pParsedBody); + return; + } + id_list = sqlite3IdListAppend(pParse, id_list, &body); + ExprList* expr_list = sqlite3ExprListAppend(pParse, NULL, sqlite3ExprAlloc(pParse->db, TK_STRING, pName, 0)); + if (!expr_list) { + sqlite3ErrorMsg(pParse, "Failed to allocate expr list"); + sqlite3SrcListDelete(pParse->db, tab_list); + sqlite3IdListDelete(pParse->db, id_list); + sqlite3DbFree(pParse->db, (void*)pParsedBody); + return; + } + + Token parsed_text = { + .z = pParsedBody, + .n = src_size + }; + expr_list = sqlite3ExprListAppend(pParse, expr_list, sqlite3ExprAlloc(pParse->db, isBlob ? TK_BLOB : TK_STRING, isBlob ? pBody : &parsed_text, 0)); + + Select* select = sqlite3SelectNew(pParse, expr_list, 0, 0, 0, 0, 0, SF_Values|SF_MultiValue, 0); + if (!select) { + sqlite3ErrorMsg(pParse, "Failed to allocate select"); + sqlite3SrcListDelete(pParse->db, tab_list); + sqlite3IdListDelete(pParse->db, id_list); + sqlite3ExprListDelete(pParse->db, expr_list); + sqlite3DbFree(pParse->db, (void*)pParsedBody); + return; + } + sqlite3Insert(pParse, tab_list, select, id_list, noErr ? OE_Ignore : OE_Default, NULL); + + // AddWasmFunc operation + char *pAddFuncData = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); + pAddFuncData = sqlite3DbRealloc(pParse->db, pAddFuncData, pName->n + 1 + src_size); + if (!pAddFuncData) { + sqlite3ErrorMsg(pParse, "Failed to allocate function name and body"); + sqlite3DbFree(pParse->db, (void *)pParsedBody); + return; + } + memcpy(pAddFuncData + pName->n + 1, pParsedBody, src_size); + sqlite3VdbeAddOp4(sqlite3GetVdbe(pParse), OP_CreateWasmFunc, noErr, pName->n, src_size, pAddFuncData, P4_DYNAMIC); + + sqlite3DbFree(pParse->db, (void*)pParsedBody); +} + +void libsql_drop_function( + Parse *pParse, /* The parsing context */ + Token *pName, /* Function name */ + int noErr /* Suppress error messages if FUNCTION does not exist */ +) { + Token table = {"libsql_wasm_func_table", 22}; + SrcList* tab_list = sqlite3SrcListAppend(pParse, NULL, &table, NULL); + if (!tab_list) { + sqlite3ErrorMsg(pParse, "Failed to allocate tab list"); + return; + } + Token name = {"name", 4}; + Expr* where = sqlite3PExpr(pParse, TK_EQ, + sqlite3ExprAlloc(pParse->db, TK_ID, &name, 0), + sqlite3ExprAlloc(pParse->db, TK_STRING, pName, 0)); + + sqlite3DeleteFrom(pParse, tab_list, where, NULL, NULL); + + char *zName = sqlite3NameFromToken(pParse->db, pName); + if (!zName) { + sqlite3OomFault(pParse->db); + return; + } + + sqlite3VdbeAddOp4(sqlite3GetVdbe(pParse), OP_DropWasmFunc, noErr, 0, 0, zName, P4_DYNAMIC); +} + +#else + +void libsql_create_function( + Parse *pParse, /* The parsing context */ + Token *pName, /* Function name */ + Token *pLang, /* Language of the function */ + Token *pBody, /* Body of the function */ + int isBlob, /* If the input token is blob */ + int noErr /* Suppress error messages if FUNCTION already exists */ +) { + sqlite3ErrorMsg(pParse, "Support for user-defined functions is not compiled-in. Try ./configure --enable-wasm-runtime"); +} + +void libsql_drop_function( + Parse *pParse, /* The parsing context */ + Token *pName, /* Function name */ + int noErr /* Suppress error messages if FUNCTION does not exist */ +) { + sqlite3ErrorMsg(pParse, "Support for user-defined functions is not compiled-in. Try ./configure --enable-wasm-runtime"); +} + +#endif /************** End of build.c ***********************************************/ /************** Begin file callback.c ****************************************/ /* @@ -126299,7 +125621,7 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction( memcpy((char*)&pBest[1], zName, nName+1); for(z=(u8*)pBest->zName; *z; z++) *z = sqlite3UpperToLower[*z]; pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest); - if( pOther==pBest ){ + if(pOther == pBest) { sqlite3DbFree(db, pBest); sqlite3OomFault(db); return 0; @@ -126412,7 +125734,7 @@ 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 ){ @@ -126567,7 +125889,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; @@ -126647,7 +125969,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; @@ -126876,7 +126198,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{ @@ -126904,8 +126226,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( if( pWInfo==0 ) goto delete_from_cleanup; eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); - assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF - || OptimizationDisabled(db, SQLITE_OnePass) ); + assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF ); if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse); if( sqlite3WhereUsesDeferredSeek(pWInfo) ){ sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur); @@ -127242,11 +126563,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 @@ -127424,12 +126743,16 @@ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ ** time functions, are implemented separately.) */ /* #include "sqliteInt.h" */ +/* #include */ /* #include */ /* #include */ #ifndef SQLITE_OMIT_FLOATING_POINT /* #include */ #endif /* #include "vdbeInt.h" */ +#ifdef LIBSQL_ENABLE_WASM_RUNTIME +/* #include "ext/udf/wasm_bindings.h" */ +#endif /* ** Return the collating function associated with a function. @@ -127559,42 +126882,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. ** @@ -127871,7 +127158,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; @@ -128071,7 +127358,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. */ @@ -128304,7 +127591,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 @@ -128637,7 +127924,6 @@ static void charFunc( *zOut++ = 0x80 + (u8)(c & 0x3F); } \ } - *zOut = 0; sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8); } @@ -128666,8 +127952,7 @@ static void hexFunc( *(z++) = hexdigits[c&0xf]; } *z = 0; - sqlite3_result_text64(context, zHex, (u64)(z-zHex), - sqlite3_free, SQLITE_UTF8); + sqlite3_result_text(context, zHex, n*2, sqlite3_free); } } @@ -128692,7 +127977,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 @@ -128961,81 +128246,6 @@ static void trimFunc( sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); } -/* The core implementation of the CONCAT(...) and CONCAT_WS(SEP,...) -** functions. -** -** Return a string value that is the concatenation of all non-null -** entries in argv[]. Use zSep as the separator. -*/ -static void concatFuncCore( - sqlite3_context *context, - int argc, - sqlite3_value **argv, - int nSep, - const char *zSep -){ - i64 j, k, n = 0; - int i; - char *z; - for(i=0; i0 ){ - const char *v = (const char*)sqlite3_value_text(argv[i]); - if( v!=0 ){ - if( j>0 && nSep>0 ){ - memcpy(&z[j], zSep, nSep); - j += nSep; - } - memcpy(&z[j], v, k); - j += k; - } - } - } - z[j] = 0; - assert( j<=n ); - sqlite3_result_text64(context, z, j, sqlite3_free, SQLITE_UTF8); -} - -/* -** The CONCAT(...) function. Generate a string result that is the -** concatentation of all non-null arguments. -*/ -static void concatFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - concatFuncCore(context, argc, argv, 0, ""); -} - -/* -** The CONCAT_WS(separator, ...) function. -** -** Generate a string that is the concatenation of 2nd through the Nth -** argument. Use the first argument (which must be non-NULL) as the -** separator. -*/ -static void concatwsFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - int nSep = sqlite3_value_bytes(argv[0]); - const char *zSep = (const char*)sqlite3_value_text(argv[0]); - if( zSep==0 ) return; - concatFuncCore(context, argc-1, argv+1, nSep, zSep); -} - #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION /* @@ -129157,68 +128367,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. ** @@ -129238,29 +128393,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; } } } @@ -129277,18 +128418,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]); } } } @@ -129299,14 +128435,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 if( !sqlite3IsNaN(p->rErr) ){ - sqlite3_result_double(context, p->rSum+p->rErr); - }else{ - sqlite3_result_double(context, p->rSum); - } + 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); } @@ -129316,29 +128448,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; - if( !sqlite3IsNaN(p->rErr) ) r += 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; - if( !sqlite3IsNaN(p->rErr) ) r += 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); } /* @@ -129457,7 +128574,6 @@ static void minMaxFinalize(sqlite3_context *context){ /* ** group_concat(EXPR, ?SEPARATOR?) -** string_agg(EXPR, SEPARATOR) ** ** The SEPARATOR goes before the EXPR string. This is tragic. The ** groupConcatInverse() implementation would have been easier if the @@ -129561,7 +128677,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 @@ -129645,10 +128761,8 @@ SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){ ** sensitive. */ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ - FuncDef *pDef; struct compareInfo *pInfo; int flags; - int nArg; if( caseSensitive ){ pInfo = (struct compareInfo*)&likeInfoAlt; flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE; @@ -129656,13 +128770,10 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive) pInfo = (struct compareInfo*)&likeInfoNorm; flags = SQLITE_FUNC_LIKE; } - for(nArg=2; nArg<=3; nArg++){ - sqlite3CreateFunc(db, "like", nArg, SQLITE_UTF8, pInfo, likeFunc, - 0, 0, 0, 0, 0); - pDef = sqlite3FindFunction(db, "like", nArg, SQLITE_UTF8, 0); - pDef->funcFlags |= flags; - pDef->funcFlags &= ~SQLITE_FUNC_UNSAFE; - } + sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); + sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); + sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags; + sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags; } /* @@ -129934,36 +129045,136 @@ 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); +#ifdef LIBSQL_ENABLE_WASM_RUNTIME +void functionDestroy(sqlite3 *db, FuncDef *p); + +// Removes a Wasm function +int deregister_wasm_function(sqlite3 *db, const char *zName) { + FuncDef *p = (FuncDef *)sqlite3HashInsert(&db->aFunc, zName, NULL); + int ret = p ? 1 : 0; + while (p) { + functionDestroy(db, p); + FuncDef *pNext = p->pNext; + sqlite3DbFree(db, p); + p = pNext; + }; + return ret; +} + +void run_wasm(sqlite3_context *context, int argc, sqlite3_value **argv) { + static libsql_wasm_udf_api api = { + .libsql_value_type = sqlite3_value_type, + .libsql_value_int = sqlite3_value_int, + .libsql_value_double = sqlite3_value_double, + .libsql_value_text = sqlite3_value_text, + .libsql_value_blob = sqlite3_value_blob, + .libsql_value_bytes = sqlite3_value_bytes, + .libsql_result_error = sqlite3_result_error, + .libsql_result_error_nomem = sqlite3_result_error_nomem, + .libsql_result_int = sqlite3_result_int, + .libsql_result_double = sqlite3_result_double, + .libsql_result_text = sqlite3_result_text, + .libsql_result_blob = sqlite3_result_blob, + .libsql_result_null = sqlite3_result_null, + .libsql_malloc = sqlite3_malloc, + .libsql_free = sqlite3_free + }; + void *user_data = sqlite3_user_data(context); + libsql_wasm_module_t *module = *(libsql_wasm_module_t **)(user_data); + const char *func_name = (const char *)user_data + sizeof(module); + libsql_run_wasm(&api, context, context->pVdbe->db->wasm.engine, module, func_name, argc, argv); +} + +// Tries to initialize and register a Wasm function dynamically. +// Returns NULL on failure and fills err_msg_buf with an error message, if not NULL. +FuncDef *try_instantiate_wasm_function(sqlite3 *db, const char *pName, int nName, const char *pSrcBody, int nBody, int nArg, char **err_msg_buf) { + FuncDef *pBest = NULL; + FuncDef *pOther = NULL; + + if (!db->wasm.engine) { + db->wasm.engine = libsql_wasm_engine_new(); + } + + libsql_wasm_module_t *module = libsql_compile_wasm_module(db->wasm.engine, pSrcBody, nBody, sqlite3MallocZero, err_msg_buf); + if (!module) { + return NULL; + } + + pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+sizeof(module)+nName+1); + memcpy(&pBest[1], &module, sizeof(module)); + pBest->zName = (const char*)&pBest[1] + sizeof(module); + memcpy((char *)pBest->zName, pName, nName); + ((char *)pBest->zName)[nName] = '\0'; + + pBest->funcFlags = 0; + pBest->xSFunc = run_wasm; + pBest->xFinalize = NULL; + pBest->xValue = NULL; + pBest->xInverse = NULL; + pBest->pUserData = &pBest[1]; + pBest->nArg = (i8)nArg; + + pBest->u.pDestructor = (FuncDestructor *)sqlite3Malloc(sizeof(FuncDestructor)); + if(!pBest->u.pDestructor) { + sqlite3OomFault(db); + libsql_free_wasm_module(pBest); + return NULL; } - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + pBest->u.pDestructor->nRef = 1; + pBest->u.pDestructor->xDestroy = libsql_free_wasm_module; + pBest->u.pDestructor->pUserData = &pBest[1]; + + // Register the function dynamically + for(u8 *z = (u8*)pBest->zName; *z; z++) { + *z = sqlite3UpperToLower[*z]; + }; + pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest); + if (pOther == pBest) { + sqlite3DbFree(db, pBest); + sqlite3OomFault(db); + return NULL; + } else { + pBest->pNext = pOther; + } + + return pBest; } -#endif /* SQLITE_DEBUG */ + +int libsql_try_initialize_wasm_func_table(sqlite3 *db) { +#ifdef SQLITE_TEST + // Tcl tests assume there are no extra tables during their execution + return SQLITE_OK; +#endif + int rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS libsql_wasm_func_table (name text PRIMARY KEY, body text) WITHOUT ROWID", NULL, NULL, NULL); + if (rc == SQLITE_OK) { + // If the table exists, register all the functions + sqlite3_stmt *stmt; + rc = sqlite3_prepare_v2(db, "SELECT name, body FROM libsql_wasm_func_table", -1, &stmt, 0); + if (rc != SQLITE_OK) return rc; + rc = SQLITE_ROW; + while (rc == SQLITE_ROW) { + rc = sqlite3_step(stmt); + if (rc == SQLITE_ROW) { + int name_type = sqlite3_column_type(stmt, 0); + int name_size = sqlite3_column_bytes(stmt, 0); + int body_type = sqlite3_column_type(stmt, 1); + int body_size = sqlite3_column_bytes(stmt, 1); + if (name_type != SQLITE_TEXT && body_type != SQLITE_TEXT && body_type != SQLITE_BLOB) { + sqlite3_finalize(stmt); + return rc; + } + const char *pName = sqlite3_column_text(stmt, 0); + const void *pBody = body_type == SQLITE_TEXT ? sqlite3_column_text(stmt, 1) : sqlite3_column_blob(stmt, 1); + try_instantiate_wasm_function(db, pName, name_size, pBody, body_size, -1, NULL); + } + } + sqlite3_finalize(stmt); + rc = SQLITE_OK; + } + return rc; +} + +#endif // LIBSQL_ENABLE_WASM_RUNTIME /* ** All of the FuncDef structures in the aBuiltinFunc[] array above @@ -130029,16 +129240,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 ), @@ -130048,11 +129255,6 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(hex, 1, 0, 0, hexFunc ), FUNCTION(unhex, 1, 0, 0, unhexFunc ), FUNCTION(unhex, 2, 0, 0, unhexFunc ), - FUNCTION(concat, -1, 0, 0, concatFunc ), - FUNCTION(concat, 0, 0, 0, 0 ), - FUNCTION(concat_ws, -1, 0, 0, concatwsFunc ), - FUNCTION(concat_ws, 0, 0, 0, 0 ), - FUNCTION(concat_ws, 1, 0, 0, 0 ), INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, 0 ), VFUNCTION(random, 0, 0, 0, randomFunc ), VFUNCTION(randomblob, 1, 0, 0, randomBlob ), @@ -130082,8 +129284,6 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), - WAGGREGATE(string_agg, 2, 0, 0, groupConcatStep, - groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), #ifdef SQLITE_CASE_SENSITIVE_LIKE @@ -131026,7 +130226,6 @@ static int isSetNullAction(Parse *pParse, FKey *pFKey){ if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull) || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull) ){ - assert( (pTop->db->flags & SQLITE_FkNoAction)==0 ); return 1; } } @@ -131221,8 +130420,6 @@ SQLITE_PRIVATE void sqlite3FkCheck( } if( regOld!=0 ){ int eAction = pFKey->aAction[aChange!=0]; - if( (db->flags & SQLITE_FkNoAction) ) eAction = OE_None; - fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1); /* If this is a deferred FK constraint, or a CASCADE or SET NULL ** action applies, then any foreign key violations caused by @@ -131338,11 +130535,7 @@ SQLITE_PRIVATE int sqlite3FkRequired( /* Check if any parent key columns are being modified. */ for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ if( fkParentIsModified(pTab, p, aChange, chngRowid) ){ - if( (pParse->db->flags & SQLITE_FkNoAction)==0 - && p->aAction[1]!=OE_None - ){ - return 2; - } + if( p->aAction[1]!=OE_None ) return 2; bHaveFK = 1; } } @@ -131392,7 +130585,6 @@ static Trigger *fkActionTrigger( int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ action = pFKey->aAction[iAction]; - if( (db->flags & SQLITE_FkNoAction) ) action = OE_None; if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){ return 0; } @@ -131624,8 +130816,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; @@ -131688,10 +130881,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)); @@ -131820,7 +131011,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 @@ -132169,7 +131360,7 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){ ** memory cell is updated. */ static void autoIncStep(Parse *pParse, int memId, int regRowid){ - if( memId>0 ){ + if( memId>0 && memId!=LIBSQL_RANDOM_ROWID_MARKER ){ sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid); } } @@ -132370,7 +131561,7 @@ SQLITE_PRIVATE void sqlite3Insert( /* Register allocations */ int regFromSelect = 0;/* Base register for data coming from SELECT */ - int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ + int regNextRowid = 0; /* Register holding the AUTOINCREMENT counter or sentinel value for RandomRowid */ int regRowCount = 0; /* Memory cell used for the row counter */ int regIns; /* Block of regs holding rowid+data being inserted */ int regRowid; /* registers holding insert rowid */ @@ -132484,9 +131675,12 @@ SQLITE_PRIVATE void sqlite3Insert( #endif /* SQLITE_OMIT_XFER_OPT */ /* If this is an AUTOINCREMENT table, look up the sequence number in the - ** sqlite_sequence table and store it in memory cell regAutoinc. + ** sqlite_sequence table and store it in memory cell regNextRowid. */ - regAutoinc = autoIncBegin(pParse, iDb, pTab); + regNextRowid = autoIncBegin(pParse, iDb, pTab); + if (pTab->tabFlags & TF_RandomRowid) { + regNextRowid = LIBSQL_RANDOM_ROWID_MARKER; + } /* Allocate a block registers to hold the rowid and the values ** for all columns of the new row. @@ -132943,7 +132137,7 @@ SQLITE_PRIVATE void sqlite3Insert( }else{ Expr *pIpk = pList->a[ipkColumn].pExpr; if( pIpk->op==TK_NULL && !IsVirtual(pTab) ){ - sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regNextRowid); appendFlag = 1; }else{ sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid); @@ -132956,7 +132150,7 @@ SQLITE_PRIVATE void sqlite3Insert( int addr1; if( !IsVirtual(pTab) ){ addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regNextRowid); sqlite3VdbeJumpHere(v, addr1); }else{ addr1 = sqlite3VdbeCurrentAddr(v); @@ -132967,10 +132161,10 @@ SQLITE_PRIVATE void sqlite3Insert( }else if( IsVirtual(pTab) || withoutRowid ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid); }else{ - sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regNextRowid); appendFlag = 1; } - autoIncStep(pParse, regAutoinc, regRowid); + autoIncStep(pParse, regNextRowid, regRowid); #ifndef SQLITE_OMIT_GENERATED_COLUMNS /* Compute the new value for generated columns after all other @@ -133112,7 +132306,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 ){ @@ -133335,7 +132529,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 */ @@ -133818,7 +133012,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 */ @@ -134313,8 +133507,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 @@ -134327,18 +133519,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] ){ @@ -134456,7 +133648,7 @@ static int xferOptimization( int emptyDestTest = 0; /* Address of test for empty pDest */ int emptySrcTest = 0; /* Address of test for empty pSrc */ Vdbe *v; /* The VDBE we are building */ - int regAutoinc; /* Memory register used by AUTOINC */ + int regNextRowid; /* Memory register used by AUTOINC or sentinel value for RandomRowid */ int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */ int regData, regRowid; /* Registers holding data and rowid */ @@ -134636,7 +133828,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 @@ -134664,7 +133856,10 @@ static int xferOptimization( sqlite3CodeVerifySchema(pParse, iDbSrc); iSrc = pParse->nTab++; iDest = pParse->nTab++; - regAutoinc = autoIncBegin(pParse, iDbDest, pDest); + regNextRowid = autoIncBegin(pParse, iDbDest, pDest); + if ( (pDest->tabFlags & TF_RandomRowid) ){ + regNextRowid = LIBSQL_RANDOM_ROWID_MARKER; + } regData = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp2(v, OP_Null, 0, regData); regRowid = sqlite3GetTempReg(pParse); @@ -134709,7 +133904,7 @@ static int xferOptimization( sqlite3RowidConstraint(pParse, onError, pDest); sqlite3VdbeJumpHere(v, addr2); } - autoIncStep(pParse, regAutoinc, regRowid); + autoIncStep(pParse, regNextRowid, regRowid); }else if( pDest->pIndex==0 && !(db->mDbFlags & DBFLAG_VacuumInto) ){ addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid); }else{ @@ -135346,11 +134541,14 @@ struct sqlite3_api_routines { int (*value_encoding)(sqlite3_value*); /* Version 3.41.0 and later */ int (*is_interrupted)(sqlite3*); - /* Version 3.43.0 and later */ - int (*stmt_explain)(sqlite3_stmt*,int); - /* Version 3.44.0 and later */ - void *(*get_clientdata)(sqlite3*,const char*); - int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); + +}; + +struct libsql_api_routines { + /* libSQL 0.1.1 */ + struct libsql_wal_methods *(*wal_methods_find)(const char *); + int (*wal_methods_register)(struct libsql_wal_methods*); + int (*wal_methods_unregister)(struct libsql_wal_methods*); }; /* @@ -135358,9 +134556,10 @@ struct sqlite3_api_routines { ** is also defined in the file "loadext.c". */ typedef int (*sqlite3_loadext_entry)( - sqlite3 *db, /* Handle to the database. */ - char **pzErrMsg, /* Used to set error string on failure. */ - const sqlite3_api_routines *pThunk /* Extension API function pointers. */ + sqlite3 *db, /* Handle to the database. */ + char **pzErrMsg, /* Used to set error string on failure. */ + const sqlite3_api_routines *pThunk, /* Extension API function pointers. */ + const libsql_api_routines *pThunkLibsql /* Extension API function pointers - libSQL.*/ ); /* @@ -135679,11 +134878,10 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_value_encoding sqlite3_api->value_encoding /* Version 3.41.0 and later */ #define sqlite3_is_interrupted sqlite3_api->is_interrupted -/* Version 3.43.0 and later */ -#define sqlite3_stmt_explain sqlite3_api->stmt_explain -/* Version 3.44.0 and later */ -#define sqlite3_get_clientdata sqlite3_api->get_clientdata -#define sqlite3_set_clientdata sqlite3_api->set_clientdata +/* libSQL 0.1.1 */ +#define libsql_wal_methods_find libsql_api->wal_methods_find +#define libsql_wal_methods_register libsql_api->wal_methods_register +#define libsql_wal_methods_unregister libsql_api->wal_methods_unregister #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) @@ -135693,12 +134891,23 @@ typedef int (*sqlite3_loadext_entry)( # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; # define SQLITE_EXTENSION_INIT3 \ extern const sqlite3_api_routines *sqlite3_api; + +# define LIBSQL_EXTENSION_INIT1 const libsql_api_routines *libsql_api=0; +# define LIBSQL_EXTENSION_INIT2(v) libsql_api=v; +# define LIBSQL_EXTENSION_INIT3 \ + extern const libsql_api_routines *libsql_api; + #else /* This case when the file is being statically linked into the ** application */ # define SQLITE_EXTENSION_INIT1 /*no-op*/ # define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ # define SQLITE_EXTENSION_INIT3 /*no-op*/ + +# define LIBSQL_EXTENSION_INIT1 /*no-op*/ +# define LIBSQL_EXTENSION_INIT2(v) (void)v; /* unused parameter */ +# define LIBSQL_EXTENSION_INIT3 /*no-op*/ + #endif #endif /* SQLITE3EXT_H */ @@ -136200,14 +135409,15 @@ static const sqlite3_api_routines sqlite3Apis = { /* Version 3.40.0 and later */ sqlite3_value_encoding, /* Version 3.41.0 and later */ - sqlite3_is_interrupted, - /* Version 3.43.0 and later */ - sqlite3_stmt_explain, - /* Version 3.44.0 and later */ - sqlite3_get_clientdata, - sqlite3_set_clientdata + sqlite3_is_interrupted }; +static const libsql_api_routines libsqlApis = { + /* libSQL 0.1.1 */ + libsql_wal_methods_find, + libsql_wal_methods_register, + libsql_wal_methods_unregister +}; /* True if x is the directory separator character */ #if SQLITE_OS_WIN @@ -136285,10 +135495,6 @@ static int sqlite3LoadExtension( */ 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; iimutex); if( onoff ){ db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc; @@ -136473,9 +135676,6 @@ SQLITE_API int sqlite3_auto_extension( void (*xInit)(void) ){ int rc = SQLITE_OK; -#ifdef SQLITE_ENABLE_API_ARMOR - if( xInit==0 ) return SQLITE_MISUSE_BKPT; -#endif #ifndef SQLITE_OMIT_AUTOINIT rc = sqlite3_initialize(); if( rc ){ @@ -136528,9 +135728,6 @@ SQLITE_API int sqlite3_cancel_auto_extension( int i; int n = 0; wsdAutoextInit; -#ifdef SQLITE_ENABLE_API_ARMOR - if( xInit==0 ) return 0; -#endif sqlite3_mutex_enter(mutex); for(i=(int)wsdAutoext.nExt-1; i>=0; i--){ if( wsdAutoext.aExt[i]==xInit ){ @@ -136587,8 +135784,10 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ #endif #ifdef SQLITE_OMIT_LOAD_EXTENSION const sqlite3_api_routines *pThunk = 0; + const libsql_api_routines *pThunkLibsql = 0; #else const sqlite3_api_routines *pThunk = &sqlite3Apis; + const libsql_api_routines *pThunkLibsql = &libsqlApis; #endif sqlite3_mutex_enter(mutex); if( i>=wsdAutoext.nExt ){ @@ -136599,7 +135798,7 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ } sqlite3_mutex_leave(mutex); zErrmsg = 0; - if( xInit && (rc = xInit(db, &zErrmsg, pThunk))!=0 ){ + if( xInit && (rc = xInit(db, &zErrmsg, pThunk, pThunkLibsql))!=0 ){ sqlite3ErrorWithMsg(db, rc, "automatic extension loading failed: %s", zErrmsg); go = 0; @@ -138130,7 +137329,7 @@ SQLITE_PRIVATE void sqlite3Pragma( ** ** The first form reports the current local setting for the ** page cache spill size. The second form turns cache spill on - ** or off. When turning cache spill on, the size is set to the + ** or off. When turnning cache spill on, the size is set to the ** current cache_size. The third form sets a spill size that ** may be different form the cache size. ** If N is positive then that is the @@ -138400,11 +137599,7 @@ SQLITE_PRIVATE void sqlite3Pragma( #endif if( sqlite3GetBoolean(zRight, 0) ){ - if( (mask & SQLITE_WriteSchema)==0 - || (db->flags & SQLITE_Defensive)==0 - ){ - db->flags |= mask; - } + db->flags |= mask; }else{ db->flags &= ~mask; if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; @@ -138912,9 +138107,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 @@ -139037,31 +138232,8 @@ SQLITE_PRIVATE void sqlite3Pragma( int r2; /* Previous key for WITHOUT ROWID tables */ int mxCol; /* Maximum non-virtual column number */ + if( !IsOrdinaryTable(pTab) ) continue; if( pObjTab && pObjTab!=pTab ) continue; - if( !IsOrdinaryTable(pTab) ){ -#ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3_vtab *pVTab; - int a1; - if( !IsVirtual(pTab) ) continue; - if( pTab->nCol<=0 ){ - const char *zMod = pTab->u.vtab.azArg[0]; - if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue; - } - sqlite3ViewGetColumnNames(pParse, pTab); - if( pTab->u.vtab.p==0 ) continue; - pVTab = pTab->u.vtab.p->pVtab; - if( NEVER(pVTab==0) ) continue; - if( NEVER(pVTab->pModule==0) ) continue; - if( pVTab->pModule->iVersion<4 ) continue; - if( pVTab->pModule->xIntegrity==0 ) continue; - sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick); - sqlite3VdbeAppendP4(v, pTab, P4_TABLE); - a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); - integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, a1); -#endif - continue; - } if( isQuick || HasRowid(pTab) ){ pPk = 0; r2 = 0; @@ -139695,7 +138867,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 */ @@ -140187,8 +139359,7 @@ static const sqlite3_module pragmaVtabModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0, /* xShadowName */ - 0 /* xIntegrity */ + 0 /* xShadowName */ }; /* @@ -140812,6 +139983,8 @@ SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse *pParse){ db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; assert( pParse->db->pParse==pParse ); db->pParse = pParse->pOuterParse; + pParse->db = 0; + pParse->disableLookaside = 0; } /* @@ -140820,7 +139993,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. @@ -140912,12 +140085,7 @@ 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"); @@ -141527,7 +140695,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: @@ -141749,7 +140917,6 @@ static void unsetJoinExpr(Expr *p, int iTable, int nullable){ } if( p->op==TK_FUNCTION ){ assert( ExprUseXList(p) ); - assert( p->pLeft==0 ); if( p->x.pList ){ int i; for(i=0; ix.pList->nExpr; i++){ @@ -141799,7 +140966,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 ){ @@ -142015,7 +141182,7 @@ static void pushOntoSorter( ** (3) Some output columns are omitted from the sort record due to ** the SQLITE_ENABLE_SORTER_REFERENCES 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. */ @@ -142071,7 +141238,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); @@ -142165,7 +141332,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, @@ -142594,16 +141761,6 @@ static void selectInnerLoop( testcase( eDest==SRT_Fifo ); testcase( eDest==SRT_DistFifo ); sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg); -#if !defined(SQLITE_ENABLE_NULL_TRIM) && defined(SQLITE_DEBUG) - /* A destination of SRT_Table and a non-zero iSDParm2 parameter means - ** that this is an "UPDATE ... FROM" on a virtual table or view. In this - ** case set the p5 parameter of the OP_MakeRecord to OPFLAG_NOCHNG_MAGIC. - ** This does not affect operation in any way - it just allows MakeRecord - ** to process OPFLAG_NOCHANGE values without an assert() failing. */ - if( eDest==SRT_Table && pDest->iSDParm2 ){ - sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); - } -#endif #ifndef SQLITE_OMIT_CTE if( eDest==SRT_DistFifo ){ /* If the destination is DistFifo, then cursor (iParm+1) is open @@ -143407,6 +142564,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; @@ -143593,7 +142757,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 @@ -143614,8 +142778,7 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( NameContext sNC; assert( pSelect!=0 ); - testcase( (pSelect->selFlags & SF_Resolved)==0 ); - assert( (pSelect->selFlags & SF_Resolved)!=0 || IN_RENAME_OBJECT ); + 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; @@ -143923,7 +143086,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 */ @@ -144523,7 +143686,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 @@ -144745,7 +143908,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 @@ -144782,7 +143945,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 */ @@ -145507,7 +144670,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." ** @@ -145599,8 +144762,7 @@ static int compoundHasDifferentAffinities(Select *p){ ** (27b) the subquery is a compound query and the RIGHT JOIN occurs ** in any arm of the compound query. (See also (17g).) ** -** (28) The subquery is not a MATERIALIZED CTE. (This is handled -** in the caller before ever reaching this routine.) +** (28) The subquery is not a MATERIALIZED CTE. ** ** ** In this routine, the "p" parameter is a pointer to the outer query. @@ -145710,9 +144872,9 @@ static int flattenSubquery( if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ return 0; /* Restriction (27a) */ } - - /* Condition (28) is blocked by the caller */ - assert( !pSubitem->fg.isCte || pSubitem->u2.pCteUse->eM10d!=M10d_Yes ); + if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){ + return 0; /* (28) */ + } /* Restriction (17): If the sub-query is a compound SELECT, then it must ** use only the UNION ALL operator. And none of the simple select queries @@ -145782,7 +144944,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); @@ -145964,7 +145126,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 @@ -146024,7 +145186,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); @@ -146059,7 +145222,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 @@ -146245,7 +145408,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 @@ -146329,7 +145492,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 ); @@ -146598,12 +145761,12 @@ static int disableUnusedSubqueryResultColumns(SrcItem *pItem){ 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->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ - testcase( pX->selFlags & SF_Distinct ); - testcase( pX->selFlags & SF_Aggregate ); - return 0; - } 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. */ @@ -147409,20 +146572,12 @@ 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( (selFlags & SF_NestedFrom)==0 ); 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++){ - int nAdd; /* Number of cols including rowid */ Table *pTab = pFrom->pTab; /* Table for this data source */ ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ char *zTabName; /* AS name for this data source */ @@ -147440,7 +146595,6 @@ static int selectExpander(Walker *pWalker, Select *p){ pNestedFrom = pFrom->pSelect->pEList; assert( pNestedFrom!=0 ); assert( pNestedFrom->nExpr==pTab->nCol ); - assert( VisibleRowid(pTab)==0 ); }else{ if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ continue; @@ -147458,7 +146612,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]; @@ -147471,48 +146624,33 @@ static int selectExpander(Walker *pWalker, Select *p){ }else{ pUsing = 0; } - - nAdd = pTab->nCol + (VisibleRowid(pTab) && (selFlags&SF_NestedFrom)); - for(j=0; jnCol; j++){ + char *zName = pTab->aCol[j].zCnName; struct ExprList_item *pX; /* Newly added ExprList term */ - if( j==pTab->nCol ){ - zName = sqlite3RowidAlias(pTab); - if( zName==0 ) continue; - }else{ - zName = pTab->aCol[j].zCnName; - - /* If pTab is actually an SF_NestedFrom sub-select, do not - ** expand any ENAME_ROWID columns. */ - if( pNestedFrom && pNestedFrom->a[j].fg.eEName==ENAME_ROWID ){ - continue; - } - - if( zTName - && pNestedFrom - && sqlite3MatchEName(&pNestedFrom->a[j], 0, zTName, 0, 0)==0 - ){ - continue; - } + assert( zName ); + if( zTName + && pNestedFrom + && sqlite3MatchEName(&pNestedFrom->a[j], 0, zTName, 0)==0 + ){ + continue; + } - /* If a column is marked as 'hidden', omit it from the expanded - ** result-set list unless the SELECT has the SF_IncludeHidden - ** bit set. - */ - if( (p->selFlags & SF_IncludeHidden)==0 - && IsHiddenColumn(&pTab->aCol[j]) - ){ - continue; - } - if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 - && zTName==0 - && (selFlags & (SF_NestedFrom))==0 - ){ - continue; - } + /* If a column is marked as 'hidden', omit it from the expanded + ** result-set list unless the SELECT has the SF_IncludeHidden + ** bit set. + */ + if( (p->selFlags & SF_IncludeHidden)==0 + && IsHiddenColumn(&pTab->aCol[j]) + ){ + continue; + } + if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 + && zTName==0 + && (selFlags & (SF_NestedFrom))==0 + ){ + continue; } - assert( zName ); tableSeen = 1; if( i>0 && zTName==0 && (selFlags & SF_NestedFrom)==0 ){ @@ -147546,7 +146684,6 @@ static int selectExpander(Walker *pWalker, Select *p){ }else{ pExpr = pRight; } - sqlite3ExprSetErrorOffset(pExpr, iErrOfst); pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); if( pNew==0 ){ break; /* OOM */ @@ -147562,11 +146699,11 @@ static int selectExpander(Walker *pWalker, Select *p){ zSchemaName, zTabName, zName); testcase( pX->zEName==0 ); } - pX->fg.eEName = (j==pTab->nCol ? ENAME_ROWID : ENAME_TAB); + pX->fg.eEName = ENAME_TAB; if( (pFrom->fg.isUsing && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0) || (pUsing && sqlite3IdListIndex(pUsing, zName)>=0) - || (jnCol && (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)) + || (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 ){ pX->fg.bNoExpand = 1; } @@ -147668,11 +146805,10 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ SrcList *pTabList; SrcItem *pFrom; + assert( p->selFlags & SF_Resolved ); if( p->selFlags & SF_HasTypeInfo ) return; p->selFlags |= SF_HasTypeInfo; pParse = pWalker->pParse; - testcase( (p->selFlags & SF_Resolved)==0 ); - assert( (p->selFlags & SF_Resolved) || IN_RENAME_OBJECT ); pTabList = p->pSrc; for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ Table *pTab = pFrom->pTab; @@ -147788,14 +146924,8 @@ static void analyzeAggFuncArgs( pNC->ncFlags |= NC_InAggFunc; for(i=0; inFunc; i++){ Expr *pExpr = pAggInfo->aFunc[i].pFExpr; - assert( pExpr->op==TK_FUNCTION || pExpr->op==TK_AGG_FUNCTION ); assert( ExprUseXList(pExpr) ); sqlite3ExprAnalyzeAggList(pNC, pExpr->x.pList); - if( pExpr->pLeft ){ - assert( pExpr->pLeft->op==TK_ORDER ); - assert( ExprUseXList(pExpr->pLeft) ); - sqlite3ExprAnalyzeAggList(pNC, pExpr->pLeft->x.pList); - } #ifndef SQLITE_OMIT_WINDOWFUNC assert( !IsWindowFunc(pExpr) ); if( ExprHasProperty(pExpr, EP_WinFunc) ){ @@ -147870,7 +147000,7 @@ static int aggregateIdxEprRefToColCallback(Walker *pWalker, Expr *pExpr){ pExpr->op = TK_AGG_COLUMN; pExpr->iTable = pCol->iTable; pExpr->iColumn = pCol->iColumn; - ExprClearProperty(pExpr, EP_Skip|EP_Collate|EP_Unlikely); + ExprClearProperty(pExpr, EP_Skip|EP_Collate); return WRC_Prune; } @@ -147901,7 +147031,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 @@ -147950,32 +147080,6 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ pFunc->pFunc->zName)); } } - if( pFunc->iOBTab>=0 ){ - ExprList *pOBList; - KeyInfo *pKeyInfo; - int nExtra = 0; - assert( pFunc->pFExpr->pLeft!=0 ); - assert( pFunc->pFExpr->pLeft->op==TK_ORDER ); - assert( ExprUseXList(pFunc->pFExpr->pLeft) ); - pOBList = pFunc->pFExpr->pLeft->x.pList; - if( !pFunc->bOBUnique ){ - nExtra++; /* One extra column for the OP_Sequence */ - } - if( pFunc->bOBPayload ){ - /* extra columns for the function arguments */ - assert( ExprUseXList(pFunc->pFExpr) ); - nExtra += pFunc->pFExpr->x.pList->nExpr; - } - pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra); - if( !pFunc->bOBUnique && pParse->nErr==0 ){ - pKeyInfo->nKeyField++; - } - sqlite3VdbeAddOp4(v, OP_OpenEphemeral, - pFunc->iOBTab, pOBList->nExpr+nExtra, 0, - (char*)pKeyInfo, P4_KEYINFO); - ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s(ORDER BY)", - pFunc->pFunc->zName)); - } } } @@ -147991,46 +147095,13 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); pList = pF->pFExpr->x.pList; - if( pF->iOBTab>=0 ){ - /* For an ORDER BY aggregate, calls to OP_AggStep where deferred and - ** all content was stored in emphermal table pF->iOBTab. Extract that - ** content now (in ORDER BY order) and make all calls to OP_AggStep - ** before doing the OP_AggFinal call. */ - int iTop; /* Start of loop for extracting columns */ - int nArg; /* Number of columns to extract */ - int nKey; /* Key columns to be skipped */ - int regAgg; /* Extract into this array */ - int j; /* Loop counter */ - - nArg = pList->nExpr; - regAgg = sqlite3GetTempRange(pParse, nArg); - - if( pF->bOBPayload==0 ){ - nKey = 0; - }else{ - assert( pF->pFExpr->pLeft!=0 ); - assert( ExprUseXList(pF->pFExpr->pLeft) ); - assert( pF->pFExpr->pLeft->x.pList!=0 ); - nKey = pF->pFExpr->pLeft->x.pList->nExpr; - if( ALWAYS(!pF->bOBUnique) ) nKey++; - } - iTop = sqlite3VdbeAddOp1(v, OP_Rewind, pF->iOBTab); VdbeCoverage(v); - for(j=nArg-1; j>=0; j--){ - sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j); - } - sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); - sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); - sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, iTop); - sqlite3ReleaseTempRange(pParse, regAgg, nArg); - } sqlite3VdbeAddOp2(v, OP_AggFinal, AggInfoFuncReg(pAggInfo,i), pList ? pList->nExpr : 0); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); } } + /* ** Generate code that will update the accumulator memory cells for an ** aggregate based on the current cursor position. @@ -148039,13 +147110,6 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ ** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator ** registers if register regAcc contains 0. The caller will take care ** of setting and clearing regAcc. -** -** For an ORDER BY aggregate, the actual accumulator memory cell update -** is deferred until after all input rows have been received, so that they -** can be run in the requested order. In that case, instead of invoking -** OP_AggStep to update the accumulator, just add the arguments that would -** have been passed into OP_AggStep into the sorting ephemeral table -** (along with the appropriate sort key). */ static void updateAccumulator( Parse *pParse, @@ -148067,8 +147131,6 @@ static void updateAccumulator( int nArg; int addrNext = 0; int regAgg; - int regAggSz = 0; - int regDistinct = 0; ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); assert( !IsWindowFunc(pF->pFExpr) ); @@ -148095,44 +147157,9 @@ static void updateAccumulator( addrNext = sqlite3VdbeMakeLabel(pParse); sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL); } - if( pF->iOBTab>=0 ){ - /* Instead of invoking AggStep, we must push the arguments that would - ** have been passed to AggStep onto the sorting table. */ - int jj; /* Registered used so far in building the record */ - ExprList *pOBList; /* The ORDER BY clause */ - assert( pList!=0 ); - nArg = pList->nExpr; - assert( nArg>0 ); - assert( pF->pFExpr->pLeft!=0 ); - assert( pF->pFExpr->pLeft->op==TK_ORDER ); - assert( ExprUseXList(pF->pFExpr->pLeft) ); - pOBList = pF->pFExpr->pLeft->x.pList; - assert( pOBList!=0 ); - assert( pOBList->nExpr>0 ); - regAggSz = pOBList->nExpr; - if( !pF->bOBUnique ){ - regAggSz++; /* One register for OP_Sequence */ - } - if( pF->bOBPayload ){ - regAggSz += nArg; - } - regAggSz++; /* One extra register to hold result of MakeRecord */ - regAgg = sqlite3GetTempRange(pParse, regAggSz); - regDistinct = regAgg; - sqlite3ExprCodeExprList(pParse, pOBList, regAgg, 0, SQLITE_ECEL_DUP); - jj = pOBList->nExpr; - if( !pF->bOBUnique ){ - sqlite3VdbeAddOp2(v, OP_Sequence, pF->iOBTab, regAgg+jj); - jj++; - } - if( pF->bOBPayload ){ - regDistinct = regAgg+jj; - sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP); - } - }else if( pList ){ + if( pList ){ nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); - regDistinct = regAgg; sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP); }else{ nArg = 0; @@ -148143,37 +147170,26 @@ static void updateAccumulator( addrNext = sqlite3VdbeMakeLabel(pParse); } pF->iDistinct = codeDistinct(pParse, eDistinctType, - pF->iDistinct, addrNext, pList, regDistinct); - } - if( pF->iOBTab>=0 ){ - /* Insert a new record into the ORDER BY table */ - sqlite3VdbeAddOp3(v, OP_MakeRecord, regAgg, regAggSz-1, - regAgg+regAggSz-1); - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pF->iOBTab, regAgg+regAggSz-1, - regAgg, regAggSz-1); - sqlite3ReleaseTempRange(pParse, regAgg, regAggSz); - }else{ - /* Invoke the AggStep function */ - if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ - CollSeq *pColl = 0; - struct ExprList_item *pItem; - int j; - assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ - for(j=0, pItem=pList->a; !pColl && jpExpr); - } - if( !pColl ){ - pColl = pParse->db->pDfltColl; - } - if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; - sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, - (char *)pColl, P4_COLLSEQ); + pF->iDistinct, addrNext, pList, regAgg); + } + if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + CollSeq *pColl = 0; + struct ExprList_item *pItem; + int j; + assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ + for(j=0, pItem=pList->a; !pColl && jpExpr); } - sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); - sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); - sqlite3ReleaseTempRange(pParse, regAgg, nArg); + if( !pColl ){ + pColl = pParse->db->pDfltColl; + } + if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); } + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } @@ -148669,58 +147685,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); - unsetJoinExpr(p->pWhere, pItem->iCursor, 0); - } - } - 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); - unsetJoinExpr(p->pWhere, pI2->iCursor, 1); - } - } - } - for(j=pTabList->nSrc-1; j>=0; 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 not a subquery */ if( pSub==0 ) continue; /* Catch mismatch in the declared columns of a view and the number of @@ -148731,14 +147711,6 @@ SQLITE_PRIVATE int sqlite3Select( goto select_end; } - /* Do not attempt the usual optimizations (flattening and ORDER BY - ** elimination) on a MATERIALIZED common table expression because - ** a MATERIALIZED common table expression is an optimization fence. - */ - if( pItem->fg.isCte && pItem->u2.pCteUse->eM10d==M10d_Yes ){ - continue; - } - /* Do not try to flatten an aggregate subquery. ** ** Flattening an aggregate subquery is only possible if the outer query @@ -148768,8 +147740,6 @@ SQLITE_PRIVATE int sqlite3Select( ** (a) The outer query has a different ORDER BY clause ** (b) The subquery is part of a join ** See forum post 062d576715d277c8 - ** - ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled. */ if( pSub->pOrderBy!=0 && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ @@ -148984,7 +147954,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); @@ -149367,7 +148337,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 */ @@ -149458,13 +148428,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; @@ -149489,23 +148455,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 @@ -150233,10 +149194,6 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); goto trigger_orphan_error; } - if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ - sqlite3ErrorMsg(pParse, "cannot create triggers on shadow tables"); - goto trigger_orphan_error; - } /* Check that the trigger name is not reserved and that no trigger of the ** specified name exists */ @@ -151020,17 +149977,10 @@ static void codeReturningTrigger( SrcList sFrom; assert( v!=0 ); - if( !pParse->bReturning ){ - /* This RETURNING trigger must be for a different statement as - ** this statement lacks a RETURNING clause. */ - return; - } + assert( pParse->bReturning ); assert( db->pParse==pParse ); pReturning = pParse->u1.pReturning; - if( pTrigger != &(pReturning->retTrig) ){ - /* This RETURNING trigger is for a different statement */ - return; - } + assert( pTrigger == &(pReturning->retTrig) ); memset(&sSelect, 0, sizeof(sSelect)); memset(&sFrom, 0, sizeof(sFrom)); sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); @@ -152284,7 +151234,7 @@ SQLITE_PRIVATE void sqlite3Update( && !hasFK && !chngKey && !bReplace - && (pWhere==0 || !ExprHasProperty(pWhere, EP_Subquery)) + && (sNC.ncFlags & NC_Subquery)==0 ){ flags |= WHERE_ONEPASS_MULTIROW; } @@ -152356,8 +151306,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 ){ @@ -152369,7 +151317,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); } @@ -152660,10 +151608,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. @@ -152758,7 +151704,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 */ @@ -152802,9 +151748,7 @@ static void updateVirtualTable( sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0) ); }else{ - Expr *pRowExpr = exprRowColumn(pParse, i); - if( pRowExpr ) pRowExpr->op2 = OPFLAG_NOCHNG; - pList = sqlite3ExprListAppend(pParse, pList, pRowExpr); + pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i)); } } @@ -152881,7 +151825,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 @@ -153089,7 +152033,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( pExpr = &sCol[0]; } for(jj=0; jja[jj].pExpr,pExpr,iCursor)<2 ){ + if( sqlite3ExprCompare(pParse,pTarget->a[jj].pExpr,pExpr,iCursor)<2 ){ break; /* Column ii of the index matches column jj of target */ } } @@ -153438,7 +152382,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 @@ -154127,7 +153071,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); @@ -154467,7 +153411,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ sqlite3_mutex_enter(db->mutex); pCtx = db->pVtabCtx; if( !pCtx || pCtx->bDeclared ){ - sqlite3Error(db, SQLITE_MISUSE_BKPT); + sqlite3Error(db, SQLITE_MISUSE); sqlite3_mutex_leave(db->mutex); return SQLITE_MISUSE_BKPT; } @@ -154871,7 +153815,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 @@ -155062,7 +154006,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 */ @@ -155123,7 +154067,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 */ @@ -155373,7 +154317,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 @@ -155658,7 +154602,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ - /* 0x02000000 -- available for reuse */ +#define WHERE_VIEWSCAN 0x02000000 /* A full-scan of a VIEW or subquery */ #define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */ #endif /* !defined(SQLITE_WHEREINT_H) */ @@ -155961,12 +154905,6 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus( 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); } } } @@ -156653,7 +155591,7 @@ 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. @@ -157091,6 +156029,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( int addrNotFound; int nConstraint = pLoop->nLTerm; + sqlite3VdbeAddOp1(v, OP_VPreparedSql, iCur); + iReg = sqlite3GetTempRange(pParse, nConstraint+2); addrNotFound = pLevel->addrBrk; for(j=0; jwtFlags & TERM_VNULL)==0 ); testcase( pStart->wtFlags & TERM_VIRTUAL ); @@ -158451,7 +157391,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" */ @@ -158667,7 +157607,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 "%" */ @@ -159240,7 +158180,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 ); @@ -159502,8 +158442,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 */ @@ -161453,17 +160393,13 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */ int iCur; /* Cursor for table getting the filter */ IndexedExpr *saved_pIdxEpr; /* saved copy of Parse.pIdxEpr */ - IndexedExpr *saved_pIdxPartExpr; /* saved copy of Parse.pIdxPartExpr */ saved_pIdxEpr = pParse->pIdxEpr; - saved_pIdxPartExpr = pParse->pIdxPartExpr; pParse->pIdxEpr = 0; - pParse->pIdxPartExpr = 0; assert( pLoop!=0 ); assert( v!=0 ); assert( pLoop->wsFlags & WHERE_BLOOMFILTER ); - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ); addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); do{ @@ -161553,7 +160489,6 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( }while( iLevel < pWInfo->nLevel ); sqlite3VdbeJumpHere(v, addrOnce); pParse->pIdxEpr = saved_pIdxEpr; - pParse->pIdxPartExpr = saved_pIdxPartExpr; } @@ -162069,7 +161004,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. ** @@ -162824,7 +161759,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 @@ -162851,7 +161786,7 @@ static WhereLoop **whereLoopFindLesser( /* If pTemplate is always better than p, then cause p to be overwritten ** with pTemplate. pTemplate is better than p if: - ** (1) pTemplate has no more dependencies than p, and + ** (1) pTemplate has no more dependences than p, and ** (2) pTemplate has an equal or lower cost than p. */ if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */ @@ -162969,7 +161904,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 ){ @@ -163169,7 +162104,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 @@ -163196,7 +162131,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 */ @@ -163506,7 +162441,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; @@ -163813,100 +162748,6 @@ static SQLITE_NOINLINE u32 whereIsCoveringIndex( return rc; } -/* -** This is an sqlite3ParserAddCleanup() callback that is invoked to -** free the Parse->pIdxEpr list when the Parse object is destroyed. -*/ -static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){ - IndexedExpr **pp = (IndexedExpr**)pObject; - while( *pp!=0 ){ - IndexedExpr *p = *pp; - *pp = p->pIENext; - sqlite3ExprDelete(db, p->pExpr); - sqlite3DbFreeNN(db, p); - } -} - -/* -** This function is called for a partial index - one with a WHERE clause - in -** two scenarios. In both cases, it determines whether or not the WHERE -** clause on the index implies that a column of the table may be safely -** replaced by a constant expression. For example, in the following -** SELECT: -** -** CREATE INDEX i1 ON t1(b, c) WHERE a=; -** SELECT a, b, c FROM t1 WHERE a= AND b=?; -** -** The "a" in the select-list may be replaced by , iff: -** -** (a) is a constant expression, and -** (b) The (a=) comparison uses the BINARY collation sequence, and -** (c) Column "a" has an affinity other than NONE or BLOB. -** -** If argument pItem is NULL, then pMask must not be NULL. In this case this -** function is being called as part of determining whether or not pIdx -** is a covering index. This function clears any bits in (*pMask) -** corresponding to columns that may be replaced by constants as described -** above. -** -** Otherwise, if pItem is not NULL, then this function is being called -** as part of coding a loop that uses index pIdx. In this case, add entries -** to the Parse.pIdxPartExpr list for each column that can be replaced -** by a constant. -*/ -static void wherePartIdxExpr( - Parse *pParse, /* Parse context */ - Index *pIdx, /* Partial index being processed */ - Expr *pPart, /* WHERE clause being processed */ - Bitmask *pMask, /* Mask to clear bits in */ - int iIdxCur, /* Cursor number for index */ - SrcItem *pItem /* The FROM clause entry for the table */ -){ - assert( pItem==0 || (pItem->fg.jointype & JT_RIGHT)==0 ); - assert( (pItem==0 || pMask==0) && (pMask!=0 || pItem!=0) ); - - if( pPart->op==TK_AND ){ - wherePartIdxExpr(pParse, pIdx, pPart->pRight, pMask, iIdxCur, pItem); - pPart = pPart->pLeft; - } - - if( (pPart->op==TK_EQ || pPart->op==TK_IS) ){ - Expr *pLeft = pPart->pLeft; - Expr *pRight = pPart->pRight; - u8 aff; - - if( pLeft->op!=TK_COLUMN ) return; - if( !sqlite3ExprIsConstant(pRight) ) return; - if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pParse, pPart)) ) return; - if( pLeft->iColumn<0 ) return; - aff = pIdx->pTable->aCol[pLeft->iColumn].affinity; - if( aff>=SQLITE_AFF_TEXT ){ - if( pItem ){ - sqlite3 *db = pParse->db; - IndexedExpr *p = (IndexedExpr*)sqlite3DbMallocRaw(db, sizeof(*p)); - if( p ){ - int bNullRow = (pItem->fg.jointype&(JT_LEFT|JT_LTORJ))!=0; - p->pExpr = sqlite3ExprDup(db, pRight, 0); - p->iDataCur = pItem->iCursor; - p->iIdxCur = iIdxCur; - p->iIdxCol = pLeft->iColumn; - p->bMaybeNullRow = bNullRow; - p->pIENext = pParse->pIdxPartExpr; - p->aff = aff; - pParse->pIdxPartExpr = p; - if( p->pIENext==0 ){ - void *pArg = (void*)&pParse->pIdxPartExpr; - sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pArg); - } - } - }else if( pLeft->iColumn<(BMS-1) ){ - *pMask &= ~((Bitmask)1 << pLeft->iColumn); - } - } - } -} - - /* ** Add all WhereLoop objects for a single table of the join where the table ** is identified by pBuilder->pNew->iTab. That table is guaranteed to be @@ -163945,7 +162786,7 @@ static void wherePartIdxExpr( */ 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 */ @@ -164110,6 +162951,9 @@ static int whereLoopAddBtree( #else pNew->rRun = rSize + 16; #endif + if( IsView(pTab) || (pTab->tabFlags & TF_Ephemeral)!=0 ){ + pNew->wsFlags |= WHERE_VIEWSCAN; + } ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); rc = whereLoopInsert(pBuilder, pNew); @@ -164122,11 +162966,6 @@ static int whereLoopAddBtree( pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; }else{ m = pSrc->colUsed & pProbe->colNotIdxed; - if( pProbe->pPartIdxWhere ){ - wherePartIdxExpr( - pWInfo->pParse, pProbe, pProbe->pPartIdxWhere, &m, 0, 0 - ); - } pNew->wsFlags = WHERE_INDEXED; if( m==TOPBIT || (pProbe->bHasExpr && !pProbe->bHasVCol && m!=0) ){ u32 isCov = whereIsCoveringIndex(pWInfo, pProbe, pSrc->iCursor); @@ -164454,7 +163293,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. ** @@ -164509,7 +163348,7 @@ SQLITE_API int sqlite3_vtab_rhs_value( sqlite3_value *pVal = 0; int rc = SQLITE_OK; if( iCons<0 || iCons>=pIdxInfo->nConstraint ){ - rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */ + rc = SQLITE_MISUSE; /* EV: R-30545-25046 */ }else{ if( pH->aRhs[iCons]==0 ){ WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset]; @@ -165415,8 +164254,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ ** For joins of 3 or more tables, track the 10 best paths */ mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); assert( nLoop<=pWInfo->pTabList->nSrc ); - WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n", - nRowEst, pParse->nQueryLoop)); + WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d)\n", nRowEst)); /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this ** case the purpose of this call is to estimate the number of rows returned @@ -165519,7 +164357,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ ); } /* TUNING: Add a small extra penalty (3) to sorting as an - ** extra encouragement to the query planner to select a plan + ** extra encouragment to the query planner to select a plan ** where the rows emerge in the correct order without any sorting ** required. */ rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 3; @@ -165533,6 +164371,13 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ rUnsorted -= 2; /* TUNING: Slight bias in favor of no-sort plans */ } + /* TUNING: A full-scan of a VIEW or subquery in the outer loop + ** is not so bad. */ + if( iLoop==0 && (pWLoop->wsFlags & WHERE_VIEWSCAN)!=0 ){ + rCost += -10; + nOut += -30; + } + /* Check to see if pWLoop should be added to the set of ** mxChoice best-so-far paths. ** @@ -166082,6 +164927,20 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( } } +/* +** This is an sqlite3ParserAddCleanup() callback that is invoked to +** free the Parse->pIdxEpr list when the Parse object is destroyed. +*/ +static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){ + Parse *pParse = (Parse*)pObject; + while( pParse->pIdxEpr!=0 ){ + IndexedExpr *p = pParse->pIdxEpr; + pParse->pIdxEpr = p->pIENext; + sqlite3ExprDelete(db, p->pExpr); + sqlite3DbFreeNN(db, p); + } +} + /* ** The index pIdx is used by a query and contains one or more expressions. ** In other words pIdx is an index on an expression. iIdxCur is the cursor @@ -166121,20 +164980,6 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( continue; } if( sqlite3ExprIsConstant(pExpr) ) continue; - if( pExpr->op==TK_FUNCTION ){ - /* Functions that might set a subtype should not be replaced by the - ** value taken from an expression index since the index omits the - ** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */ - int n; - FuncDef *pDef; - sqlite3 *db = pParse->db; - assert( ExprUseXList(pExpr) ); - n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; - pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); - if( pDef==0 || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ - continue; - } - } p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); if( p==0 ) break; p->pIENext = pParse->pIdxEpr; @@ -166157,30 +165002,7 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( #endif pParse->pIdxEpr = p; if( p->pIENext==0 ){ - void *pArg = (void*)&pParse->pIdxEpr; - sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pArg); - } - } -} - -/* -** Set the reverse-scan order mask to one for all tables in the query -** with the exception of MATERIALIZED common table expressions that have -** their own internal ORDER BY clauses. -** -** This implements the PRAGMA reverse_unordered_selects=ON setting. -** (Also SQLITE_DBCONFIG_REVERSE_SCANORDER). -*/ -static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){ - int ii; - for(ii=0; iipTabList->nSrc; ii++){ - SrcItem *pItem = &pWInfo->pTabList->a[ii]; - if( !pItem->fg.isCte - || pItem->u2.pCteUse->eM10d!=M10d_Yes - || NEVER(pItem->pSelect==0) - || pItem->pSelect->pOrderBy==0 - ){ - pWInfo->revMask |= MASKBIT(ii); + sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pParse); } } } @@ -166243,7 +165065,7 @@ static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){ ** ** 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 @@ -166398,7 +165220,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** ** The N-th term of the FROM clause is assigned a bitmask of 1<nRowOut+1); if( db->mallocFailed ) goto whereBeginError; } - - /* TUNING: Assume that a DISTINCT clause on a subquery reduces - ** the output size by a factor of 8 (LogEst -30). - */ - if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){ - WHERETRACE(0x0080,("nRowOut reduced from %d to %d due to DISTINCT\n", - pWInfo->nRowOut, pWInfo->nRowOut-30)); - pWInfo->nRowOut -= 30; - } - } - assert( pWInfo->pTabList!=0 ); if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ - whereReverseScanOrder(pWInfo); + pWInfo->revMask = ALLBITS; } if( pParse->nErr ){ goto whereBeginError; @@ -166661,7 +165472,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) && !IsVirtual(pTabList->a[0].pTab) && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) - && OptimizationEnabled(db, SQLITE_OnePass) )){ pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ @@ -166770,11 +165580,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( pIx->bHasExpr && OptimizationEnabled(db, SQLITE_IndexedExpr) ){ whereAddIndexedExpr(pParse, pIx, iIndexCur, pTabItem); } - if( pIx->pPartIdxWhere && (pTabItem->fg.jointype & JT_RIGHT)==0 ){ - wherePartIdxExpr( - pParse, pIx, pIx->pPartIdxWhere, 0, iIndexCur, pTabItem - ); - } } pLevel->iIdxCur = iIndexCur; assert( pIx!=0 ); @@ -167396,7 +166201,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. @@ -167926,7 +166731,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. @@ -168317,7 +167122,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ assert( ExprUseXList(pWin->pOwner) ); assert( pWin->pWFunc!=0 ); pArgs = pWin->pOwner->x.pList; - if( pWin->pWFunc->funcFlags & SQLITE_SUBTYPE ){ + if( pWin->pWFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){ selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist); pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); pWin->bExprArgs = 1; @@ -168547,7 +167352,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 @@ -168591,9 +167396,8 @@ SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ if( p ){ assert( p->op==TK_FUNCTION ); assert( pWin ); - assert( ExprIsFullSize(p) ); p->y.pWin = pWin; - ExprSetProperty(p, EP_WinFunc|EP_FullSize); + ExprSetProperty(p, EP_WinFunc); pWin->pOwner = p; if( (p->flags & EP_Distinct) && pWin->eFrmType!=TK_FILTER ){ sqlite3ErrorMsg(pParse, @@ -168854,7 +167658,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 @@ -169863,7 +168667,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: @@ -170142,7 +168946,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; @@ -170383,8 +169187,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". -*/ +** source file "parse.y". */ /* ** 2001-09-15 ** @@ -170401,7 +169204,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. */ @@ -170638,164 +169441,166 @@ static void updateDeleteLimitError( #define TK_AS 24 #define TK_COMMA 25 #define TK_WITHOUT 26 -#define TK_ABORT 27 -#define TK_ACTION 28 -#define TK_AFTER 29 -#define TK_ANALYZE 30 -#define TK_ASC 31 -#define TK_ATTACH 32 -#define TK_BEFORE 33 -#define TK_BY 34 -#define TK_CASCADE 35 -#define TK_CAST 36 -#define TK_CONFLICT 37 -#define TK_DATABASE 38 -#define TK_DESC 39 -#define TK_DETACH 40 -#define TK_EACH 41 -#define TK_FAIL 42 -#define TK_OR 43 -#define TK_AND 44 -#define TK_IS 45 -#define TK_MATCH 46 -#define TK_LIKE_KW 47 -#define TK_BETWEEN 48 -#define TK_IN 49 -#define TK_ISNULL 50 -#define TK_NOTNULL 51 -#define TK_NE 52 -#define TK_EQ 53 -#define TK_GT 54 -#define TK_LE 55 -#define TK_LT 56 -#define TK_GE 57 -#define TK_ESCAPE 58 -#define TK_ID 59 -#define TK_COLUMNKW 60 -#define TK_DO 61 -#define TK_FOR 62 -#define TK_IGNORE 63 -#define TK_INITIALLY 64 -#define TK_INSTEAD 65 -#define TK_NO 66 -#define TK_KEY 67 -#define TK_OF 68 -#define TK_OFFSET 69 -#define TK_PRAGMA 70 -#define TK_RAISE 71 -#define TK_RECURSIVE 72 -#define TK_REPLACE 73 -#define TK_RESTRICT 74 -#define TK_ROW 75 -#define TK_ROWS 76 -#define TK_TRIGGER 77 -#define TK_VACUUM 78 -#define TK_VIEW 79 -#define TK_VIRTUAL 80 -#define TK_WITH 81 -#define TK_NULLS 82 -#define TK_FIRST 83 -#define TK_LAST 84 -#define TK_CURRENT 85 -#define TK_FOLLOWING 86 -#define TK_PARTITION 87 -#define TK_PRECEDING 88 -#define TK_RANGE 89 -#define TK_UNBOUNDED 90 -#define TK_EXCLUDE 91 -#define TK_GROUPS 92 -#define TK_OTHERS 93 -#define TK_TIES 94 -#define TK_GENERATED 95 -#define TK_ALWAYS 96 -#define TK_MATERIALIZED 97 -#define TK_REINDEX 98 -#define TK_RENAME 99 -#define TK_CTIME_KW 100 -#define TK_ANY 101 -#define TK_BITAND 102 -#define TK_BITOR 103 -#define TK_LSHIFT 104 -#define TK_RSHIFT 105 -#define TK_PLUS 106 -#define TK_MINUS 107 -#define TK_STAR 108 -#define TK_SLASH 109 -#define TK_REM 110 -#define TK_CONCAT 111 -#define TK_PTR 112 -#define TK_COLLATE 113 -#define TK_BITNOT 114 -#define TK_ON 115 -#define TK_INDEXED 116 -#define TK_STRING 117 -#define TK_JOIN_KW 118 -#define TK_CONSTRAINT 119 -#define TK_DEFAULT 120 -#define TK_NULL 121 -#define TK_PRIMARY 122 -#define TK_UNIQUE 123 -#define TK_CHECK 124 -#define TK_REFERENCES 125 -#define TK_AUTOINCR 126 -#define TK_INSERT 127 -#define TK_DELETE 128 -#define TK_UPDATE 129 -#define TK_SET 130 -#define TK_DEFERRABLE 131 -#define TK_FOREIGN 132 -#define TK_DROP 133 -#define TK_UNION 134 -#define TK_ALL 135 -#define TK_EXCEPT 136 -#define TK_INTERSECT 137 -#define TK_SELECT 138 -#define TK_VALUES 139 -#define TK_DISTINCT 140 -#define TK_DOT 141 -#define TK_FROM 142 -#define TK_JOIN 143 -#define TK_USING 144 -#define TK_ORDER 145 -#define TK_GROUP 146 -#define TK_HAVING 147 -#define TK_LIMIT 148 -#define TK_WHERE 149 -#define TK_RETURNING 150 -#define TK_INTO 151 -#define TK_NOTHING 152 -#define TK_FLOAT 153 -#define TK_BLOB 154 -#define TK_INTEGER 155 -#define TK_VARIABLE 156 -#define TK_CASE 157 -#define TK_WHEN 158 -#define TK_THEN 159 -#define TK_ELSE 160 -#define TK_INDEX 161 -#define TK_ALTER 162 -#define TK_ADD 163 -#define TK_WINDOW 164 -#define TK_OVER 165 -#define TK_FILTER 166 -#define TK_COLUMN 167 -#define TK_AGG_FUNCTION 168 -#define TK_AGG_COLUMN 169 -#define TK_TRUEFALSE 170 -#define TK_ISNOT 171 -#define TK_FUNCTION 172 -#define TK_UMINUS 173 -#define TK_UPLUS 174 -#define TK_TRUTH 175 -#define TK_REGISTER 176 -#define TK_VECTOR 177 -#define TK_SELECT_COLUMN 178 -#define TK_IF_NULL_ROW 179 -#define TK_ASTERISK 180 -#define TK_SPAN 181 -#define TK_ERROR 182 -#define TK_SPACE 183 -#define TK_ILLEGAL 184 +#define TK_RANDOM 27 +#define TK_ABORT 28 +#define TK_ACTION 29 +#define TK_AFTER 30 +#define TK_ANALYZE 31 +#define TK_ASC 32 +#define TK_ATTACH 33 +#define TK_BEFORE 34 +#define TK_BY 35 +#define TK_CASCADE 36 +#define TK_CAST 37 +#define TK_CONFLICT 38 +#define TK_DATABASE 39 +#define TK_DESC 40 +#define TK_DETACH 41 +#define TK_EACH 42 +#define TK_FAIL 43 +#define TK_FUNCTION 44 +#define TK_LANGUAGE 45 +#define TK_OR 46 +#define TK_AND 47 +#define TK_IS 48 +#define TK_MATCH 49 +#define TK_LIKE_KW 50 +#define TK_BETWEEN 51 +#define TK_IN 52 +#define TK_ISNULL 53 +#define TK_NOTNULL 54 +#define TK_NE 55 +#define TK_EQ 56 +#define TK_GT 57 +#define TK_LE 58 +#define TK_LT 59 +#define TK_GE 60 +#define TK_ESCAPE 61 +#define TK_ID 62 +#define TK_COLUMNKW 63 +#define TK_DO 64 +#define TK_FOR 65 +#define TK_IGNORE 66 +#define TK_INITIALLY 67 +#define TK_INSTEAD 68 +#define TK_NO 69 +#define TK_KEY 70 +#define TK_OF 71 +#define TK_OFFSET 72 +#define TK_PRAGMA 73 +#define TK_RAISE 74 +#define TK_RECURSIVE 75 +#define TK_REPLACE 76 +#define TK_RESTRICT 77 +#define TK_ROW 78 +#define TK_ROWS 79 +#define TK_TRIGGER 80 +#define TK_VACUUM 81 +#define TK_VIEW 82 +#define TK_VIRTUAL 83 +#define TK_WITH 84 +#define TK_NULLS 85 +#define TK_FIRST 86 +#define TK_LAST 87 +#define TK_CURRENT 88 +#define TK_FOLLOWING 89 +#define TK_PARTITION 90 +#define TK_PRECEDING 91 +#define TK_RANGE 92 +#define TK_UNBOUNDED 93 +#define TK_EXCLUDE 94 +#define TK_GROUPS 95 +#define TK_OTHERS 96 +#define TK_TIES 97 +#define TK_GENERATED 98 +#define TK_ALWAYS 99 +#define TK_MATERIALIZED 100 +#define TK_REINDEX 101 +#define TK_RENAME 102 +#define TK_CTIME_KW 103 +#define TK_ANY 104 +#define TK_BITAND 105 +#define TK_BITOR 106 +#define TK_LSHIFT 107 +#define TK_RSHIFT 108 +#define TK_PLUS 109 +#define TK_MINUS 110 +#define TK_STAR 111 +#define TK_SLASH 112 +#define TK_REM 113 +#define TK_CONCAT 114 +#define TK_PTR 115 +#define TK_COLLATE 116 +#define TK_BITNOT 117 +#define TK_ON 118 +#define TK_INDEXED 119 +#define TK_STRING 120 +#define TK_JOIN_KW 121 +#define TK_CONSTRAINT 122 +#define TK_DEFAULT 123 +#define TK_NULL 124 +#define TK_PRIMARY 125 +#define TK_UNIQUE 126 +#define TK_CHECK 127 +#define TK_REFERENCES 128 +#define TK_AUTOINCR 129 +#define TK_INSERT 130 +#define TK_DELETE 131 +#define TK_UPDATE 132 +#define TK_SET 133 +#define TK_DEFERRABLE 134 +#define TK_FOREIGN 135 +#define TK_DROP 136 +#define TK_BLOB 137 +#define TK_UNION 138 +#define TK_ALL 139 +#define TK_EXCEPT 140 +#define TK_INTERSECT 141 +#define TK_SELECT 142 +#define TK_VALUES 143 +#define TK_DISTINCT 144 +#define TK_DOT 145 +#define TK_FROM 146 +#define TK_JOIN 147 +#define TK_USING 148 +#define TK_ORDER 149 +#define TK_GROUP 150 +#define TK_HAVING 151 +#define TK_LIMIT 152 +#define TK_WHERE 153 +#define TK_RETURNING 154 +#define TK_INTO 155 +#define TK_NOTHING 156 +#define TK_FLOAT 157 +#define TK_INTEGER 158 +#define TK_VARIABLE 159 +#define TK_CASE 160 +#define TK_WHEN 161 +#define TK_THEN 162 +#define TK_ELSE 163 +#define TK_INDEX 164 +#define TK_ALTER 165 +#define TK_ADD 166 +#define TK_WINDOW 167 +#define TK_OVER 168 +#define TK_FILTER 169 +#define TK_COLUMN 170 +#define TK_AGG_FUNCTION 171 +#define TK_AGG_COLUMN 172 +#define TK_TRUEFALSE 173 +#define TK_ISNOT 174 +#define TK_UMINUS 175 +#define TK_UPLUS 176 +#define TK_TRUTH 177 +#define TK_REGISTER 178 +#define TK_VECTOR 179 +#define TK_SELECT_COLUMN 180 +#define TK_IF_NULL_ROW 181 +#define TK_ASTERISK 182 +#define TK_SPAN 183 +#define TK_ERROR 184 +#define TK_SPACE 185 +#define TK_ILLEGAL 186 #endif /**************** End token definitions ***************************************/ @@ -170855,31 +169660,31 @@ static void updateDeleteLimitError( #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 319 +#define YYNOCODE 321 #define YYACTIONTYPE unsigned short int -#define YYWILDCARD 101 +#define YYWILDCARD 104 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; - TriggerStep* yy33; - Window* yy41; - Select* yy47; - SrcList* yy131; - struct TrigEvent yy180; - struct {int value; int mask;} yy231; - IdList* yy254; - u32 yy285; - ExprList* yy322; - Cte* yy385; - int yy394; - Upsert* yy444; - u8 yy516; - With* yy521; - const char* yy522; - Expr* yy528; - OnOrUsing yy561; - struct FrameBound yy595; + OnOrUsing yy5; + Upsert* yy6; + With* yy19; + u32 yy135; + Select* yy136; + TriggerStep* yy137; + Expr* yy224; + struct {int value; int mask;} yy275; + int yy436; + u8 yy480; + SrcList* yy493; + struct TrigEvent yy510; + struct FrameBound yy537; + ExprList* yy586; + Window* yy591; + const char* yy594; + IdList* yy600; + Cte* yy615; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -170895,18 +169700,18 @@ typedef union { #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 -#define YYNSTATE 579 -#define YYNRULE 405 -#define YYNRULE_WITH_ACTION 340 -#define YYNTOKEN 185 -#define YY_MAX_SHIFT 578 -#define YY_MIN_SHIFTREDUCE 838 -#define YY_MAX_SHIFTREDUCE 1242 -#define YY_ERROR_ACTION 1243 -#define YY_ACCEPT_ACTION 1244 -#define YY_NO_ACTION 1245 -#define YY_MIN_REDUCE 1246 -#define YY_MAX_REDUCE 1650 +#define YYNSTATE 590 +#define YYNRULE 408 +#define YYNRULE_WITH_ACTION 345 +#define YYNTOKEN 187 +#define YY_MAX_SHIFT 589 +#define YY_MIN_SHIFTREDUCE 852 +#define YY_MAX_SHIFTREDUCE 1259 +#define YY_ERROR_ACTION 1260 +#define YY_ACCEPT_ACTION 1261 +#define YY_NO_ACTION 1262 +#define YY_MIN_REDUCE 1263 +#define YY_MAX_REDUCE 1670 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -170973,619 +169778,622 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2100) +#define YY_ACTTAB_COUNT (2103) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 572, 210, 572, 119, 116, 231, 572, 119, 116, 231, - /* 10 */ 572, 1317, 379, 1296, 410, 566, 566, 566, 572, 411, - /* 20 */ 380, 1317, 1279, 42, 42, 42, 42, 210, 1529, 72, - /* 30 */ 72, 974, 421, 42, 42, 495, 305, 281, 305, 975, - /* 40 */ 399, 72, 72, 126, 127, 81, 1217, 1217, 1054, 1057, - /* 50 */ 1044, 1044, 124, 124, 125, 125, 125, 125, 480, 411, - /* 60 */ 1244, 1, 1, 578, 2, 1248, 554, 119, 116, 231, - /* 70 */ 319, 484, 147, 484, 528, 119, 116, 231, 533, 1330, - /* 80 */ 419, 527, 143, 126, 127, 81, 1217, 1217, 1054, 1057, - /* 90 */ 1044, 1044, 124, 124, 125, 125, 125, 125, 119, 116, - /* 100 */ 231, 329, 123, 123, 123, 123, 122, 122, 121, 121, - /* 110 */ 121, 120, 117, 448, 286, 286, 286, 286, 446, 446, - /* 120 */ 446, 1568, 378, 1570, 1193, 377, 1164, 569, 1164, 569, - /* 130 */ 411, 1568, 541, 261, 228, 448, 102, 146, 453, 318, - /* 140 */ 563, 242, 123, 123, 123, 123, 122, 122, 121, 121, - /* 150 */ 121, 120, 117, 448, 126, 127, 81, 1217, 1217, 1054, - /* 160 */ 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, 143, - /* 170 */ 296, 1193, 341, 452, 121, 121, 121, 120, 117, 448, - /* 180 */ 128, 1193, 1194, 1193, 149, 445, 444, 572, 120, 117, - /* 190 */ 448, 125, 125, 125, 125, 118, 123, 123, 123, 123, - /* 200 */ 122, 122, 121, 121, 121, 120, 117, 448, 458, 114, - /* 210 */ 13, 13, 550, 123, 123, 123, 123, 122, 122, 121, - /* 220 */ 121, 121, 120, 117, 448, 424, 318, 563, 1193, 1194, - /* 230 */ 1193, 150, 1225, 411, 1225, 125, 125, 125, 125, 123, - /* 240 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117, - /* 250 */ 448, 469, 344, 1041, 1041, 1055, 1058, 126, 127, 81, - /* 260 */ 1217, 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, - /* 270 */ 125, 125, 1282, 526, 224, 1193, 572, 411, 226, 519, - /* 280 */ 177, 83, 84, 123, 123, 123, 123, 122, 122, 121, - /* 290 */ 121, 121, 120, 117, 448, 1010, 16, 16, 1193, 134, - /* 300 */ 134, 126, 127, 81, 1217, 1217, 1054, 1057, 1044, 1044, - /* 310 */ 124, 124, 125, 125, 125, 125, 123, 123, 123, 123, - /* 320 */ 122, 122, 121, 121, 121, 120, 117, 448, 1045, 550, - /* 330 */ 1193, 375, 1193, 1194, 1193, 254, 1438, 401, 508, 505, - /* 340 */ 504, 112, 564, 570, 4, 929, 929, 435, 503, 342, - /* 350 */ 464, 330, 362, 396, 1238, 1193, 1194, 1193, 567, 572, - /* 360 */ 123, 123, 123, 123, 122, 122, 121, 121, 121, 120, - /* 370 */ 117, 448, 286, 286, 371, 1581, 1607, 445, 444, 155, - /* 380 */ 411, 449, 72, 72, 1289, 569, 1222, 1193, 1194, 1193, - /* 390 */ 86, 1224, 273, 561, 547, 520, 520, 572, 99, 1223, - /* 400 */ 6, 1281, 476, 143, 126, 127, 81, 1217, 1217, 1054, - /* 410 */ 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, 554, - /* 420 */ 13, 13, 1031, 511, 1225, 1193, 1225, 553, 110, 110, - /* 430 */ 224, 572, 1239, 177, 572, 429, 111, 199, 449, 573, - /* 440 */ 449, 432, 1555, 1019, 327, 555, 1193, 272, 289, 370, - /* 450 */ 514, 365, 513, 259, 72, 72, 547, 72, 72, 361, - /* 460 */ 318, 563, 1613, 123, 123, 123, 123, 122, 122, 121, - /* 470 */ 121, 121, 120, 117, 448, 1019, 1019, 1021, 1022, 28, - /* 480 */ 286, 286, 1193, 1194, 1193, 1159, 572, 1612, 411, 904, - /* 490 */ 192, 554, 358, 569, 554, 940, 537, 521, 1159, 437, - /* 500 */ 415, 1159, 556, 1193, 1194, 1193, 572, 548, 548, 52, - /* 510 */ 52, 216, 126, 127, 81, 1217, 1217, 1054, 1057, 1044, - /* 520 */ 1044, 124, 124, 125, 125, 125, 125, 1193, 478, 136, - /* 530 */ 136, 411, 286, 286, 1493, 509, 122, 122, 121, 121, - /* 540 */ 121, 120, 117, 448, 1010, 569, 522, 219, 545, 545, - /* 550 */ 318, 563, 143, 6, 536, 126, 127, 81, 1217, 1217, - /* 560 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, - /* 570 */ 1557, 123, 123, 123, 123, 122, 122, 121, 121, 121, - /* 580 */ 120, 117, 448, 489, 1193, 1194, 1193, 486, 283, 1270, - /* 590 */ 960, 254, 1193, 375, 508, 505, 504, 1193, 342, 574, - /* 600 */ 1193, 574, 411, 294, 503, 960, 879, 193, 484, 318, - /* 610 */ 563, 386, 292, 382, 123, 123, 123, 123, 122, 122, - /* 620 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, - /* 630 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 640 */ 125, 411, 396, 1139, 1193, 872, 101, 286, 286, 1193, - /* 650 */ 1194, 1193, 375, 1096, 1193, 1194, 1193, 1193, 1194, 1193, - /* 660 */ 569, 459, 33, 375, 235, 126, 127, 81, 1217, 1217, - /* 670 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, - /* 680 */ 1437, 962, 572, 230, 961, 123, 123, 123, 123, 122, - /* 690 */ 122, 121, 121, 121, 120, 117, 448, 1159, 230, 1193, - /* 700 */ 158, 1193, 1194, 1193, 1556, 13, 13, 303, 960, 1233, - /* 710 */ 1159, 154, 411, 1159, 375, 1584, 1177, 5, 371, 1581, - /* 720 */ 431, 1239, 3, 960, 123, 123, 123, 123, 122, 122, - /* 730 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, - /* 740 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 750 */ 125, 411, 210, 571, 1193, 1032, 1193, 1194, 1193, 1193, - /* 760 */ 390, 855, 156, 1555, 376, 404, 1101, 1101, 492, 572, - /* 770 */ 469, 344, 1322, 1322, 1555, 126, 127, 81, 1217, 1217, - /* 780 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, - /* 790 */ 130, 572, 13, 13, 532, 123, 123, 123, 123, 122, - /* 800 */ 122, 121, 121, 121, 120, 117, 448, 304, 572, 457, - /* 810 */ 229, 1193, 1194, 1193, 13, 13, 1193, 1194, 1193, 1300, - /* 820 */ 467, 1270, 411, 1320, 1320, 1555, 1015, 457, 456, 436, - /* 830 */ 301, 72, 72, 1268, 123, 123, 123, 123, 122, 122, - /* 840 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, - /* 850 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 860 */ 125, 411, 384, 1076, 1159, 286, 286, 421, 314, 280, - /* 870 */ 280, 287, 287, 461, 408, 407, 1539, 1159, 569, 572, - /* 880 */ 1159, 1196, 569, 409, 569, 126, 127, 81, 1217, 1217, - /* 890 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, - /* 900 */ 457, 1485, 13, 13, 1541, 123, 123, 123, 123, 122, - /* 910 */ 122, 121, 121, 121, 120, 117, 448, 202, 572, 462, - /* 920 */ 1587, 578, 2, 1248, 843, 844, 845, 1563, 319, 409, - /* 930 */ 147, 6, 411, 257, 256, 255, 208, 1330, 9, 1196, - /* 940 */ 264, 72, 72, 1436, 123, 123, 123, 123, 122, 122, - /* 950 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, - /* 960 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 970 */ 125, 572, 286, 286, 572, 1213, 411, 577, 315, 1248, - /* 980 */ 421, 371, 1581, 356, 319, 569, 147, 495, 529, 1644, - /* 990 */ 397, 935, 495, 1330, 71, 71, 934, 72, 72, 242, - /* 1000 */ 1328, 105, 81, 1217, 1217, 1054, 1057, 1044, 1044, 124, - /* 1010 */ 124, 125, 125, 125, 125, 123, 123, 123, 123, 122, - /* 1020 */ 122, 121, 121, 121, 120, 117, 448, 1117, 286, 286, - /* 1030 */ 1422, 452, 1528, 1213, 443, 286, 286, 1492, 1355, 313, - /* 1040 */ 478, 569, 1118, 454, 351, 495, 354, 1266, 569, 209, - /* 1050 */ 572, 418, 179, 572, 1031, 242, 385, 1119, 523, 123, - /* 1060 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117, - /* 1070 */ 448, 1020, 108, 72, 72, 1019, 13, 13, 915, 572, - /* 1080 */ 1498, 572, 286, 286, 98, 530, 1537, 452, 916, 1334, - /* 1090 */ 1329, 203, 411, 286, 286, 569, 152, 211, 1498, 1500, - /* 1100 */ 426, 569, 56, 56, 57, 57, 569, 1019, 1019, 1021, - /* 1110 */ 447, 572, 411, 531, 12, 297, 126, 127, 81, 1217, - /* 1120 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 1130 */ 125, 572, 411, 867, 15, 15, 126, 127, 81, 1217, - /* 1140 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 1150 */ 125, 373, 529, 264, 44, 44, 126, 115, 81, 1217, - /* 1160 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 1170 */ 125, 1498, 478, 1271, 417, 123, 123, 123, 123, 122, - /* 1180 */ 122, 121, 121, 121, 120, 117, 448, 205, 1213, 495, - /* 1190 */ 430, 867, 468, 322, 495, 123, 123, 123, 123, 122, - /* 1200 */ 122, 121, 121, 121, 120, 117, 448, 572, 557, 1140, - /* 1210 */ 1642, 1422, 1642, 543, 572, 123, 123, 123, 123, 122, - /* 1220 */ 122, 121, 121, 121, 120, 117, 448, 572, 1422, 572, - /* 1230 */ 13, 13, 542, 323, 1325, 411, 334, 58, 58, 349, - /* 1240 */ 1422, 1170, 326, 286, 286, 549, 1213, 300, 895, 530, - /* 1250 */ 45, 45, 59, 59, 1140, 1643, 569, 1643, 565, 417, - /* 1260 */ 127, 81, 1217, 1217, 1054, 1057, 1044, 1044, 124, 124, - /* 1270 */ 125, 125, 125, 125, 1367, 373, 500, 290, 1193, 512, - /* 1280 */ 1366, 427, 394, 394, 393, 275, 391, 896, 1138, 852, - /* 1290 */ 478, 258, 1422, 1170, 463, 1159, 12, 331, 428, 333, - /* 1300 */ 1117, 460, 236, 258, 325, 460, 544, 1544, 1159, 1098, - /* 1310 */ 491, 1159, 324, 1098, 440, 1118, 335, 516, 123, 123, - /* 1320 */ 123, 123, 122, 122, 121, 121, 121, 120, 117, 448, - /* 1330 */ 1119, 318, 563, 1138, 572, 1193, 1194, 1193, 112, 564, - /* 1340 */ 201, 4, 238, 433, 935, 490, 285, 228, 1517, 934, - /* 1350 */ 170, 560, 572, 142, 1516, 567, 572, 60, 60, 572, - /* 1360 */ 416, 572, 441, 572, 535, 302, 875, 8, 487, 572, - /* 1370 */ 237, 572, 416, 572, 485, 61, 61, 572, 449, 62, - /* 1380 */ 62, 332, 63, 63, 46, 46, 47, 47, 361, 572, - /* 1390 */ 561, 572, 48, 48, 50, 50, 51, 51, 572, 295, - /* 1400 */ 64, 64, 482, 295, 539, 412, 471, 1031, 572, 538, - /* 1410 */ 318, 563, 65, 65, 66, 66, 409, 475, 572, 1031, - /* 1420 */ 572, 14, 14, 875, 1020, 110, 110, 409, 1019, 572, - /* 1430 */ 474, 67, 67, 111, 455, 449, 573, 449, 98, 317, - /* 1440 */ 1019, 132, 132, 133, 133, 572, 1561, 572, 974, 409, - /* 1450 */ 6, 1562, 68, 68, 1560, 6, 975, 572, 6, 1559, - /* 1460 */ 1019, 1019, 1021, 6, 346, 218, 101, 531, 53, 53, - /* 1470 */ 69, 69, 1019, 1019, 1021, 1022, 28, 1586, 1181, 451, - /* 1480 */ 70, 70, 290, 87, 215, 31, 1363, 394, 394, 393, - /* 1490 */ 275, 391, 350, 109, 852, 107, 572, 112, 564, 483, - /* 1500 */ 4, 1212, 572, 239, 153, 572, 39, 236, 1299, 325, - /* 1510 */ 112, 564, 1298, 4, 567, 572, 32, 324, 572, 54, - /* 1520 */ 54, 572, 1135, 353, 398, 165, 165, 567, 166, 166, - /* 1530 */ 572, 291, 355, 572, 17, 357, 572, 449, 77, 77, - /* 1540 */ 1313, 55, 55, 1297, 73, 73, 572, 238, 470, 561, - /* 1550 */ 449, 472, 364, 135, 135, 170, 74, 74, 142, 163, - /* 1560 */ 163, 374, 561, 539, 572, 321, 572, 886, 540, 137, - /* 1570 */ 137, 339, 1353, 422, 298, 237, 539, 572, 1031, 572, - /* 1580 */ 340, 538, 101, 369, 110, 110, 162, 131, 131, 164, - /* 1590 */ 164, 1031, 111, 368, 449, 573, 449, 110, 110, 1019, - /* 1600 */ 157, 157, 141, 141, 572, 111, 572, 449, 573, 449, - /* 1610 */ 412, 288, 1019, 572, 882, 318, 563, 572, 219, 572, - /* 1620 */ 241, 1012, 477, 263, 263, 894, 893, 140, 140, 138, - /* 1630 */ 138, 1019, 1019, 1021, 1022, 28, 139, 139, 525, 455, - /* 1640 */ 76, 76, 78, 78, 1019, 1019, 1021, 1022, 28, 1181, - /* 1650 */ 451, 572, 1083, 290, 112, 564, 1575, 4, 394, 394, - /* 1660 */ 393, 275, 391, 572, 1023, 852, 572, 479, 345, 263, - /* 1670 */ 101, 567, 882, 1376, 75, 75, 1421, 501, 236, 260, - /* 1680 */ 325, 112, 564, 359, 4, 101, 43, 43, 324, 49, - /* 1690 */ 49, 901, 902, 161, 449, 101, 977, 978, 567, 1079, - /* 1700 */ 1349, 260, 965, 932, 263, 114, 561, 1095, 517, 1095, - /* 1710 */ 1083, 1094, 865, 1094, 151, 933, 1144, 114, 238, 1361, - /* 1720 */ 558, 449, 1023, 559, 1426, 1278, 170, 1269, 1257, 142, - /* 1730 */ 1601, 1256, 1258, 561, 1594, 1031, 496, 278, 213, 1346, - /* 1740 */ 310, 110, 110, 939, 311, 312, 237, 11, 234, 111, - /* 1750 */ 221, 449, 573, 449, 293, 395, 1019, 1408, 337, 1403, - /* 1760 */ 1396, 338, 1031, 299, 343, 1413, 1412, 481, 110, 110, - /* 1770 */ 506, 402, 225, 1296, 206, 367, 111, 1358, 449, 573, - /* 1780 */ 449, 412, 1359, 1019, 1489, 1488, 318, 563, 1019, 1019, - /* 1790 */ 1021, 1022, 28, 562, 207, 220, 80, 564, 389, 4, - /* 1800 */ 1597, 1357, 552, 1356, 1233, 181, 267, 232, 1536, 1534, - /* 1810 */ 455, 1230, 420, 567, 82, 1019, 1019, 1021, 1022, 28, - /* 1820 */ 86, 217, 85, 1494, 190, 175, 183, 465, 185, 466, - /* 1830 */ 36, 1409, 186, 187, 188, 499, 449, 244, 37, 99, - /* 1840 */ 400, 1415, 1414, 488, 1417, 194, 473, 403, 561, 1483, - /* 1850 */ 248, 92, 1505, 494, 198, 279, 112, 564, 250, 4, - /* 1860 */ 348, 497, 405, 352, 1259, 251, 252, 515, 1316, 434, - /* 1870 */ 1315, 1314, 94, 567, 1307, 886, 1306, 1031, 226, 406, - /* 1880 */ 1611, 1610, 438, 110, 110, 1580, 1286, 524, 439, 308, - /* 1890 */ 266, 111, 1285, 449, 573, 449, 449, 309, 1019, 366, - /* 1900 */ 1284, 1609, 265, 1566, 1565, 442, 372, 1381, 561, 129, - /* 1910 */ 550, 1380, 10, 1470, 383, 106, 316, 551, 100, 35, - /* 1920 */ 534, 575, 212, 1339, 381, 387, 1187, 1338, 274, 276, - /* 1930 */ 1019, 1019, 1021, 1022, 28, 277, 413, 1031, 576, 1254, - /* 1940 */ 388, 1521, 1249, 110, 110, 167, 1522, 168, 148, 1520, - /* 1950 */ 1519, 111, 306, 449, 573, 449, 222, 223, 1019, 839, - /* 1960 */ 169, 79, 450, 214, 414, 233, 320, 145, 1093, 1091, - /* 1970 */ 328, 182, 171, 1212, 918, 184, 240, 336, 243, 1107, - /* 1980 */ 189, 172, 173, 423, 425, 88, 180, 191, 89, 90, - /* 1990 */ 1019, 1019, 1021, 1022, 28, 91, 174, 1110, 245, 1106, - /* 2000 */ 246, 159, 18, 247, 347, 1099, 263, 195, 1227, 493, - /* 2010 */ 249, 196, 38, 854, 498, 368, 253, 360, 897, 197, - /* 2020 */ 502, 93, 19, 20, 507, 884, 363, 510, 95, 307, - /* 2030 */ 160, 96, 518, 97, 1175, 1060, 1146, 40, 21, 227, - /* 2040 */ 176, 1145, 282, 284, 969, 200, 963, 114, 262, 1165, - /* 2050 */ 22, 23, 24, 1161, 1169, 25, 1163, 1150, 34, 26, - /* 2060 */ 1168, 546, 27, 204, 101, 103, 104, 1074, 7, 1061, - /* 2070 */ 1059, 1063, 1116, 1064, 1115, 268, 269, 29, 41, 270, - /* 2080 */ 1024, 866, 113, 30, 568, 392, 1183, 144, 178, 1182, - /* 2090 */ 271, 928, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1602, + /* 0 */ 506, 487, 583, 286, 211, 118, 115, 232, 1261, 1, + /* 10 */ 1, 589, 2, 1265, 118, 115, 232, 418, 324, 420, + /* 20 */ 143, 1609, 589, 2, 1265, 41, 41, 1351, 1629, 324, + /* 30 */ 1288, 143, 992, 409, 1443, 1548, 1307, 1297, 1351, 310, + /* 40 */ 993, 310, 1285, 506, 538, 423, 125, 126, 80, 1236, + /* 50 */ 1236, 1070, 1073, 1060, 1060, 123, 123, 124, 124, 124, + /* 60 */ 124, 583, 291, 291, 118, 115, 232, 1300, 291, 291, + /* 70 */ 211, 583, 386, 291, 291, 580, 299, 332, 583, 291, + /* 80 */ 291, 580, 532, 406, 13, 13, 580, 177, 1547, 243, + /* 90 */ 1299, 387, 580, 489, 51, 51, 265, 229, 485, 432, + /* 100 */ 243, 41, 41, 460, 434, 122, 122, 122, 122, 121, + /* 110 */ 121, 120, 120, 120, 119, 116, 455, 291, 291, 1666, + /* 120 */ 404, 459, 129, 1590, 385, 420, 583, 118, 115, 232, + /* 130 */ 580, 533, 459, 122, 122, 122, 122, 121, 121, 120, + /* 140 */ 120, 120, 119, 116, 455, 420, 118, 115, 232, 41, + /* 150 */ 41, 101, 125, 126, 80, 1236, 1236, 1070, 1073, 1060, + /* 160 */ 1060, 123, 123, 124, 124, 124, 124, 1512, 1057, 1057, + /* 170 */ 1071, 1074, 125, 126, 80, 1236, 1236, 1070, 1073, 1060, + /* 180 */ 1060, 123, 123, 124, 124, 124, 124, 120, 120, 120, + /* 190 */ 119, 116, 455, 487, 1288, 1183, 540, 1183, 127, 1592, + /* 200 */ 455, 384, 530, 1584, 585, 1212, 585, 6, 177, 416, + /* 210 */ 415, 122, 122, 122, 122, 121, 121, 120, 120, 120, + /* 220 */ 119, 116, 455, 121, 121, 120, 120, 120, 119, 116, + /* 230 */ 455, 122, 122, 122, 122, 121, 121, 120, 120, 120, + /* 240 */ 119, 116, 455, 1061, 478, 350, 583, 1590, 552, 452, + /* 250 */ 451, 420, 452, 451, 506, 124, 124, 124, 124, 117, + /* 260 */ 1178, 1241, 1212, 1213, 1212, 558, 1243, 1028, 302, 70, + /* 270 */ 70, 548, 1635, 1178, 1242, 144, 1178, 144, 125, 126, + /* 280 */ 80, 1236, 1236, 1070, 1073, 1060, 1060, 123, 123, 124, + /* 290 */ 124, 124, 124, 278, 277, 97, 541, 1244, 1244, 1511, + /* 300 */ 1244, 1244, 82, 122, 122, 122, 122, 121, 121, 120, + /* 310 */ 120, 120, 119, 116, 455, 429, 467, 124, 124, 124, + /* 320 */ 124, 348, 420, 556, 1584, 542, 1028, 83, 6, 1212, + /* 330 */ 547, 392, 1606, 323, 574, 323, 574, 122, 122, 122, + /* 340 */ 122, 121, 121, 120, 120, 120, 119, 116, 455, 125, + /* 350 */ 126, 80, 1236, 1236, 1070, 1073, 1060, 1060, 123, 123, + /* 360 */ 124, 124, 124, 124, 420, 122, 122, 122, 122, 121, + /* 370 */ 121, 120, 120, 120, 119, 116, 455, 100, 559, 1577, + /* 380 */ 348, 473, 335, 583, 334, 200, 1212, 1213, 1212, 382, + /* 390 */ 382, 125, 126, 80, 1236, 1236, 1070, 1073, 1060, 1060, + /* 400 */ 123, 123, 124, 124, 124, 124, 13, 13, 122, 122, + /* 410 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 455, + /* 420 */ 144, 437, 537, 258, 937, 583, 519, 516, 515, 1212, + /* 430 */ 1335, 1178, 1314, 227, 529, 420, 514, 1212, 154, 365, + /* 440 */ 1335, 938, 146, 151, 1178, 16, 16, 1178, 71, 71, + /* 450 */ 122, 122, 122, 122, 121, 121, 120, 120, 120, 119, + /* 460 */ 116, 455, 125, 126, 80, 1236, 1236, 1070, 1073, 1060, + /* 470 */ 1060, 123, 123, 124, 124, 124, 124, 420, 323, 574, + /* 480 */ 1212, 520, 588, 882, 1265, 565, 1212, 1213, 1212, 324, + /* 490 */ 558, 143, 429, 539, 1212, 1213, 1212, 380, 1351, 217, + /* 500 */ 1576, 1575, 323, 574, 125, 126, 80, 1236, 1236, 1070, + /* 510 */ 1073, 1060, 1060, 123, 123, 124, 124, 124, 124, 1340, + /* 520 */ 1340, 122, 122, 122, 122, 121, 121, 120, 120, 120, + /* 530 */ 119, 116, 455, 291, 291, 583, 439, 1212, 1213, 1212, + /* 540 */ 258, 882, 211, 519, 516, 515, 580, 468, 420, 1212, + /* 550 */ 397, 382, 894, 514, 1212, 412, 193, 382, 71, 71, + /* 560 */ 243, 209, 148, 122, 122, 122, 122, 121, 121, 120, + /* 570 */ 120, 120, 119, 116, 455, 125, 126, 80, 1236, 1236, + /* 580 */ 1070, 1073, 1060, 1060, 123, 123, 124, 124, 124, 124, + /* 590 */ 420, 583, 459, 1318, 887, 565, 1212, 211, 382, 157, + /* 600 */ 577, 577, 577, 564, 1578, 153, 1212, 1213, 1212, 583, + /* 610 */ 407, 1212, 1213, 1212, 71, 71, 910, 125, 126, 80, + /* 620 */ 1236, 1236, 1070, 1073, 1060, 1060, 123, 123, 124, 124, + /* 630 */ 124, 124, 133, 133, 122, 122, 122, 122, 121, 121, + /* 640 */ 120, 120, 120, 119, 116, 455, 155, 85, 583, 523, + /* 650 */ 582, 565, 429, 1212, 1213, 1212, 1112, 911, 393, 531, + /* 660 */ 389, 420, 1575, 1338, 1338, 1196, 194, 493, 1575, 1212, + /* 670 */ 32, 71, 71, 1457, 5, 540, 122, 122, 122, 122, + /* 680 */ 121, 121, 120, 120, 120, 119, 116, 455, 125, 126, + /* 690 */ 80, 1236, 1236, 1070, 1073, 1060, 1060, 123, 123, 124, + /* 700 */ 124, 124, 124, 420, 285, 285, 1212, 1048, 544, 1575, + /* 710 */ 1212, 378, 1603, 442, 1212, 1585, 211, 580, 958, 6, + /* 720 */ 3, 210, 583, 453, 453, 453, 1212, 1213, 1212, 461, + /* 730 */ 125, 126, 80, 1236, 1236, 1070, 1073, 1060, 1060, 123, + /* 740 */ 123, 124, 124, 124, 124, 71, 71, 122, 122, 122, + /* 750 */ 122, 121, 121, 120, 120, 120, 119, 116, 455, 12, + /* 760 */ 1212, 583, 1215, 1212, 1213, 1212, 301, 1212, 1213, 1212, + /* 770 */ 1178, 1212, 1213, 1212, 420, 541, 478, 350, 1033, 1117, + /* 780 */ 1117, 503, 319, 1178, 71, 71, 1178, 383, 297, 122, + /* 790 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116, + /* 800 */ 455, 125, 126, 80, 1236, 1236, 1070, 1073, 1060, 1060, + /* 810 */ 123, 123, 124, 124, 124, 124, 420, 1212, 1213, 1212, + /* 820 */ 1215, 320, 543, 291, 291, 292, 292, 230, 119, 116, + /* 830 */ 455, 581, 206, 947, 947, 583, 580, 477, 580, 1376, + /* 840 */ 318, 306, 391, 125, 126, 80, 1236, 1236, 1070, 1073, + /* 850 */ 1060, 1060, 123, 123, 124, 124, 124, 124, 71, 71, + /* 860 */ 122, 122, 122, 122, 121, 121, 120, 120, 120, 119, + /* 870 */ 116, 455, 1212, 340, 487, 583, 291, 291, 466, 1317, + /* 880 */ 1157, 1664, 1443, 1664, 857, 858, 859, 420, 444, 580, + /* 890 */ 261, 260, 259, 369, 363, 450, 466, 465, 71, 71, + /* 900 */ 483, 338, 122, 122, 122, 122, 121, 121, 120, 120, + /* 910 */ 120, 119, 116, 455, 125, 126, 80, 1236, 1236, 1070, + /* 920 */ 1073, 1060, 1060, 123, 123, 124, 124, 124, 124, 1212, + /* 930 */ 1213, 1212, 583, 527, 1133, 454, 219, 336, 1316, 339, + /* 940 */ 583, 1157, 1665, 487, 1665, 869, 1443, 403, 1257, 305, + /* 950 */ 1134, 566, 435, 1289, 426, 13, 13, 980, 358, 104, + /* 960 */ 361, 953, 1155, 71, 71, 1135, 952, 522, 354, 466, + /* 970 */ 440, 511, 1456, 122, 122, 122, 122, 121, 121, 120, + /* 980 */ 120, 120, 119, 116, 455, 441, 291, 291, 930, 1212, + /* 990 */ 583, 276, 294, 377, 525, 372, 524, 263, 931, 580, + /* 1000 */ 565, 262, 583, 368, 420, 470, 1178, 476, 567, 212, + /* 1010 */ 378, 1603, 1443, 13, 13, 417, 436, 555, 307, 1178, + /* 1020 */ 1212, 337, 1178, 1155, 420, 135, 135, 890, 309, 1258, + /* 1030 */ 107, 125, 126, 80, 1236, 1236, 1070, 1073, 1060, 1060, + /* 1040 */ 123, 123, 124, 124, 124, 124, 1212, 1213, 1212, 583, + /* 1050 */ 1092, 125, 126, 80, 1236, 1236, 1070, 1073, 1060, 1060, + /* 1060 */ 123, 123, 124, 124, 124, 124, 424, 1582, 1047, 1558, + /* 1070 */ 425, 6, 13, 13, 403, 1156, 546, 1212, 1213, 1212, + /* 1080 */ 1560, 978, 502, 506, 890, 1038, 368, 203, 1504, 1037, + /* 1090 */ 122, 122, 122, 122, 121, 121, 120, 120, 120, 119, + /* 1100 */ 116, 455, 1037, 583, 1346, 979, 1517, 9, 583, 268, + /* 1110 */ 122, 122, 122, 122, 121, 121, 120, 120, 120, 119, + /* 1120 */ 116, 455, 1037, 1039, 1517, 1519, 13, 13, 1347, 1583, + /* 1130 */ 420, 13, 13, 6, 1315, 288, 493, 978, 1443, 291, + /* 1140 */ 291, 204, 576, 426, 323, 574, 560, 1232, 506, 498, + /* 1150 */ 420, 583, 580, 495, 493, 463, 1258, 125, 114, 80, + /* 1160 */ 1236, 1236, 1070, 1073, 1060, 1060, 123, 123, 124, 124, + /* 1170 */ 124, 124, 583, 554, 55, 55, 583, 231, 126, 80, + /* 1180 */ 1236, 1236, 1070, 1073, 1060, 1060, 123, 123, 124, 124, + /* 1190 */ 124, 124, 553, 356, 1047, 56, 56, 1517, 296, 15, + /* 1200 */ 15, 1189, 108, 978, 106, 1232, 506, 236, 448, 469, + /* 1210 */ 1581, 1038, 561, 469, 6, 1037, 122, 122, 122, 122, + /* 1220 */ 121, 121, 120, 120, 120, 119, 116, 455, 1037, 1283, + /* 1230 */ 149, 534, 326, 231, 568, 347, 122, 122, 122, 122, + /* 1240 */ 121, 121, 120, 120, 120, 119, 116, 455, 1037, 1039, + /* 1250 */ 583, 1343, 1133, 308, 1189, 1252, 420, 583, 1634, 978, + /* 1260 */ 919, 462, 380, 491, 291, 291, 291, 291, 1134, 291, + /* 1270 */ 291, 100, 1114, 43, 43, 583, 1114, 580, 225, 580, + /* 1280 */ 57, 57, 580, 1135, 583, 80, 1236, 1236, 1070, 1073, + /* 1290 */ 1060, 1060, 123, 123, 124, 124, 124, 124, 44, 44, + /* 1300 */ 583, 447, 583, 225, 583, 1556, 571, 58, 58, 583, + /* 1310 */ 501, 111, 575, 583, 4, 583, 300, 583, 268, 1355, + /* 1320 */ 300, 12, 327, 59, 59, 60, 60, 61, 61, 578, + /* 1330 */ 1580, 580, 62, 62, 6, 583, 45, 45, 46, 46, + /* 1340 */ 47, 47, 122, 122, 122, 122, 121, 121, 120, 120, + /* 1350 */ 120, 119, 116, 455, 456, 583, 1232, 583, 49, 49, + /* 1360 */ 583, 471, 583, 492, 111, 575, 572, 4, 583, 992, + /* 1370 */ 583, 417, 427, 178, 583, 901, 144, 993, 50, 50, + /* 1380 */ 63, 63, 578, 64, 64, 65, 65, 290, 229, 262, + /* 1390 */ 480, 14, 14, 66, 66, 1047, 8, 131, 131, 494, + /* 1400 */ 417, 109, 109, 86, 216, 484, 98, 456, 1231, 110, + /* 1410 */ 328, 456, 584, 456, 1232, 417, 1037, 583, 322, 572, + /* 1420 */ 583, 152, 583, 38, 220, 953, 97, 30, 417, 1037, + /* 1430 */ 952, 17, 570, 550, 323, 574, 583, 1152, 549, 405, + /* 1440 */ 132, 132, 113, 67, 67, 52, 52, 240, 1047, 1037, + /* 1450 */ 1039, 1040, 27, 583, 109, 109, 542, 479, 425, 68, + /* 1460 */ 68, 31, 110, 583, 456, 584, 456, 481, 346, 1037, + /* 1470 */ 100, 331, 1030, 430, 267, 583, 69, 69, 486, 1388, + /* 1480 */ 267, 345, 1037, 1608, 1200, 458, 53, 53, 295, 111, + /* 1490 */ 575, 303, 4, 401, 401, 400, 280, 398, 163, 163, + /* 1500 */ 866, 536, 1037, 1039, 1040, 27, 1387, 578, 472, 488, + /* 1510 */ 583, 267, 1350, 583, 237, 351, 330, 100, 512, 583, + /* 1520 */ 264, 366, 583, 100, 329, 583, 293, 897, 583, 220, + /* 1530 */ 1374, 583, 456, 164, 164, 1099, 76, 76, 583, 909, + /* 1540 */ 908, 1564, 54, 54, 572, 72, 72, 583, 134, 134, + /* 1550 */ 341, 73, 73, 583, 161, 161, 239, 1536, 550, 916, + /* 1560 */ 917, 136, 136, 551, 170, 376, 561, 142, 242, 1535, + /* 1570 */ 130, 130, 583, 1047, 583, 375, 162, 162, 202, 109, + /* 1580 */ 109, 583, 1161, 496, 238, 897, 352, 110, 583, 456, + /* 1590 */ 584, 456, 583, 1099, 1037, 156, 156, 140, 140, 111, + /* 1600 */ 575, 1095, 4, 264, 139, 139, 499, 1037, 583, 995, + /* 1610 */ 996, 137, 137, 583, 500, 138, 138, 578, 983, 419, + /* 1620 */ 267, 950, 880, 113, 150, 323, 574, 1037, 1039, 1040, + /* 1630 */ 27, 75, 75, 951, 583, 113, 77, 77, 1041, 583, + /* 1640 */ 1597, 583, 456, 1384, 1111, 1111, 1110, 1110, 464, 1623, + /* 1650 */ 507, 357, 360, 362, 572, 364, 1331, 74, 74, 371, + /* 1660 */ 283, 381, 42, 42, 48, 48, 1397, 1442, 550, 1370, + /* 1670 */ 1382, 569, 1447, 549, 1296, 1200, 458, 214, 1367, 295, + /* 1680 */ 1287, 315, 316, 1047, 401, 401, 400, 280, 398, 109, + /* 1690 */ 109, 866, 1286, 317, 1274, 1273, 1041, 110, 1275, 456, + /* 1700 */ 584, 456, 1616, 402, 1037, 237, 222, 330, 11, 235, + /* 1710 */ 1429, 1424, 1417, 1434, 298, 329, 344, 1037, 517, 226, + /* 1720 */ 1433, 343, 490, 410, 1619, 1252, 304, 349, 1314, 374, + /* 1730 */ 1508, 180, 1507, 573, 233, 271, 221, 1037, 1039, 1040, + /* 1740 */ 27, 396, 1379, 1555, 295, 1380, 1553, 239, 1249, 401, + /* 1750 */ 401, 400, 280, 398, 1378, 170, 866, 207, 142, 111, + /* 1760 */ 575, 428, 4, 1377, 208, 81, 85, 218, 191, 175, + /* 1770 */ 237, 184, 330, 474, 475, 238, 186, 578, 111, 575, + /* 1780 */ 329, 4, 187, 510, 244, 188, 189, 35, 1430, 246, + /* 1790 */ 98, 1436, 1435, 36, 1438, 497, 578, 1513, 408, 482, + /* 1800 */ 195, 84, 456, 411, 1502, 250, 252, 91, 1524, 505, + /* 1810 */ 419, 355, 239, 254, 572, 199, 323, 574, 284, 508, + /* 1820 */ 170, 456, 359, 142, 255, 413, 1276, 256, 526, 1334, + /* 1830 */ 443, 93, 1325, 572, 1333, 1332, 901, 1304, 227, 464, + /* 1840 */ 238, 373, 1302, 1047, 1633, 1632, 1602, 445, 414, 109, + /* 1850 */ 109, 957, 1303, 1631, 446, 535, 1324, 110, 313, 456, + /* 1860 */ 584, 456, 1047, 314, 1037, 379, 269, 270, 109, 109, + /* 1870 */ 79, 575, 1588, 4, 449, 419, 110, 1037, 456, 584, + /* 1880 */ 456, 323, 574, 1037, 1587, 128, 561, 1360, 578, 111, + /* 1890 */ 575, 388, 4, 10, 390, 1402, 1037, 1037, 1039, 1040, + /* 1900 */ 27, 1401, 105, 563, 464, 1359, 213, 578, 1489, 99, + /* 1910 */ 545, 395, 321, 456, 394, 34, 1037, 1039, 1040, 27, + /* 1920 */ 586, 1206, 279, 281, 282, 572, 587, 165, 1271, 1266, + /* 1930 */ 166, 167, 456, 223, 1540, 1541, 147, 421, 311, 1539, + /* 1940 */ 179, 422, 853, 1538, 572, 224, 78, 457, 215, 325, + /* 1950 */ 181, 168, 182, 145, 1047, 234, 1109, 1107, 333, 183, + /* 1960 */ 109, 109, 171, 185, 1231, 241, 933, 245, 110, 342, + /* 1970 */ 456, 584, 456, 1047, 1123, 1037, 190, 172, 173, 109, + /* 1980 */ 109, 431, 192, 433, 87, 88, 89, 110, 1037, 456, + /* 1990 */ 584, 456, 90, 174, 1037, 562, 1126, 247, 248, 1122, + /* 2000 */ 158, 18, 249, 353, 438, 251, 267, 1037, 1037, 1039, + /* 2010 */ 1040, 27, 504, 1115, 196, 197, 37, 253, 198, 868, + /* 2020 */ 509, 375, 257, 367, 513, 1246, 92, 1037, 1039, 1040, + /* 2030 */ 27, 19, 20, 518, 899, 370, 912, 94, 312, 159, + /* 2040 */ 176, 95, 528, 96, 1194, 160, 1076, 521, 1163, 39, + /* 2050 */ 1162, 228, 287, 289, 266, 201, 981, 113, 1180, 21, + /* 2060 */ 1184, 22, 1188, 23, 1182, 1187, 24, 1168, 987, 33, + /* 2070 */ 25, 205, 557, 26, 100, 1090, 1077, 102, 103, 1075, + /* 2080 */ 1079, 7, 1132, 272, 1131, 273, 1080, 28, 40, 579, + /* 2090 */ 1042, 881, 112, 29, 946, 141, 274, 275, 169, 399, + /* 2100 */ 1202, 1624, 1201, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276, - /* 10 */ 193, 223, 219, 225, 206, 210, 211, 212, 193, 19, - /* 20 */ 219, 233, 216, 216, 217, 216, 217, 193, 295, 216, - /* 30 */ 217, 31, 193, 216, 217, 193, 228, 213, 230, 39, - /* 40 */ 206, 216, 217, 43, 44, 45, 46, 47, 48, 49, - /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 193, 19, - /* 60 */ 185, 186, 187, 188, 189, 190, 253, 274, 275, 276, - /* 70 */ 195, 193, 197, 193, 261, 274, 275, 276, 253, 204, - /* 80 */ 238, 204, 81, 43, 44, 45, 46, 47, 48, 49, - /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 274, 275, - /* 100 */ 276, 262, 102, 103, 104, 105, 106, 107, 108, 109, - /* 110 */ 110, 111, 112, 113, 239, 240, 239, 240, 210, 211, - /* 120 */ 212, 314, 315, 314, 59, 316, 86, 252, 88, 252, - /* 130 */ 19, 314, 315, 256, 257, 113, 25, 72, 296, 138, - /* 140 */ 139, 266, 102, 103, 104, 105, 106, 107, 108, 109, - /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48, - /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 81, - /* 170 */ 292, 59, 292, 298, 108, 109, 110, 111, 112, 113, - /* 180 */ 69, 116, 117, 118, 72, 106, 107, 193, 111, 112, - /* 190 */ 113, 54, 55, 56, 57, 58, 102, 103, 104, 105, - /* 200 */ 106, 107, 108, 109, 110, 111, 112, 113, 120, 25, - /* 210 */ 216, 217, 145, 102, 103, 104, 105, 106, 107, 108, - /* 220 */ 109, 110, 111, 112, 113, 231, 138, 139, 116, 117, - /* 230 */ 118, 164, 153, 19, 155, 54, 55, 56, 57, 102, - /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 250 */ 113, 128, 129, 46, 47, 48, 49, 43, 44, 45, - /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - /* 270 */ 56, 57, 216, 193, 25, 59, 193, 19, 165, 166, - /* 280 */ 193, 67, 24, 102, 103, 104, 105, 106, 107, 108, - /* 290 */ 109, 110, 111, 112, 113, 73, 216, 217, 59, 216, - /* 300 */ 217, 43, 44, 45, 46, 47, 48, 49, 50, 51, - /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105, - /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 121, 145, - /* 330 */ 59, 193, 116, 117, 118, 119, 273, 204, 122, 123, - /* 340 */ 124, 19, 20, 134, 22, 136, 137, 19, 132, 127, - /* 350 */ 128, 129, 24, 22, 23, 116, 117, 118, 36, 193, - /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 370 */ 112, 113, 239, 240, 311, 312, 215, 106, 107, 241, - /* 380 */ 19, 59, 216, 217, 223, 252, 115, 116, 117, 118, - /* 390 */ 151, 120, 26, 71, 193, 308, 309, 193, 149, 128, - /* 400 */ 313, 216, 269, 81, 43, 44, 45, 46, 47, 48, - /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 253, - /* 420 */ 216, 217, 100, 95, 153, 59, 155, 261, 106, 107, - /* 430 */ 25, 193, 101, 193, 193, 231, 114, 25, 116, 117, - /* 440 */ 118, 113, 304, 121, 193, 204, 59, 119, 120, 121, - /* 450 */ 122, 123, 124, 125, 216, 217, 193, 216, 217, 131, - /* 460 */ 138, 139, 230, 102, 103, 104, 105, 106, 107, 108, - /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157, - /* 480 */ 239, 240, 116, 117, 118, 76, 193, 23, 19, 25, - /* 490 */ 22, 253, 23, 252, 253, 108, 87, 204, 89, 261, - /* 500 */ 198, 92, 261, 116, 117, 118, 193, 306, 307, 216, - /* 510 */ 217, 150, 43, 44, 45, 46, 47, 48, 49, 50, - /* 520 */ 51, 52, 53, 54, 55, 56, 57, 59, 193, 216, - /* 530 */ 217, 19, 239, 240, 283, 23, 106, 107, 108, 109, - /* 540 */ 110, 111, 112, 113, 73, 252, 253, 142, 308, 309, - /* 550 */ 138, 139, 81, 313, 145, 43, 44, 45, 46, 47, - /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 570 */ 307, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 580 */ 111, 112, 113, 281, 116, 117, 118, 285, 23, 193, - /* 590 */ 25, 119, 59, 193, 122, 123, 124, 59, 127, 203, - /* 600 */ 59, 205, 19, 268, 132, 25, 23, 22, 193, 138, - /* 610 */ 139, 249, 204, 251, 102, 103, 104, 105, 106, 107, - /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 640 */ 57, 19, 22, 23, 59, 23, 25, 239, 240, 116, - /* 650 */ 117, 118, 193, 11, 116, 117, 118, 116, 117, 118, - /* 660 */ 252, 269, 22, 193, 15, 43, 44, 45, 46, 47, - /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 680 */ 273, 143, 193, 118, 143, 102, 103, 104, 105, 106, - /* 690 */ 107, 108, 109, 110, 111, 112, 113, 76, 118, 59, - /* 700 */ 241, 116, 117, 118, 304, 216, 217, 292, 143, 60, - /* 710 */ 89, 241, 19, 92, 193, 193, 23, 22, 311, 312, - /* 720 */ 231, 101, 22, 143, 102, 103, 104, 105, 106, 107, - /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 750 */ 57, 19, 193, 193, 59, 23, 116, 117, 118, 59, - /* 760 */ 201, 21, 241, 304, 193, 206, 127, 128, 129, 193, - /* 770 */ 128, 129, 235, 236, 304, 43, 44, 45, 46, 47, - /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 790 */ 22, 193, 216, 217, 193, 102, 103, 104, 105, 106, - /* 800 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 193, - /* 810 */ 193, 116, 117, 118, 216, 217, 116, 117, 118, 226, - /* 820 */ 80, 193, 19, 235, 236, 304, 23, 211, 212, 231, - /* 830 */ 204, 216, 217, 205, 102, 103, 104, 105, 106, 107, - /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 860 */ 57, 19, 193, 123, 76, 239, 240, 193, 253, 239, - /* 870 */ 240, 239, 240, 244, 106, 107, 193, 89, 252, 193, - /* 880 */ 92, 59, 252, 254, 252, 43, 44, 45, 46, 47, - /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 900 */ 284, 161, 216, 217, 193, 102, 103, 104, 105, 106, - /* 910 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 244, - /* 920 */ 187, 188, 189, 190, 7, 8, 9, 309, 195, 254, - /* 930 */ 197, 313, 19, 127, 128, 129, 262, 204, 22, 117, - /* 940 */ 24, 216, 217, 273, 102, 103, 104, 105, 106, 107, - /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 970 */ 57, 193, 239, 240, 193, 59, 19, 188, 253, 190, - /* 980 */ 193, 311, 312, 16, 195, 252, 197, 193, 19, 301, - /* 990 */ 302, 135, 193, 204, 216, 217, 140, 216, 217, 266, - /* 1000 */ 204, 159, 45, 46, 47, 48, 49, 50, 51, 52, - /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106, - /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 12, 239, 240, - /* 1030 */ 193, 298, 238, 117, 253, 239, 240, 238, 259, 260, - /* 1040 */ 193, 252, 27, 193, 77, 193, 79, 204, 252, 262, - /* 1050 */ 193, 299, 300, 193, 100, 266, 278, 42, 204, 102, - /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 1070 */ 113, 117, 159, 216, 217, 121, 216, 217, 63, 193, - /* 1080 */ 193, 193, 239, 240, 115, 116, 193, 298, 73, 240, - /* 1090 */ 238, 231, 19, 239, 240, 252, 22, 24, 211, 212, - /* 1100 */ 263, 252, 216, 217, 216, 217, 252, 153, 154, 155, - /* 1110 */ 253, 193, 19, 144, 213, 268, 43, 44, 45, 46, - /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1130 */ 57, 193, 19, 59, 216, 217, 43, 44, 45, 46, - /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1150 */ 57, 193, 19, 24, 216, 217, 43, 44, 45, 46, - /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1170 */ 57, 284, 193, 208, 209, 102, 103, 104, 105, 106, - /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 286, 59, 193, - /* 1190 */ 232, 117, 291, 193, 193, 102, 103, 104, 105, 106, - /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 193, 204, 22, - /* 1210 */ 23, 193, 25, 66, 193, 102, 103, 104, 105, 106, - /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 193, 193, 193, - /* 1230 */ 216, 217, 85, 193, 238, 19, 16, 216, 217, 238, - /* 1240 */ 193, 94, 193, 239, 240, 231, 117, 268, 35, 116, - /* 1250 */ 216, 217, 216, 217, 22, 23, 252, 25, 208, 209, - /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 1270 */ 54, 55, 56, 57, 193, 193, 19, 5, 59, 66, - /* 1280 */ 193, 263, 10, 11, 12, 13, 14, 74, 101, 17, - /* 1290 */ 193, 46, 193, 146, 193, 76, 213, 77, 263, 79, - /* 1300 */ 12, 260, 30, 46, 32, 264, 87, 193, 89, 29, - /* 1310 */ 263, 92, 40, 33, 232, 27, 193, 108, 102, 103, - /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - /* 1330 */ 42, 138, 139, 101, 193, 116, 117, 118, 19, 20, - /* 1340 */ 255, 22, 70, 130, 135, 65, 256, 257, 193, 140, - /* 1350 */ 78, 63, 193, 81, 193, 36, 193, 216, 217, 193, - /* 1360 */ 115, 193, 263, 193, 145, 268, 59, 48, 193, 193, - /* 1370 */ 98, 193, 115, 193, 291, 216, 217, 193, 59, 216, - /* 1380 */ 217, 161, 216, 217, 216, 217, 216, 217, 131, 193, - /* 1390 */ 71, 193, 216, 217, 216, 217, 216, 217, 193, 260, - /* 1400 */ 216, 217, 19, 264, 85, 133, 244, 100, 193, 90, - /* 1410 */ 138, 139, 216, 217, 216, 217, 254, 244, 193, 100, - /* 1420 */ 193, 216, 217, 116, 117, 106, 107, 254, 121, 193, - /* 1430 */ 115, 216, 217, 114, 162, 116, 117, 118, 115, 244, - /* 1440 */ 121, 216, 217, 216, 217, 193, 309, 193, 31, 254, - /* 1450 */ 313, 309, 216, 217, 309, 313, 39, 193, 313, 309, - /* 1460 */ 153, 154, 155, 313, 193, 150, 25, 144, 216, 217, - /* 1470 */ 216, 217, 153, 154, 155, 156, 157, 0, 1, 2, - /* 1480 */ 216, 217, 5, 149, 150, 22, 193, 10, 11, 12, - /* 1490 */ 13, 14, 193, 158, 17, 160, 193, 19, 20, 116, - /* 1500 */ 22, 25, 193, 24, 22, 193, 24, 30, 226, 32, - /* 1510 */ 19, 20, 226, 22, 36, 193, 53, 40, 193, 216, - /* 1520 */ 217, 193, 23, 193, 25, 216, 217, 36, 216, 217, - /* 1530 */ 193, 99, 193, 193, 22, 193, 193, 59, 216, 217, - /* 1540 */ 193, 216, 217, 193, 216, 217, 193, 70, 129, 71, - /* 1550 */ 59, 129, 193, 216, 217, 78, 216, 217, 81, 216, - /* 1560 */ 217, 193, 71, 85, 193, 133, 193, 126, 90, 216, - /* 1570 */ 217, 152, 258, 61, 152, 98, 85, 193, 100, 193, - /* 1580 */ 23, 90, 25, 121, 106, 107, 23, 216, 217, 216, - /* 1590 */ 217, 100, 114, 131, 116, 117, 118, 106, 107, 121, - /* 1600 */ 216, 217, 216, 217, 193, 114, 193, 116, 117, 118, - /* 1610 */ 133, 22, 121, 193, 59, 138, 139, 193, 142, 193, - /* 1620 */ 141, 23, 23, 25, 25, 120, 121, 216, 217, 216, - /* 1630 */ 217, 153, 154, 155, 156, 157, 216, 217, 19, 162, - /* 1640 */ 216, 217, 216, 217, 153, 154, 155, 156, 157, 1, - /* 1650 */ 2, 193, 59, 5, 19, 20, 318, 22, 10, 11, - /* 1660 */ 12, 13, 14, 193, 59, 17, 193, 23, 23, 25, - /* 1670 */ 25, 36, 117, 193, 216, 217, 193, 23, 30, 25, - /* 1680 */ 32, 19, 20, 23, 22, 25, 216, 217, 40, 216, - /* 1690 */ 217, 7, 8, 23, 59, 25, 83, 84, 36, 23, - /* 1700 */ 193, 25, 23, 23, 25, 25, 71, 153, 145, 155, - /* 1710 */ 117, 153, 23, 155, 25, 23, 97, 25, 70, 193, - /* 1720 */ 193, 59, 117, 236, 193, 193, 78, 193, 193, 81, - /* 1730 */ 141, 193, 193, 71, 193, 100, 288, 287, 242, 255, - /* 1740 */ 255, 106, 107, 108, 255, 255, 98, 243, 297, 114, - /* 1750 */ 214, 116, 117, 118, 245, 191, 121, 271, 293, 267, - /* 1760 */ 267, 246, 100, 246, 245, 271, 271, 293, 106, 107, - /* 1770 */ 220, 271, 229, 225, 249, 219, 114, 259, 116, 117, - /* 1780 */ 118, 133, 259, 121, 219, 219, 138, 139, 153, 154, - /* 1790 */ 155, 156, 157, 280, 249, 243, 19, 20, 245, 22, - /* 1800 */ 196, 259, 140, 259, 60, 297, 141, 297, 200, 200, - /* 1810 */ 162, 38, 200, 36, 294, 153, 154, 155, 156, 157, - /* 1820 */ 151, 150, 294, 283, 22, 43, 234, 18, 237, 200, - /* 1830 */ 270, 272, 237, 237, 237, 18, 59, 199, 270, 149, - /* 1840 */ 246, 272, 272, 200, 234, 234, 246, 246, 71, 246, - /* 1850 */ 199, 158, 290, 62, 22, 200, 19, 20, 199, 22, - /* 1860 */ 289, 221, 221, 200, 200, 199, 199, 115, 218, 64, - /* 1870 */ 218, 218, 22, 36, 227, 126, 227, 100, 165, 221, - /* 1880 */ 224, 224, 24, 106, 107, 312, 218, 305, 113, 282, - /* 1890 */ 91, 114, 220, 116, 117, 118, 59, 282, 121, 218, - /* 1900 */ 218, 218, 200, 317, 317, 82, 221, 265, 71, 148, - /* 1910 */ 145, 265, 22, 277, 200, 158, 279, 140, 147, 25, - /* 1920 */ 146, 202, 248, 250, 249, 247, 13, 250, 194, 194, - /* 1930 */ 153, 154, 155, 156, 157, 6, 303, 100, 192, 192, - /* 1940 */ 246, 213, 192, 106, 107, 207, 213, 207, 222, 213, - /* 1950 */ 213, 114, 222, 116, 117, 118, 214, 214, 121, 4, - /* 1960 */ 207, 213, 3, 22, 303, 15, 163, 16, 23, 23, - /* 1970 */ 139, 151, 130, 25, 20, 142, 24, 16, 144, 1, - /* 1980 */ 142, 130, 130, 61, 37, 53, 300, 151, 53, 53, - /* 1990 */ 153, 154, 155, 156, 157, 53, 130, 116, 34, 1, - /* 2000 */ 141, 5, 22, 115, 161, 68, 25, 68, 75, 41, - /* 2010 */ 141, 115, 24, 20, 19, 131, 125, 23, 28, 22, - /* 2020 */ 67, 22, 22, 22, 67, 59, 24, 96, 22, 67, - /* 2030 */ 23, 149, 22, 25, 23, 23, 23, 22, 34, 141, - /* 2040 */ 37, 97, 23, 23, 116, 22, 143, 25, 34, 75, - /* 2050 */ 34, 34, 34, 88, 75, 34, 86, 23, 22, 34, - /* 2060 */ 93, 24, 34, 25, 25, 142, 142, 23, 44, 23, - /* 2070 */ 23, 23, 23, 11, 23, 25, 22, 22, 22, 141, - /* 2080 */ 23, 23, 22, 22, 25, 15, 1, 23, 25, 1, - /* 2090 */ 141, 135, 319, 319, 319, 319, 319, 319, 319, 141, - /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2130 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2140 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2150 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2160 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2170 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2180 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2190 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2250 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2260 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2270 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2280 */ 319, 319, 319, 319, 319, + /* 0 */ 195, 195, 195, 215, 195, 276, 277, 278, 187, 188, + /* 10 */ 189, 190, 191, 192, 276, 277, 278, 208, 197, 19, + /* 20 */ 199, 189, 190, 191, 192, 218, 219, 206, 217, 197, + /* 30 */ 195, 199, 32, 206, 195, 297, 225, 218, 206, 230, + /* 40 */ 40, 232, 207, 195, 206, 240, 46, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + /* 60 */ 60, 195, 241, 242, 276, 277, 278, 218, 241, 242, + /* 70 */ 195, 195, 221, 241, 242, 254, 270, 195, 195, 241, + /* 80 */ 242, 254, 206, 208, 218, 219, 254, 195, 240, 268, + /* 90 */ 218, 221, 254, 195, 218, 219, 258, 259, 271, 233, + /* 100 */ 268, 218, 219, 298, 265, 105, 106, 107, 108, 109, + /* 110 */ 110, 111, 112, 113, 114, 115, 116, 241, 242, 303, + /* 120 */ 304, 300, 22, 316, 317, 19, 195, 276, 277, 278, + /* 130 */ 254, 255, 300, 105, 106, 107, 108, 109, 110, 111, + /* 140 */ 112, 113, 114, 115, 116, 19, 276, 277, 278, 218, + /* 150 */ 219, 25, 46, 47, 48, 49, 50, 51, 52, 53, + /* 160 */ 54, 55, 56, 57, 58, 59, 60, 285, 49, 50, + /* 170 */ 51, 52, 46, 47, 48, 49, 50, 51, 52, 53, + /* 180 */ 54, 55, 56, 57, 58, 59, 60, 111, 112, 113, + /* 190 */ 114, 115, 116, 195, 195, 89, 19, 91, 72, 316, + /* 200 */ 116, 318, 310, 311, 205, 62, 207, 315, 195, 109, + /* 210 */ 110, 105, 106, 107, 108, 109, 110, 111, 112, 113, + /* 220 */ 114, 115, 116, 109, 110, 111, 112, 113, 114, 115, + /* 230 */ 116, 105, 106, 107, 108, 109, 110, 111, 112, 113, + /* 240 */ 114, 115, 116, 124, 131, 132, 195, 316, 317, 109, + /* 250 */ 110, 19, 109, 110, 195, 57, 58, 59, 60, 61, + /* 260 */ 79, 118, 119, 120, 121, 195, 123, 76, 270, 218, + /* 270 */ 219, 90, 232, 92, 131, 84, 95, 84, 46, 47, + /* 280 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 290 */ 58, 59, 60, 26, 27, 118, 119, 157, 158, 240, + /* 300 */ 157, 158, 70, 105, 106, 107, 108, 109, 110, 111, + /* 310 */ 112, 113, 114, 115, 116, 195, 123, 57, 58, 59, + /* 320 */ 60, 130, 19, 310, 311, 148, 76, 24, 315, 62, + /* 330 */ 149, 280, 195, 142, 143, 142, 143, 105, 106, 107, + /* 340 */ 108, 109, 110, 111, 112, 113, 114, 115, 116, 46, + /* 350 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 360 */ 57, 58, 59, 60, 19, 105, 106, 107, 108, 109, + /* 370 */ 110, 111, 112, 113, 114, 115, 116, 25, 308, 309, + /* 380 */ 130, 131, 132, 195, 264, 25, 119, 120, 121, 195, + /* 390 */ 195, 46, 47, 48, 49, 50, 51, 52, 53, 54, + /* 400 */ 55, 56, 57, 58, 59, 60, 218, 219, 105, 106, + /* 410 */ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + /* 420 */ 84, 233, 195, 122, 120, 195, 125, 126, 127, 62, + /* 430 */ 225, 79, 227, 168, 169, 19, 135, 62, 243, 23, + /* 440 */ 235, 137, 75, 22, 92, 218, 219, 95, 218, 219, + /* 450 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 460 */ 115, 116, 46, 47, 48, 49, 50, 51, 52, 53, + /* 470 */ 54, 55, 56, 57, 58, 59, 60, 19, 142, 143, + /* 480 */ 62, 23, 190, 62, 192, 255, 119, 120, 121, 197, + /* 490 */ 195, 199, 195, 263, 119, 120, 121, 195, 206, 154, + /* 500 */ 306, 306, 142, 143, 46, 47, 48, 49, 50, 51, + /* 510 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 237, + /* 520 */ 238, 105, 106, 107, 108, 109, 110, 111, 112, 113, + /* 530 */ 114, 115, 116, 241, 242, 195, 234, 119, 120, 121, + /* 540 */ 122, 120, 195, 125, 126, 127, 254, 271, 19, 62, + /* 550 */ 203, 195, 23, 135, 62, 208, 22, 195, 218, 219, + /* 560 */ 268, 264, 75, 105, 106, 107, 108, 109, 110, 111, + /* 570 */ 112, 113, 114, 115, 116, 46, 47, 48, 49, 50, + /* 580 */ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + /* 590 */ 19, 195, 300, 228, 23, 255, 62, 195, 195, 243, + /* 600 */ 212, 213, 214, 263, 309, 243, 119, 120, 121, 195, + /* 610 */ 208, 119, 120, 121, 218, 219, 36, 46, 47, 48, + /* 620 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 630 */ 59, 60, 218, 219, 105, 106, 107, 108, 109, 110, + /* 640 */ 111, 112, 113, 114, 115, 116, 243, 155, 195, 69, + /* 650 */ 195, 255, 195, 119, 120, 121, 11, 77, 251, 263, + /* 660 */ 253, 19, 306, 237, 238, 23, 22, 195, 306, 62, + /* 670 */ 22, 218, 219, 275, 22, 19, 105, 106, 107, 108, + /* 680 */ 109, 110, 111, 112, 113, 114, 115, 116, 46, 47, + /* 690 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 700 */ 58, 59, 60, 19, 241, 242, 62, 23, 255, 306, + /* 710 */ 62, 313, 314, 133, 62, 311, 195, 254, 111, 315, + /* 720 */ 22, 264, 195, 212, 213, 214, 119, 120, 121, 208, + /* 730 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + /* 740 */ 56, 57, 58, 59, 60, 218, 219, 105, 106, 107, + /* 750 */ 108, 109, 110, 111, 112, 113, 114, 115, 116, 215, + /* 760 */ 62, 195, 62, 119, 120, 121, 294, 119, 120, 121, + /* 770 */ 79, 119, 120, 121, 19, 119, 131, 132, 23, 130, + /* 780 */ 131, 132, 255, 92, 218, 219, 95, 195, 206, 105, + /* 790 */ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + /* 800 */ 116, 46, 47, 48, 49, 50, 51, 52, 53, 54, + /* 810 */ 55, 56, 57, 58, 59, 60, 19, 119, 120, 121, + /* 820 */ 120, 255, 195, 241, 242, 241, 242, 195, 114, 115, + /* 830 */ 116, 138, 288, 140, 141, 195, 254, 293, 254, 261, + /* 840 */ 262, 206, 195, 46, 47, 48, 49, 50, 51, 52, + /* 850 */ 53, 54, 55, 56, 57, 58, 59, 60, 218, 219, + /* 860 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 870 */ 115, 116, 62, 16, 195, 195, 241, 242, 195, 228, + /* 880 */ 22, 23, 195, 25, 7, 8, 9, 19, 19, 254, + /* 890 */ 130, 131, 132, 24, 16, 255, 213, 214, 218, 219, + /* 900 */ 118, 44, 105, 106, 107, 108, 109, 110, 111, 112, + /* 910 */ 113, 114, 115, 116, 46, 47, 48, 49, 50, 51, + /* 920 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 119, + /* 930 */ 120, 121, 195, 111, 12, 255, 154, 80, 228, 82, + /* 940 */ 195, 22, 23, 195, 25, 21, 195, 22, 23, 270, + /* 950 */ 28, 206, 265, 210, 211, 218, 219, 147, 80, 162, + /* 960 */ 82, 139, 104, 218, 219, 43, 144, 98, 44, 286, + /* 970 */ 233, 19, 275, 105, 106, 107, 108, 109, 110, 111, + /* 980 */ 112, 113, 114, 115, 116, 116, 241, 242, 66, 62, + /* 990 */ 195, 122, 123, 124, 125, 126, 127, 128, 76, 254, + /* 1000 */ 255, 49, 195, 134, 19, 246, 79, 83, 263, 24, + /* 1010 */ 313, 314, 195, 218, 219, 256, 265, 90, 270, 92, + /* 1020 */ 62, 164, 95, 104, 19, 218, 219, 62, 233, 104, + /* 1030 */ 162, 46, 47, 48, 49, 50, 51, 52, 53, 54, + /* 1040 */ 55, 56, 57, 58, 59, 60, 119, 120, 121, 195, + /* 1050 */ 126, 46, 47, 48, 49, 50, 51, 52, 53, 54, + /* 1060 */ 55, 56, 57, 58, 59, 60, 200, 311, 103, 195, + /* 1070 */ 118, 315, 218, 219, 22, 23, 149, 119, 120, 121, + /* 1080 */ 195, 25, 265, 195, 119, 120, 134, 233, 164, 124, + /* 1090 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 1100 */ 115, 116, 137, 195, 206, 147, 195, 22, 195, 24, + /* 1110 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 1120 */ 115, 116, 157, 158, 213, 214, 218, 219, 240, 311, + /* 1130 */ 19, 218, 219, 315, 195, 23, 195, 25, 195, 241, + /* 1140 */ 242, 233, 210, 211, 142, 143, 233, 62, 195, 283, + /* 1150 */ 19, 195, 254, 287, 195, 195, 104, 46, 47, 48, + /* 1160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 1170 */ 59, 60, 195, 69, 218, 219, 195, 121, 47, 48, + /* 1180 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 1190 */ 59, 60, 88, 240, 103, 218, 219, 286, 102, 218, + /* 1200 */ 219, 97, 161, 147, 163, 120, 195, 15, 265, 262, + /* 1210 */ 311, 120, 149, 266, 315, 124, 105, 106, 107, 108, + /* 1220 */ 109, 110, 111, 112, 113, 114, 115, 116, 137, 206, + /* 1230 */ 167, 206, 136, 121, 206, 294, 105, 106, 107, 108, + /* 1240 */ 109, 110, 111, 112, 113, 114, 115, 116, 157, 158, + /* 1250 */ 195, 240, 12, 294, 150, 63, 19, 195, 23, 147, + /* 1260 */ 25, 165, 195, 19, 241, 242, 241, 242, 28, 241, + /* 1270 */ 242, 25, 30, 218, 219, 195, 34, 254, 25, 254, + /* 1280 */ 218, 219, 254, 43, 195, 48, 49, 50, 51, 52, + /* 1290 */ 53, 54, 55, 56, 57, 58, 59, 60, 218, 219, + /* 1300 */ 195, 234, 195, 25, 195, 195, 66, 218, 219, 195, + /* 1310 */ 68, 19, 20, 195, 22, 195, 262, 195, 24, 242, + /* 1320 */ 266, 215, 195, 218, 219, 218, 219, 218, 219, 37, + /* 1330 */ 311, 254, 218, 219, 315, 195, 218, 219, 218, 219, + /* 1340 */ 218, 219, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1350 */ 113, 114, 115, 116, 62, 195, 62, 195, 218, 219, + /* 1360 */ 195, 246, 195, 119, 19, 20, 74, 22, 195, 32, + /* 1370 */ 195, 256, 301, 302, 195, 129, 84, 40, 218, 219, + /* 1380 */ 218, 219, 37, 218, 219, 218, 219, 258, 259, 49, + /* 1390 */ 246, 218, 219, 218, 219, 103, 51, 218, 219, 293, + /* 1400 */ 256, 109, 110, 153, 154, 246, 153, 62, 25, 117, + /* 1410 */ 195, 119, 120, 121, 120, 256, 124, 195, 246, 74, + /* 1420 */ 195, 22, 195, 24, 146, 139, 118, 22, 256, 137, + /* 1430 */ 144, 22, 238, 88, 142, 143, 195, 23, 93, 25, + /* 1440 */ 218, 219, 25, 218, 219, 218, 219, 24, 103, 157, + /* 1450 */ 158, 159, 160, 195, 109, 110, 148, 132, 118, 218, + /* 1460 */ 219, 56, 117, 195, 119, 120, 121, 132, 23, 124, + /* 1470 */ 25, 195, 23, 64, 25, 195, 218, 219, 23, 195, + /* 1480 */ 25, 156, 137, 0, 1, 2, 218, 219, 5, 19, + /* 1490 */ 20, 156, 22, 10, 11, 12, 13, 14, 218, 219, + /* 1500 */ 17, 19, 157, 158, 159, 160, 195, 37, 195, 23, + /* 1510 */ 195, 25, 195, 195, 31, 23, 33, 25, 23, 195, + /* 1520 */ 25, 23, 195, 25, 41, 195, 22, 62, 195, 146, + /* 1530 */ 260, 195, 62, 218, 219, 62, 218, 219, 195, 123, + /* 1540 */ 124, 195, 218, 219, 74, 218, 219, 195, 218, 219, + /* 1550 */ 195, 218, 219, 195, 218, 219, 73, 195, 88, 7, + /* 1560 */ 8, 218, 219, 93, 81, 124, 149, 84, 145, 195, + /* 1570 */ 218, 219, 195, 103, 195, 134, 218, 219, 257, 109, + /* 1580 */ 110, 195, 100, 195, 101, 120, 195, 117, 195, 119, + /* 1590 */ 120, 121, 195, 120, 124, 218, 219, 218, 219, 19, + /* 1600 */ 20, 23, 22, 25, 218, 219, 195, 137, 195, 86, + /* 1610 */ 87, 218, 219, 195, 195, 218, 219, 37, 23, 136, + /* 1620 */ 25, 23, 23, 25, 25, 142, 143, 157, 158, 159, + /* 1630 */ 160, 218, 219, 23, 195, 25, 218, 219, 62, 195, + /* 1640 */ 320, 195, 62, 195, 157, 158, 157, 158, 165, 145, + /* 1650 */ 290, 195, 195, 195, 74, 195, 195, 218, 219, 195, + /* 1660 */ 289, 195, 218, 219, 218, 219, 195, 195, 88, 195, + /* 1670 */ 195, 195, 195, 93, 195, 1, 2, 244, 257, 5, + /* 1680 */ 195, 257, 257, 103, 10, 11, 12, 13, 14, 109, + /* 1690 */ 110, 17, 195, 257, 195, 195, 120, 117, 195, 119, + /* 1700 */ 120, 121, 195, 193, 124, 31, 216, 33, 245, 299, + /* 1710 */ 273, 269, 269, 273, 247, 41, 248, 137, 222, 231, + /* 1720 */ 273, 295, 295, 273, 198, 63, 248, 247, 227, 221, + /* 1730 */ 221, 299, 221, 282, 299, 145, 245, 157, 158, 159, + /* 1740 */ 160, 247, 261, 202, 5, 261, 202, 73, 39, 10, + /* 1750 */ 11, 12, 13, 14, 261, 81, 17, 251, 84, 19, + /* 1760 */ 20, 202, 22, 261, 251, 296, 155, 154, 22, 46, + /* 1770 */ 31, 236, 33, 18, 202, 101, 239, 37, 19, 20, + /* 1780 */ 41, 22, 239, 18, 239, 239, 239, 272, 274, 201, + /* 1790 */ 153, 274, 274, 272, 236, 202, 37, 285, 248, 248, + /* 1800 */ 236, 296, 62, 248, 248, 201, 201, 161, 292, 65, + /* 1810 */ 136, 291, 73, 201, 74, 22, 142, 143, 202, 223, + /* 1820 */ 81, 62, 202, 84, 201, 223, 202, 201, 118, 220, + /* 1830 */ 67, 22, 229, 74, 220, 220, 129, 220, 168, 165, + /* 1840 */ 101, 220, 220, 103, 226, 226, 314, 24, 223, 109, + /* 1850 */ 110, 111, 222, 220, 116, 307, 229, 117, 284, 119, + /* 1860 */ 120, 121, 103, 284, 124, 223, 202, 94, 109, 110, + /* 1870 */ 19, 20, 319, 22, 85, 136, 117, 137, 119, 120, + /* 1880 */ 121, 142, 143, 124, 319, 152, 149, 252, 37, 19, + /* 1890 */ 20, 251, 22, 22, 202, 267, 137, 157, 158, 159, + /* 1900 */ 160, 267, 161, 144, 165, 252, 250, 37, 279, 151, + /* 1910 */ 150, 248, 281, 62, 249, 25, 157, 158, 159, 160, + /* 1920 */ 204, 13, 196, 196, 6, 74, 194, 209, 194, 194, + /* 1930 */ 209, 209, 62, 216, 215, 215, 224, 305, 224, 215, + /* 1940 */ 302, 305, 4, 215, 74, 216, 215, 3, 22, 166, + /* 1950 */ 15, 209, 63, 16, 103, 15, 23, 23, 143, 155, + /* 1960 */ 109, 110, 133, 146, 25, 24, 20, 148, 117, 16, + /* 1970 */ 119, 120, 121, 103, 1, 124, 146, 133, 133, 109, + /* 1980 */ 110, 64, 155, 38, 56, 56, 56, 117, 137, 119, + /* 1990 */ 120, 121, 56, 133, 124, 144, 119, 35, 145, 1, + /* 2000 */ 5, 22, 118, 164, 24, 45, 25, 137, 157, 158, + /* 2010 */ 159, 160, 42, 71, 71, 118, 24, 145, 22, 20, + /* 2020 */ 19, 134, 128, 23, 70, 78, 22, 157, 158, 159, + /* 2030 */ 160, 22, 22, 70, 62, 24, 29, 22, 70, 23, + /* 2040 */ 38, 153, 22, 25, 23, 23, 23, 99, 23, 22, + /* 2050 */ 100, 145, 23, 23, 35, 22, 147, 25, 91, 35, + /* 2060 */ 78, 35, 78, 35, 89, 96, 35, 23, 119, 22, + /* 2070 */ 35, 25, 24, 35, 25, 23, 23, 146, 146, 23, + /* 2080 */ 23, 47, 23, 25, 23, 22, 11, 22, 22, 25, + /* 2090 */ 23, 23, 22, 22, 139, 23, 145, 145, 25, 15, + /* 2100 */ 1, 145, 1, 321, 321, 321, 321, 321, 321, 321, + /* 2110 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2120 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2130 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2140 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2150 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2160 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2170 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2180 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2190 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2200 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2210 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2220 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2230 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2240 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2250 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2260 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2270 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + /* 2280 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, }; -#define YY_SHIFT_COUNT (578) +#define YY_SHIFT_COUNT (589) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2088) +#define YY_SHIFT_MAX (2101) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 1648, 1477, 1272, 322, 322, 1, 1319, 1478, 1491, 1837, - /* 10 */ 1837, 1837, 471, 0, 0, 214, 1093, 1837, 1837, 1837, - /* 20 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 30 */ 1837, 271, 271, 1219, 1219, 216, 88, 1, 1, 1, - /* 40 */ 1, 1, 40, 111, 258, 361, 469, 512, 583, 622, - /* 50 */ 693, 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, - /* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, - /* 70 */ 1093, 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, - /* 80 */ 1662, 1777, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 90 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 100 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 110 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 120 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 130 */ 1837, 137, 181, 181, 181, 181, 181, 181, 181, 94, - /* 140 */ 430, 66, 65, 112, 366, 533, 533, 740, 1257, 533, - /* 150 */ 533, 79, 79, 533, 412, 412, 412, 77, 412, 123, - /* 160 */ 113, 113, 113, 22, 22, 2100, 2100, 328, 328, 328, - /* 170 */ 239, 468, 468, 468, 468, 1015, 1015, 409, 366, 1187, - /* 180 */ 1232, 533, 533, 533, 533, 533, 533, 533, 533, 533, - /* 190 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, - /* 200 */ 533, 969, 621, 621, 533, 642, 788, 788, 1133, 1133, - /* 210 */ 822, 822, 67, 1193, 2100, 2100, 2100, 2100, 2100, 2100, - /* 220 */ 2100, 1307, 954, 954, 585, 472, 640, 387, 695, 538, - /* 230 */ 541, 700, 533, 533, 533, 533, 533, 533, 533, 533, - /* 240 */ 533, 533, 222, 533, 533, 533, 533, 533, 533, 533, - /* 250 */ 533, 533, 533, 533, 533, 1213, 1213, 1213, 533, 533, - /* 260 */ 533, 565, 533, 533, 533, 916, 1147, 533, 533, 1288, - /* 270 */ 533, 533, 533, 533, 533, 533, 533, 533, 639, 1280, - /* 280 */ 209, 1129, 1129, 1129, 1129, 580, 209, 209, 1209, 768, - /* 290 */ 917, 649, 1315, 1334, 405, 1334, 1383, 249, 1315, 1315, - /* 300 */ 249, 1315, 405, 1383, 1441, 464, 1245, 1417, 1417, 1417, - /* 310 */ 1323, 1323, 1323, 1323, 184, 184, 1335, 1476, 856, 1482, - /* 320 */ 1744, 1744, 1665, 1665, 1773, 1773, 1665, 1669, 1671, 1802, - /* 330 */ 1782, 1809, 1809, 1809, 1809, 1665, 1817, 1690, 1671, 1671, - /* 340 */ 1690, 1802, 1782, 1690, 1782, 1690, 1665, 1817, 1693, 1791, - /* 350 */ 1665, 1817, 1832, 1665, 1817, 1665, 1817, 1832, 1752, 1752, - /* 360 */ 1752, 1805, 1850, 1850, 1832, 1752, 1749, 1752, 1805, 1752, - /* 370 */ 1752, 1713, 1858, 1775, 1775, 1832, 1665, 1799, 1799, 1823, - /* 380 */ 1823, 1761, 1765, 1890, 1665, 1757, 1761, 1771, 1774, 1690, - /* 390 */ 1894, 1913, 1913, 1929, 1929, 1929, 2100, 2100, 2100, 2100, - /* 400 */ 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, - /* 410 */ 2100, 207, 1220, 331, 620, 967, 806, 1074, 1499, 1432, - /* 420 */ 1463, 1479, 1419, 1422, 1557, 1512, 1598, 1599, 1644, 1645, - /* 430 */ 1654, 1660, 1555, 1505, 1684, 1462, 1670, 1563, 1619, 1593, - /* 440 */ 1676, 1679, 1613, 1680, 1554, 1558, 1689, 1692, 1605, 1589, - /* 450 */ 1955, 1959, 1941, 1803, 1950, 1951, 1945, 1946, 1831, 1820, - /* 460 */ 1842, 1948, 1948, 1952, 1833, 1954, 1834, 1961, 1978, 1838, - /* 470 */ 1851, 1948, 1852, 1922, 1947, 1948, 1836, 1932, 1935, 1936, - /* 480 */ 1942, 1866, 1881, 1964, 1859, 1998, 1996, 1980, 1888, 1843, - /* 490 */ 1937, 1981, 1939, 1933, 1968, 1869, 1896, 1988, 1993, 1995, - /* 500 */ 1884, 1891, 1997, 1953, 1999, 2000, 1994, 2001, 1957, 1966, - /* 510 */ 2002, 1931, 1990, 2006, 1962, 2003, 2007, 2004, 1882, 2010, - /* 520 */ 2011, 2012, 2008, 2013, 2015, 1944, 1898, 2019, 2020, 1928, - /* 530 */ 2014, 2023, 1903, 2022, 2016, 2017, 2018, 2021, 1965, 1974, - /* 540 */ 1970, 2024, 1979, 1967, 2025, 2034, 2036, 2037, 2038, 2039, - /* 550 */ 2028, 1923, 1924, 2044, 2022, 2046, 2047, 2048, 2049, 2050, - /* 560 */ 2051, 2054, 2062, 2055, 2056, 2057, 2058, 2060, 2061, 2059, - /* 570 */ 1956, 1938, 1949, 1958, 2063, 2064, 2070, 2085, 2088, + /* 0 */ 1674, 1483, 1739, 1292, 1292, 336, 1345, 1470, 1580, 1870, + /* 10 */ 1870, 1870, 191, 0, 0, 232, 1005, 1870, 1870, 1870, + /* 20 */ 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, + /* 30 */ 143, 143, 927, 927, 418, 193, 336, 336, 336, 336, + /* 40 */ 336, 106, 126, 303, 345, 416, 458, 529, 571, 642, + /* 50 */ 684, 755, 797, 868, 985, 1005, 1005, 1005, 1005, 1005, + /* 60 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, + /* 70 */ 1005, 1005, 1005, 1111, 1005, 1131, 1237, 1237, 1740, 1759, + /* 80 */ 1851, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, + /* 90 */ 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, + /* 100 */ 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, + /* 110 */ 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, + /* 120 */ 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, + /* 130 */ 198, 260, 260, 260, 260, 260, 260, 260, 28, 114, + /* 140 */ 76, 267, 367, 924, 487, 375, 375, 952, 375, 375, + /* 150 */ 140, 140, 375, 360, 360, 360, 714, 360, 113, 265, + /* 160 */ 265, 84, 84, 2103, 2103, 869, 869, 869, 869, 267, + /* 170 */ 492, 534, 534, 534, 534, 922, 922, 181, 858, 919, + /* 180 */ 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + /* 190 */ 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + /* 200 */ 375, 375, 177, 352, 352, 375, 645, 691, 691, 656, + /* 210 */ 656, 700, 700, 1063, 1002, 2103, 2103, 2103, 2103, 2103, + /* 220 */ 2103, 2103, 965, 1091, 1091, 644, 301, 648, 607, 652, + /* 230 */ 810, 958, 698, 375, 375, 375, 375, 375, 375, 375, + /* 240 */ 375, 375, 375, 250, 375, 375, 375, 375, 375, 375, + /* 250 */ 375, 375, 375, 375, 375, 375, 375, 375, 375, 580, + /* 260 */ 580, 580, 375, 375, 375, 1112, 375, 375, 375, 1085, + /* 270 */ 1104, 375, 375, 1240, 375, 375, 375, 375, 375, 375, + /* 280 */ 375, 375, 375, 649, 1242, 693, 1294, 1294, 1294, 1294, + /* 290 */ 1056, 693, 693, 822, 100, 877, 1192, 782, 1250, 1278, + /* 300 */ 1250, 1244, 1253, 782, 782, 1253, 782, 1278, 1244, 1246, + /* 310 */ 1235, 1340, 1337, 1337, 1337, 1308, 1308, 1308, 1308, 1417, + /* 320 */ 1417, 1041, 1383, 1286, 1399, 1662, 1662, 1590, 1590, 1709, + /* 330 */ 1709, 1590, 1611, 1613, 1746, 1723, 1755, 1755, 1755, 1755, + /* 340 */ 1755, 1590, 1765, 1637, 1613, 1613, 1637, 1746, 1723, 1637, + /* 350 */ 1723, 1637, 1590, 1765, 1765, 1646, 1744, 1590, 1765, 1793, + /* 360 */ 1590, 1765, 1590, 1765, 1793, 1710, 1710, 1710, 1763, 1809, + /* 370 */ 1809, 1793, 1710, 1707, 1710, 1763, 1710, 1710, 1670, 1823, + /* 380 */ 1738, 1738, 1793, 1590, 1773, 1773, 1789, 1789, 1733, 1737, + /* 390 */ 1871, 1590, 1741, 1733, 1758, 1760, 1637, 1890, 1908, 1908, + /* 400 */ 1918, 1918, 1918, 2103, 2103, 2103, 2103, 2103, 2103, 2103, + /* 410 */ 2103, 2103, 2103, 2103, 2103, 2103, 2103, 2103, 2103, 857, + /* 420 */ 119, 925, 1052, 1096, 878, 760, 421, 1414, 1405, 1423, + /* 430 */ 1325, 1335, 1445, 1409, 1449, 1455, 1486, 1492, 304, 1495, + /* 440 */ 1498, 1465, 1416, 1552, 1441, 1482, 1473, 1578, 1595, 1523, + /* 450 */ 1598, 1487, 1489, 1599, 1610, 1576, 1504, 1938, 1944, 1926, + /* 460 */ 1783, 1935, 1889, 1940, 1937, 1933, 1934, 1815, 1804, 1829, + /* 470 */ 1939, 1939, 1941, 1817, 1946, 1819, 1953, 1973, 1830, 1844, + /* 480 */ 1939, 1845, 1917, 1945, 1939, 1827, 1928, 1929, 1930, 1936, + /* 490 */ 1860, 1877, 1962, 1853, 1998, 1995, 1979, 1884, 1839, 1980, + /* 500 */ 1960, 1942, 1981, 1943, 1947, 1970, 1872, 1897, 1992, 1999, + /* 510 */ 2001, 1887, 1894, 1996, 1954, 2004, 2009, 2000, 2010, 1963, + /* 520 */ 1972, 2011, 1948, 2007, 2015, 1968, 2002, 2016, 1888, 2020, + /* 530 */ 2021, 2022, 2023, 2018, 2025, 2027, 1950, 1906, 2029, 2030, + /* 540 */ 1949, 2019, 2033, 1909, 2032, 2024, 2026, 2028, 2031, 1967, + /* 550 */ 1982, 1975, 2034, 1984, 1969, 2035, 2044, 2047, 2048, 2046, + /* 560 */ 2049, 2038, 1931, 1932, 2052, 2032, 2053, 2056, 2057, 2059, + /* 570 */ 2058, 2061, 2063, 2075, 2065, 2066, 2067, 2068, 2070, 2071, + /* 580 */ 2064, 1955, 1951, 1952, 1956, 2073, 2072, 2084, 2099, 2101, }; -#define YY_REDUCE_COUNT (410) +#define YY_REDUCE_COUNT (418) #define YY_REDUCE_MIN (-271) -#define YY_REDUCE_MAX (1753) +#define YY_REDUCE_MAX (1742) static const short yy_reduce_ofst[] = { - /* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187, - /* 10 */ 166, 238, 133, -207, -199, -267, -176, -6, 204, 489, - /* 20 */ 576, 598, -175, 686, 860, 615, 725, 1014, 778, 781, - /* 30 */ 857, 616, 887, 87, 240, -192, 408, 626, 796, 843, - /* 40 */ 854, 1004, -271, -271, -271, -271, -271, -271, -271, -271, + /* 0 */ -179, -168, 292, 745, -124, -162, -193, -117, -69, 230, + /* 10 */ 340, 396, -173, -149, -130, -262, -212, -134, 188, 737, + /* 20 */ 795, 453, 854, 908, 527, 566, 913, 51, 640, 680, + /* 30 */ 683, 911, -108, 13, -191, 582, 635, 898, 1023, 1025, + /* 40 */ 1028, -271, -271, -271, -271, -271, -271, -271, -271, -271, /* 50 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, /* 60 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, - /* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, 80, - /* 80 */ 83, 313, 886, 888, 918, 938, 1021, 1034, 1036, 1141, - /* 90 */ 1159, 1163, 1166, 1168, 1170, 1176, 1178, 1180, 1184, 1196, - /* 100 */ 1198, 1205, 1215, 1225, 1227, 1236, 1252, 1254, 1264, 1303, - /* 110 */ 1309, 1312, 1322, 1325, 1328, 1337, 1340, 1343, 1353, 1371, - /* 120 */ 1373, 1384, 1386, 1411, 1413, 1420, 1424, 1426, 1458, 1470, - /* 130 */ 1473, -271, -271, -271, -271, -271, -271, -271, -271, -271, - /* 140 */ -271, -271, 138, 459, 396, -158, 470, 302, -212, 521, - /* 150 */ 201, -195, -92, 559, 630, 632, 630, -271, 632, 901, - /* 160 */ 63, 407, 670, -271, -271, -271, -271, 161, 161, 161, - /* 170 */ 251, 335, 847, 979, 1097, 537, 588, 618, 628, 688, - /* 180 */ 688, -166, -161, 674, 787, 794, 799, 852, 996, -122, - /* 190 */ 837, -120, 1018, 1035, 415, 1047, 1001, 958, 1082, 400, - /* 200 */ 1099, 779, 1137, 1142, 263, 1083, 1145, 1150, 1041, 1139, - /* 210 */ 965, 1050, 362, 849, 752, 629, 675, 1162, 1173, 1090, - /* 220 */ 1195, -194, 56, 185, -135, 232, 522, 560, 571, 601, - /* 230 */ 617, 669, 683, 711, 850, 893, 1000, 1040, 1049, 1081, - /* 240 */ 1087, 1101, 392, 1114, 1123, 1155, 1161, 1175, 1271, 1293, - /* 250 */ 1299, 1330, 1339, 1342, 1347, 593, 1282, 1286, 1350, 1359, - /* 260 */ 1368, 1314, 1480, 1483, 1507, 1085, 1338, 1526, 1527, 1487, - /* 270 */ 1531, 560, 1532, 1534, 1535, 1538, 1539, 1541, 1448, 1450, - /* 280 */ 1496, 1484, 1485, 1489, 1490, 1314, 1496, 1496, 1504, 1536, - /* 290 */ 1564, 1451, 1486, 1492, 1509, 1493, 1465, 1515, 1494, 1495, - /* 300 */ 1517, 1500, 1519, 1474, 1550, 1543, 1548, 1556, 1565, 1566, - /* 310 */ 1518, 1523, 1542, 1544, 1525, 1545, 1513, 1553, 1552, 1604, - /* 320 */ 1508, 1510, 1608, 1609, 1520, 1528, 1612, 1540, 1559, 1560, - /* 330 */ 1592, 1591, 1595, 1596, 1597, 1629, 1638, 1594, 1569, 1570, - /* 340 */ 1600, 1568, 1610, 1601, 1611, 1603, 1643, 1651, 1562, 1571, - /* 350 */ 1655, 1659, 1640, 1663, 1666, 1664, 1667, 1641, 1650, 1652, - /* 360 */ 1653, 1647, 1656, 1657, 1658, 1668, 1672, 1681, 1649, 1682, - /* 370 */ 1683, 1573, 1582, 1607, 1615, 1685, 1702, 1586, 1587, 1642, - /* 380 */ 1646, 1673, 1675, 1636, 1714, 1637, 1677, 1674, 1678, 1694, - /* 390 */ 1719, 1734, 1735, 1746, 1747, 1750, 1633, 1661, 1686, 1738, - /* 400 */ 1728, 1733, 1736, 1737, 1740, 1726, 1730, 1742, 1743, 1748, - /* 410 */ 1753, + /* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, 227, 414, + /* 80 */ 807, 956, 977, 981, 1055, 1062, 1080, 1089, 1105, 1107, + /* 90 */ 1109, 1114, 1118, 1120, 1122, 1140, 1160, 1162, 1165, 1167, + /* 100 */ 1173, 1175, 1179, 1222, 1225, 1227, 1241, 1258, 1268, 1280, + /* 110 */ 1315, 1318, 1324, 1327, 1330, 1333, 1336, 1343, 1352, 1358, + /* 120 */ 1377, 1379, 1386, 1393, 1397, 1413, 1418, 1439, 1444, 1446, + /* 130 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, + /* 140 */ -271, -1, 195, 866, 356, -195, 362, 205, 403, 70, + /* 150 */ 388, 511, 347, 463, 584, 463, -271, 584, 544, 398, + /* 160 */ 697, -271, -271, -271, -271, -189, -189, -189, -189, -165, + /* 170 */ -118, -194, -2, 679, 748, 282, 426, 404, -184, -184, + /* 180 */ -125, 402, 521, 120, 297, 457, -152, 59, 888, 1011, + /* 190 */ 472, -161, 941, 687, 751, 959, 817, 953, 302, 1067, + /* 200 */ 194, 943, 578, 756, 818, 295, 1106, 899, 1019, 947, + /* 210 */ 1054, 743, 932, 407, 1077, 1071, 759, 1115, 1144, 1159, + /* 220 */ 1129, 1172, -181, -151, -128, -102, 40, 137, 455, 592, + /* 230 */ 627, 632, 647, 874, 885, 960, 1110, 1127, 1215, 1276, + /* 240 */ 1284, 1311, 1313, 276, 1317, 1346, 1355, 1362, 1374, 1388, + /* 250 */ 1391, 1411, 1419, 1448, 1456, 1457, 1458, 1460, 1461, 365, + /* 260 */ 651, 710, 939, 1464, 1466, 1270, 1471, 1472, 1474, 1321, + /* 270 */ 1320, 1475, 1476, 1194, 1477, 455, 1479, 1485, 1497, 1499, + /* 280 */ 1500, 1503, 1507, 1360, 1371, 1433, 1421, 1424, 1425, 1436, + /* 290 */ 1270, 1433, 1433, 1463, 1490, 1510, 1410, 1437, 1442, 1467, + /* 300 */ 1443, 1426, 1468, 1440, 1447, 1478, 1450, 1480, 1427, 1496, + /* 310 */ 1488, 1501, 1508, 1509, 1511, 1481, 1484, 1493, 1502, 1506, + /* 320 */ 1513, 1451, 1494, 1491, 1526, 1432, 1435, 1541, 1544, 1469, + /* 330 */ 1505, 1559, 1512, 1514, 1515, 1535, 1537, 1543, 1545, 1546, + /* 340 */ 1547, 1572, 1588, 1550, 1517, 1518, 1551, 1521, 1558, 1555, + /* 350 */ 1564, 1556, 1593, 1604, 1605, 1516, 1520, 1616, 1612, 1596, + /* 360 */ 1620, 1623, 1624, 1626, 1602, 1609, 1614, 1615, 1603, 1618, + /* 370 */ 1619, 1625, 1617, 1630, 1621, 1627, 1622, 1633, 1532, 1548, + /* 380 */ 1574, 1579, 1642, 1664, 1553, 1565, 1628, 1634, 1635, 1640, + /* 390 */ 1629, 1692, 1631, 1653, 1656, 1665, 1663, 1716, 1726, 1727, + /* 400 */ 1732, 1734, 1735, 1632, 1636, 1638, 1718, 1721, 1719, 1720, + /* 410 */ 1724, 1728, 1722, 1712, 1714, 1717, 1729, 1731, 1742, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1648, 1648, 1648, 1478, 1243, 1354, 1243, 1243, 1243, 1478, - /* 10 */ 1478, 1478, 1243, 1384, 1384, 1531, 1276, 1243, 1243, 1243, - /* 20 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1477, 1243, - /* 30 */ 1243, 1243, 1243, 1564, 1564, 1243, 1243, 1243, 1243, 1243, - /* 40 */ 1243, 1243, 1243, 1393, 1243, 1400, 1243, 1243, 1243, 1243, - /* 50 */ 1243, 1479, 1480, 1243, 1243, 1243, 1530, 1532, 1495, 1407, - /* 60 */ 1406, 1405, 1404, 1513, 1372, 1398, 1391, 1395, 1474, 1475, - /* 70 */ 1473, 1626, 1480, 1479, 1243, 1394, 1442, 1458, 1441, 1243, - /* 80 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 90 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 100 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 110 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 120 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 130 */ 1243, 1450, 1457, 1456, 1455, 1464, 1454, 1451, 1444, 1443, - /* 140 */ 1445, 1446, 1243, 1243, 1267, 1243, 1243, 1264, 1318, 1243, - /* 150 */ 1243, 1243, 1243, 1243, 1550, 1549, 1243, 1447, 1243, 1276, - /* 160 */ 1435, 1434, 1433, 1461, 1448, 1460, 1459, 1538, 1600, 1599, - /* 170 */ 1496, 1243, 1243, 1243, 1243, 1243, 1243, 1564, 1243, 1243, - /* 180 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 190 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 200 */ 1243, 1374, 1564, 1564, 1243, 1276, 1564, 1564, 1375, 1375, - /* 210 */ 1272, 1272, 1378, 1243, 1545, 1345, 1345, 1345, 1345, 1354, - /* 220 */ 1345, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 230 */ 1243, 1243, 1243, 1243, 1243, 1243, 1535, 1533, 1243, 1243, - /* 240 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 250 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 260 */ 1243, 1243, 1243, 1243, 1243, 1350, 1243, 1243, 1243, 1243, - /* 270 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1593, 1243, 1508, - /* 280 */ 1332, 1350, 1350, 1350, 1350, 1352, 1333, 1331, 1344, 1277, - /* 290 */ 1250, 1640, 1410, 1399, 1351, 1399, 1637, 1397, 1410, 1410, - /* 300 */ 1397, 1410, 1351, 1637, 1293, 1615, 1288, 1384, 1384, 1384, - /* 310 */ 1374, 1374, 1374, 1374, 1378, 1378, 1476, 1351, 1344, 1243, - /* 320 */ 1640, 1640, 1360, 1360, 1639, 1639, 1360, 1496, 1623, 1419, - /* 330 */ 1321, 1327, 1327, 1327, 1327, 1360, 1261, 1397, 1623, 1623, - /* 340 */ 1397, 1419, 1321, 1397, 1321, 1397, 1360, 1261, 1512, 1634, - /* 350 */ 1360, 1261, 1486, 1360, 1261, 1360, 1261, 1486, 1319, 1319, - /* 360 */ 1319, 1308, 1243, 1243, 1486, 1319, 1293, 1319, 1308, 1319, - /* 370 */ 1319, 1582, 1243, 1490, 1490, 1486, 1360, 1574, 1574, 1387, - /* 380 */ 1387, 1392, 1378, 1481, 1360, 1243, 1392, 1390, 1388, 1397, - /* 390 */ 1311, 1596, 1596, 1592, 1592, 1592, 1645, 1645, 1545, 1608, - /* 400 */ 1276, 1276, 1276, 1276, 1608, 1295, 1295, 1277, 1277, 1276, - /* 410 */ 1608, 1243, 1243, 1243, 1243, 1243, 1243, 1603, 1243, 1540, - /* 420 */ 1497, 1364, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 430 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1551, 1243, - /* 440 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1424, - /* 450 */ 1243, 1246, 1542, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 460 */ 1243, 1401, 1402, 1365, 1243, 1243, 1243, 1243, 1243, 1243, - /* 470 */ 1243, 1416, 1243, 1243, 1243, 1411, 1243, 1243, 1243, 1243, - /* 480 */ 1243, 1243, 1243, 1243, 1636, 1243, 1243, 1243, 1243, 1243, - /* 490 */ 1243, 1511, 1510, 1243, 1243, 1362, 1243, 1243, 1243, 1243, - /* 500 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1291, - /* 510 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 520 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 530 */ 1243, 1243, 1243, 1389, 1243, 1243, 1243, 1243, 1243, 1243, - /* 540 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1579, 1379, - /* 550 */ 1243, 1243, 1243, 1243, 1627, 1243, 1243, 1243, 1243, 1243, - /* 560 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1619, - /* 570 */ 1335, 1425, 1243, 1428, 1265, 1243, 1255, 1243, 1243, + /* 0 */ 1670, 1670, 1670, 1497, 1260, 1375, 1260, 1260, 1260, 1497, + /* 10 */ 1497, 1497, 1260, 1405, 1405, 1550, 1294, 1260, 1260, 1260, + /* 20 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1496, 1260, 1260, + /* 30 */ 1260, 1260, 1586, 1586, 1260, 1260, 1260, 1260, 1260, 1260, + /* 40 */ 1260, 1260, 1414, 1260, 1421, 1260, 1260, 1260, 1260, 1260, + /* 50 */ 1498, 1499, 1260, 1260, 1260, 1549, 1551, 1514, 1428, 1427, + /* 60 */ 1426, 1425, 1532, 1393, 1419, 1412, 1416, 1493, 1494, 1492, + /* 70 */ 1648, 1499, 1498, 1260, 1415, 1461, 1477, 1460, 1260, 1260, + /* 80 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 90 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 100 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 110 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 120 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 130 */ 1469, 1476, 1475, 1474, 1483, 1473, 1470, 1463, 1462, 1464, + /* 140 */ 1465, 1284, 1260, 1281, 1260, 1260, 1260, 1336, 1260, 1260, + /* 150 */ 1260, 1260, 1260, 1570, 1569, 1260, 1466, 1260, 1294, 1455, + /* 160 */ 1454, 1480, 1467, 1479, 1478, 1557, 1561, 1622, 1621, 1260, + /* 170 */ 1515, 1260, 1260, 1260, 1260, 1260, 1260, 1586, 1260, 1260, + /* 180 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 190 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 200 */ 1260, 1260, 1395, 1586, 1586, 1260, 1294, 1586, 1586, 1396, + /* 210 */ 1396, 1290, 1290, 1399, 1260, 1565, 1366, 1366, 1366, 1366, + /* 220 */ 1375, 1366, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 230 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1554, 1552, 1260, + /* 240 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 250 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 260 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1371, + /* 270 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 280 */ 1260, 1260, 1615, 1260, 1527, 1353, 1371, 1371, 1371, 1371, + /* 290 */ 1373, 1354, 1352, 1365, 1295, 1267, 1662, 1431, 1420, 1372, + /* 300 */ 1420, 1659, 1418, 1431, 1431, 1418, 1431, 1372, 1659, 1311, + /* 310 */ 1637, 1306, 1405, 1405, 1405, 1395, 1395, 1395, 1395, 1399, + /* 320 */ 1399, 1495, 1372, 1365, 1260, 1662, 1662, 1381, 1381, 1661, + /* 330 */ 1661, 1381, 1515, 1645, 1440, 1339, 1345, 1345, 1345, 1345, + /* 340 */ 1345, 1381, 1278, 1418, 1645, 1645, 1418, 1440, 1339, 1418, + /* 350 */ 1339, 1418, 1381, 1278, 1278, 1531, 1656, 1381, 1278, 1505, + /* 360 */ 1381, 1278, 1381, 1278, 1505, 1337, 1337, 1337, 1326, 1260, + /* 370 */ 1260, 1505, 1337, 1311, 1337, 1326, 1337, 1337, 1604, 1260, + /* 380 */ 1509, 1509, 1505, 1381, 1596, 1596, 1408, 1408, 1413, 1399, + /* 390 */ 1500, 1381, 1260, 1413, 1411, 1409, 1418, 1329, 1618, 1618, + /* 400 */ 1614, 1614, 1614, 1667, 1667, 1565, 1630, 1630, 1294, 1294, + /* 410 */ 1294, 1294, 1630, 1313, 1313, 1295, 1295, 1294, 1630, 1260, + /* 420 */ 1260, 1260, 1260, 1559, 1260, 1260, 1625, 1260, 1516, 1385, + /* 430 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 440 */ 1260, 1260, 1260, 1260, 1260, 1571, 1260, 1260, 1260, 1260, + /* 450 */ 1260, 1260, 1260, 1260, 1260, 1260, 1445, 1260, 1263, 1562, + /* 460 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 470 */ 1422, 1423, 1386, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 480 */ 1437, 1260, 1260, 1260, 1432, 1260, 1260, 1260, 1260, 1260, + /* 490 */ 1260, 1260, 1260, 1658, 1260, 1260, 1260, 1260, 1260, 1260, + /* 500 */ 1260, 1260, 1530, 1529, 1260, 1260, 1383, 1260, 1260, 1260, + /* 510 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 520 */ 1309, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 530 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 540 */ 1260, 1260, 1260, 1260, 1410, 1260, 1260, 1260, 1260, 1260, + /* 550 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1601, + /* 560 */ 1400, 1260, 1260, 1260, 1260, 1649, 1260, 1260, 1260, 1260, + /* 570 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, + /* 580 */ 1641, 1356, 1446, 1260, 1449, 1282, 1260, 1272, 1260, 1260, }; /********** End of lemon-generated parsing tables *****************************/ @@ -171607,52 +170415,55 @@ static const YYACTIONTYPE yy_default[] = { static const YYCODETYPE yyFallback[] = { 0, /* $ => nothing */ 0, /* SEMI => nothing */ - 59, /* EXPLAIN => ID */ - 59, /* QUERY => ID */ - 59, /* PLAN => ID */ - 59, /* BEGIN => ID */ + 62, /* EXPLAIN => ID */ + 62, /* QUERY => ID */ + 62, /* PLAN => ID */ + 62, /* BEGIN => ID */ 0, /* TRANSACTION => nothing */ - 59, /* DEFERRED => ID */ - 59, /* IMMEDIATE => ID */ - 59, /* EXCLUSIVE => ID */ + 62, /* DEFERRED => ID */ + 62, /* IMMEDIATE => ID */ + 62, /* EXCLUSIVE => ID */ 0, /* COMMIT => nothing */ - 59, /* END => ID */ - 59, /* ROLLBACK => ID */ - 59, /* SAVEPOINT => ID */ - 59, /* RELEASE => ID */ + 62, /* END => ID */ + 62, /* ROLLBACK => ID */ + 62, /* SAVEPOINT => ID */ + 62, /* RELEASE => ID */ 0, /* TO => nothing */ 0, /* TABLE => nothing */ 0, /* CREATE => nothing */ - 59, /* IF => ID */ + 62, /* IF => ID */ 0, /* NOT => nothing */ 0, /* EXISTS => nothing */ - 59, /* TEMP => ID */ + 62, /* TEMP => ID */ 0, /* LP => nothing */ 0, /* RP => nothing */ 0, /* AS => nothing */ 0, /* COMMA => nothing */ - 59, /* WITHOUT => ID */ - 59, /* ABORT => ID */ - 59, /* ACTION => ID */ - 59, /* AFTER => ID */ - 59, /* ANALYZE => ID */ - 59, /* ASC => ID */ - 59, /* ATTACH => ID */ - 59, /* BEFORE => ID */ - 59, /* BY => ID */ - 59, /* CASCADE => ID */ - 59, /* CAST => ID */ - 59, /* CONFLICT => ID */ - 59, /* DATABASE => ID */ - 59, /* DESC => ID */ - 59, /* DETACH => ID */ - 59, /* EACH => ID */ - 59, /* FAIL => ID */ + 62, /* WITHOUT => ID */ + 62, /* RANDOM => ID */ + 62, /* ABORT => ID */ + 62, /* ACTION => ID */ + 62, /* AFTER => ID */ + 62, /* ANALYZE => ID */ + 62, /* ASC => ID */ + 62, /* ATTACH => ID */ + 62, /* BEFORE => ID */ + 62, /* BY => ID */ + 62, /* CASCADE => ID */ + 62, /* CAST => ID */ + 62, /* CONFLICT => ID */ + 62, /* DATABASE => ID */ + 62, /* DESC => ID */ + 62, /* DETACH => ID */ + 62, /* EACH => ID */ + 62, /* FAIL => ID */ + 62, /* FUNCTION => ID */ + 62, /* LANGUAGE => ID */ 0, /* OR => nothing */ 0, /* AND => nothing */ 0, /* IS => nothing */ - 59, /* MATCH => ID */ - 59, /* LIKE_KW => ID */ + 62, /* MATCH => ID */ + 62, /* LIKE_KW => ID */ 0, /* BETWEEN => nothing */ 0, /* IN => nothing */ 0, /* ISNULL => nothing */ @@ -171665,47 +170476,47 @@ static const YYCODETYPE yyFallback[] = { 0, /* GE => nothing */ 0, /* ESCAPE => nothing */ 0, /* ID => nothing */ - 59, /* COLUMNKW => ID */ - 59, /* DO => ID */ - 59, /* FOR => ID */ - 59, /* IGNORE => ID */ - 59, /* INITIALLY => ID */ - 59, /* INSTEAD => ID */ - 59, /* NO => ID */ - 59, /* KEY => ID */ - 59, /* OF => ID */ - 59, /* OFFSET => ID */ - 59, /* PRAGMA => ID */ - 59, /* RAISE => ID */ - 59, /* RECURSIVE => ID */ - 59, /* REPLACE => ID */ - 59, /* RESTRICT => ID */ - 59, /* ROW => ID */ - 59, /* ROWS => ID */ - 59, /* TRIGGER => ID */ - 59, /* VACUUM => ID */ - 59, /* VIEW => ID */ - 59, /* VIRTUAL => ID */ - 59, /* WITH => ID */ - 59, /* NULLS => ID */ - 59, /* FIRST => ID */ - 59, /* LAST => ID */ - 59, /* CURRENT => ID */ - 59, /* FOLLOWING => ID */ - 59, /* PARTITION => ID */ - 59, /* PRECEDING => ID */ - 59, /* RANGE => ID */ - 59, /* UNBOUNDED => ID */ - 59, /* EXCLUDE => ID */ - 59, /* GROUPS => ID */ - 59, /* OTHERS => ID */ - 59, /* TIES => ID */ - 59, /* GENERATED => ID */ - 59, /* ALWAYS => ID */ - 59, /* MATERIALIZED => ID */ - 59, /* REINDEX => ID */ - 59, /* RENAME => ID */ - 59, /* CTIME_KW => ID */ + 62, /* COLUMNKW => ID */ + 62, /* DO => ID */ + 62, /* FOR => ID */ + 62, /* IGNORE => ID */ + 62, /* INITIALLY => ID */ + 62, /* INSTEAD => ID */ + 62, /* NO => ID */ + 62, /* KEY => ID */ + 62, /* OF => ID */ + 62, /* OFFSET => ID */ + 62, /* PRAGMA => ID */ + 62, /* RAISE => ID */ + 62, /* RECURSIVE => ID */ + 62, /* REPLACE => ID */ + 62, /* RESTRICT => ID */ + 62, /* ROW => ID */ + 62, /* ROWS => ID */ + 62, /* TRIGGER => ID */ + 62, /* VACUUM => ID */ + 62, /* VIEW => ID */ + 62, /* VIRTUAL => ID */ + 62, /* WITH => ID */ + 62, /* NULLS => ID */ + 62, /* FIRST => ID */ + 62, /* LAST => ID */ + 62, /* CURRENT => ID */ + 62, /* FOLLOWING => ID */ + 62, /* PARTITION => ID */ + 62, /* PRECEDING => ID */ + 62, /* RANGE => ID */ + 62, /* UNBOUNDED => ID */ + 62, /* EXCLUDE => ID */ + 62, /* GROUPS => ID */ + 62, /* OTHERS => ID */ + 62, /* TIES => ID */ + 62, /* GENERATED => ID */ + 62, /* ALWAYS => ID */ + 62, /* MATERIALIZED => ID */ + 62, /* REINDEX => ID */ + 62, /* RENAME => ID */ + 62, /* CTIME_KW => ID */ 0, /* ANY => nothing */ 0, /* BITAND => nothing */ 0, /* BITOR => nothing */ @@ -171739,6 +170550,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* DEFERRABLE => nothing */ 0, /* FOREIGN => nothing */ 0, /* DROP => nothing */ + 0, /* BLOB => nothing */ 0, /* UNION => nothing */ 0, /* ALL => nothing */ 0, /* EXCEPT => nothing */ @@ -171759,7 +170571,6 @@ static const YYCODETYPE yyFallback[] = { 0, /* INTO => nothing */ 0, /* NOTHING => nothing */ 0, /* FLOAT => nothing */ - 0, /* BLOB => nothing */ 0, /* INTEGER => nothing */ 0, /* VARIABLE => nothing */ 0, /* CASE => nothing */ @@ -171777,7 +170588,6 @@ static const YYCODETYPE yyFallback[] = { 0, /* AGG_COLUMN => nothing */ 0, /* TRUEFALSE => nothing */ 0, /* ISNOT => nothing */ - 0, /* FUNCTION => nothing */ 0, /* UMINUS => nothing */ 0, /* UPLUS => nothing */ 0, /* TRUTH => nothing */ @@ -171905,298 +170715,300 @@ static const char *const yyTokenName[] = { /* 24 */ "AS", /* 25 */ "COMMA", /* 26 */ "WITHOUT", - /* 27 */ "ABORT", - /* 28 */ "ACTION", - /* 29 */ "AFTER", - /* 30 */ "ANALYZE", - /* 31 */ "ASC", - /* 32 */ "ATTACH", - /* 33 */ "BEFORE", - /* 34 */ "BY", - /* 35 */ "CASCADE", - /* 36 */ "CAST", - /* 37 */ "CONFLICT", - /* 38 */ "DATABASE", - /* 39 */ "DESC", - /* 40 */ "DETACH", - /* 41 */ "EACH", - /* 42 */ "FAIL", - /* 43 */ "OR", - /* 44 */ "AND", - /* 45 */ "IS", - /* 46 */ "MATCH", - /* 47 */ "LIKE_KW", - /* 48 */ "BETWEEN", - /* 49 */ "IN", - /* 50 */ "ISNULL", - /* 51 */ "NOTNULL", - /* 52 */ "NE", - /* 53 */ "EQ", - /* 54 */ "GT", - /* 55 */ "LE", - /* 56 */ "LT", - /* 57 */ "GE", - /* 58 */ "ESCAPE", - /* 59 */ "ID", - /* 60 */ "COLUMNKW", - /* 61 */ "DO", - /* 62 */ "FOR", - /* 63 */ "IGNORE", - /* 64 */ "INITIALLY", - /* 65 */ "INSTEAD", - /* 66 */ "NO", - /* 67 */ "KEY", - /* 68 */ "OF", - /* 69 */ "OFFSET", - /* 70 */ "PRAGMA", - /* 71 */ "RAISE", - /* 72 */ "RECURSIVE", - /* 73 */ "REPLACE", - /* 74 */ "RESTRICT", - /* 75 */ "ROW", - /* 76 */ "ROWS", - /* 77 */ "TRIGGER", - /* 78 */ "VACUUM", - /* 79 */ "VIEW", - /* 80 */ "VIRTUAL", - /* 81 */ "WITH", - /* 82 */ "NULLS", - /* 83 */ "FIRST", - /* 84 */ "LAST", - /* 85 */ "CURRENT", - /* 86 */ "FOLLOWING", - /* 87 */ "PARTITION", - /* 88 */ "PRECEDING", - /* 89 */ "RANGE", - /* 90 */ "UNBOUNDED", - /* 91 */ "EXCLUDE", - /* 92 */ "GROUPS", - /* 93 */ "OTHERS", - /* 94 */ "TIES", - /* 95 */ "GENERATED", - /* 96 */ "ALWAYS", - /* 97 */ "MATERIALIZED", - /* 98 */ "REINDEX", - /* 99 */ "RENAME", - /* 100 */ "CTIME_KW", - /* 101 */ "ANY", - /* 102 */ "BITAND", - /* 103 */ "BITOR", - /* 104 */ "LSHIFT", - /* 105 */ "RSHIFT", - /* 106 */ "PLUS", - /* 107 */ "MINUS", - /* 108 */ "STAR", - /* 109 */ "SLASH", - /* 110 */ "REM", - /* 111 */ "CONCAT", - /* 112 */ "PTR", - /* 113 */ "COLLATE", - /* 114 */ "BITNOT", - /* 115 */ "ON", - /* 116 */ "INDEXED", - /* 117 */ "STRING", - /* 118 */ "JOIN_KW", - /* 119 */ "CONSTRAINT", - /* 120 */ "DEFAULT", - /* 121 */ "NULL", - /* 122 */ "PRIMARY", - /* 123 */ "UNIQUE", - /* 124 */ "CHECK", - /* 125 */ "REFERENCES", - /* 126 */ "AUTOINCR", - /* 127 */ "INSERT", - /* 128 */ "DELETE", - /* 129 */ "UPDATE", - /* 130 */ "SET", - /* 131 */ "DEFERRABLE", - /* 132 */ "FOREIGN", - /* 133 */ "DROP", - /* 134 */ "UNION", - /* 135 */ "ALL", - /* 136 */ "EXCEPT", - /* 137 */ "INTERSECT", - /* 138 */ "SELECT", - /* 139 */ "VALUES", - /* 140 */ "DISTINCT", - /* 141 */ "DOT", - /* 142 */ "FROM", - /* 143 */ "JOIN", - /* 144 */ "USING", - /* 145 */ "ORDER", - /* 146 */ "GROUP", - /* 147 */ "HAVING", - /* 148 */ "LIMIT", - /* 149 */ "WHERE", - /* 150 */ "RETURNING", - /* 151 */ "INTO", - /* 152 */ "NOTHING", - /* 153 */ "FLOAT", - /* 154 */ "BLOB", - /* 155 */ "INTEGER", - /* 156 */ "VARIABLE", - /* 157 */ "CASE", - /* 158 */ "WHEN", - /* 159 */ "THEN", - /* 160 */ "ELSE", - /* 161 */ "INDEX", - /* 162 */ "ALTER", - /* 163 */ "ADD", - /* 164 */ "WINDOW", - /* 165 */ "OVER", - /* 166 */ "FILTER", - /* 167 */ "COLUMN", - /* 168 */ "AGG_FUNCTION", - /* 169 */ "AGG_COLUMN", - /* 170 */ "TRUEFALSE", - /* 171 */ "ISNOT", - /* 172 */ "FUNCTION", - /* 173 */ "UMINUS", - /* 174 */ "UPLUS", - /* 175 */ "TRUTH", - /* 176 */ "REGISTER", - /* 177 */ "VECTOR", - /* 178 */ "SELECT_COLUMN", - /* 179 */ "IF_NULL_ROW", - /* 180 */ "ASTERISK", - /* 181 */ "SPAN", - /* 182 */ "ERROR", - /* 183 */ "SPACE", - /* 184 */ "ILLEGAL", - /* 185 */ "input", - /* 186 */ "cmdlist", - /* 187 */ "ecmd", - /* 188 */ "cmdx", - /* 189 */ "explain", - /* 190 */ "cmd", - /* 191 */ "transtype", - /* 192 */ "trans_opt", - /* 193 */ "nm", - /* 194 */ "savepoint_opt", - /* 195 */ "create_table", - /* 196 */ "create_table_args", - /* 197 */ "createkw", - /* 198 */ "temp", - /* 199 */ "ifnotexists", - /* 200 */ "dbnm", - /* 201 */ "columnlist", - /* 202 */ "conslist_opt", - /* 203 */ "table_option_set", - /* 204 */ "select", - /* 205 */ "table_option", - /* 206 */ "columnname", - /* 207 */ "carglist", - /* 208 */ "typetoken", - /* 209 */ "typename", - /* 210 */ "signed", - /* 211 */ "plus_num", - /* 212 */ "minus_num", - /* 213 */ "scanpt", - /* 214 */ "scantok", - /* 215 */ "ccons", - /* 216 */ "term", - /* 217 */ "expr", - /* 218 */ "onconf", - /* 219 */ "sortorder", - /* 220 */ "autoinc", - /* 221 */ "eidlist_opt", - /* 222 */ "refargs", - /* 223 */ "defer_subclause", - /* 224 */ "generated", - /* 225 */ "refarg", - /* 226 */ "refact", - /* 227 */ "init_deferred_pred_opt", - /* 228 */ "conslist", - /* 229 */ "tconscomma", - /* 230 */ "tcons", - /* 231 */ "sortlist", - /* 232 */ "eidlist", - /* 233 */ "defer_subclause_opt", - /* 234 */ "orconf", - /* 235 */ "resolvetype", - /* 236 */ "raisetype", - /* 237 */ "ifexists", - /* 238 */ "fullname", - /* 239 */ "selectnowith", - /* 240 */ "oneselect", - /* 241 */ "wqlist", - /* 242 */ "multiselect_op", - /* 243 */ "distinct", - /* 244 */ "selcollist", - /* 245 */ "from", - /* 246 */ "where_opt", - /* 247 */ "groupby_opt", - /* 248 */ "having_opt", - /* 249 */ "orderby_opt", - /* 250 */ "limit_opt", - /* 251 */ "window_clause", - /* 252 */ "values", - /* 253 */ "nexprlist", - /* 254 */ "sclp", - /* 255 */ "as", - /* 256 */ "seltablist", - /* 257 */ "stl_prefix", - /* 258 */ "joinop", - /* 259 */ "on_using", - /* 260 */ "indexed_by", - /* 261 */ "exprlist", - /* 262 */ "xfullname", - /* 263 */ "idlist", - /* 264 */ "indexed_opt", - /* 265 */ "nulls", - /* 266 */ "with", - /* 267 */ "where_opt_ret", - /* 268 */ "setlist", - /* 269 */ "insert_cmd", - /* 270 */ "idlist_opt", - /* 271 */ "upsert", - /* 272 */ "returning", - /* 273 */ "filter_over", - /* 274 */ "likeop", - /* 275 */ "between_op", - /* 276 */ "in_op", - /* 277 */ "paren_exprlist", - /* 278 */ "case_operand", - /* 279 */ "case_exprlist", - /* 280 */ "case_else", - /* 281 */ "uniqueflag", - /* 282 */ "collate", - /* 283 */ "vinto", - /* 284 */ "nmnum", - /* 285 */ "trigger_decl", - /* 286 */ "trigger_cmd_list", - /* 287 */ "trigger_time", - /* 288 */ "trigger_event", - /* 289 */ "foreach_clause", - /* 290 */ "when_clause", - /* 291 */ "trigger_cmd", - /* 292 */ "trnm", - /* 293 */ "tridxby", - /* 294 */ "database_kw_opt", - /* 295 */ "key_opt", - /* 296 */ "add_column_fullname", - /* 297 */ "kwcolumn_opt", - /* 298 */ "create_vtab", - /* 299 */ "vtabarglist", - /* 300 */ "vtabarg", - /* 301 */ "vtabargtoken", - /* 302 */ "lp", - /* 303 */ "anylist", - /* 304 */ "wqitem", - /* 305 */ "wqas", - /* 306 */ "windowdefn_list", - /* 307 */ "windowdefn", - /* 308 */ "window", - /* 309 */ "frame_opt", - /* 310 */ "part_opt", - /* 311 */ "filter_clause", - /* 312 */ "over_clause", - /* 313 */ "range_or_rows", - /* 314 */ "frame_bound", - /* 315 */ "frame_bound_s", - /* 316 */ "frame_bound_e", - /* 317 */ "frame_exclude_opt", - /* 318 */ "frame_exclude", + /* 27 */ "RANDOM", + /* 28 */ "ABORT", + /* 29 */ "ACTION", + /* 30 */ "AFTER", + /* 31 */ "ANALYZE", + /* 32 */ "ASC", + /* 33 */ "ATTACH", + /* 34 */ "BEFORE", + /* 35 */ "BY", + /* 36 */ "CASCADE", + /* 37 */ "CAST", + /* 38 */ "CONFLICT", + /* 39 */ "DATABASE", + /* 40 */ "DESC", + /* 41 */ "DETACH", + /* 42 */ "EACH", + /* 43 */ "FAIL", + /* 44 */ "FUNCTION", + /* 45 */ "LANGUAGE", + /* 46 */ "OR", + /* 47 */ "AND", + /* 48 */ "IS", + /* 49 */ "MATCH", + /* 50 */ "LIKE_KW", + /* 51 */ "BETWEEN", + /* 52 */ "IN", + /* 53 */ "ISNULL", + /* 54 */ "NOTNULL", + /* 55 */ "NE", + /* 56 */ "EQ", + /* 57 */ "GT", + /* 58 */ "LE", + /* 59 */ "LT", + /* 60 */ "GE", + /* 61 */ "ESCAPE", + /* 62 */ "ID", + /* 63 */ "COLUMNKW", + /* 64 */ "DO", + /* 65 */ "FOR", + /* 66 */ "IGNORE", + /* 67 */ "INITIALLY", + /* 68 */ "INSTEAD", + /* 69 */ "NO", + /* 70 */ "KEY", + /* 71 */ "OF", + /* 72 */ "OFFSET", + /* 73 */ "PRAGMA", + /* 74 */ "RAISE", + /* 75 */ "RECURSIVE", + /* 76 */ "REPLACE", + /* 77 */ "RESTRICT", + /* 78 */ "ROW", + /* 79 */ "ROWS", + /* 80 */ "TRIGGER", + /* 81 */ "VACUUM", + /* 82 */ "VIEW", + /* 83 */ "VIRTUAL", + /* 84 */ "WITH", + /* 85 */ "NULLS", + /* 86 */ "FIRST", + /* 87 */ "LAST", + /* 88 */ "CURRENT", + /* 89 */ "FOLLOWING", + /* 90 */ "PARTITION", + /* 91 */ "PRECEDING", + /* 92 */ "RANGE", + /* 93 */ "UNBOUNDED", + /* 94 */ "EXCLUDE", + /* 95 */ "GROUPS", + /* 96 */ "OTHERS", + /* 97 */ "TIES", + /* 98 */ "GENERATED", + /* 99 */ "ALWAYS", + /* 100 */ "MATERIALIZED", + /* 101 */ "REINDEX", + /* 102 */ "RENAME", + /* 103 */ "CTIME_KW", + /* 104 */ "ANY", + /* 105 */ "BITAND", + /* 106 */ "BITOR", + /* 107 */ "LSHIFT", + /* 108 */ "RSHIFT", + /* 109 */ "PLUS", + /* 110 */ "MINUS", + /* 111 */ "STAR", + /* 112 */ "SLASH", + /* 113 */ "REM", + /* 114 */ "CONCAT", + /* 115 */ "PTR", + /* 116 */ "COLLATE", + /* 117 */ "BITNOT", + /* 118 */ "ON", + /* 119 */ "INDEXED", + /* 120 */ "STRING", + /* 121 */ "JOIN_KW", + /* 122 */ "CONSTRAINT", + /* 123 */ "DEFAULT", + /* 124 */ "NULL", + /* 125 */ "PRIMARY", + /* 126 */ "UNIQUE", + /* 127 */ "CHECK", + /* 128 */ "REFERENCES", + /* 129 */ "AUTOINCR", + /* 130 */ "INSERT", + /* 131 */ "DELETE", + /* 132 */ "UPDATE", + /* 133 */ "SET", + /* 134 */ "DEFERRABLE", + /* 135 */ "FOREIGN", + /* 136 */ "DROP", + /* 137 */ "BLOB", + /* 138 */ "UNION", + /* 139 */ "ALL", + /* 140 */ "EXCEPT", + /* 141 */ "INTERSECT", + /* 142 */ "SELECT", + /* 143 */ "VALUES", + /* 144 */ "DISTINCT", + /* 145 */ "DOT", + /* 146 */ "FROM", + /* 147 */ "JOIN", + /* 148 */ "USING", + /* 149 */ "ORDER", + /* 150 */ "GROUP", + /* 151 */ "HAVING", + /* 152 */ "LIMIT", + /* 153 */ "WHERE", + /* 154 */ "RETURNING", + /* 155 */ "INTO", + /* 156 */ "NOTHING", + /* 157 */ "FLOAT", + /* 158 */ "INTEGER", + /* 159 */ "VARIABLE", + /* 160 */ "CASE", + /* 161 */ "WHEN", + /* 162 */ "THEN", + /* 163 */ "ELSE", + /* 164 */ "INDEX", + /* 165 */ "ALTER", + /* 166 */ "ADD", + /* 167 */ "WINDOW", + /* 168 */ "OVER", + /* 169 */ "FILTER", + /* 170 */ "COLUMN", + /* 171 */ "AGG_FUNCTION", + /* 172 */ "AGG_COLUMN", + /* 173 */ "TRUEFALSE", + /* 174 */ "ISNOT", + /* 175 */ "UMINUS", + /* 176 */ "UPLUS", + /* 177 */ "TRUTH", + /* 178 */ "REGISTER", + /* 179 */ "VECTOR", + /* 180 */ "SELECT_COLUMN", + /* 181 */ "IF_NULL_ROW", + /* 182 */ "ASTERISK", + /* 183 */ "SPAN", + /* 184 */ "ERROR", + /* 185 */ "SPACE", + /* 186 */ "ILLEGAL", + /* 187 */ "input", + /* 188 */ "cmdlist", + /* 189 */ "ecmd", + /* 190 */ "cmdx", + /* 191 */ "explain", + /* 192 */ "cmd", + /* 193 */ "transtype", + /* 194 */ "trans_opt", + /* 195 */ "nm", + /* 196 */ "savepoint_opt", + /* 197 */ "create_table", + /* 198 */ "create_table_args", + /* 199 */ "createkw", + /* 200 */ "temp", + /* 201 */ "ifnotexists", + /* 202 */ "dbnm", + /* 203 */ "columnlist", + /* 204 */ "conslist_opt", + /* 205 */ "table_option_set", + /* 206 */ "select", + /* 207 */ "table_option", + /* 208 */ "columnname", + /* 209 */ "carglist", + /* 210 */ "typetoken", + /* 211 */ "typename", + /* 212 */ "signed", + /* 213 */ "plus_num", + /* 214 */ "minus_num", + /* 215 */ "scanpt", + /* 216 */ "scantok", + /* 217 */ "ccons", + /* 218 */ "term", + /* 219 */ "expr", + /* 220 */ "onconf", + /* 221 */ "sortorder", + /* 222 */ "autoinc", + /* 223 */ "eidlist_opt", + /* 224 */ "refargs", + /* 225 */ "defer_subclause", + /* 226 */ "generated", + /* 227 */ "refarg", + /* 228 */ "refact", + /* 229 */ "init_deferred_pred_opt", + /* 230 */ "conslist", + /* 231 */ "tconscomma", + /* 232 */ "tcons", + /* 233 */ "sortlist", + /* 234 */ "eidlist", + /* 235 */ "defer_subclause_opt", + /* 236 */ "orconf", + /* 237 */ "resolvetype", + /* 238 */ "raisetype", + /* 239 */ "ifexists", + /* 240 */ "fullname", + /* 241 */ "selectnowith", + /* 242 */ "oneselect", + /* 243 */ "wqlist", + /* 244 */ "multiselect_op", + /* 245 */ "distinct", + /* 246 */ "selcollist", + /* 247 */ "from", + /* 248 */ "where_opt", + /* 249 */ "groupby_opt", + /* 250 */ "having_opt", + /* 251 */ "orderby_opt", + /* 252 */ "limit_opt", + /* 253 */ "window_clause", + /* 254 */ "values", + /* 255 */ "nexprlist", + /* 256 */ "sclp", + /* 257 */ "as", + /* 258 */ "seltablist", + /* 259 */ "stl_prefix", + /* 260 */ "joinop", + /* 261 */ "on_using", + /* 262 */ "indexed_by", + /* 263 */ "exprlist", + /* 264 */ "xfullname", + /* 265 */ "idlist", + /* 266 */ "indexed_opt", + /* 267 */ "nulls", + /* 268 */ "with", + /* 269 */ "where_opt_ret", + /* 270 */ "setlist", + /* 271 */ "insert_cmd", + /* 272 */ "idlist_opt", + /* 273 */ "upsert", + /* 274 */ "returning", + /* 275 */ "filter_over", + /* 276 */ "likeop", + /* 277 */ "between_op", + /* 278 */ "in_op", + /* 279 */ "paren_exprlist", + /* 280 */ "case_operand", + /* 281 */ "case_exprlist", + /* 282 */ "case_else", + /* 283 */ "uniqueflag", + /* 284 */ "collate", + /* 285 */ "vinto", + /* 286 */ "nmnum", + /* 287 */ "trigger_decl", + /* 288 */ "trigger_cmd_list", + /* 289 */ "trigger_time", + /* 290 */ "trigger_event", + /* 291 */ "foreach_clause", + /* 292 */ "when_clause", + /* 293 */ "trigger_cmd", + /* 294 */ "trnm", + /* 295 */ "tridxby", + /* 296 */ "database_kw_opt", + /* 297 */ "key_opt", + /* 298 */ "add_column_fullname", + /* 299 */ "kwcolumn_opt", + /* 300 */ "create_vtab", + /* 301 */ "vtabarglist", + /* 302 */ "vtabarg", + /* 303 */ "vtabargtoken", + /* 304 */ "lp", + /* 305 */ "anylist", + /* 306 */ "wqitem", + /* 307 */ "wqas", + /* 308 */ "windowdefn_list", + /* 309 */ "windowdefn", + /* 310 */ "window", + /* 311 */ "frame_opt", + /* 312 */ "part_opt", + /* 313 */ "filter_clause", + /* 314 */ "over_clause", + /* 315 */ "range_or_rows", + /* 316 */ "frame_bound", + /* 317 */ "frame_bound_s", + /* 318 */ "frame_bound_e", + /* 319 */ "frame_exclude_opt", + /* 320 */ "frame_exclude", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -172228,387 +171040,390 @@ static const char *const yyRuleName[] = { /* 21 */ "table_option_set ::=", /* 22 */ "table_option_set ::= table_option_set COMMA table_option", /* 23 */ "table_option ::= WITHOUT nm", - /* 24 */ "table_option ::= nm", - /* 25 */ "columnname ::= nm typetoken", - /* 26 */ "typetoken ::=", - /* 27 */ "typetoken ::= typename LP signed RP", - /* 28 */ "typetoken ::= typename LP signed COMMA signed RP", - /* 29 */ "typename ::= typename ID|STRING", - /* 30 */ "scanpt ::=", - /* 31 */ "scantok ::=", - /* 32 */ "ccons ::= CONSTRAINT nm", - /* 33 */ "ccons ::= DEFAULT scantok term", - /* 34 */ "ccons ::= DEFAULT LP expr RP", - /* 35 */ "ccons ::= DEFAULT PLUS scantok term", - /* 36 */ "ccons ::= DEFAULT MINUS scantok term", - /* 37 */ "ccons ::= DEFAULT scantok ID|INDEXED", - /* 38 */ "ccons ::= NOT NULL onconf", - /* 39 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", - /* 40 */ "ccons ::= UNIQUE onconf", - /* 41 */ "ccons ::= CHECK LP expr RP", - /* 42 */ "ccons ::= REFERENCES nm eidlist_opt refargs", - /* 43 */ "ccons ::= defer_subclause", - /* 44 */ "ccons ::= COLLATE ID|STRING", - /* 45 */ "generated ::= LP expr RP", - /* 46 */ "generated ::= LP expr RP ID", - /* 47 */ "autoinc ::=", - /* 48 */ "autoinc ::= AUTOINCR", - /* 49 */ "refargs ::=", - /* 50 */ "refargs ::= refargs refarg", - /* 51 */ "refarg ::= MATCH nm", - /* 52 */ "refarg ::= ON INSERT refact", - /* 53 */ "refarg ::= ON DELETE refact", - /* 54 */ "refarg ::= ON UPDATE refact", - /* 55 */ "refact ::= SET NULL", - /* 56 */ "refact ::= SET DEFAULT", - /* 57 */ "refact ::= CASCADE", - /* 58 */ "refact ::= RESTRICT", - /* 59 */ "refact ::= NO ACTION", - /* 60 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", - /* 61 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", - /* 62 */ "init_deferred_pred_opt ::=", - /* 63 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", - /* 64 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", - /* 65 */ "conslist_opt ::=", - /* 66 */ "tconscomma ::= COMMA", - /* 67 */ "tcons ::= CONSTRAINT nm", - /* 68 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf", - /* 69 */ "tcons ::= UNIQUE LP sortlist RP onconf", - /* 70 */ "tcons ::= CHECK LP expr RP onconf", - /* 71 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt", - /* 72 */ "defer_subclause_opt ::=", - /* 73 */ "onconf ::=", - /* 74 */ "onconf ::= ON CONFLICT resolvetype", - /* 75 */ "orconf ::=", - /* 76 */ "orconf ::= OR resolvetype", - /* 77 */ "resolvetype ::= IGNORE", - /* 78 */ "resolvetype ::= REPLACE", - /* 79 */ "cmd ::= DROP TABLE ifexists fullname", - /* 80 */ "ifexists ::= IF EXISTS", - /* 81 */ "ifexists ::=", - /* 82 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select", - /* 83 */ "cmd ::= DROP VIEW ifexists fullname", - /* 84 */ "cmd ::= select", - /* 85 */ "select ::= WITH wqlist selectnowith", - /* 86 */ "select ::= WITH RECURSIVE wqlist selectnowith", - /* 87 */ "select ::= selectnowith", - /* 88 */ "selectnowith ::= selectnowith multiselect_op oneselect", - /* 89 */ "multiselect_op ::= UNION", - /* 90 */ "multiselect_op ::= UNION ALL", - /* 91 */ "multiselect_op ::= EXCEPT|INTERSECT", - /* 92 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", - /* 93 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt", - /* 94 */ "values ::= VALUES LP nexprlist RP", - /* 95 */ "values ::= values COMMA LP nexprlist RP", - /* 96 */ "distinct ::= DISTINCT", - /* 97 */ "distinct ::= ALL", - /* 98 */ "distinct ::=", - /* 99 */ "sclp ::=", - /* 100 */ "selcollist ::= sclp scanpt expr scanpt as", - /* 101 */ "selcollist ::= sclp scanpt STAR", - /* 102 */ "selcollist ::= sclp scanpt nm DOT STAR", - /* 103 */ "as ::= AS nm", - /* 104 */ "as ::=", - /* 105 */ "from ::=", - /* 106 */ "from ::= FROM seltablist", - /* 107 */ "stl_prefix ::= seltablist joinop", - /* 108 */ "stl_prefix ::=", - /* 109 */ "seltablist ::= stl_prefix nm dbnm as on_using", - /* 110 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using", - /* 111 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using", - /* 112 */ "seltablist ::= stl_prefix LP select RP as on_using", - /* 113 */ "seltablist ::= stl_prefix LP seltablist RP as on_using", - /* 114 */ "dbnm ::=", - /* 115 */ "dbnm ::= DOT nm", - /* 116 */ "fullname ::= nm", - /* 117 */ "fullname ::= nm DOT nm", - /* 118 */ "xfullname ::= nm", - /* 119 */ "xfullname ::= nm DOT nm", - /* 120 */ "xfullname ::= nm DOT nm AS nm", - /* 121 */ "xfullname ::= nm AS nm", - /* 122 */ "joinop ::= COMMA|JOIN", - /* 123 */ "joinop ::= JOIN_KW JOIN", - /* 124 */ "joinop ::= JOIN_KW nm JOIN", - /* 125 */ "joinop ::= JOIN_KW nm nm JOIN", - /* 126 */ "on_using ::= ON expr", - /* 127 */ "on_using ::= USING LP idlist RP", - /* 128 */ "on_using ::=", - /* 129 */ "indexed_opt ::=", - /* 130 */ "indexed_by ::= INDEXED BY nm", - /* 131 */ "indexed_by ::= NOT INDEXED", - /* 132 */ "orderby_opt ::=", - /* 133 */ "orderby_opt ::= ORDER BY sortlist", - /* 134 */ "sortlist ::= sortlist COMMA expr sortorder nulls", - /* 135 */ "sortlist ::= expr sortorder nulls", - /* 136 */ "sortorder ::= ASC", - /* 137 */ "sortorder ::= DESC", - /* 138 */ "sortorder ::=", - /* 139 */ "nulls ::= NULLS FIRST", - /* 140 */ "nulls ::= NULLS LAST", - /* 141 */ "nulls ::=", - /* 142 */ "groupby_opt ::=", - /* 143 */ "groupby_opt ::= GROUP BY nexprlist", - /* 144 */ "having_opt ::=", - /* 145 */ "having_opt ::= HAVING expr", - /* 146 */ "limit_opt ::=", - /* 147 */ "limit_opt ::= LIMIT expr", - /* 148 */ "limit_opt ::= LIMIT expr OFFSET expr", - /* 149 */ "limit_opt ::= LIMIT expr COMMA expr", - /* 150 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret", - /* 151 */ "where_opt ::=", - /* 152 */ "where_opt ::= WHERE expr", - /* 153 */ "where_opt_ret ::=", - /* 154 */ "where_opt_ret ::= WHERE expr", - /* 155 */ "where_opt_ret ::= RETURNING selcollist", - /* 156 */ "where_opt_ret ::= WHERE expr RETURNING selcollist", - /* 157 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret", - /* 158 */ "setlist ::= setlist COMMA nm EQ expr", - /* 159 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", - /* 160 */ "setlist ::= nm EQ expr", - /* 161 */ "setlist ::= LP idlist RP EQ expr", - /* 162 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", - /* 163 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning", - /* 164 */ "upsert ::=", - /* 165 */ "upsert ::= RETURNING selcollist", - /* 166 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert", - /* 167 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert", - /* 168 */ "upsert ::= ON CONFLICT DO NOTHING returning", - /* 169 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning", - /* 170 */ "returning ::= RETURNING selcollist", - /* 171 */ "insert_cmd ::= INSERT orconf", - /* 172 */ "insert_cmd ::= REPLACE", - /* 173 */ "idlist_opt ::=", - /* 174 */ "idlist_opt ::= LP idlist RP", - /* 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 distinct exprlist ORDER BY sortlist RP", - /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP", - /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over", - /* 191 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over", - /* 192 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over", - /* 193 */ "term ::= CTIME_KW", - /* 194 */ "expr ::= LP nexprlist COMMA expr RP", - /* 195 */ "expr ::= expr AND expr", - /* 196 */ "expr ::= expr OR expr", - /* 197 */ "expr ::= expr LT|GT|GE|LE expr", - /* 198 */ "expr ::= expr EQ|NE expr", - /* 199 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", - /* 200 */ "expr ::= expr PLUS|MINUS expr", - /* 201 */ "expr ::= expr STAR|SLASH|REM expr", - /* 202 */ "expr ::= expr CONCAT expr", - /* 203 */ "likeop ::= NOT LIKE_KW|MATCH", - /* 204 */ "expr ::= expr likeop expr", - /* 205 */ "expr ::= expr likeop expr ESCAPE expr", - /* 206 */ "expr ::= expr ISNULL|NOTNULL", - /* 207 */ "expr ::= expr NOT NULL", - /* 208 */ "expr ::= expr IS expr", - /* 209 */ "expr ::= expr IS NOT expr", - /* 210 */ "expr ::= expr IS NOT DISTINCT FROM expr", - /* 211 */ "expr ::= expr IS DISTINCT FROM expr", - /* 212 */ "expr ::= NOT expr", - /* 213 */ "expr ::= BITNOT expr", - /* 214 */ "expr ::= PLUS|MINUS expr", - /* 215 */ "expr ::= expr PTR expr", - /* 216 */ "between_op ::= BETWEEN", - /* 217 */ "between_op ::= NOT BETWEEN", - /* 218 */ "expr ::= expr between_op expr AND expr", - /* 219 */ "in_op ::= IN", - /* 220 */ "in_op ::= NOT IN", - /* 221 */ "expr ::= expr in_op LP exprlist RP", - /* 222 */ "expr ::= LP select RP", - /* 223 */ "expr ::= expr in_op LP select RP", - /* 224 */ "expr ::= expr in_op nm dbnm paren_exprlist", - /* 225 */ "expr ::= EXISTS LP select RP", - /* 226 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 227 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 228 */ "case_exprlist ::= WHEN expr THEN expr", - /* 229 */ "case_else ::= ELSE expr", - /* 230 */ "case_else ::=", - /* 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_list COMMA windowdefn", - /* 312 */ "windowdefn ::= nm AS LP window RP", - /* 313 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", - /* 314 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", - /* 315 */ "window ::= ORDER BY sortlist frame_opt", - /* 316 */ "window ::= nm ORDER BY sortlist frame_opt", - /* 317 */ "window ::= nm frame_opt", - /* 318 */ "frame_opt ::=", - /* 319 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", - /* 320 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", - /* 321 */ "range_or_rows ::= RANGE|ROWS|GROUPS", - /* 322 */ "frame_bound_s ::= frame_bound", - /* 323 */ "frame_bound_s ::= UNBOUNDED PRECEDING", - /* 324 */ "frame_bound_e ::= frame_bound", - /* 325 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", - /* 326 */ "frame_bound ::= expr PRECEDING|FOLLOWING", - /* 327 */ "frame_bound ::= CURRENT ROW", - /* 328 */ "frame_exclude_opt ::=", - /* 329 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", - /* 330 */ "frame_exclude ::= NO OTHERS", - /* 331 */ "frame_exclude ::= CURRENT ROW", - /* 332 */ "frame_exclude ::= GROUP|TIES", - /* 333 */ "window_clause ::= WINDOW windowdefn_list", - /* 334 */ "filter_over ::= filter_clause over_clause", - /* 335 */ "filter_over ::= over_clause", - /* 336 */ "filter_over ::= filter_clause", - /* 337 */ "over_clause ::= OVER LP window RP", - /* 338 */ "over_clause ::= OVER nm", - /* 339 */ "filter_clause ::= FILTER LP WHERE expr RP", - /* 340 */ "input ::= cmdlist", - /* 341 */ "cmdlist ::= cmdlist ecmd", - /* 342 */ "cmdlist ::= ecmd", - /* 343 */ "ecmd ::= SEMI", - /* 344 */ "ecmd ::= cmdx SEMI", - /* 345 */ "ecmd ::= explain cmdx SEMI", - /* 346 */ "trans_opt ::=", - /* 347 */ "trans_opt ::= TRANSACTION", - /* 348 */ "trans_opt ::= TRANSACTION nm", - /* 349 */ "savepoint_opt ::= SAVEPOINT", - /* 350 */ "savepoint_opt ::=", - /* 351 */ "cmd ::= create_table create_table_args", - /* 352 */ "table_option_set ::= table_option", - /* 353 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 354 */ "columnlist ::= columnname carglist", - /* 355 */ "nm ::= ID|INDEXED|JOIN_KW", - /* 356 */ "nm ::= STRING", - /* 357 */ "typetoken ::= typename", - /* 358 */ "typename ::= ID|STRING", - /* 359 */ "signed ::= plus_num", - /* 360 */ "signed ::= minus_num", - /* 361 */ "carglist ::= carglist ccons", - /* 362 */ "carglist ::=", - /* 363 */ "ccons ::= NULL onconf", - /* 364 */ "ccons ::= GENERATED ALWAYS AS generated", - /* 365 */ "ccons ::= AS generated", - /* 366 */ "conslist_opt ::= COMMA conslist", - /* 367 */ "conslist ::= conslist tconscomma tcons", - /* 368 */ "conslist ::= tcons", - /* 369 */ "tconscomma ::=", - /* 370 */ "defer_subclause_opt ::= defer_subclause", - /* 371 */ "resolvetype ::= raisetype", - /* 372 */ "selectnowith ::= oneselect", - /* 373 */ "oneselect ::= values", - /* 374 */ "sclp ::= selcollist COMMA", - /* 375 */ "as ::= ID|STRING", - /* 376 */ "indexed_opt ::= indexed_by", - /* 377 */ "returning ::=", - /* 378 */ "expr ::= term", - /* 379 */ "likeop ::= LIKE_KW|MATCH", - /* 380 */ "case_operand ::= expr", - /* 381 */ "exprlist ::= nexprlist", - /* 382 */ "nmnum ::= plus_num", - /* 383 */ "nmnum ::= nm", - /* 384 */ "nmnum ::= ON", - /* 385 */ "nmnum ::= DELETE", - /* 386 */ "nmnum ::= DEFAULT", - /* 387 */ "plus_num ::= INTEGER|FLOAT", - /* 388 */ "foreach_clause ::=", - /* 389 */ "foreach_clause ::= FOR EACH ROW", - /* 390 */ "trnm ::= nm", - /* 391 */ "tridxby ::=", - /* 392 */ "database_kw_opt ::= DATABASE", - /* 393 */ "database_kw_opt ::=", - /* 394 */ "kwcolumn_opt ::=", - /* 395 */ "kwcolumn_opt ::= COLUMNKW", - /* 396 */ "vtabarglist ::= vtabarg", - /* 397 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 398 */ "vtabarg ::= vtabarg vtabargtoken", - /* 399 */ "anylist ::=", - /* 400 */ "anylist ::= anylist LP anylist RP", - /* 401 */ "anylist ::= anylist ANY", - /* 402 */ "with ::=", - /* 403 */ "windowdefn_list ::= windowdefn", - /* 404 */ "window ::= frame_opt", + /* 24 */ "table_option ::= RANDOM nm", + /* 25 */ "table_option ::= nm", + /* 26 */ "columnname ::= nm typetoken", + /* 27 */ "typetoken ::=", + /* 28 */ "typetoken ::= typename LP signed RP", + /* 29 */ "typetoken ::= typename LP signed COMMA signed RP", + /* 30 */ "typename ::= typename ID|STRING", + /* 31 */ "scanpt ::=", + /* 32 */ "scantok ::=", + /* 33 */ "ccons ::= CONSTRAINT nm", + /* 34 */ "ccons ::= DEFAULT scantok term", + /* 35 */ "ccons ::= DEFAULT LP expr RP", + /* 36 */ "ccons ::= DEFAULT PLUS scantok term", + /* 37 */ "ccons ::= DEFAULT MINUS scantok term", + /* 38 */ "ccons ::= DEFAULT scantok ID|INDEXED", + /* 39 */ "ccons ::= NOT NULL onconf", + /* 40 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", + /* 41 */ "ccons ::= UNIQUE onconf", + /* 42 */ "ccons ::= CHECK LP expr RP", + /* 43 */ "ccons ::= REFERENCES nm eidlist_opt refargs", + /* 44 */ "ccons ::= defer_subclause", + /* 45 */ "ccons ::= COLLATE ID|STRING", + /* 46 */ "generated ::= LP expr RP", + /* 47 */ "generated ::= LP expr RP ID", + /* 48 */ "autoinc ::=", + /* 49 */ "autoinc ::= AUTOINCR", + /* 50 */ "refargs ::=", + /* 51 */ "refargs ::= refargs refarg", + /* 52 */ "refarg ::= MATCH nm", + /* 53 */ "refarg ::= ON INSERT refact", + /* 54 */ "refarg ::= ON DELETE refact", + /* 55 */ "refarg ::= ON UPDATE refact", + /* 56 */ "refact ::= SET NULL", + /* 57 */ "refact ::= SET DEFAULT", + /* 58 */ "refact ::= CASCADE", + /* 59 */ "refact ::= RESTRICT", + /* 60 */ "refact ::= NO ACTION", + /* 61 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", + /* 62 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", + /* 63 */ "init_deferred_pred_opt ::=", + /* 64 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", + /* 65 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", + /* 66 */ "conslist_opt ::=", + /* 67 */ "tconscomma ::= COMMA", + /* 68 */ "tcons ::= CONSTRAINT nm", + /* 69 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf", + /* 70 */ "tcons ::= UNIQUE LP sortlist RP onconf", + /* 71 */ "tcons ::= CHECK LP expr RP onconf", + /* 72 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt", + /* 73 */ "defer_subclause_opt ::=", + /* 74 */ "onconf ::=", + /* 75 */ "onconf ::= ON CONFLICT resolvetype", + /* 76 */ "orconf ::=", + /* 77 */ "orconf ::= OR resolvetype", + /* 78 */ "resolvetype ::= IGNORE", + /* 79 */ "resolvetype ::= REPLACE", + /* 80 */ "cmd ::= DROP TABLE ifexists fullname", + /* 81 */ "ifexists ::= IF EXISTS", + /* 82 */ "ifexists ::=", + /* 83 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select", + /* 84 */ "cmd ::= DROP VIEW ifexists fullname", + /* 85 */ "cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS STRING", + /* 86 */ "cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS BLOB", + /* 87 */ "cmd ::= DROP FUNCTION ifexists nm", + /* 88 */ "cmd ::= select", + /* 89 */ "select ::= WITH wqlist selectnowith", + /* 90 */ "select ::= WITH RECURSIVE wqlist selectnowith", + /* 91 */ "select ::= selectnowith", + /* 92 */ "selectnowith ::= selectnowith multiselect_op oneselect", + /* 93 */ "multiselect_op ::= UNION", + /* 94 */ "multiselect_op ::= UNION ALL", + /* 95 */ "multiselect_op ::= EXCEPT|INTERSECT", + /* 96 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", + /* 97 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt", + /* 98 */ "values ::= VALUES LP nexprlist RP", + /* 99 */ "values ::= values COMMA LP nexprlist RP", + /* 100 */ "distinct ::= DISTINCT", + /* 101 */ "distinct ::= ALL", + /* 102 */ "distinct ::=", + /* 103 */ "sclp ::=", + /* 104 */ "selcollist ::= sclp scanpt expr scanpt as", + /* 105 */ "selcollist ::= sclp scanpt STAR", + /* 106 */ "selcollist ::= sclp scanpt nm DOT STAR", + /* 107 */ "as ::= AS nm", + /* 108 */ "as ::=", + /* 109 */ "from ::=", + /* 110 */ "from ::= FROM seltablist", + /* 111 */ "stl_prefix ::= seltablist joinop", + /* 112 */ "stl_prefix ::=", + /* 113 */ "seltablist ::= stl_prefix nm dbnm as on_using", + /* 114 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using", + /* 115 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using", + /* 116 */ "seltablist ::= stl_prefix LP select RP as on_using", + /* 117 */ "seltablist ::= stl_prefix LP seltablist RP as on_using", + /* 118 */ "dbnm ::=", + /* 119 */ "dbnm ::= DOT nm", + /* 120 */ "fullname ::= nm", + /* 121 */ "fullname ::= nm DOT nm", + /* 122 */ "xfullname ::= nm", + /* 123 */ "xfullname ::= nm DOT nm", + /* 124 */ "xfullname ::= nm DOT nm AS nm", + /* 125 */ "xfullname ::= nm AS nm", + /* 126 */ "joinop ::= COMMA|JOIN", + /* 127 */ "joinop ::= JOIN_KW JOIN", + /* 128 */ "joinop ::= JOIN_KW nm JOIN", + /* 129 */ "joinop ::= JOIN_KW nm nm JOIN", + /* 130 */ "on_using ::= ON expr", + /* 131 */ "on_using ::= USING LP idlist RP", + /* 132 */ "on_using ::=", + /* 133 */ "indexed_opt ::=", + /* 134 */ "indexed_by ::= INDEXED BY nm", + /* 135 */ "indexed_by ::= NOT INDEXED", + /* 136 */ "orderby_opt ::=", + /* 137 */ "orderby_opt ::= ORDER BY sortlist", + /* 138 */ "sortlist ::= sortlist COMMA expr sortorder nulls", + /* 139 */ "sortlist ::= expr sortorder nulls", + /* 140 */ "sortorder ::= ASC", + /* 141 */ "sortorder ::= DESC", + /* 142 */ "sortorder ::=", + /* 143 */ "nulls ::= NULLS FIRST", + /* 144 */ "nulls ::= NULLS LAST", + /* 145 */ "nulls ::=", + /* 146 */ "groupby_opt ::=", + /* 147 */ "groupby_opt ::= GROUP BY nexprlist", + /* 148 */ "having_opt ::=", + /* 149 */ "having_opt ::= HAVING expr", + /* 150 */ "limit_opt ::=", + /* 151 */ "limit_opt ::= LIMIT expr", + /* 152 */ "limit_opt ::= LIMIT expr OFFSET expr", + /* 153 */ "limit_opt ::= LIMIT expr COMMA expr", + /* 154 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret", + /* 155 */ "where_opt ::=", + /* 156 */ "where_opt ::= WHERE expr", + /* 157 */ "where_opt_ret ::=", + /* 158 */ "where_opt_ret ::= WHERE expr", + /* 159 */ "where_opt_ret ::= RETURNING selcollist", + /* 160 */ "where_opt_ret ::= WHERE expr RETURNING selcollist", + /* 161 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret", + /* 162 */ "setlist ::= setlist COMMA nm EQ expr", + /* 163 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", + /* 164 */ "setlist ::= nm EQ expr", + /* 165 */ "setlist ::= LP idlist RP EQ expr", + /* 166 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", + /* 167 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning", + /* 168 */ "upsert ::=", + /* 169 */ "upsert ::= RETURNING selcollist", + /* 170 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert", + /* 171 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert", + /* 172 */ "upsert ::= ON CONFLICT DO NOTHING returning", + /* 173 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning", + /* 174 */ "returning ::= RETURNING selcollist", + /* 175 */ "insert_cmd ::= INSERT orconf", + /* 176 */ "insert_cmd ::= REPLACE", + /* 177 */ "idlist_opt ::=", + /* 178 */ "idlist_opt ::= LP idlist RP", + /* 179 */ "idlist ::= idlist COMMA nm", + /* 180 */ "idlist ::= nm", + /* 181 */ "expr ::= LP expr RP", + /* 182 */ "expr ::= ID|INDEXED|JOIN_KW", + /* 183 */ "expr ::= nm DOT nm", + /* 184 */ "expr ::= nm DOT nm DOT nm", + /* 185 */ "term ::= NULL|FLOAT|BLOB", + /* 186 */ "term ::= STRING", + /* 187 */ "term ::= INTEGER", + /* 188 */ "expr ::= VARIABLE", + /* 189 */ "expr ::= expr COLLATE ID|STRING", + /* 190 */ "expr ::= CAST LP expr AS typetoken RP", + /* 191 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP", + /* 192 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP", + /* 193 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over", + /* 194 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over", + /* 195 */ "term ::= CTIME_KW", + /* 196 */ "expr ::= LP nexprlist COMMA expr RP", + /* 197 */ "expr ::= expr AND expr", + /* 198 */ "expr ::= expr OR expr", + /* 199 */ "expr ::= expr LT|GT|GE|LE expr", + /* 200 */ "expr ::= expr EQ|NE expr", + /* 201 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 202 */ "expr ::= expr PLUS|MINUS expr", + /* 203 */ "expr ::= expr STAR|SLASH|REM expr", + /* 204 */ "expr ::= expr CONCAT expr", + /* 205 */ "likeop ::= NOT LIKE_KW|MATCH", + /* 206 */ "expr ::= expr likeop expr", + /* 207 */ "expr ::= expr likeop expr ESCAPE expr", + /* 208 */ "expr ::= expr ISNULL|NOTNULL", + /* 209 */ "expr ::= expr NOT NULL", + /* 210 */ "expr ::= expr IS expr", + /* 211 */ "expr ::= expr IS NOT expr", + /* 212 */ "expr ::= expr IS NOT DISTINCT FROM expr", + /* 213 */ "expr ::= expr IS DISTINCT FROM expr", + /* 214 */ "expr ::= NOT expr", + /* 215 */ "expr ::= BITNOT expr", + /* 216 */ "expr ::= PLUS|MINUS expr", + /* 217 */ "expr ::= expr PTR expr", + /* 218 */ "between_op ::= BETWEEN", + /* 219 */ "between_op ::= NOT BETWEEN", + /* 220 */ "expr ::= expr between_op expr AND expr", + /* 221 */ "in_op ::= IN", + /* 222 */ "in_op ::= NOT IN", + /* 223 */ "expr ::= expr in_op LP exprlist RP", + /* 224 */ "expr ::= LP select RP", + /* 225 */ "expr ::= expr in_op LP select RP", + /* 226 */ "expr ::= expr in_op nm dbnm paren_exprlist", + /* 227 */ "expr ::= EXISTS LP select RP", + /* 228 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 229 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 230 */ "case_exprlist ::= WHEN expr THEN expr", + /* 231 */ "case_else ::= ELSE expr", + /* 232 */ "case_else ::=", + /* 233 */ "case_operand ::=", + /* 234 */ "exprlist ::=", + /* 235 */ "nexprlist ::= nexprlist COMMA expr", + /* 236 */ "nexprlist ::= expr", + /* 237 */ "paren_exprlist ::=", + /* 238 */ "paren_exprlist ::= LP exprlist RP", + /* 239 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", + /* 240 */ "uniqueflag ::= UNIQUE", + /* 241 */ "uniqueflag ::=", + /* 242 */ "eidlist_opt ::=", + /* 243 */ "eidlist_opt ::= LP eidlist RP", + /* 244 */ "eidlist ::= eidlist COMMA nm collate sortorder", + /* 245 */ "eidlist ::= nm collate sortorder", + /* 246 */ "collate ::=", + /* 247 */ "collate ::= COLLATE ID|STRING", + /* 248 */ "cmd ::= DROP INDEX ifexists fullname", + /* 249 */ "cmd ::= VACUUM vinto", + /* 250 */ "cmd ::= VACUUM nm vinto", + /* 251 */ "vinto ::= INTO expr", + /* 252 */ "vinto ::=", + /* 253 */ "cmd ::= PRAGMA nm dbnm", + /* 254 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 255 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 256 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 257 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 258 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 259 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 260 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 261 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 262 */ "trigger_time ::= BEFORE|AFTER", + /* 263 */ "trigger_time ::= INSTEAD OF", + /* 264 */ "trigger_time ::=", + /* 265 */ "trigger_event ::= DELETE|INSERT", + /* 266 */ "trigger_event ::= UPDATE", + /* 267 */ "trigger_event ::= UPDATE OF idlist", + /* 268 */ "when_clause ::=", + /* 269 */ "when_clause ::= WHEN expr", + /* 270 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 271 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 272 */ "trnm ::= nm DOT nm", + /* 273 */ "tridxby ::= INDEXED BY nm", + /* 274 */ "tridxby ::= NOT INDEXED", + /* 275 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", + /* 276 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", + /* 277 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", + /* 278 */ "trigger_cmd ::= scanpt select scanpt", + /* 279 */ "expr ::= RAISE LP IGNORE RP", + /* 280 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 281 */ "raisetype ::= ROLLBACK", + /* 282 */ "raisetype ::= ABORT", + /* 283 */ "raisetype ::= FAIL", + /* 284 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 285 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 286 */ "cmd ::= DETACH database_kw_opt expr", + /* 287 */ "key_opt ::=", + /* 288 */ "key_opt ::= KEY expr", + /* 289 */ "cmd ::= REINDEX", + /* 290 */ "cmd ::= REINDEX nm dbnm", + /* 291 */ "cmd ::= ANALYZE", + /* 292 */ "cmd ::= ANALYZE nm dbnm", + /* 293 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 294 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 295 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", + /* 296 */ "add_column_fullname ::= fullname", + /* 297 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 298 */ "cmd ::= ALTER TABLE fullname ALTER COLUMNKW columnname TO columnname carglist", + /* 299 */ "cmd ::= create_vtab", + /* 300 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 301 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 302 */ "vtabarg ::=", + /* 303 */ "vtabargtoken ::= ANY", + /* 304 */ "vtabargtoken ::= lp anylist RP", + /* 305 */ "lp ::= LP", + /* 306 */ "with ::= WITH wqlist", + /* 307 */ "with ::= WITH RECURSIVE wqlist", + /* 308 */ "wqas ::= AS", + /* 309 */ "wqas ::= AS MATERIALIZED", + /* 310 */ "wqas ::= AS NOT MATERIALIZED", + /* 311 */ "wqitem ::= nm eidlist_opt wqas LP select RP", + /* 312 */ "wqlist ::= wqitem", + /* 313 */ "wqlist ::= wqlist COMMA wqitem", + /* 314 */ "windowdefn_list ::= windowdefn", + /* 315 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 316 */ "windowdefn ::= nm AS LP window RP", + /* 317 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", + /* 318 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", + /* 319 */ "window ::= ORDER BY sortlist frame_opt", + /* 320 */ "window ::= nm ORDER BY sortlist frame_opt", + /* 321 */ "window ::= frame_opt", + /* 322 */ "window ::= nm frame_opt", + /* 323 */ "frame_opt ::=", + /* 324 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", + /* 325 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", + /* 326 */ "range_or_rows ::= RANGE|ROWS|GROUPS", + /* 327 */ "frame_bound_s ::= frame_bound", + /* 328 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 329 */ "frame_bound_e ::= frame_bound", + /* 330 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 331 */ "frame_bound ::= expr PRECEDING|FOLLOWING", + /* 332 */ "frame_bound ::= CURRENT ROW", + /* 333 */ "frame_exclude_opt ::=", + /* 334 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", + /* 335 */ "frame_exclude ::= NO OTHERS", + /* 336 */ "frame_exclude ::= CURRENT ROW", + /* 337 */ "frame_exclude ::= GROUP|TIES", + /* 338 */ "window_clause ::= WINDOW windowdefn_list", + /* 339 */ "filter_over ::= filter_clause over_clause", + /* 340 */ "filter_over ::= over_clause", + /* 341 */ "filter_over ::= filter_clause", + /* 342 */ "over_clause ::= OVER LP window RP", + /* 343 */ "over_clause ::= OVER nm", + /* 344 */ "filter_clause ::= FILTER LP WHERE expr RP", + /* 345 */ "input ::= cmdlist", + /* 346 */ "cmdlist ::= cmdlist ecmd", + /* 347 */ "cmdlist ::= ecmd", + /* 348 */ "ecmd ::= SEMI", + /* 349 */ "ecmd ::= cmdx SEMI", + /* 350 */ "ecmd ::= explain cmdx SEMI", + /* 351 */ "trans_opt ::=", + /* 352 */ "trans_opt ::= TRANSACTION", + /* 353 */ "trans_opt ::= TRANSACTION nm", + /* 354 */ "savepoint_opt ::= SAVEPOINT", + /* 355 */ "savepoint_opt ::=", + /* 356 */ "cmd ::= create_table create_table_args", + /* 357 */ "table_option_set ::= table_option", + /* 358 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 359 */ "columnlist ::= columnname carglist", + /* 360 */ "nm ::= ID|INDEXED|JOIN_KW", + /* 361 */ "nm ::= STRING", + /* 362 */ "typetoken ::= typename", + /* 363 */ "typename ::= ID|STRING", + /* 364 */ "signed ::= plus_num", + /* 365 */ "signed ::= minus_num", + /* 366 */ "carglist ::= carglist ccons", + /* 367 */ "carglist ::=", + /* 368 */ "ccons ::= NULL onconf", + /* 369 */ "ccons ::= GENERATED ALWAYS AS generated", + /* 370 */ "ccons ::= AS generated", + /* 371 */ "conslist_opt ::= COMMA conslist", + /* 372 */ "conslist ::= conslist tconscomma tcons", + /* 373 */ "conslist ::= tcons", + /* 374 */ "tconscomma ::=", + /* 375 */ "defer_subclause_opt ::= defer_subclause", + /* 376 */ "resolvetype ::= raisetype", + /* 377 */ "selectnowith ::= oneselect", + /* 378 */ "oneselect ::= values", + /* 379 */ "sclp ::= selcollist COMMA", + /* 380 */ "as ::= ID|STRING", + /* 381 */ "indexed_opt ::= indexed_by", + /* 382 */ "returning ::=", + /* 383 */ "expr ::= term", + /* 384 */ "likeop ::= LIKE_KW|MATCH", + /* 385 */ "case_operand ::= expr", + /* 386 */ "exprlist ::= nexprlist", + /* 387 */ "nmnum ::= plus_num", + /* 388 */ "nmnum ::= nm", + /* 389 */ "nmnum ::= ON", + /* 390 */ "nmnum ::= DELETE", + /* 391 */ "nmnum ::= DEFAULT", + /* 392 */ "plus_num ::= INTEGER|FLOAT", + /* 393 */ "foreach_clause ::=", + /* 394 */ "foreach_clause ::= FOR EACH ROW", + /* 395 */ "trnm ::= nm", + /* 396 */ "tridxby ::=", + /* 397 */ "database_kw_opt ::= DATABASE", + /* 398 */ "database_kw_opt ::=", + /* 399 */ "kwcolumn_opt ::=", + /* 400 */ "kwcolumn_opt ::= COLUMNKW", + /* 401 */ "vtabarglist ::= vtabarg", + /* 402 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 403 */ "vtabarg ::= vtabarg vtabargtoken", + /* 404 */ "anylist ::=", + /* 405 */ "anylist ::= anylist LP anylist RP", + /* 406 */ "anylist ::= anylist ANY", + /* 407 */ "with ::=", }; #endif /* NDEBUG */ @@ -172734,97 +171549,97 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 204: /* select */ - case 239: /* selectnowith */ - case 240: /* oneselect */ - case 252: /* values */ + case 206: /* select */ + case 241: /* selectnowith */ + case 242: /* oneselect */ + case 254: /* values */ { -sqlite3SelectDelete(pParse->db, (yypminor->yy47)); -} - break; - case 216: /* term */ - case 217: /* expr */ - case 246: /* where_opt */ - case 248: /* having_opt */ - case 267: /* where_opt_ret */ - case 278: /* case_operand */ - case 280: /* case_else */ - case 283: /* vinto */ - case 290: /* when_clause */ - case 295: /* key_opt */ - case 311: /* filter_clause */ +sqlite3SelectDelete(pParse->db, (yypminor->yy136)); +} + break; + case 218: /* term */ + case 219: /* expr */ + case 248: /* where_opt */ + case 250: /* having_opt */ + case 269: /* where_opt_ret */ + case 280: /* case_operand */ + case 282: /* case_else */ + case 285: /* vinto */ + case 292: /* when_clause */ + case 297: /* key_opt */ + case 313: /* filter_clause */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy528)); -} - break; - case 221: /* eidlist_opt */ - case 231: /* sortlist */ - case 232: /* eidlist */ - case 244: /* selcollist */ - case 247: /* groupby_opt */ - case 249: /* orderby_opt */ - case 253: /* nexprlist */ - case 254: /* sclp */ - case 261: /* exprlist */ - case 268: /* setlist */ - case 277: /* paren_exprlist */ - case 279: /* case_exprlist */ - case 310: /* part_opt */ +sqlite3ExprDelete(pParse->db, (yypminor->yy224)); +} + break; + case 223: /* eidlist_opt */ + case 233: /* sortlist */ + case 234: /* eidlist */ + case 246: /* selcollist */ + case 249: /* groupby_opt */ + case 251: /* orderby_opt */ + case 255: /* nexprlist */ + case 256: /* sclp */ + case 263: /* exprlist */ + case 270: /* setlist */ + case 279: /* paren_exprlist */ + case 281: /* case_exprlist */ + case 312: /* part_opt */ { -sqlite3ExprListDelete(pParse->db, (yypminor->yy322)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy586)); } break; - case 238: /* fullname */ - case 245: /* from */ - case 256: /* seltablist */ - case 257: /* stl_prefix */ - case 262: /* xfullname */ + case 240: /* fullname */ + case 247: /* from */ + case 258: /* seltablist */ + case 259: /* stl_prefix */ + case 264: /* xfullname */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy131)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy493)); } break; - case 241: /* wqlist */ + case 243: /* wqlist */ { -sqlite3WithDelete(pParse->db, (yypminor->yy521)); +sqlite3WithDelete(pParse->db, (yypminor->yy19)); } break; - case 251: /* window_clause */ - case 306: /* windowdefn_list */ + case 253: /* window_clause */ + case 308: /* windowdefn_list */ { -sqlite3WindowListDelete(pParse->db, (yypminor->yy41)); +sqlite3WindowListDelete(pParse->db, (yypminor->yy591)); } break; - case 263: /* idlist */ - case 270: /* idlist_opt */ + case 265: /* idlist */ + case 272: /* idlist_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy254)); +sqlite3IdListDelete(pParse->db, (yypminor->yy600)); } break; - case 273: /* filter_over */ - case 307: /* windowdefn */ - case 308: /* window */ - case 309: /* frame_opt */ - case 312: /* over_clause */ + case 275: /* filter_over */ + case 309: /* windowdefn */ + case 310: /* window */ + case 311: /* frame_opt */ + case 314: /* over_clause */ { -sqlite3WindowDelete(pParse->db, (yypminor->yy41)); +sqlite3WindowDelete(pParse->db, (yypminor->yy591)); } break; - case 286: /* trigger_cmd_list */ - case 291: /* trigger_cmd */ + case 288: /* trigger_cmd_list */ + case 293: /* trigger_cmd */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy33)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy137)); } break; - case 288: /* trigger_event */ + case 290: /* trigger_event */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy180).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy510).b); } break; - case 314: /* frame_bound */ - case 315: /* frame_bound_s */ - case 316: /* frame_bound_e */ + case 316: /* frame_bound */ + case 317: /* frame_bound_s */ + case 318: /* frame_bound_e */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy595).pExpr); +sqlite3ExprDelete(pParse->db, (yypminor->yy537).pExpr); } break; /********* End destructor definitions *****************************************/ @@ -173115,411 +171930,414 @@ static void yy_shift( /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side ** of that rule */ static const YYCODETYPE yyRuleInfoLhs[] = { - 189, /* (0) explain ::= EXPLAIN */ - 189, /* (1) explain ::= EXPLAIN QUERY PLAN */ - 188, /* (2) cmdx ::= cmd */ - 190, /* (3) cmd ::= BEGIN transtype trans_opt */ - 191, /* (4) transtype ::= */ - 191, /* (5) transtype ::= DEFERRED */ - 191, /* (6) transtype ::= IMMEDIATE */ - 191, /* (7) transtype ::= EXCLUSIVE */ - 190, /* (8) cmd ::= COMMIT|END trans_opt */ - 190, /* (9) cmd ::= ROLLBACK trans_opt */ - 190, /* (10) cmd ::= SAVEPOINT nm */ - 190, /* (11) cmd ::= RELEASE savepoint_opt nm */ - 190, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ - 195, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ - 197, /* (14) createkw ::= CREATE */ - 199, /* (15) ifnotexists ::= */ - 199, /* (16) ifnotexists ::= IF NOT EXISTS */ - 198, /* (17) temp ::= TEMP */ - 198, /* (18) temp ::= */ - 196, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ - 196, /* (20) create_table_args ::= AS select */ - 203, /* (21) table_option_set ::= */ - 203, /* (22) table_option_set ::= table_option_set COMMA table_option */ - 205, /* (23) table_option ::= WITHOUT nm */ - 205, /* (24) table_option ::= nm */ - 206, /* (25) columnname ::= nm typetoken */ - 208, /* (26) typetoken ::= */ - 208, /* (27) typetoken ::= typename LP signed RP */ - 208, /* (28) typetoken ::= typename LP signed COMMA signed RP */ - 209, /* (29) typename ::= typename ID|STRING */ - 213, /* (30) scanpt ::= */ - 214, /* (31) scantok ::= */ - 215, /* (32) ccons ::= CONSTRAINT nm */ - 215, /* (33) ccons ::= DEFAULT scantok term */ - 215, /* (34) ccons ::= DEFAULT LP expr RP */ - 215, /* (35) ccons ::= DEFAULT PLUS scantok term */ - 215, /* (36) ccons ::= DEFAULT MINUS scantok term */ - 215, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ - 215, /* (38) ccons ::= NOT NULL onconf */ - 215, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ - 215, /* (40) ccons ::= UNIQUE onconf */ - 215, /* (41) ccons ::= CHECK LP expr RP */ - 215, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ - 215, /* (43) ccons ::= defer_subclause */ - 215, /* (44) ccons ::= COLLATE ID|STRING */ - 224, /* (45) generated ::= LP expr RP */ - 224, /* (46) generated ::= LP expr RP ID */ - 220, /* (47) autoinc ::= */ - 220, /* (48) autoinc ::= AUTOINCR */ - 222, /* (49) refargs ::= */ - 222, /* (50) refargs ::= refargs refarg */ - 225, /* (51) refarg ::= MATCH nm */ - 225, /* (52) refarg ::= ON INSERT refact */ - 225, /* (53) refarg ::= ON DELETE refact */ - 225, /* (54) refarg ::= ON UPDATE refact */ - 226, /* (55) refact ::= SET NULL */ - 226, /* (56) refact ::= SET DEFAULT */ - 226, /* (57) refact ::= CASCADE */ - 226, /* (58) refact ::= RESTRICT */ - 226, /* (59) refact ::= NO ACTION */ - 223, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ - 223, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - 227, /* (62) init_deferred_pred_opt ::= */ - 227, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ - 227, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ - 202, /* (65) conslist_opt ::= */ - 229, /* (66) tconscomma ::= COMMA */ - 230, /* (67) tcons ::= CONSTRAINT nm */ - 230, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ - 230, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ - 230, /* (70) tcons ::= CHECK LP expr RP onconf */ - 230, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ - 233, /* (72) defer_subclause_opt ::= */ - 218, /* (73) onconf ::= */ - 218, /* (74) onconf ::= ON CONFLICT resolvetype */ - 234, /* (75) orconf ::= */ - 234, /* (76) orconf ::= OR resolvetype */ - 235, /* (77) resolvetype ::= IGNORE */ - 235, /* (78) resolvetype ::= REPLACE */ - 190, /* (79) cmd ::= DROP TABLE ifexists fullname */ - 237, /* (80) ifexists ::= IF EXISTS */ - 237, /* (81) ifexists ::= */ - 190, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ - 190, /* (83) cmd ::= DROP VIEW ifexists fullname */ - 190, /* (84) cmd ::= select */ - 204, /* (85) select ::= WITH wqlist selectnowith */ - 204, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ - 204, /* (87) select ::= selectnowith */ - 239, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ - 242, /* (89) multiselect_op ::= UNION */ - 242, /* (90) multiselect_op ::= UNION ALL */ - 242, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ - 240, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ - 240, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ - 252, /* (94) values ::= VALUES LP nexprlist RP */ - 252, /* (95) values ::= values COMMA LP nexprlist RP */ - 243, /* (96) distinct ::= DISTINCT */ - 243, /* (97) distinct ::= ALL */ - 243, /* (98) distinct ::= */ - 254, /* (99) sclp ::= */ - 244, /* (100) selcollist ::= sclp scanpt expr scanpt as */ - 244, /* (101) selcollist ::= sclp scanpt STAR */ - 244, /* (102) selcollist ::= sclp scanpt nm DOT STAR */ - 255, /* (103) as ::= AS nm */ - 255, /* (104) as ::= */ - 245, /* (105) from ::= */ - 245, /* (106) from ::= FROM seltablist */ - 257, /* (107) stl_prefix ::= seltablist joinop */ - 257, /* (108) stl_prefix ::= */ - 256, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */ - 256, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ - 256, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ - 256, /* (112) seltablist ::= stl_prefix LP select RP as on_using */ - 256, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */ - 200, /* (114) dbnm ::= */ - 200, /* (115) dbnm ::= DOT nm */ - 238, /* (116) fullname ::= nm */ - 238, /* (117) fullname ::= nm DOT nm */ - 262, /* (118) xfullname ::= nm */ - 262, /* (119) xfullname ::= nm DOT nm */ - 262, /* (120) xfullname ::= nm DOT nm AS nm */ - 262, /* (121) xfullname ::= nm AS nm */ - 258, /* (122) joinop ::= COMMA|JOIN */ - 258, /* (123) joinop ::= JOIN_KW JOIN */ - 258, /* (124) joinop ::= JOIN_KW nm JOIN */ - 258, /* (125) joinop ::= JOIN_KW nm nm JOIN */ - 259, /* (126) on_using ::= ON expr */ - 259, /* (127) on_using ::= USING LP idlist RP */ - 259, /* (128) on_using ::= */ - 264, /* (129) indexed_opt ::= */ - 260, /* (130) indexed_by ::= INDEXED BY nm */ - 260, /* (131) indexed_by ::= NOT INDEXED */ - 249, /* (132) orderby_opt ::= */ - 249, /* (133) orderby_opt ::= ORDER BY sortlist */ - 231, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ - 231, /* (135) sortlist ::= expr sortorder nulls */ - 219, /* (136) sortorder ::= ASC */ - 219, /* (137) sortorder ::= DESC */ - 219, /* (138) sortorder ::= */ - 265, /* (139) nulls ::= NULLS FIRST */ - 265, /* (140) nulls ::= NULLS LAST */ - 265, /* (141) nulls ::= */ - 247, /* (142) groupby_opt ::= */ - 247, /* (143) groupby_opt ::= GROUP BY nexprlist */ - 248, /* (144) having_opt ::= */ - 248, /* (145) having_opt ::= HAVING expr */ - 250, /* (146) limit_opt ::= */ - 250, /* (147) limit_opt ::= LIMIT expr */ - 250, /* (148) limit_opt ::= LIMIT expr OFFSET expr */ - 250, /* (149) limit_opt ::= LIMIT expr COMMA expr */ - 190, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ - 246, /* (151) where_opt ::= */ - 246, /* (152) where_opt ::= WHERE expr */ - 267, /* (153) where_opt_ret ::= */ - 267, /* (154) where_opt_ret ::= WHERE expr */ - 267, /* (155) where_opt_ret ::= RETURNING selcollist */ - 267, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */ - 190, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ - 268, /* (158) setlist ::= setlist COMMA nm EQ expr */ - 268, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */ - 268, /* (160) setlist ::= nm EQ expr */ - 268, /* (161) setlist ::= LP idlist RP EQ expr */ - 190, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - 190, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ - 271, /* (164) upsert ::= */ - 271, /* (165) upsert ::= RETURNING selcollist */ - 271, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ - 271, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ - 271, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */ - 271, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ - 272, /* (170) returning ::= RETURNING selcollist */ - 269, /* (171) insert_cmd ::= INSERT orconf */ - 269, /* (172) insert_cmd ::= REPLACE */ - 270, /* (173) idlist_opt ::= */ - 270, /* (174) idlist_opt ::= LP idlist RP */ - 263, /* (175) idlist ::= idlist COMMA nm */ - 263, /* (176) idlist ::= nm */ - 217, /* (177) expr ::= LP expr RP */ - 217, /* (178) expr ::= ID|INDEXED|JOIN_KW */ - 217, /* (179) expr ::= nm DOT nm */ - 217, /* (180) expr ::= nm DOT nm DOT nm */ - 216, /* (181) term ::= NULL|FLOAT|BLOB */ - 216, /* (182) term ::= STRING */ - 216, /* (183) term ::= INTEGER */ - 217, /* (184) expr ::= VARIABLE */ - 217, /* (185) expr ::= expr COLLATE ID|STRING */ - 217, /* (186) expr ::= CAST LP expr AS typetoken RP */ - 217, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ - 217, /* (188) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ - 217, /* (189) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ - 217, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ - 217, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ - 217, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ - 216, /* (193) term ::= CTIME_KW */ - 217, /* (194) expr ::= LP nexprlist COMMA expr RP */ - 217, /* (195) expr ::= expr AND expr */ - 217, /* (196) expr ::= expr OR expr */ - 217, /* (197) expr ::= expr LT|GT|GE|LE expr */ - 217, /* (198) expr ::= expr EQ|NE expr */ - 217, /* (199) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - 217, /* (200) expr ::= expr PLUS|MINUS expr */ - 217, /* (201) expr ::= expr STAR|SLASH|REM expr */ - 217, /* (202) expr ::= expr CONCAT expr */ - 274, /* (203) likeop ::= NOT LIKE_KW|MATCH */ - 217, /* (204) expr ::= expr likeop expr */ - 217, /* (205) expr ::= expr likeop expr ESCAPE expr */ - 217, /* (206) expr ::= expr ISNULL|NOTNULL */ - 217, /* (207) expr ::= expr NOT NULL */ - 217, /* (208) expr ::= expr IS expr */ - 217, /* (209) expr ::= expr IS NOT expr */ - 217, /* (210) expr ::= expr IS NOT DISTINCT FROM expr */ - 217, /* (211) expr ::= expr IS DISTINCT FROM expr */ - 217, /* (212) expr ::= NOT expr */ - 217, /* (213) expr ::= BITNOT expr */ - 217, /* (214) expr ::= PLUS|MINUS expr */ - 217, /* (215) expr ::= expr PTR expr */ - 275, /* (216) between_op ::= BETWEEN */ - 275, /* (217) between_op ::= NOT BETWEEN */ - 217, /* (218) expr ::= expr between_op expr AND expr */ - 276, /* (219) in_op ::= IN */ - 276, /* (220) in_op ::= NOT IN */ - 217, /* (221) expr ::= expr in_op LP exprlist RP */ - 217, /* (222) expr ::= LP select RP */ - 217, /* (223) expr ::= expr in_op LP select RP */ - 217, /* (224) expr ::= expr in_op nm dbnm paren_exprlist */ - 217, /* (225) expr ::= EXISTS LP select RP */ - 217, /* (226) expr ::= CASE case_operand case_exprlist case_else END */ - 279, /* (227) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - 279, /* (228) case_exprlist ::= WHEN expr THEN expr */ - 280, /* (229) case_else ::= ELSE expr */ - 280, /* (230) case_else ::= */ - 278, /* (231) case_operand ::= */ - 261, /* (232) exprlist ::= */ - 253, /* (233) nexprlist ::= nexprlist COMMA expr */ - 253, /* (234) nexprlist ::= expr */ - 277, /* (235) paren_exprlist ::= */ - 277, /* (236) paren_exprlist ::= LP exprlist RP */ - 190, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - 281, /* (238) uniqueflag ::= UNIQUE */ - 281, /* (239) uniqueflag ::= */ - 221, /* (240) eidlist_opt ::= */ - 221, /* (241) eidlist_opt ::= LP eidlist RP */ - 232, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */ - 232, /* (243) eidlist ::= nm collate sortorder */ - 282, /* (244) collate ::= */ - 282, /* (245) collate ::= COLLATE ID|STRING */ - 190, /* (246) cmd ::= DROP INDEX ifexists fullname */ - 190, /* (247) cmd ::= VACUUM vinto */ - 190, /* (248) cmd ::= VACUUM nm vinto */ - 283, /* (249) vinto ::= INTO expr */ - 283, /* (250) vinto ::= */ - 190, /* (251) cmd ::= PRAGMA nm dbnm */ - 190, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */ - 190, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - 190, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */ - 190, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - 211, /* (256) plus_num ::= PLUS INTEGER|FLOAT */ - 212, /* (257) minus_num ::= MINUS INTEGER|FLOAT */ - 190, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - 285, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - 287, /* (260) trigger_time ::= BEFORE|AFTER */ - 287, /* (261) trigger_time ::= INSTEAD OF */ - 287, /* (262) trigger_time ::= */ - 288, /* (263) trigger_event ::= DELETE|INSERT */ - 288, /* (264) trigger_event ::= UPDATE */ - 288, /* (265) trigger_event ::= UPDATE OF idlist */ - 290, /* (266) when_clause ::= */ - 290, /* (267) when_clause ::= WHEN expr */ - 286, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - 286, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */ - 292, /* (270) trnm ::= nm DOT nm */ - 293, /* (271) tridxby ::= INDEXED BY nm */ - 293, /* (272) tridxby ::= NOT INDEXED */ - 291, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - 291, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - 291, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - 291, /* (276) trigger_cmd ::= scanpt select scanpt */ - 217, /* (277) expr ::= RAISE LP IGNORE RP */ - 217, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */ - 236, /* (279) raisetype ::= ROLLBACK */ - 236, /* (280) raisetype ::= ABORT */ - 236, /* (281) raisetype ::= FAIL */ - 190, /* (282) cmd ::= DROP TRIGGER ifexists fullname */ - 190, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - 190, /* (284) cmd ::= DETACH database_kw_opt expr */ - 295, /* (285) key_opt ::= */ - 295, /* (286) key_opt ::= KEY expr */ - 190, /* (287) cmd ::= REINDEX */ - 190, /* (288) cmd ::= REINDEX nm dbnm */ - 190, /* (289) cmd ::= ANALYZE */ - 190, /* (290) cmd ::= ANALYZE nm dbnm */ - 190, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */ - 190, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - 190, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - 296, /* (294) add_column_fullname ::= fullname */ - 190, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - 190, /* (296) cmd ::= create_vtab */ - 190, /* (297) cmd ::= create_vtab LP vtabarglist RP */ - 298, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 300, /* (299) vtabarg ::= */ - 301, /* (300) vtabargtoken ::= ANY */ - 301, /* (301) vtabargtoken ::= lp anylist RP */ - 302, /* (302) lp ::= LP */ - 266, /* (303) with ::= WITH wqlist */ - 266, /* (304) with ::= WITH RECURSIVE wqlist */ - 305, /* (305) wqas ::= AS */ - 305, /* (306) wqas ::= AS MATERIALIZED */ - 305, /* (307) wqas ::= AS NOT MATERIALIZED */ - 304, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */ - 241, /* (309) wqlist ::= wqitem */ - 241, /* (310) wqlist ::= wqlist COMMA wqitem */ - 306, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - 307, /* (312) windowdefn ::= nm AS LP window RP */ - 308, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - 308, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - 308, /* (315) window ::= ORDER BY sortlist frame_opt */ - 308, /* (316) window ::= nm ORDER BY sortlist frame_opt */ - 308, /* (317) window ::= nm frame_opt */ - 309, /* (318) frame_opt ::= */ - 309, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - 309, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - 313, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ - 315, /* (322) frame_bound_s ::= frame_bound */ - 315, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ - 316, /* (324) frame_bound_e ::= frame_bound */ - 316, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ - 314, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ - 314, /* (327) frame_bound ::= CURRENT ROW */ - 317, /* (328) frame_exclude_opt ::= */ - 317, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ - 318, /* (330) frame_exclude ::= NO OTHERS */ - 318, /* (331) frame_exclude ::= CURRENT ROW */ - 318, /* (332) frame_exclude ::= GROUP|TIES */ - 251, /* (333) window_clause ::= WINDOW windowdefn_list */ - 273, /* (334) filter_over ::= filter_clause over_clause */ - 273, /* (335) filter_over ::= over_clause */ - 273, /* (336) filter_over ::= filter_clause */ - 312, /* (337) over_clause ::= OVER LP window RP */ - 312, /* (338) over_clause ::= OVER nm */ - 311, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ - 185, /* (340) input ::= cmdlist */ - 186, /* (341) cmdlist ::= cmdlist ecmd */ - 186, /* (342) cmdlist ::= ecmd */ - 187, /* (343) ecmd ::= SEMI */ - 187, /* (344) ecmd ::= cmdx SEMI */ - 187, /* (345) ecmd ::= explain cmdx SEMI */ - 192, /* (346) trans_opt ::= */ - 192, /* (347) trans_opt ::= TRANSACTION */ - 192, /* (348) trans_opt ::= TRANSACTION nm */ - 194, /* (349) savepoint_opt ::= SAVEPOINT */ - 194, /* (350) savepoint_opt ::= */ - 190, /* (351) cmd ::= create_table create_table_args */ - 203, /* (352) table_option_set ::= table_option */ - 201, /* (353) columnlist ::= columnlist COMMA columnname carglist */ - 201, /* (354) columnlist ::= columnname carglist */ - 193, /* (355) nm ::= ID|INDEXED|JOIN_KW */ - 193, /* (356) nm ::= STRING */ - 208, /* (357) typetoken ::= typename */ - 209, /* (358) typename ::= ID|STRING */ - 210, /* (359) signed ::= plus_num */ - 210, /* (360) signed ::= minus_num */ - 207, /* (361) carglist ::= carglist ccons */ - 207, /* (362) carglist ::= */ - 215, /* (363) ccons ::= NULL onconf */ - 215, /* (364) ccons ::= GENERATED ALWAYS AS generated */ - 215, /* (365) ccons ::= AS generated */ - 202, /* (366) conslist_opt ::= COMMA conslist */ - 228, /* (367) conslist ::= conslist tconscomma tcons */ - 228, /* (368) conslist ::= tcons */ - 229, /* (369) tconscomma ::= */ - 233, /* (370) defer_subclause_opt ::= defer_subclause */ - 235, /* (371) resolvetype ::= raisetype */ - 239, /* (372) selectnowith ::= oneselect */ - 240, /* (373) oneselect ::= values */ - 254, /* (374) sclp ::= selcollist COMMA */ - 255, /* (375) as ::= ID|STRING */ - 264, /* (376) indexed_opt ::= indexed_by */ - 272, /* (377) returning ::= */ - 217, /* (378) expr ::= term */ - 274, /* (379) likeop ::= LIKE_KW|MATCH */ - 278, /* (380) case_operand ::= expr */ - 261, /* (381) exprlist ::= nexprlist */ - 284, /* (382) nmnum ::= plus_num */ - 284, /* (383) nmnum ::= nm */ - 284, /* (384) nmnum ::= ON */ - 284, /* (385) nmnum ::= DELETE */ - 284, /* (386) nmnum ::= DEFAULT */ - 211, /* (387) plus_num ::= INTEGER|FLOAT */ - 289, /* (388) foreach_clause ::= */ - 289, /* (389) foreach_clause ::= FOR EACH ROW */ - 292, /* (390) trnm ::= nm */ - 293, /* (391) tridxby ::= */ - 294, /* (392) database_kw_opt ::= DATABASE */ - 294, /* (393) database_kw_opt ::= */ - 297, /* (394) kwcolumn_opt ::= */ - 297, /* (395) kwcolumn_opt ::= COLUMNKW */ - 299, /* (396) vtabarglist ::= vtabarg */ - 299, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ - 300, /* (398) vtabarg ::= vtabarg vtabargtoken */ - 303, /* (399) anylist ::= */ - 303, /* (400) anylist ::= anylist LP anylist RP */ - 303, /* (401) anylist ::= anylist ANY */ - 266, /* (402) with ::= */ - 306, /* (403) windowdefn_list ::= windowdefn */ - 308, /* (404) window ::= frame_opt */ + 191, /* (0) explain ::= EXPLAIN */ + 191, /* (1) explain ::= EXPLAIN QUERY PLAN */ + 190, /* (2) cmdx ::= cmd */ + 192, /* (3) cmd ::= BEGIN transtype trans_opt */ + 193, /* (4) transtype ::= */ + 193, /* (5) transtype ::= DEFERRED */ + 193, /* (6) transtype ::= IMMEDIATE */ + 193, /* (7) transtype ::= EXCLUSIVE */ + 192, /* (8) cmd ::= COMMIT|END trans_opt */ + 192, /* (9) cmd ::= ROLLBACK trans_opt */ + 192, /* (10) cmd ::= SAVEPOINT nm */ + 192, /* (11) cmd ::= RELEASE savepoint_opt nm */ + 192, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + 197, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + 199, /* (14) createkw ::= CREATE */ + 201, /* (15) ifnotexists ::= */ + 201, /* (16) ifnotexists ::= IF NOT EXISTS */ + 200, /* (17) temp ::= TEMP */ + 200, /* (18) temp ::= */ + 198, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ + 198, /* (20) create_table_args ::= AS select */ + 205, /* (21) table_option_set ::= */ + 205, /* (22) table_option_set ::= table_option_set COMMA table_option */ + 207, /* (23) table_option ::= WITHOUT nm */ + 207, /* (24) table_option ::= RANDOM nm */ + 207, /* (25) table_option ::= nm */ + 208, /* (26) columnname ::= nm typetoken */ + 210, /* (27) typetoken ::= */ + 210, /* (28) typetoken ::= typename LP signed RP */ + 210, /* (29) typetoken ::= typename LP signed COMMA signed RP */ + 211, /* (30) typename ::= typename ID|STRING */ + 215, /* (31) scanpt ::= */ + 216, /* (32) scantok ::= */ + 217, /* (33) ccons ::= CONSTRAINT nm */ + 217, /* (34) ccons ::= DEFAULT scantok term */ + 217, /* (35) ccons ::= DEFAULT LP expr RP */ + 217, /* (36) ccons ::= DEFAULT PLUS scantok term */ + 217, /* (37) ccons ::= DEFAULT MINUS scantok term */ + 217, /* (38) ccons ::= DEFAULT scantok ID|INDEXED */ + 217, /* (39) ccons ::= NOT NULL onconf */ + 217, /* (40) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + 217, /* (41) ccons ::= UNIQUE onconf */ + 217, /* (42) ccons ::= CHECK LP expr RP */ + 217, /* (43) ccons ::= REFERENCES nm eidlist_opt refargs */ + 217, /* (44) ccons ::= defer_subclause */ + 217, /* (45) ccons ::= COLLATE ID|STRING */ + 226, /* (46) generated ::= LP expr RP */ + 226, /* (47) generated ::= LP expr RP ID */ + 222, /* (48) autoinc ::= */ + 222, /* (49) autoinc ::= AUTOINCR */ + 224, /* (50) refargs ::= */ + 224, /* (51) refargs ::= refargs refarg */ + 227, /* (52) refarg ::= MATCH nm */ + 227, /* (53) refarg ::= ON INSERT refact */ + 227, /* (54) refarg ::= ON DELETE refact */ + 227, /* (55) refarg ::= ON UPDATE refact */ + 228, /* (56) refact ::= SET NULL */ + 228, /* (57) refact ::= SET DEFAULT */ + 228, /* (58) refact ::= CASCADE */ + 228, /* (59) refact ::= RESTRICT */ + 228, /* (60) refact ::= NO ACTION */ + 225, /* (61) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + 225, /* (62) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 229, /* (63) init_deferred_pred_opt ::= */ + 229, /* (64) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + 229, /* (65) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 204, /* (66) conslist_opt ::= */ + 231, /* (67) tconscomma ::= COMMA */ + 232, /* (68) tcons ::= CONSTRAINT nm */ + 232, /* (69) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + 232, /* (70) tcons ::= UNIQUE LP sortlist RP onconf */ + 232, /* (71) tcons ::= CHECK LP expr RP onconf */ + 232, /* (72) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 235, /* (73) defer_subclause_opt ::= */ + 220, /* (74) onconf ::= */ + 220, /* (75) onconf ::= ON CONFLICT resolvetype */ + 236, /* (76) orconf ::= */ + 236, /* (77) orconf ::= OR resolvetype */ + 237, /* (78) resolvetype ::= IGNORE */ + 237, /* (79) resolvetype ::= REPLACE */ + 192, /* (80) cmd ::= DROP TABLE ifexists fullname */ + 239, /* (81) ifexists ::= IF EXISTS */ + 239, /* (82) ifexists ::= */ + 192, /* (83) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + 192, /* (84) cmd ::= DROP VIEW ifexists fullname */ + 192, /* (85) cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS STRING */ + 192, /* (86) cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS BLOB */ + 192, /* (87) cmd ::= DROP FUNCTION ifexists nm */ + 192, /* (88) cmd ::= select */ + 206, /* (89) select ::= WITH wqlist selectnowith */ + 206, /* (90) select ::= WITH RECURSIVE wqlist selectnowith */ + 206, /* (91) select ::= selectnowith */ + 241, /* (92) selectnowith ::= selectnowith multiselect_op oneselect */ + 244, /* (93) multiselect_op ::= UNION */ + 244, /* (94) multiselect_op ::= UNION ALL */ + 244, /* (95) multiselect_op ::= EXCEPT|INTERSECT */ + 242, /* (96) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + 242, /* (97) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + 254, /* (98) values ::= VALUES LP nexprlist RP */ + 254, /* (99) values ::= values COMMA LP nexprlist RP */ + 245, /* (100) distinct ::= DISTINCT */ + 245, /* (101) distinct ::= ALL */ + 245, /* (102) distinct ::= */ + 256, /* (103) sclp ::= */ + 246, /* (104) selcollist ::= sclp scanpt expr scanpt as */ + 246, /* (105) selcollist ::= sclp scanpt STAR */ + 246, /* (106) selcollist ::= sclp scanpt nm DOT STAR */ + 257, /* (107) as ::= AS nm */ + 257, /* (108) as ::= */ + 247, /* (109) from ::= */ + 247, /* (110) from ::= FROM seltablist */ + 259, /* (111) stl_prefix ::= seltablist joinop */ + 259, /* (112) stl_prefix ::= */ + 258, /* (113) seltablist ::= stl_prefix nm dbnm as on_using */ + 258, /* (114) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ + 258, /* (115) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ + 258, /* (116) seltablist ::= stl_prefix LP select RP as on_using */ + 258, /* (117) seltablist ::= stl_prefix LP seltablist RP as on_using */ + 202, /* (118) dbnm ::= */ + 202, /* (119) dbnm ::= DOT nm */ + 240, /* (120) fullname ::= nm */ + 240, /* (121) fullname ::= nm DOT nm */ + 264, /* (122) xfullname ::= nm */ + 264, /* (123) xfullname ::= nm DOT nm */ + 264, /* (124) xfullname ::= nm DOT nm AS nm */ + 264, /* (125) xfullname ::= nm AS nm */ + 260, /* (126) joinop ::= COMMA|JOIN */ + 260, /* (127) joinop ::= JOIN_KW JOIN */ + 260, /* (128) joinop ::= JOIN_KW nm JOIN */ + 260, /* (129) joinop ::= JOIN_KW nm nm JOIN */ + 261, /* (130) on_using ::= ON expr */ + 261, /* (131) on_using ::= USING LP idlist RP */ + 261, /* (132) on_using ::= */ + 266, /* (133) indexed_opt ::= */ + 262, /* (134) indexed_by ::= INDEXED BY nm */ + 262, /* (135) indexed_by ::= NOT INDEXED */ + 251, /* (136) orderby_opt ::= */ + 251, /* (137) orderby_opt ::= ORDER BY sortlist */ + 233, /* (138) sortlist ::= sortlist COMMA expr sortorder nulls */ + 233, /* (139) sortlist ::= expr sortorder nulls */ + 221, /* (140) sortorder ::= ASC */ + 221, /* (141) sortorder ::= DESC */ + 221, /* (142) sortorder ::= */ + 267, /* (143) nulls ::= NULLS FIRST */ + 267, /* (144) nulls ::= NULLS LAST */ + 267, /* (145) nulls ::= */ + 249, /* (146) groupby_opt ::= */ + 249, /* (147) groupby_opt ::= GROUP BY nexprlist */ + 250, /* (148) having_opt ::= */ + 250, /* (149) having_opt ::= HAVING expr */ + 252, /* (150) limit_opt ::= */ + 252, /* (151) limit_opt ::= LIMIT expr */ + 252, /* (152) limit_opt ::= LIMIT expr OFFSET expr */ + 252, /* (153) limit_opt ::= LIMIT expr COMMA expr */ + 192, /* (154) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + 248, /* (155) where_opt ::= */ + 248, /* (156) where_opt ::= WHERE expr */ + 269, /* (157) where_opt_ret ::= */ + 269, /* (158) where_opt_ret ::= WHERE expr */ + 269, /* (159) where_opt_ret ::= RETURNING selcollist */ + 269, /* (160) where_opt_ret ::= WHERE expr RETURNING selcollist */ + 192, /* (161) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + 270, /* (162) setlist ::= setlist COMMA nm EQ expr */ + 270, /* (163) setlist ::= setlist COMMA LP idlist RP EQ expr */ + 270, /* (164) setlist ::= nm EQ expr */ + 270, /* (165) setlist ::= LP idlist RP EQ expr */ + 192, /* (166) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + 192, /* (167) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 273, /* (168) upsert ::= */ + 273, /* (169) upsert ::= RETURNING selcollist */ + 273, /* (170) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + 273, /* (171) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + 273, /* (172) upsert ::= ON CONFLICT DO NOTHING returning */ + 273, /* (173) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + 274, /* (174) returning ::= RETURNING selcollist */ + 271, /* (175) insert_cmd ::= INSERT orconf */ + 271, /* (176) insert_cmd ::= REPLACE */ + 272, /* (177) idlist_opt ::= */ + 272, /* (178) idlist_opt ::= LP idlist RP */ + 265, /* (179) idlist ::= idlist COMMA nm */ + 265, /* (180) idlist ::= nm */ + 219, /* (181) expr ::= LP expr RP */ + 219, /* (182) expr ::= ID|INDEXED|JOIN_KW */ + 219, /* (183) expr ::= nm DOT nm */ + 219, /* (184) expr ::= nm DOT nm DOT nm */ + 218, /* (185) term ::= NULL|FLOAT|BLOB */ + 218, /* (186) term ::= STRING */ + 218, /* (187) term ::= INTEGER */ + 219, /* (188) expr ::= VARIABLE */ + 219, /* (189) expr ::= expr COLLATE ID|STRING */ + 219, /* (190) expr ::= CAST LP expr AS typetoken RP */ + 219, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ + 219, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + 219, /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + 219, /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + 218, /* (195) term ::= CTIME_KW */ + 219, /* (196) expr ::= LP nexprlist COMMA expr RP */ + 219, /* (197) expr ::= expr AND expr */ + 219, /* (198) expr ::= expr OR expr */ + 219, /* (199) expr ::= expr LT|GT|GE|LE expr */ + 219, /* (200) expr ::= expr EQ|NE expr */ + 219, /* (201) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + 219, /* (202) expr ::= expr PLUS|MINUS expr */ + 219, /* (203) expr ::= expr STAR|SLASH|REM expr */ + 219, /* (204) expr ::= expr CONCAT expr */ + 276, /* (205) likeop ::= NOT LIKE_KW|MATCH */ + 219, /* (206) expr ::= expr likeop expr */ + 219, /* (207) expr ::= expr likeop expr ESCAPE expr */ + 219, /* (208) expr ::= expr ISNULL|NOTNULL */ + 219, /* (209) expr ::= expr NOT NULL */ + 219, /* (210) expr ::= expr IS expr */ + 219, /* (211) expr ::= expr IS NOT expr */ + 219, /* (212) expr ::= expr IS NOT DISTINCT FROM expr */ + 219, /* (213) expr ::= expr IS DISTINCT FROM expr */ + 219, /* (214) expr ::= NOT expr */ + 219, /* (215) expr ::= BITNOT expr */ + 219, /* (216) expr ::= PLUS|MINUS expr */ + 219, /* (217) expr ::= expr PTR expr */ + 277, /* (218) between_op ::= BETWEEN */ + 277, /* (219) between_op ::= NOT BETWEEN */ + 219, /* (220) expr ::= expr between_op expr AND expr */ + 278, /* (221) in_op ::= IN */ + 278, /* (222) in_op ::= NOT IN */ + 219, /* (223) expr ::= expr in_op LP exprlist RP */ + 219, /* (224) expr ::= LP select RP */ + 219, /* (225) expr ::= expr in_op LP select RP */ + 219, /* (226) expr ::= expr in_op nm dbnm paren_exprlist */ + 219, /* (227) expr ::= EXISTS LP select RP */ + 219, /* (228) expr ::= CASE case_operand case_exprlist case_else END */ + 281, /* (229) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + 281, /* (230) case_exprlist ::= WHEN expr THEN expr */ + 282, /* (231) case_else ::= ELSE expr */ + 282, /* (232) case_else ::= */ + 280, /* (233) case_operand ::= */ + 263, /* (234) exprlist ::= */ + 255, /* (235) nexprlist ::= nexprlist COMMA expr */ + 255, /* (236) nexprlist ::= expr */ + 279, /* (237) paren_exprlist ::= */ + 279, /* (238) paren_exprlist ::= LP exprlist RP */ + 192, /* (239) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + 283, /* (240) uniqueflag ::= UNIQUE */ + 283, /* (241) uniqueflag ::= */ + 223, /* (242) eidlist_opt ::= */ + 223, /* (243) eidlist_opt ::= LP eidlist RP */ + 234, /* (244) eidlist ::= eidlist COMMA nm collate sortorder */ + 234, /* (245) eidlist ::= nm collate sortorder */ + 284, /* (246) collate ::= */ + 284, /* (247) collate ::= COLLATE ID|STRING */ + 192, /* (248) cmd ::= DROP INDEX ifexists fullname */ + 192, /* (249) cmd ::= VACUUM vinto */ + 192, /* (250) cmd ::= VACUUM nm vinto */ + 285, /* (251) vinto ::= INTO expr */ + 285, /* (252) vinto ::= */ + 192, /* (253) cmd ::= PRAGMA nm dbnm */ + 192, /* (254) cmd ::= PRAGMA nm dbnm EQ nmnum */ + 192, /* (255) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + 192, /* (256) cmd ::= PRAGMA nm dbnm EQ minus_num */ + 192, /* (257) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + 213, /* (258) plus_num ::= PLUS INTEGER|FLOAT */ + 214, /* (259) minus_num ::= MINUS INTEGER|FLOAT */ + 192, /* (260) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + 287, /* (261) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + 289, /* (262) trigger_time ::= BEFORE|AFTER */ + 289, /* (263) trigger_time ::= INSTEAD OF */ + 289, /* (264) trigger_time ::= */ + 290, /* (265) trigger_event ::= DELETE|INSERT */ + 290, /* (266) trigger_event ::= UPDATE */ + 290, /* (267) trigger_event ::= UPDATE OF idlist */ + 292, /* (268) when_clause ::= */ + 292, /* (269) when_clause ::= WHEN expr */ + 288, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 288, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */ + 294, /* (272) trnm ::= nm DOT nm */ + 295, /* (273) tridxby ::= INDEXED BY nm */ + 295, /* (274) tridxby ::= NOT INDEXED */ + 293, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + 293, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + 293, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + 293, /* (278) trigger_cmd ::= scanpt select scanpt */ + 219, /* (279) expr ::= RAISE LP IGNORE RP */ + 219, /* (280) expr ::= RAISE LP raisetype COMMA nm RP */ + 238, /* (281) raisetype ::= ROLLBACK */ + 238, /* (282) raisetype ::= ABORT */ + 238, /* (283) raisetype ::= FAIL */ + 192, /* (284) cmd ::= DROP TRIGGER ifexists fullname */ + 192, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 192, /* (286) cmd ::= DETACH database_kw_opt expr */ + 297, /* (287) key_opt ::= */ + 297, /* (288) key_opt ::= KEY expr */ + 192, /* (289) cmd ::= REINDEX */ + 192, /* (290) cmd ::= REINDEX nm dbnm */ + 192, /* (291) cmd ::= ANALYZE */ + 192, /* (292) cmd ::= ANALYZE nm dbnm */ + 192, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 192, /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + 192, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + 298, /* (296) add_column_fullname ::= fullname */ + 192, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 192, /* (298) cmd ::= ALTER TABLE fullname ALTER COLUMNKW columnname TO columnname carglist */ + 192, /* (299) cmd ::= create_vtab */ + 192, /* (300) cmd ::= create_vtab LP vtabarglist RP */ + 300, /* (301) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 302, /* (302) vtabarg ::= */ + 303, /* (303) vtabargtoken ::= ANY */ + 303, /* (304) vtabargtoken ::= lp anylist RP */ + 304, /* (305) lp ::= LP */ + 268, /* (306) with ::= WITH wqlist */ + 268, /* (307) with ::= WITH RECURSIVE wqlist */ + 307, /* (308) wqas ::= AS */ + 307, /* (309) wqas ::= AS MATERIALIZED */ + 307, /* (310) wqas ::= AS NOT MATERIALIZED */ + 306, /* (311) wqitem ::= nm eidlist_opt wqas LP select RP */ + 243, /* (312) wqlist ::= wqitem */ + 243, /* (313) wqlist ::= wqlist COMMA wqitem */ + 308, /* (314) windowdefn_list ::= windowdefn */ + 308, /* (315) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + 309, /* (316) windowdefn ::= nm AS LP window RP */ + 310, /* (317) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + 310, /* (318) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + 310, /* (319) window ::= ORDER BY sortlist frame_opt */ + 310, /* (320) window ::= nm ORDER BY sortlist frame_opt */ + 310, /* (321) window ::= frame_opt */ + 310, /* (322) window ::= nm frame_opt */ + 311, /* (323) frame_opt ::= */ + 311, /* (324) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + 311, /* (325) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + 315, /* (326) range_or_rows ::= RANGE|ROWS|GROUPS */ + 317, /* (327) frame_bound_s ::= frame_bound */ + 317, /* (328) frame_bound_s ::= UNBOUNDED PRECEDING */ + 318, /* (329) frame_bound_e ::= frame_bound */ + 318, /* (330) frame_bound_e ::= UNBOUNDED FOLLOWING */ + 316, /* (331) frame_bound ::= expr PRECEDING|FOLLOWING */ + 316, /* (332) frame_bound ::= CURRENT ROW */ + 319, /* (333) frame_exclude_opt ::= */ + 319, /* (334) frame_exclude_opt ::= EXCLUDE frame_exclude */ + 320, /* (335) frame_exclude ::= NO OTHERS */ + 320, /* (336) frame_exclude ::= CURRENT ROW */ + 320, /* (337) frame_exclude ::= GROUP|TIES */ + 253, /* (338) window_clause ::= WINDOW windowdefn_list */ + 275, /* (339) filter_over ::= filter_clause over_clause */ + 275, /* (340) filter_over ::= over_clause */ + 275, /* (341) filter_over ::= filter_clause */ + 314, /* (342) over_clause ::= OVER LP window RP */ + 314, /* (343) over_clause ::= OVER nm */ + 313, /* (344) filter_clause ::= FILTER LP WHERE expr RP */ + 187, /* (345) input ::= cmdlist */ + 188, /* (346) cmdlist ::= cmdlist ecmd */ + 188, /* (347) cmdlist ::= ecmd */ + 189, /* (348) ecmd ::= SEMI */ + 189, /* (349) ecmd ::= cmdx SEMI */ + 189, /* (350) ecmd ::= explain cmdx SEMI */ + 194, /* (351) trans_opt ::= */ + 194, /* (352) trans_opt ::= TRANSACTION */ + 194, /* (353) trans_opt ::= TRANSACTION nm */ + 196, /* (354) savepoint_opt ::= SAVEPOINT */ + 196, /* (355) savepoint_opt ::= */ + 192, /* (356) cmd ::= create_table create_table_args */ + 205, /* (357) table_option_set ::= table_option */ + 203, /* (358) columnlist ::= columnlist COMMA columnname carglist */ + 203, /* (359) columnlist ::= columnname carglist */ + 195, /* (360) nm ::= ID|INDEXED|JOIN_KW */ + 195, /* (361) nm ::= STRING */ + 210, /* (362) typetoken ::= typename */ + 211, /* (363) typename ::= ID|STRING */ + 212, /* (364) signed ::= plus_num */ + 212, /* (365) signed ::= minus_num */ + 209, /* (366) carglist ::= carglist ccons */ + 209, /* (367) carglist ::= */ + 217, /* (368) ccons ::= NULL onconf */ + 217, /* (369) ccons ::= GENERATED ALWAYS AS generated */ + 217, /* (370) ccons ::= AS generated */ + 204, /* (371) conslist_opt ::= COMMA conslist */ + 230, /* (372) conslist ::= conslist tconscomma tcons */ + 230, /* (373) conslist ::= tcons */ + 231, /* (374) tconscomma ::= */ + 235, /* (375) defer_subclause_opt ::= defer_subclause */ + 237, /* (376) resolvetype ::= raisetype */ + 241, /* (377) selectnowith ::= oneselect */ + 242, /* (378) oneselect ::= values */ + 256, /* (379) sclp ::= selcollist COMMA */ + 257, /* (380) as ::= ID|STRING */ + 266, /* (381) indexed_opt ::= indexed_by */ + 274, /* (382) returning ::= */ + 219, /* (383) expr ::= term */ + 276, /* (384) likeop ::= LIKE_KW|MATCH */ + 280, /* (385) case_operand ::= expr */ + 263, /* (386) exprlist ::= nexprlist */ + 286, /* (387) nmnum ::= plus_num */ + 286, /* (388) nmnum ::= nm */ + 286, /* (389) nmnum ::= ON */ + 286, /* (390) nmnum ::= DELETE */ + 286, /* (391) nmnum ::= DEFAULT */ + 213, /* (392) plus_num ::= INTEGER|FLOAT */ + 291, /* (393) foreach_clause ::= */ + 291, /* (394) foreach_clause ::= FOR EACH ROW */ + 294, /* (395) trnm ::= nm */ + 295, /* (396) tridxby ::= */ + 296, /* (397) database_kw_opt ::= DATABASE */ + 296, /* (398) database_kw_opt ::= */ + 299, /* (399) kwcolumn_opt ::= */ + 299, /* (400) kwcolumn_opt ::= COLUMNKW */ + 301, /* (401) vtabarglist ::= vtabarg */ + 301, /* (402) vtabarglist ::= vtabarglist COMMA vtabarg */ + 302, /* (403) vtabarg ::= vtabarg vtabargtoken */ + 305, /* (404) anylist ::= */ + 305, /* (405) anylist ::= anylist LP anylist RP */ + 305, /* (406) anylist ::= anylist ANY */ + 268, /* (407) with ::= */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -173549,387 +172367,390 @@ static const signed char yyRuleInfoNRhs[] = { 0, /* (21) table_option_set ::= */ -3, /* (22) table_option_set ::= table_option_set COMMA table_option */ -2, /* (23) table_option ::= WITHOUT nm */ - -1, /* (24) table_option ::= nm */ - -2, /* (25) columnname ::= nm typetoken */ - 0, /* (26) typetoken ::= */ - -4, /* (27) typetoken ::= typename LP signed RP */ - -6, /* (28) typetoken ::= typename LP signed COMMA signed RP */ - -2, /* (29) typename ::= typename ID|STRING */ - 0, /* (30) scanpt ::= */ - 0, /* (31) scantok ::= */ - -2, /* (32) ccons ::= CONSTRAINT nm */ - -3, /* (33) ccons ::= DEFAULT scantok term */ - -4, /* (34) ccons ::= DEFAULT LP expr RP */ - -4, /* (35) ccons ::= DEFAULT PLUS scantok term */ - -4, /* (36) ccons ::= DEFAULT MINUS scantok term */ - -3, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ - -3, /* (38) ccons ::= NOT NULL onconf */ - -5, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ - -2, /* (40) ccons ::= UNIQUE onconf */ - -4, /* (41) ccons ::= CHECK LP expr RP */ - -4, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ - -1, /* (43) ccons ::= defer_subclause */ - -2, /* (44) ccons ::= COLLATE ID|STRING */ - -3, /* (45) generated ::= LP expr RP */ - -4, /* (46) generated ::= LP expr RP ID */ - 0, /* (47) autoinc ::= */ - -1, /* (48) autoinc ::= AUTOINCR */ - 0, /* (49) refargs ::= */ - -2, /* (50) refargs ::= refargs refarg */ - -2, /* (51) refarg ::= MATCH nm */ - -3, /* (52) refarg ::= ON INSERT refact */ - -3, /* (53) refarg ::= ON DELETE refact */ - -3, /* (54) refarg ::= ON UPDATE refact */ - -2, /* (55) refact ::= SET NULL */ - -2, /* (56) refact ::= SET DEFAULT */ - -1, /* (57) refact ::= CASCADE */ - -1, /* (58) refact ::= RESTRICT */ - -2, /* (59) refact ::= NO ACTION */ - -3, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ - -2, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - 0, /* (62) init_deferred_pred_opt ::= */ - -2, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ - -2, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ - 0, /* (65) conslist_opt ::= */ - -1, /* (66) tconscomma ::= COMMA */ - -2, /* (67) tcons ::= CONSTRAINT nm */ - -7, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ - -5, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ - -5, /* (70) tcons ::= CHECK LP expr RP onconf */ - -10, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ - 0, /* (72) defer_subclause_opt ::= */ - 0, /* (73) onconf ::= */ - -3, /* (74) onconf ::= ON CONFLICT resolvetype */ - 0, /* (75) orconf ::= */ - -2, /* (76) orconf ::= OR resolvetype */ - -1, /* (77) resolvetype ::= IGNORE */ - -1, /* (78) resolvetype ::= REPLACE */ - -4, /* (79) cmd ::= DROP TABLE ifexists fullname */ - -2, /* (80) ifexists ::= IF EXISTS */ - 0, /* (81) ifexists ::= */ - -9, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ - -4, /* (83) cmd ::= DROP VIEW ifexists fullname */ - -1, /* (84) cmd ::= select */ - -3, /* (85) select ::= WITH wqlist selectnowith */ - -4, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ - -1, /* (87) select ::= selectnowith */ - -3, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ - -1, /* (89) multiselect_op ::= UNION */ - -2, /* (90) multiselect_op ::= UNION ALL */ - -1, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ - -9, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ - -10, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ - -4, /* (94) values ::= VALUES LP nexprlist RP */ - -5, /* (95) values ::= values COMMA LP nexprlist RP */ - -1, /* (96) distinct ::= DISTINCT */ - -1, /* (97) distinct ::= ALL */ - 0, /* (98) distinct ::= */ - 0, /* (99) sclp ::= */ - -5, /* (100) selcollist ::= sclp scanpt expr scanpt as */ - -3, /* (101) selcollist ::= sclp scanpt STAR */ - -5, /* (102) selcollist ::= sclp scanpt nm DOT STAR */ - -2, /* (103) as ::= AS nm */ - 0, /* (104) as ::= */ - 0, /* (105) from ::= */ - -2, /* (106) from ::= FROM seltablist */ - -2, /* (107) stl_prefix ::= seltablist joinop */ - 0, /* (108) stl_prefix ::= */ - -5, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */ - -6, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ - -8, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ - -6, /* (112) seltablist ::= stl_prefix LP select RP as on_using */ - -6, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */ - 0, /* (114) dbnm ::= */ - -2, /* (115) dbnm ::= DOT nm */ - -1, /* (116) fullname ::= nm */ - -3, /* (117) fullname ::= nm DOT nm */ - -1, /* (118) xfullname ::= nm */ - -3, /* (119) xfullname ::= nm DOT nm */ - -5, /* (120) xfullname ::= nm DOT nm AS nm */ - -3, /* (121) xfullname ::= nm AS nm */ - -1, /* (122) joinop ::= COMMA|JOIN */ - -2, /* (123) joinop ::= JOIN_KW JOIN */ - -3, /* (124) joinop ::= JOIN_KW nm JOIN */ - -4, /* (125) joinop ::= JOIN_KW nm nm JOIN */ - -2, /* (126) on_using ::= ON expr */ - -4, /* (127) on_using ::= USING LP idlist RP */ - 0, /* (128) on_using ::= */ - 0, /* (129) indexed_opt ::= */ - -3, /* (130) indexed_by ::= INDEXED BY nm */ - -2, /* (131) indexed_by ::= NOT INDEXED */ - 0, /* (132) orderby_opt ::= */ - -3, /* (133) orderby_opt ::= ORDER BY sortlist */ - -5, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ - -3, /* (135) sortlist ::= expr sortorder nulls */ - -1, /* (136) sortorder ::= ASC */ - -1, /* (137) sortorder ::= DESC */ - 0, /* (138) sortorder ::= */ - -2, /* (139) nulls ::= NULLS FIRST */ - -2, /* (140) nulls ::= NULLS LAST */ - 0, /* (141) nulls ::= */ - 0, /* (142) groupby_opt ::= */ - -3, /* (143) groupby_opt ::= GROUP BY nexprlist */ - 0, /* (144) having_opt ::= */ - -2, /* (145) having_opt ::= HAVING expr */ - 0, /* (146) limit_opt ::= */ - -2, /* (147) limit_opt ::= LIMIT expr */ - -4, /* (148) limit_opt ::= LIMIT expr OFFSET expr */ - -4, /* (149) limit_opt ::= LIMIT expr COMMA expr */ - -6, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ - 0, /* (151) where_opt ::= */ - -2, /* (152) where_opt ::= WHERE expr */ - 0, /* (153) where_opt_ret ::= */ - -2, /* (154) where_opt_ret ::= WHERE expr */ - -2, /* (155) where_opt_ret ::= RETURNING selcollist */ - -4, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */ - -9, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ - -5, /* (158) setlist ::= setlist COMMA nm EQ expr */ - -7, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */ - -3, /* (160) setlist ::= nm EQ expr */ - -5, /* (161) setlist ::= LP idlist RP EQ expr */ - -7, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - -8, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ - 0, /* (164) upsert ::= */ - -2, /* (165) upsert ::= RETURNING selcollist */ - -12, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ - -9, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ - -5, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */ - -8, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ - -2, /* (170) returning ::= RETURNING selcollist */ - -2, /* (171) insert_cmd ::= INSERT orconf */ - -1, /* (172) insert_cmd ::= REPLACE */ - 0, /* (173) idlist_opt ::= */ - -3, /* (174) idlist_opt ::= LP idlist RP */ - -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 */ - -8, /* (188) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ - -4, /* (189) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ - -6, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ - -9, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ - -5, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ - -1, /* (193) term ::= CTIME_KW */ - -5, /* (194) expr ::= LP nexprlist COMMA expr RP */ - -3, /* (195) expr ::= expr AND expr */ - -3, /* (196) expr ::= expr OR expr */ - -3, /* (197) expr ::= expr LT|GT|GE|LE expr */ - -3, /* (198) expr ::= expr EQ|NE expr */ - -3, /* (199) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - -3, /* (200) expr ::= expr PLUS|MINUS expr */ - -3, /* (201) expr ::= expr STAR|SLASH|REM expr */ - -3, /* (202) expr ::= expr CONCAT expr */ - -2, /* (203) likeop ::= NOT LIKE_KW|MATCH */ - -3, /* (204) expr ::= expr likeop expr */ - -5, /* (205) expr ::= expr likeop expr ESCAPE expr */ - -2, /* (206) expr ::= expr ISNULL|NOTNULL */ - -3, /* (207) expr ::= expr NOT NULL */ - -3, /* (208) expr ::= expr IS expr */ - -4, /* (209) expr ::= expr IS NOT expr */ - -6, /* (210) expr ::= expr IS NOT DISTINCT FROM expr */ - -5, /* (211) expr ::= expr IS DISTINCT FROM expr */ - -2, /* (212) expr ::= NOT expr */ - -2, /* (213) expr ::= BITNOT expr */ - -2, /* (214) expr ::= PLUS|MINUS expr */ - -3, /* (215) expr ::= expr PTR expr */ - -1, /* (216) between_op ::= BETWEEN */ - -2, /* (217) between_op ::= NOT BETWEEN */ - -5, /* (218) expr ::= expr between_op expr AND expr */ - -1, /* (219) in_op ::= IN */ - -2, /* (220) in_op ::= NOT IN */ - -5, /* (221) expr ::= expr in_op LP exprlist RP */ - -3, /* (222) expr ::= LP select RP */ - -5, /* (223) expr ::= expr in_op LP select RP */ - -5, /* (224) expr ::= expr in_op nm dbnm paren_exprlist */ - -4, /* (225) expr ::= EXISTS LP select RP */ - -5, /* (226) expr ::= CASE case_operand case_exprlist case_else END */ - -5, /* (227) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - -4, /* (228) case_exprlist ::= WHEN expr THEN expr */ - -2, /* (229) case_else ::= ELSE expr */ - 0, /* (230) case_else ::= */ - 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 */ - -3, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - -5, /* (312) windowdefn ::= nm AS LP window RP */ - -5, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - -6, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - -4, /* (315) window ::= ORDER BY sortlist frame_opt */ - -5, /* (316) window ::= nm ORDER BY sortlist frame_opt */ - -2, /* (317) window ::= nm frame_opt */ - 0, /* (318) frame_opt ::= */ - -3, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - -6, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - -1, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ - -1, /* (322) frame_bound_s ::= frame_bound */ - -2, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ - -1, /* (324) frame_bound_e ::= frame_bound */ - -2, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ - -2, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ - -2, /* (327) frame_bound ::= CURRENT ROW */ - 0, /* (328) frame_exclude_opt ::= */ - -2, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ - -2, /* (330) frame_exclude ::= NO OTHERS */ - -2, /* (331) frame_exclude ::= CURRENT ROW */ - -1, /* (332) frame_exclude ::= GROUP|TIES */ - -2, /* (333) window_clause ::= WINDOW windowdefn_list */ - -2, /* (334) filter_over ::= filter_clause over_clause */ - -1, /* (335) filter_over ::= over_clause */ - -1, /* (336) filter_over ::= filter_clause */ - -4, /* (337) over_clause ::= OVER LP window RP */ - -2, /* (338) over_clause ::= OVER nm */ - -5, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ - -1, /* (340) input ::= cmdlist */ - -2, /* (341) cmdlist ::= cmdlist ecmd */ - -1, /* (342) cmdlist ::= ecmd */ - -1, /* (343) ecmd ::= SEMI */ - -2, /* (344) ecmd ::= cmdx SEMI */ - -3, /* (345) ecmd ::= explain cmdx SEMI */ - 0, /* (346) trans_opt ::= */ - -1, /* (347) trans_opt ::= TRANSACTION */ - -2, /* (348) trans_opt ::= TRANSACTION nm */ - -1, /* (349) savepoint_opt ::= SAVEPOINT */ - 0, /* (350) savepoint_opt ::= */ - -2, /* (351) cmd ::= create_table create_table_args */ - -1, /* (352) table_option_set ::= table_option */ - -4, /* (353) columnlist ::= columnlist COMMA columnname carglist */ - -2, /* (354) columnlist ::= columnname carglist */ - -1, /* (355) nm ::= ID|INDEXED|JOIN_KW */ - -1, /* (356) nm ::= STRING */ - -1, /* (357) typetoken ::= typename */ - -1, /* (358) typename ::= ID|STRING */ - -1, /* (359) signed ::= plus_num */ - -1, /* (360) signed ::= minus_num */ - -2, /* (361) carglist ::= carglist ccons */ - 0, /* (362) carglist ::= */ - -2, /* (363) ccons ::= NULL onconf */ - -4, /* (364) ccons ::= GENERATED ALWAYS AS generated */ - -2, /* (365) ccons ::= AS generated */ - -2, /* (366) conslist_opt ::= COMMA conslist */ - -3, /* (367) conslist ::= conslist tconscomma tcons */ - -1, /* (368) conslist ::= tcons */ - 0, /* (369) tconscomma ::= */ - -1, /* (370) defer_subclause_opt ::= defer_subclause */ - -1, /* (371) resolvetype ::= raisetype */ - -1, /* (372) selectnowith ::= oneselect */ - -1, /* (373) oneselect ::= values */ - -2, /* (374) sclp ::= selcollist COMMA */ - -1, /* (375) as ::= ID|STRING */ - -1, /* (376) indexed_opt ::= indexed_by */ - 0, /* (377) returning ::= */ - -1, /* (378) expr ::= term */ - -1, /* (379) likeop ::= LIKE_KW|MATCH */ - -1, /* (380) case_operand ::= expr */ - -1, /* (381) exprlist ::= nexprlist */ - -1, /* (382) nmnum ::= plus_num */ - -1, /* (383) nmnum ::= nm */ - -1, /* (384) nmnum ::= ON */ - -1, /* (385) nmnum ::= DELETE */ - -1, /* (386) nmnum ::= DEFAULT */ - -1, /* (387) plus_num ::= INTEGER|FLOAT */ - 0, /* (388) foreach_clause ::= */ - -3, /* (389) foreach_clause ::= FOR EACH ROW */ - -1, /* (390) trnm ::= nm */ - 0, /* (391) tridxby ::= */ - -1, /* (392) database_kw_opt ::= DATABASE */ - 0, /* (393) database_kw_opt ::= */ - 0, /* (394) kwcolumn_opt ::= */ - -1, /* (395) kwcolumn_opt ::= COLUMNKW */ - -1, /* (396) vtabarglist ::= vtabarg */ - -3, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ - -2, /* (398) vtabarg ::= vtabarg vtabargtoken */ - 0, /* (399) anylist ::= */ - -4, /* (400) anylist ::= anylist LP anylist RP */ - -2, /* (401) anylist ::= anylist ANY */ - 0, /* (402) with ::= */ - -1, /* (403) windowdefn_list ::= windowdefn */ - -1, /* (404) window ::= frame_opt */ + -2, /* (24) table_option ::= RANDOM nm */ + -1, /* (25) table_option ::= nm */ + -2, /* (26) columnname ::= nm typetoken */ + 0, /* (27) typetoken ::= */ + -4, /* (28) typetoken ::= typename LP signed RP */ + -6, /* (29) typetoken ::= typename LP signed COMMA signed RP */ + -2, /* (30) typename ::= typename ID|STRING */ + 0, /* (31) scanpt ::= */ + 0, /* (32) scantok ::= */ + -2, /* (33) ccons ::= CONSTRAINT nm */ + -3, /* (34) ccons ::= DEFAULT scantok term */ + -4, /* (35) ccons ::= DEFAULT LP expr RP */ + -4, /* (36) ccons ::= DEFAULT PLUS scantok term */ + -4, /* (37) ccons ::= DEFAULT MINUS scantok term */ + -3, /* (38) ccons ::= DEFAULT scantok ID|INDEXED */ + -3, /* (39) ccons ::= NOT NULL onconf */ + -5, /* (40) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + -2, /* (41) ccons ::= UNIQUE onconf */ + -4, /* (42) ccons ::= CHECK LP expr RP */ + -4, /* (43) ccons ::= REFERENCES nm eidlist_opt refargs */ + -1, /* (44) ccons ::= defer_subclause */ + -2, /* (45) ccons ::= COLLATE ID|STRING */ + -3, /* (46) generated ::= LP expr RP */ + -4, /* (47) generated ::= LP expr RP ID */ + 0, /* (48) autoinc ::= */ + -1, /* (49) autoinc ::= AUTOINCR */ + 0, /* (50) refargs ::= */ + -2, /* (51) refargs ::= refargs refarg */ + -2, /* (52) refarg ::= MATCH nm */ + -3, /* (53) refarg ::= ON INSERT refact */ + -3, /* (54) refarg ::= ON DELETE refact */ + -3, /* (55) refarg ::= ON UPDATE refact */ + -2, /* (56) refact ::= SET NULL */ + -2, /* (57) refact ::= SET DEFAULT */ + -1, /* (58) refact ::= CASCADE */ + -1, /* (59) refact ::= RESTRICT */ + -2, /* (60) refact ::= NO ACTION */ + -3, /* (61) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + -2, /* (62) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 0, /* (63) init_deferred_pred_opt ::= */ + -2, /* (64) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + -2, /* (65) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 0, /* (66) conslist_opt ::= */ + -1, /* (67) tconscomma ::= COMMA */ + -2, /* (68) tcons ::= CONSTRAINT nm */ + -7, /* (69) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + -5, /* (70) tcons ::= UNIQUE LP sortlist RP onconf */ + -5, /* (71) tcons ::= CHECK LP expr RP onconf */ + -10, /* (72) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 0, /* (73) defer_subclause_opt ::= */ + 0, /* (74) onconf ::= */ + -3, /* (75) onconf ::= ON CONFLICT resolvetype */ + 0, /* (76) orconf ::= */ + -2, /* (77) orconf ::= OR resolvetype */ + -1, /* (78) resolvetype ::= IGNORE */ + -1, /* (79) resolvetype ::= REPLACE */ + -4, /* (80) cmd ::= DROP TABLE ifexists fullname */ + -2, /* (81) ifexists ::= IF EXISTS */ + 0, /* (82) ifexists ::= */ + -9, /* (83) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + -4, /* (84) cmd ::= DROP VIEW ifexists fullname */ + -8, /* (85) cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS STRING */ + -8, /* (86) cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS BLOB */ + -4, /* (87) cmd ::= DROP FUNCTION ifexists nm */ + -1, /* (88) cmd ::= select */ + -3, /* (89) select ::= WITH wqlist selectnowith */ + -4, /* (90) select ::= WITH RECURSIVE wqlist selectnowith */ + -1, /* (91) select ::= selectnowith */ + -3, /* (92) selectnowith ::= selectnowith multiselect_op oneselect */ + -1, /* (93) multiselect_op ::= UNION */ + -2, /* (94) multiselect_op ::= UNION ALL */ + -1, /* (95) multiselect_op ::= EXCEPT|INTERSECT */ + -9, /* (96) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + -10, /* (97) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + -4, /* (98) values ::= VALUES LP nexprlist RP */ + -5, /* (99) values ::= values COMMA LP nexprlist RP */ + -1, /* (100) distinct ::= DISTINCT */ + -1, /* (101) distinct ::= ALL */ + 0, /* (102) distinct ::= */ + 0, /* (103) sclp ::= */ + -5, /* (104) selcollist ::= sclp scanpt expr scanpt as */ + -3, /* (105) selcollist ::= sclp scanpt STAR */ + -5, /* (106) selcollist ::= sclp scanpt nm DOT STAR */ + -2, /* (107) as ::= AS nm */ + 0, /* (108) as ::= */ + 0, /* (109) from ::= */ + -2, /* (110) from ::= FROM seltablist */ + -2, /* (111) stl_prefix ::= seltablist joinop */ + 0, /* (112) stl_prefix ::= */ + -5, /* (113) seltablist ::= stl_prefix nm dbnm as on_using */ + -6, /* (114) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ + -8, /* (115) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ + -6, /* (116) seltablist ::= stl_prefix LP select RP as on_using */ + -6, /* (117) seltablist ::= stl_prefix LP seltablist RP as on_using */ + 0, /* (118) dbnm ::= */ + -2, /* (119) dbnm ::= DOT nm */ + -1, /* (120) fullname ::= nm */ + -3, /* (121) fullname ::= nm DOT nm */ + -1, /* (122) xfullname ::= nm */ + -3, /* (123) xfullname ::= nm DOT nm */ + -5, /* (124) xfullname ::= nm DOT nm AS nm */ + -3, /* (125) xfullname ::= nm AS nm */ + -1, /* (126) joinop ::= COMMA|JOIN */ + -2, /* (127) joinop ::= JOIN_KW JOIN */ + -3, /* (128) joinop ::= JOIN_KW nm JOIN */ + -4, /* (129) joinop ::= JOIN_KW nm nm JOIN */ + -2, /* (130) on_using ::= ON expr */ + -4, /* (131) on_using ::= USING LP idlist RP */ + 0, /* (132) on_using ::= */ + 0, /* (133) indexed_opt ::= */ + -3, /* (134) indexed_by ::= INDEXED BY nm */ + -2, /* (135) indexed_by ::= NOT INDEXED */ + 0, /* (136) orderby_opt ::= */ + -3, /* (137) orderby_opt ::= ORDER BY sortlist */ + -5, /* (138) sortlist ::= sortlist COMMA expr sortorder nulls */ + -3, /* (139) sortlist ::= expr sortorder nulls */ + -1, /* (140) sortorder ::= ASC */ + -1, /* (141) sortorder ::= DESC */ + 0, /* (142) sortorder ::= */ + -2, /* (143) nulls ::= NULLS FIRST */ + -2, /* (144) nulls ::= NULLS LAST */ + 0, /* (145) nulls ::= */ + 0, /* (146) groupby_opt ::= */ + -3, /* (147) groupby_opt ::= GROUP BY nexprlist */ + 0, /* (148) having_opt ::= */ + -2, /* (149) having_opt ::= HAVING expr */ + 0, /* (150) limit_opt ::= */ + -2, /* (151) limit_opt ::= LIMIT expr */ + -4, /* (152) limit_opt ::= LIMIT expr OFFSET expr */ + -4, /* (153) limit_opt ::= LIMIT expr COMMA expr */ + -6, /* (154) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + 0, /* (155) where_opt ::= */ + -2, /* (156) where_opt ::= WHERE expr */ + 0, /* (157) where_opt_ret ::= */ + -2, /* (158) where_opt_ret ::= WHERE expr */ + -2, /* (159) where_opt_ret ::= RETURNING selcollist */ + -4, /* (160) where_opt_ret ::= WHERE expr RETURNING selcollist */ + -9, /* (161) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + -5, /* (162) setlist ::= setlist COMMA nm EQ expr */ + -7, /* (163) setlist ::= setlist COMMA LP idlist RP EQ expr */ + -3, /* (164) setlist ::= nm EQ expr */ + -5, /* (165) setlist ::= LP idlist RP EQ expr */ + -7, /* (166) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + -8, /* (167) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 0, /* (168) upsert ::= */ + -2, /* (169) upsert ::= RETURNING selcollist */ + -12, /* (170) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + -9, /* (171) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + -5, /* (172) upsert ::= ON CONFLICT DO NOTHING returning */ + -8, /* (173) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + -2, /* (174) returning ::= RETURNING selcollist */ + -2, /* (175) insert_cmd ::= INSERT orconf */ + -1, /* (176) insert_cmd ::= REPLACE */ + 0, /* (177) idlist_opt ::= */ + -3, /* (178) idlist_opt ::= LP idlist RP */ + -3, /* (179) idlist ::= idlist COMMA nm */ + -1, /* (180) idlist ::= nm */ + -3, /* (181) expr ::= LP expr RP */ + -1, /* (182) expr ::= ID|INDEXED|JOIN_KW */ + -3, /* (183) expr ::= nm DOT nm */ + -5, /* (184) expr ::= nm DOT nm DOT nm */ + -1, /* (185) term ::= NULL|FLOAT|BLOB */ + -1, /* (186) term ::= STRING */ + -1, /* (187) term ::= INTEGER */ + -1, /* (188) expr ::= VARIABLE */ + -3, /* (189) expr ::= expr COLLATE ID|STRING */ + -6, /* (190) expr ::= CAST LP expr AS typetoken RP */ + -5, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ + -4, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + -6, /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + -5, /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + -1, /* (195) term ::= CTIME_KW */ + -5, /* (196) expr ::= LP nexprlist COMMA expr RP */ + -3, /* (197) expr ::= expr AND expr */ + -3, /* (198) expr ::= expr OR expr */ + -3, /* (199) expr ::= expr LT|GT|GE|LE expr */ + -3, /* (200) expr ::= expr EQ|NE expr */ + -3, /* (201) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + -3, /* (202) expr ::= expr PLUS|MINUS expr */ + -3, /* (203) expr ::= expr STAR|SLASH|REM expr */ + -3, /* (204) expr ::= expr CONCAT expr */ + -2, /* (205) likeop ::= NOT LIKE_KW|MATCH */ + -3, /* (206) expr ::= expr likeop expr */ + -5, /* (207) expr ::= expr likeop expr ESCAPE expr */ + -2, /* (208) expr ::= expr ISNULL|NOTNULL */ + -3, /* (209) expr ::= expr NOT NULL */ + -3, /* (210) expr ::= expr IS expr */ + -4, /* (211) expr ::= expr IS NOT expr */ + -6, /* (212) expr ::= expr IS NOT DISTINCT FROM expr */ + -5, /* (213) expr ::= expr IS DISTINCT FROM expr */ + -2, /* (214) expr ::= NOT expr */ + -2, /* (215) expr ::= BITNOT expr */ + -2, /* (216) expr ::= PLUS|MINUS expr */ + -3, /* (217) expr ::= expr PTR expr */ + -1, /* (218) between_op ::= BETWEEN */ + -2, /* (219) between_op ::= NOT BETWEEN */ + -5, /* (220) expr ::= expr between_op expr AND expr */ + -1, /* (221) in_op ::= IN */ + -2, /* (222) in_op ::= NOT IN */ + -5, /* (223) expr ::= expr in_op LP exprlist RP */ + -3, /* (224) expr ::= LP select RP */ + -5, /* (225) expr ::= expr in_op LP select RP */ + -5, /* (226) expr ::= expr in_op nm dbnm paren_exprlist */ + -4, /* (227) expr ::= EXISTS LP select RP */ + -5, /* (228) expr ::= CASE case_operand case_exprlist case_else END */ + -5, /* (229) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + -4, /* (230) case_exprlist ::= WHEN expr THEN expr */ + -2, /* (231) case_else ::= ELSE expr */ + 0, /* (232) case_else ::= */ + 0, /* (233) case_operand ::= */ + 0, /* (234) exprlist ::= */ + -3, /* (235) nexprlist ::= nexprlist COMMA expr */ + -1, /* (236) nexprlist ::= expr */ + 0, /* (237) paren_exprlist ::= */ + -3, /* (238) paren_exprlist ::= LP exprlist RP */ + -12, /* (239) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + -1, /* (240) uniqueflag ::= UNIQUE */ + 0, /* (241) uniqueflag ::= */ + 0, /* (242) eidlist_opt ::= */ + -3, /* (243) eidlist_opt ::= LP eidlist RP */ + -5, /* (244) eidlist ::= eidlist COMMA nm collate sortorder */ + -3, /* (245) eidlist ::= nm collate sortorder */ + 0, /* (246) collate ::= */ + -2, /* (247) collate ::= COLLATE ID|STRING */ + -4, /* (248) cmd ::= DROP INDEX ifexists fullname */ + -2, /* (249) cmd ::= VACUUM vinto */ + -3, /* (250) cmd ::= VACUUM nm vinto */ + -2, /* (251) vinto ::= INTO expr */ + 0, /* (252) vinto ::= */ + -3, /* (253) cmd ::= PRAGMA nm dbnm */ + -5, /* (254) cmd ::= PRAGMA nm dbnm EQ nmnum */ + -6, /* (255) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + -5, /* (256) cmd ::= PRAGMA nm dbnm EQ minus_num */ + -6, /* (257) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + -2, /* (258) plus_num ::= PLUS INTEGER|FLOAT */ + -2, /* (259) minus_num ::= MINUS INTEGER|FLOAT */ + -5, /* (260) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + -11, /* (261) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + -1, /* (262) trigger_time ::= BEFORE|AFTER */ + -2, /* (263) trigger_time ::= INSTEAD OF */ + 0, /* (264) trigger_time ::= */ + -1, /* (265) trigger_event ::= DELETE|INSERT */ + -1, /* (266) trigger_event ::= UPDATE */ + -3, /* (267) trigger_event ::= UPDATE OF idlist */ + 0, /* (268) when_clause ::= */ + -2, /* (269) when_clause ::= WHEN expr */ + -3, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */ + -3, /* (272) trnm ::= nm DOT nm */ + -3, /* (273) tridxby ::= INDEXED BY nm */ + -2, /* (274) tridxby ::= NOT INDEXED */ + -9, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + -8, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + -6, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + -3, /* (278) trigger_cmd ::= scanpt select scanpt */ + -4, /* (279) expr ::= RAISE LP IGNORE RP */ + -6, /* (280) expr ::= RAISE LP raisetype COMMA nm RP */ + -1, /* (281) raisetype ::= ROLLBACK */ + -1, /* (282) raisetype ::= ABORT */ + -1, /* (283) raisetype ::= FAIL */ + -4, /* (284) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (286) cmd ::= DETACH database_kw_opt expr */ + 0, /* (287) key_opt ::= */ + -2, /* (288) key_opt ::= KEY expr */ + -1, /* (289) cmd ::= REINDEX */ + -3, /* (290) cmd ::= REINDEX nm dbnm */ + -1, /* (291) cmd ::= ANALYZE */ + -3, /* (292) cmd ::= ANALYZE nm dbnm */ + -6, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -7, /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + -6, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + -1, /* (296) add_column_fullname ::= fullname */ + -8, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -9, /* (298) cmd ::= ALTER TABLE fullname ALTER COLUMNKW columnname TO columnname carglist */ + -1, /* (299) cmd ::= create_vtab */ + -4, /* (300) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (301) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (302) vtabarg ::= */ + -1, /* (303) vtabargtoken ::= ANY */ + -3, /* (304) vtabargtoken ::= lp anylist RP */ + -1, /* (305) lp ::= LP */ + -2, /* (306) with ::= WITH wqlist */ + -3, /* (307) with ::= WITH RECURSIVE wqlist */ + -1, /* (308) wqas ::= AS */ + -2, /* (309) wqas ::= AS MATERIALIZED */ + -3, /* (310) wqas ::= AS NOT MATERIALIZED */ + -6, /* (311) wqitem ::= nm eidlist_opt wqas LP select RP */ + -1, /* (312) wqlist ::= wqitem */ + -3, /* (313) wqlist ::= wqlist COMMA wqitem */ + -1, /* (314) windowdefn_list ::= windowdefn */ + -3, /* (315) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + -5, /* (316) windowdefn ::= nm AS LP window RP */ + -5, /* (317) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + -6, /* (318) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + -4, /* (319) window ::= ORDER BY sortlist frame_opt */ + -5, /* (320) window ::= nm ORDER BY sortlist frame_opt */ + -1, /* (321) window ::= frame_opt */ + -2, /* (322) window ::= nm frame_opt */ + 0, /* (323) frame_opt ::= */ + -3, /* (324) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + -6, /* (325) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + -1, /* (326) range_or_rows ::= RANGE|ROWS|GROUPS */ + -1, /* (327) frame_bound_s ::= frame_bound */ + -2, /* (328) frame_bound_s ::= UNBOUNDED PRECEDING */ + -1, /* (329) frame_bound_e ::= frame_bound */ + -2, /* (330) frame_bound_e ::= UNBOUNDED FOLLOWING */ + -2, /* (331) frame_bound ::= expr PRECEDING|FOLLOWING */ + -2, /* (332) frame_bound ::= CURRENT ROW */ + 0, /* (333) frame_exclude_opt ::= */ + -2, /* (334) frame_exclude_opt ::= EXCLUDE frame_exclude */ + -2, /* (335) frame_exclude ::= NO OTHERS */ + -2, /* (336) frame_exclude ::= CURRENT ROW */ + -1, /* (337) frame_exclude ::= GROUP|TIES */ + -2, /* (338) window_clause ::= WINDOW windowdefn_list */ + -2, /* (339) filter_over ::= filter_clause over_clause */ + -1, /* (340) filter_over ::= over_clause */ + -1, /* (341) filter_over ::= filter_clause */ + -4, /* (342) over_clause ::= OVER LP window RP */ + -2, /* (343) over_clause ::= OVER nm */ + -5, /* (344) filter_clause ::= FILTER LP WHERE expr RP */ + -1, /* (345) input ::= cmdlist */ + -2, /* (346) cmdlist ::= cmdlist ecmd */ + -1, /* (347) cmdlist ::= ecmd */ + -1, /* (348) ecmd ::= SEMI */ + -2, /* (349) ecmd ::= cmdx SEMI */ + -3, /* (350) ecmd ::= explain cmdx SEMI */ + 0, /* (351) trans_opt ::= */ + -1, /* (352) trans_opt ::= TRANSACTION */ + -2, /* (353) trans_opt ::= TRANSACTION nm */ + -1, /* (354) savepoint_opt ::= SAVEPOINT */ + 0, /* (355) savepoint_opt ::= */ + -2, /* (356) cmd ::= create_table create_table_args */ + -1, /* (357) table_option_set ::= table_option */ + -4, /* (358) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (359) columnlist ::= columnname carglist */ + -1, /* (360) nm ::= ID|INDEXED|JOIN_KW */ + -1, /* (361) nm ::= STRING */ + -1, /* (362) typetoken ::= typename */ + -1, /* (363) typename ::= ID|STRING */ + -1, /* (364) signed ::= plus_num */ + -1, /* (365) signed ::= minus_num */ + -2, /* (366) carglist ::= carglist ccons */ + 0, /* (367) carglist ::= */ + -2, /* (368) ccons ::= NULL onconf */ + -4, /* (369) ccons ::= GENERATED ALWAYS AS generated */ + -2, /* (370) ccons ::= AS generated */ + -2, /* (371) conslist_opt ::= COMMA conslist */ + -3, /* (372) conslist ::= conslist tconscomma tcons */ + -1, /* (373) conslist ::= tcons */ + 0, /* (374) tconscomma ::= */ + -1, /* (375) defer_subclause_opt ::= defer_subclause */ + -1, /* (376) resolvetype ::= raisetype */ + -1, /* (377) selectnowith ::= oneselect */ + -1, /* (378) oneselect ::= values */ + -2, /* (379) sclp ::= selcollist COMMA */ + -1, /* (380) as ::= ID|STRING */ + -1, /* (381) indexed_opt ::= indexed_by */ + 0, /* (382) returning ::= */ + -1, /* (383) expr ::= term */ + -1, /* (384) likeop ::= LIKE_KW|MATCH */ + -1, /* (385) case_operand ::= expr */ + -1, /* (386) exprlist ::= nexprlist */ + -1, /* (387) nmnum ::= plus_num */ + -1, /* (388) nmnum ::= nm */ + -1, /* (389) nmnum ::= ON */ + -1, /* (390) nmnum ::= DELETE */ + -1, /* (391) nmnum ::= DEFAULT */ + -1, /* (392) plus_num ::= INTEGER|FLOAT */ + 0, /* (393) foreach_clause ::= */ + -3, /* (394) foreach_clause ::= FOR EACH ROW */ + -1, /* (395) trnm ::= nm */ + 0, /* (396) tridxby ::= */ + -1, /* (397) database_kw_opt ::= DATABASE */ + 0, /* (398) database_kw_opt ::= */ + 0, /* (399) kwcolumn_opt ::= */ + -1, /* (400) kwcolumn_opt ::= COLUMNKW */ + -1, /* (401) vtabarglist ::= vtabarg */ + -3, /* (402) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (403) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (404) anylist ::= */ + -4, /* (405) anylist ::= anylist LP anylist RP */ + -2, /* (406) anylist ::= anylist ANY */ + 0, /* (407) with ::= */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -173972,25 +172793,25 @@ 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); } break; case 3: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy394);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy436);} break; case 4: /* transtype ::= */ -{yymsp[1].minor.yy394 = TK_DEFERRED;} +{yymsp[1].minor.yy436 = TK_DEFERRED;} break; case 5: /* transtype ::= DEFERRED */ case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); - case 321: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==321); -{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/} + case 326: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==326); +{yymsp[0].minor.yy436 = yymsp[0].major; /*A-overwrites-X*/} break; case 8: /* cmd ::= COMMIT|END trans_opt */ case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); @@ -174013,7 +172834,7 @@ static YYACTIONTYPE yy_reduce( break; case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { - sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy394,0,0,yymsp[-2].minor.yy394); + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy436,0,0,yymsp[-2].minor.yy436); } break; case 14: /* createkw ::= CREATE */ @@ -174021,112 +172842,122 @@ static YYACTIONTYPE yy_reduce( break; case 15: /* ifnotexists ::= */ case 18: /* temp ::= */ yytestcase(yyruleno==18); - case 47: /* autoinc ::= */ yytestcase(yyruleno==47); - case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62); - case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72); - case 81: /* ifexists ::= */ yytestcase(yyruleno==81); - case 98: /* distinct ::= */ yytestcase(yyruleno==98); - case 244: /* collate ::= */ yytestcase(yyruleno==244); -{yymsp[1].minor.yy394 = 0;} + case 48: /* autoinc ::= */ yytestcase(yyruleno==48); + case 63: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==63); + case 73: /* defer_subclause_opt ::= */ yytestcase(yyruleno==73); + case 82: /* ifexists ::= */ yytestcase(yyruleno==82); + case 102: /* distinct ::= */ yytestcase(yyruleno==102); + case 246: /* collate ::= */ yytestcase(yyruleno==246); +{yymsp[1].minor.yy436 = 0;} break; case 16: /* ifnotexists ::= IF NOT EXISTS */ -{yymsp[-2].minor.yy394 = 1;} +{yymsp[-2].minor.yy436 = 1;} break; case 17: /* temp ::= TEMP */ -{yymsp[0].minor.yy394 = pParse->db->init.busy==0;} +{yymsp[0].minor.yy436 = pParse->db->init.busy==0;} break; case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */ { - sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy285,0); + sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy135,0); } break; case 20: /* create_table_args ::= AS select */ { - sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy47); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47); + sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy136); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy136); } break; case 21: /* table_option_set ::= */ -{yymsp[1].minor.yy285 = 0;} +{yymsp[1].minor.yy135 = 0;} break; case 22: /* table_option_set ::= table_option_set COMMA table_option */ -{yylhsminor.yy285 = yymsp[-2].minor.yy285|yymsp[0].minor.yy285;} - yymsp[-2].minor.yy285 = yylhsminor.yy285; +{yylhsminor.yy135 = yymsp[-2].minor.yy135|yymsp[0].minor.yy135;} + yymsp[-2].minor.yy135 = yylhsminor.yy135; break; case 23: /* table_option ::= WITHOUT nm */ { if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ - yymsp[-1].minor.yy285 = TF_WithoutRowid | TF_NoVisibleRowid; + yymsp[-1].minor.yy135 = TF_WithoutRowid | TF_NoVisibleRowid; }else{ - yymsp[-1].minor.yy285 = 0; + yymsp[-1].minor.yy135 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } break; - case 24: /* table_option ::= nm */ + case 24: /* table_option ::= RANDOM nm */ +{ + if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ + yymsp[-1].minor.yy135 = TF_RandomRowid; + }else{ + yymsp[-1].minor.yy135 = 0; + sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); + } +} + break; + case 25: /* table_option ::= nm */ { if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){ - yylhsminor.yy285 = TF_Strict; + yylhsminor.yy135 = TF_Strict; }else{ - yylhsminor.yy285 = 0; + yylhsminor.yy135 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } - yymsp[0].minor.yy285 = yylhsminor.yy285; + yymsp[0].minor.yy135 = yylhsminor.yy135; break; - case 25: /* columnname ::= nm typetoken */ + case 26: /* columnname ::= nm typetoken */ {sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);} break; - case 26: /* typetoken ::= */ - case 65: /* conslist_opt ::= */ yytestcase(yyruleno==65); - case 104: /* as ::= */ yytestcase(yyruleno==104); + case 27: /* typetoken ::= */ + case 66: /* conslist_opt ::= */ yytestcase(yyruleno==66); + case 108: /* as ::= */ yytestcase(yyruleno==108); {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;} break; - case 27: /* typetoken ::= typename LP signed RP */ + case 28: /* typetoken ::= typename LP signed RP */ { yymsp[-3].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z); } break; - case 28: /* typetoken ::= typename LP signed COMMA signed RP */ + case 29: /* typetoken ::= typename LP signed COMMA signed RP */ { yymsp[-5].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z); } break; - case 29: /* typename ::= typename ID|STRING */ + case 30: /* typename ::= typename ID|STRING */ {yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);} break; - case 30: /* scanpt ::= */ + case 31: /* scanpt ::= */ { assert( yyLookahead!=YYNOCODE ); - yymsp[1].minor.yy522 = yyLookaheadToken.z; + yymsp[1].minor.yy594 = yyLookaheadToken.z; } break; - case 31: /* scantok ::= */ + case 32: /* scantok ::= */ { assert( yyLookahead!=YYNOCODE ); yymsp[1].minor.yy0 = yyLookaheadToken; } break; - case 32: /* ccons ::= CONSTRAINT nm */ - case 67: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==67); + case 33: /* ccons ::= CONSTRAINT nm */ + case 68: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==68); {pParse->constraintName = yymsp[0].minor.yy0;} break; - case 33: /* ccons ::= DEFAULT scantok term */ -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} + case 34: /* ccons ::= DEFAULT scantok term */ +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy224,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; - case 34: /* ccons ::= DEFAULT LP expr RP */ -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} + case 35: /* ccons ::= DEFAULT LP expr RP */ +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy224,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} break; - case 35: /* ccons ::= DEFAULT PLUS scantok term */ -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} + case 36: /* ccons ::= DEFAULT PLUS scantok term */ +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy224,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; - case 36: /* ccons ::= DEFAULT MINUS scantok term */ + case 37: /* ccons ::= DEFAULT MINUS scantok term */ { - Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy528, 0); + Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy224, 0); sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); } break; - case 37: /* ccons ::= DEFAULT scantok ID|INDEXED */ + case 38: /* ccons ::= DEFAULT scantok ID|INDEXED */ { Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0); if( p ){ @@ -174136,161 +172967,177 @@ static YYACTIONTYPE yy_reduce( sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n); } break; - case 38: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy394);} + case 39: /* ccons ::= NOT NULL onconf */ +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy436);} break; - case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy394,yymsp[0].minor.yy394,yymsp[-2].minor.yy394);} + case 40: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy436,yymsp[0].minor.yy436,yymsp[-2].minor.yy436);} break; - case 40: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy394,0,0,0,0, + case 41: /* ccons ::= UNIQUE onconf */ +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy436,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; - case 41: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} + case 42: /* ccons ::= CHECK LP expr RP */ +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy224,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} break; - case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */ -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy394);} + case 43: /* ccons ::= REFERENCES nm eidlist_opt refargs */ +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy586,yymsp[0].minor.yy436);} break; - case 43: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy394);} + case 44: /* ccons ::= defer_subclause */ +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy436);} break; - case 44: /* ccons ::= COLLATE ID|STRING */ + case 45: /* ccons ::= COLLATE ID|STRING */ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; - case 45: /* generated ::= LP expr RP */ -{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy528,0);} + case 46: /* generated ::= LP expr RP */ +{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy224,0);} break; - case 46: /* generated ::= LP expr RP ID */ -{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy528,&yymsp[0].minor.yy0);} + case 47: /* generated ::= LP expr RP ID */ +{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy224,&yymsp[0].minor.yy0);} break; - case 48: /* autoinc ::= AUTOINCR */ -{yymsp[0].minor.yy394 = 1;} + case 49: /* autoinc ::= AUTOINCR */ +{yymsp[0].minor.yy436 = 1;} break; - case 49: /* refargs ::= */ -{ yymsp[1].minor.yy394 = OE_None*0x0101; /* EV: R-19803-45884 */} + case 50: /* refargs ::= */ +{ yymsp[1].minor.yy436 = OE_None*0x0101; /* EV: R-19803-45884 */} break; - case 50: /* refargs ::= refargs refarg */ -{ yymsp[-1].minor.yy394 = (yymsp[-1].minor.yy394 & ~yymsp[0].minor.yy231.mask) | yymsp[0].minor.yy231.value; } + case 51: /* refargs ::= refargs refarg */ +{ yymsp[-1].minor.yy436 = (yymsp[-1].minor.yy436 & ~yymsp[0].minor.yy275.mask) | yymsp[0].minor.yy275.value; } break; - case 51: /* refarg ::= MATCH nm */ -{ yymsp[-1].minor.yy231.value = 0; yymsp[-1].minor.yy231.mask = 0x000000; } + case 52: /* refarg ::= MATCH nm */ +{ yymsp[-1].minor.yy275.value = 0; yymsp[-1].minor.yy275.mask = 0x000000; } break; - case 52: /* refarg ::= ON INSERT refact */ -{ yymsp[-2].minor.yy231.value = 0; yymsp[-2].minor.yy231.mask = 0x000000; } + case 53: /* refarg ::= ON INSERT refact */ +{ yymsp[-2].minor.yy275.value = 0; yymsp[-2].minor.yy275.mask = 0x000000; } break; - case 53: /* refarg ::= ON DELETE refact */ -{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394; yymsp[-2].minor.yy231.mask = 0x0000ff; } + case 54: /* refarg ::= ON DELETE refact */ +{ yymsp[-2].minor.yy275.value = yymsp[0].minor.yy436; yymsp[-2].minor.yy275.mask = 0x0000ff; } break; - case 54: /* refarg ::= ON UPDATE refact */ -{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394<<8; yymsp[-2].minor.yy231.mask = 0x00ff00; } + case 55: /* refarg ::= ON UPDATE refact */ +{ yymsp[-2].minor.yy275.value = yymsp[0].minor.yy436<<8; yymsp[-2].minor.yy275.mask = 0x00ff00; } break; - case 55: /* refact ::= SET NULL */ -{ yymsp[-1].minor.yy394 = OE_SetNull; /* EV: R-33326-45252 */} + case 56: /* refact ::= SET NULL */ +{ yymsp[-1].minor.yy436 = OE_SetNull; /* EV: R-33326-45252 */} break; - case 56: /* refact ::= SET DEFAULT */ -{ yymsp[-1].minor.yy394 = OE_SetDflt; /* EV: R-33326-45252 */} + case 57: /* refact ::= SET DEFAULT */ +{ yymsp[-1].minor.yy436 = OE_SetDflt; /* EV: R-33326-45252 */} break; - case 57: /* refact ::= CASCADE */ -{ yymsp[0].minor.yy394 = OE_Cascade; /* EV: R-33326-45252 */} + case 58: /* refact ::= CASCADE */ +{ yymsp[0].minor.yy436 = OE_Cascade; /* EV: R-33326-45252 */} break; - case 58: /* refact ::= RESTRICT */ -{ yymsp[0].minor.yy394 = OE_Restrict; /* EV: R-33326-45252 */} + case 59: /* refact ::= RESTRICT */ +{ yymsp[0].minor.yy436 = OE_Restrict; /* EV: R-33326-45252 */} break; - case 59: /* refact ::= NO ACTION */ -{ yymsp[-1].minor.yy394 = OE_None; /* EV: R-33326-45252 */} + case 60: /* refact ::= NO ACTION */ +{ yymsp[-1].minor.yy436 = OE_None; /* EV: R-33326-45252 */} break; - case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -{yymsp[-2].minor.yy394 = 0;} + case 61: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ +{yymsp[-2].minor.yy436 = 0;} break; - case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76); - case 171: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==171); -{yymsp[-1].minor.yy394 = yymsp[0].minor.yy394;} + case 62: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + case 77: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==77); + case 175: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==175); +{yymsp[-1].minor.yy436 = yymsp[0].minor.yy436;} break; - case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ - case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); - case 217: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==217); - case 220: /* in_op ::= NOT IN */ yytestcase(yyruleno==220); - case 245: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==245); -{yymsp[-1].minor.yy394 = 1;} + case 64: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ + case 81: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==81); + case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219); + case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222); + case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247); +{yymsp[-1].minor.yy436 = 1;} break; - case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -{yymsp[-1].minor.yy394 = 0;} + case 65: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ +{yymsp[-1].minor.yy436 = 0;} break; - case 66: /* tconscomma ::= COMMA */ + case 67: /* tconscomma ::= COMMA */ {pParse->constraintName.n = 0;} break; - case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy394,yymsp[-2].minor.yy394,0);} + case 69: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy586,yymsp[0].minor.yy436,yymsp[-2].minor.yy436,0);} break; - case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */ -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy394,0,0,0,0, + case 70: /* tcons ::= UNIQUE LP sortlist RP onconf */ +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy586,yymsp[0].minor.yy436,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; - case 70: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy528,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} + case 71: /* tcons ::= CHECK LP expr RP onconf */ +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy224,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} break; - case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + case 72: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy394); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy394); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy586, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy586, yymsp[-1].minor.yy436); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy436); } break; - case 73: /* onconf ::= */ - case 75: /* orconf ::= */ yytestcase(yyruleno==75); -{yymsp[1].minor.yy394 = OE_Default;} + case 74: /* onconf ::= */ + case 76: /* orconf ::= */ yytestcase(yyruleno==76); +{yymsp[1].minor.yy436 = OE_Default;} break; - case 74: /* onconf ::= ON CONFLICT resolvetype */ -{yymsp[-2].minor.yy394 = yymsp[0].minor.yy394;} + case 75: /* onconf ::= ON CONFLICT resolvetype */ +{yymsp[-2].minor.yy436 = yymsp[0].minor.yy436;} break; - case 77: /* resolvetype ::= IGNORE */ -{yymsp[0].minor.yy394 = OE_Ignore;} + case 78: /* resolvetype ::= IGNORE */ +{yymsp[0].minor.yy436 = OE_Ignore;} break; - case 78: /* resolvetype ::= REPLACE */ - case 172: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==172); -{yymsp[0].minor.yy394 = OE_Replace;} + case 79: /* resolvetype ::= REPLACE */ + case 176: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==176); +{yymsp[0].minor.yy436 = OE_Replace;} break; - case 79: /* cmd ::= DROP TABLE ifexists fullname */ + case 80: /* cmd ::= DROP TABLE ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy131, 0, yymsp[-1].minor.yy394); + sqlite3DropTable(pParse, yymsp[0].minor.yy493, 0, yymsp[-1].minor.yy436); } break; - case 82: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + case 83: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ { - sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[0].minor.yy47, yymsp[-7].minor.yy394, yymsp[-5].minor.yy394); + sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy586, yymsp[0].minor.yy136, yymsp[-7].minor.yy436, yymsp[-5].minor.yy436); } break; - case 83: /* cmd ::= DROP VIEW ifexists fullname */ + case 84: /* cmd ::= DROP VIEW ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy131, 1, yymsp[-1].minor.yy394); + sqlite3DropTable(pParse, yymsp[0].minor.yy493, 1, yymsp[-1].minor.yy436); } break; - case 84: /* cmd ::= select */ + case 85: /* cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS STRING */ +{ + libsql_create_function(pParse, &yymsp[-4].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, 0, yymsp[-5].minor.yy436); +} + break; + case 86: /* cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS BLOB */ +{ + libsql_create_function(pParse, &yymsp[-4].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, 1, yymsp[-5].minor.yy436); +} + break; + case 87: /* cmd ::= DROP FUNCTION ifexists nm */ +{ + libsql_drop_function(pParse, &yymsp[0].minor.yy0, yymsp[-1].minor.yy436); +} + break; + case 88: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy47, &dest); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47); + sqlite3Select(pParse, yymsp[0].minor.yy136, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy136); } break; - case 85: /* select ::= WITH wqlist selectnowith */ -{yymsp[-2].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);} + case 89: /* select ::= WITH wqlist selectnowith */ +{yymsp[-2].minor.yy136 = attachWithToSelect(pParse,yymsp[0].minor.yy136,yymsp[-1].minor.yy19);} break; - case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */ -{yymsp[-3].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);} + case 90: /* select ::= WITH RECURSIVE wqlist selectnowith */ +{yymsp[-3].minor.yy136 = attachWithToSelect(pParse,yymsp[0].minor.yy136,yymsp[-1].minor.yy19);} break; - case 87: /* select ::= selectnowith */ + case 91: /* select ::= selectnowith */ { - Select *p = yymsp[0].minor.yy47; + Select *p = yymsp[0].minor.yy136; if( p ){ parserDoubleLinkSelect(pParse, p); } + yymsp[0].minor.yy136 = p; /*A-overwrites-X*/ } break; - case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */ + case 92: /* selectnowith ::= selectnowith multiselect_op oneselect */ { - Select *pRhs = yymsp[0].minor.yy47; - Select *pLhs = yymsp[-2].minor.yy47; + Select *pRhs = yymsp[0].minor.yy136; + Select *pLhs = yymsp[-2].minor.yy136; if( pRhs && pRhs->pPrior ){ SrcList *pFrom; Token x; @@ -174300,148 +173147,145 @@ static YYACTIONTYPE yy_reduce( pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ - pRhs->op = (u8)yymsp[-1].minor.yy394; + pRhs->op = (u8)yymsp[-1].minor.yy436; pRhs->pPrior = pLhs; if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; pRhs->selFlags &= ~SF_MultiValue; - if( yymsp[-1].minor.yy394!=TK_ALL ) pParse->hasCompound = 1; + if( yymsp[-1].minor.yy436!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); } - yymsp[-2].minor.yy47 = pRhs; + yymsp[-2].minor.yy136 = pRhs; } break; - case 89: /* multiselect_op ::= UNION */ - case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91); -{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-OP*/} + case 93: /* multiselect_op ::= UNION */ + case 95: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==95); +{yymsp[0].minor.yy436 = yymsp[0].major; /*A-overwrites-OP*/} break; - case 90: /* multiselect_op ::= UNION ALL */ -{yymsp[-1].minor.yy394 = TK_ALL;} + case 94: /* multiselect_op ::= UNION ALL */ +{yymsp[-1].minor.yy436 = TK_ALL;} break; - case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + case 96: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { - yymsp[-8].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy131,yymsp[-4].minor.yy528,yymsp[-3].minor.yy322,yymsp[-2].minor.yy528,yymsp[-1].minor.yy322,yymsp[-7].minor.yy394,yymsp[0].minor.yy528); + yymsp[-8].minor.yy136 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy586,yymsp[-5].minor.yy493,yymsp[-4].minor.yy224,yymsp[-3].minor.yy586,yymsp[-2].minor.yy224,yymsp[-1].minor.yy586,yymsp[-7].minor.yy436,yymsp[0].minor.yy224); } break; - case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + case 97: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ { - yymsp[-9].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy322,yymsp[-6].minor.yy131,yymsp[-5].minor.yy528,yymsp[-4].minor.yy322,yymsp[-3].minor.yy528,yymsp[-1].minor.yy322,yymsp[-8].minor.yy394,yymsp[0].minor.yy528); - if( yymsp[-9].minor.yy47 ){ - yymsp[-9].minor.yy47->pWinDefn = yymsp[-2].minor.yy41; + yymsp[-9].minor.yy136 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy586,yymsp[-6].minor.yy493,yymsp[-5].minor.yy224,yymsp[-4].minor.yy586,yymsp[-3].minor.yy224,yymsp[-1].minor.yy586,yymsp[-8].minor.yy436,yymsp[0].minor.yy224); + if( yymsp[-9].minor.yy136 ){ + yymsp[-9].minor.yy136->pWinDefn = yymsp[-2].minor.yy591; }else{ - sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy41); + sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy591); } } break; - case 94: /* values ::= VALUES LP nexprlist RP */ + case 98: /* values ::= VALUES LP nexprlist RP */ { - yymsp[-3].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values,0); + yymsp[-3].minor.yy136 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy586,0,0,0,0,0,SF_Values,0); } break; - case 95: /* values ::= values COMMA LP nexprlist RP */ + case 99: /* values ::= values COMMA LP nexprlist RP */ { - Select *pRight, *pLeft = yymsp[-4].minor.yy47; - pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values|SF_MultiValue,0); + Select *pRight, *pLeft = yymsp[-4].minor.yy136; + pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy586,0,0,0,0,0,SF_Values|SF_MultiValue,0); if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; if( pRight ){ pRight->op = TK_ALL; pRight->pPrior = pLeft; - yymsp[-4].minor.yy47 = pRight; + yymsp[-4].minor.yy136 = pRight; }else{ - yymsp[-4].minor.yy47 = pLeft; + yymsp[-4].minor.yy136 = pLeft; } } break; - case 96: /* distinct ::= DISTINCT */ -{yymsp[0].minor.yy394 = SF_Distinct;} + case 100: /* distinct ::= DISTINCT */ +{yymsp[0].minor.yy436 = SF_Distinct;} break; - case 97: /* distinct ::= ALL */ -{yymsp[0].minor.yy394 = SF_All;} + case 101: /* distinct ::= ALL */ +{yymsp[0].minor.yy436 = SF_All;} break; - case 99: /* sclp ::= */ - case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132); - case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142); - case 232: /* exprlist ::= */ yytestcase(yyruleno==232); - case 235: /* paren_exprlist ::= */ yytestcase(yyruleno==235); - case 240: /* eidlist_opt ::= */ yytestcase(yyruleno==240); -{yymsp[1].minor.yy322 = 0;} + case 103: /* sclp ::= */ + case 136: /* orderby_opt ::= */ yytestcase(yyruleno==136); + case 146: /* groupby_opt ::= */ yytestcase(yyruleno==146); + case 234: /* exprlist ::= */ yytestcase(yyruleno==234); + case 237: /* paren_exprlist ::= */ yytestcase(yyruleno==237); + case 242: /* eidlist_opt ::= */ yytestcase(yyruleno==242); +{yymsp[1].minor.yy586 = 0;} break; - case 100: /* selcollist ::= sclp scanpt expr scanpt as */ + case 104: /* selcollist ::= sclp scanpt expr scanpt as */ { - yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy322,yymsp[-3].minor.yy522,yymsp[-1].minor.yy522); + yymsp[-4].minor.yy586 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy586, yymsp[-2].minor.yy224); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy586, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy586,yymsp[-3].minor.yy594,yymsp[-1].minor.yy594); } break; - case 101: /* selcollist ::= sclp scanpt STAR */ + case 105: /* 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.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, p); + yymsp[-2].minor.yy586 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy586, p); } break; - case 102: /* selcollist ::= sclp scanpt nm DOT STAR */ + case 106: /* 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); - yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot); -} - break; - case 103: /* as ::= AS nm */ - case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115); - case 256: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==256); - case 257: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==257); + 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.yy586 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy586, pDot); +} + break; + case 107: /* as ::= AS nm */ + case 119: /* dbnm ::= DOT nm */ yytestcase(yyruleno==119); + case 258: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==258); + case 259: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==259); {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} break; - case 105: /* from ::= */ - case 108: /* stl_prefix ::= */ yytestcase(yyruleno==108); -{yymsp[1].minor.yy131 = 0;} + case 109: /* from ::= */ + case 112: /* stl_prefix ::= */ yytestcase(yyruleno==112); +{yymsp[1].minor.yy493 = 0;} break; - case 106: /* from ::= FROM seltablist */ + case 110: /* from ::= FROM seltablist */ { - yymsp[-1].minor.yy131 = yymsp[0].minor.yy131; - sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy131); + yymsp[-1].minor.yy493 = yymsp[0].minor.yy493; + sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy493); } break; - case 107: /* stl_prefix ::= seltablist joinop */ + case 111: /* stl_prefix ::= seltablist joinop */ { - if( ALWAYS(yymsp[-1].minor.yy131 && yymsp[-1].minor.yy131->nSrc>0) ) yymsp[-1].minor.yy131->a[yymsp[-1].minor.yy131->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy394; + if( ALWAYS(yymsp[-1].minor.yy493 && yymsp[-1].minor.yy493->nSrc>0) ) yymsp[-1].minor.yy493->a[yymsp[-1].minor.yy493->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy436; } break; - case 109: /* seltablist ::= stl_prefix nm dbnm as on_using */ + case 113: /* seltablist ::= stl_prefix nm dbnm as on_using */ { - yymsp[-4].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy131,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); + yymsp[-4].minor.yy493 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy493,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy5); } break; - case 110: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ + case 114: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ { - yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy561); - sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-1].minor.yy0); + yymsp[-5].minor.yy493 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy493,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy5); + sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy493, &yymsp[-1].minor.yy0); } break; - case 111: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ + case 115: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ { - yymsp[-7].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy131,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); - sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy131, yymsp[-3].minor.yy322); + yymsp[-7].minor.yy493 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy493,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy5); + sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy493, yymsp[-3].minor.yy586); } break; - case 112: /* seltablist ::= stl_prefix LP select RP as on_using */ + case 116: /* seltablist ::= stl_prefix LP select RP as on_using */ { - yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy47,&yymsp[0].minor.yy561); + yymsp[-5].minor.yy493 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy493,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy136,&yymsp[0].minor.yy5); } break; - case 113: /* seltablist ::= stl_prefix LP seltablist RP as on_using */ + case 117: /* seltablist ::= stl_prefix LP seltablist RP as on_using */ { - if( yymsp[-5].minor.yy131==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy561.pOn==0 && yymsp[0].minor.yy561.pUsing==0 ){ - yymsp[-5].minor.yy131 = yymsp[-3].minor.yy131; - }else if( ALWAYS(yymsp[-3].minor.yy131!=0) && yymsp[-3].minor.yy131->nSrc==1 ){ - yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); - if( yymsp[-5].minor.yy131 ){ - SrcItem *pNew = &yymsp[-5].minor.yy131->a[yymsp[-5].minor.yy131->nSrc-1]; - SrcItem *pOld = yymsp[-3].minor.yy131->a; + if( yymsp[-5].minor.yy493==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy5.pOn==0 && yymsp[0].minor.yy5.pUsing==0 ){ + yymsp[-5].minor.yy493 = yymsp[-3].minor.yy493; + }else if( ALWAYS(yymsp[-3].minor.yy493!=0) && yymsp[-3].minor.yy493->nSrc==1 ){ + yymsp[-5].minor.yy493 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy493,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy5); + if( yymsp[-5].minor.yy493 ){ + SrcItem *pNew = &yymsp[-5].minor.yy493->a[yymsp[-5].minor.yy493->nSrc-1]; + SrcItem *pOld = yymsp[-3].minor.yy493->a; pNew->zName = pOld->zName; pNew->zDatabase = pOld->zDatabase; pNew->pSelect = pOld->pSelect; @@ -174457,153 +173301,153 @@ static YYACTIONTYPE yy_reduce( pOld->zName = pOld->zDatabase = 0; pOld->pSelect = 0; } - sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy131); + sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy493); }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy131); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy131,0,0,0,0,SF_NestedFrom,0); - yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy561); + sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy493); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy493,0,0,0,0,SF_NestedFrom,0); + yymsp[-5].minor.yy493 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy493,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy5); } } break; - case 114: /* dbnm ::= */ - case 129: /* indexed_opt ::= */ yytestcase(yyruleno==129); + case 118: /* dbnm ::= */ + case 133: /* indexed_opt ::= */ yytestcase(yyruleno==133); {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} break; - case 116: /* fullname ::= nm */ + case 120: /* fullname ::= nm */ { - yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); - if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy493 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); + if( IN_RENAME_OBJECT && yylhsminor.yy493 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy493->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy131 = yylhsminor.yy131; + yymsp[0].minor.yy493 = yylhsminor.yy493; break; - case 117: /* fullname ::= nm DOT nm */ + case 121: /* fullname ::= nm DOT nm */ { - yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); - if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy493 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + if( IN_RENAME_OBJECT && yylhsminor.yy493 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy493->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy131 = yylhsminor.yy131; + yymsp[-2].minor.yy493 = yylhsminor.yy493; break; - case 118: /* xfullname ::= nm */ -{yymsp[0].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} + case 122: /* xfullname ::= nm */ +{yymsp[0].minor.yy493 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} break; - case 119: /* xfullname ::= nm DOT nm */ -{yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 123: /* xfullname ::= nm DOT nm */ +{yymsp[-2].minor.yy493 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 120: /* xfullname ::= nm DOT nm AS nm */ + case 124: /* xfullname ::= nm DOT nm AS nm */ { - yymsp[-4].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ - if( yymsp[-4].minor.yy131 ) yymsp[-4].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-4].minor.yy493 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ + if( yymsp[-4].minor.yy493 ) yymsp[-4].minor.yy493->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; - case 121: /* xfullname ::= nm AS nm */ + case 125: /* xfullname ::= nm AS nm */ { - yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ - if( yymsp[-2].minor.yy131 ) yymsp[-2].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-2].minor.yy493 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ + if( yymsp[-2].minor.yy493 ) yymsp[-2].minor.yy493->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; - case 122: /* joinop ::= COMMA|JOIN */ -{ yymsp[0].minor.yy394 = JT_INNER; } + case 126: /* joinop ::= COMMA|JOIN */ +{ yymsp[0].minor.yy436 = JT_INNER; } break; - case 123: /* joinop ::= JOIN_KW JOIN */ -{yymsp[-1].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} + case 127: /* joinop ::= JOIN_KW JOIN */ +{yymsp[-1].minor.yy436 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} break; - case 124: /* joinop ::= JOIN_KW nm JOIN */ -{yymsp[-2].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} + case 128: /* joinop ::= JOIN_KW nm JOIN */ +{yymsp[-2].minor.yy436 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} break; - case 125: /* joinop ::= JOIN_KW nm nm JOIN */ -{yymsp[-3].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} + case 129: /* joinop ::= JOIN_KW nm nm JOIN */ +{yymsp[-3].minor.yy436 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} break; - case 126: /* on_using ::= ON expr */ -{yymsp[-1].minor.yy561.pOn = yymsp[0].minor.yy528; yymsp[-1].minor.yy561.pUsing = 0;} + case 130: /* on_using ::= ON expr */ +{yymsp[-1].minor.yy5.pOn = yymsp[0].minor.yy224; yymsp[-1].minor.yy5.pUsing = 0;} break; - case 127: /* on_using ::= USING LP idlist RP */ -{yymsp[-3].minor.yy561.pOn = 0; yymsp[-3].minor.yy561.pUsing = yymsp[-1].minor.yy254;} + case 131: /* on_using ::= USING LP idlist RP */ +{yymsp[-3].minor.yy5.pOn = 0; yymsp[-3].minor.yy5.pUsing = yymsp[-1].minor.yy600;} break; - case 128: /* on_using ::= */ -{yymsp[1].minor.yy561.pOn = 0; yymsp[1].minor.yy561.pUsing = 0;} + case 132: /* on_using ::= */ +{yymsp[1].minor.yy5.pOn = 0; yymsp[1].minor.yy5.pUsing = 0;} break; - case 130: /* indexed_by ::= INDEXED BY nm */ + case 134: /* indexed_by ::= INDEXED BY nm */ {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} break; - case 131: /* indexed_by ::= NOT INDEXED */ + case 135: /* indexed_by ::= NOT INDEXED */ {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} break; - case 133: /* orderby_opt ::= ORDER BY sortlist */ - case 143: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==143); -{yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;} + case 137: /* orderby_opt ::= ORDER BY sortlist */ + case 147: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==147); +{yymsp[-2].minor.yy586 = yymsp[0].minor.yy586;} break; - case 134: /* sortlist ::= sortlist COMMA expr sortorder nulls */ + case 138: /* sortlist ::= sortlist COMMA expr sortorder nulls */ { - yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322,yymsp[-2].minor.yy528); - sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394); + yymsp[-4].minor.yy586 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy586,yymsp[-2].minor.yy224); + sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy586,yymsp[-1].minor.yy436,yymsp[0].minor.yy436); } break; - case 135: /* sortlist ::= expr sortorder nulls */ + case 139: /* sortlist ::= expr sortorder nulls */ { - yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy528); /*A-overwrites-Y*/ - sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394); + yymsp[-2].minor.yy586 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy224); /*A-overwrites-Y*/ + sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy586,yymsp[-1].minor.yy436,yymsp[0].minor.yy436); } break; - case 136: /* sortorder ::= ASC */ -{yymsp[0].minor.yy394 = SQLITE_SO_ASC;} + case 140: /* sortorder ::= ASC */ +{yymsp[0].minor.yy436 = SQLITE_SO_ASC;} break; - case 137: /* sortorder ::= DESC */ -{yymsp[0].minor.yy394 = SQLITE_SO_DESC;} + case 141: /* sortorder ::= DESC */ +{yymsp[0].minor.yy436 = SQLITE_SO_DESC;} break; - case 138: /* sortorder ::= */ - case 141: /* nulls ::= */ yytestcase(yyruleno==141); -{yymsp[1].minor.yy394 = SQLITE_SO_UNDEFINED;} + case 142: /* sortorder ::= */ + case 145: /* nulls ::= */ yytestcase(yyruleno==145); +{yymsp[1].minor.yy436 = SQLITE_SO_UNDEFINED;} break; - case 139: /* nulls ::= NULLS FIRST */ -{yymsp[-1].minor.yy394 = SQLITE_SO_ASC;} + case 143: /* nulls ::= NULLS FIRST */ +{yymsp[-1].minor.yy436 = SQLITE_SO_ASC;} break; - case 140: /* nulls ::= NULLS LAST */ -{yymsp[-1].minor.yy394 = SQLITE_SO_DESC;} + case 144: /* nulls ::= NULLS LAST */ +{yymsp[-1].minor.yy436 = SQLITE_SO_DESC;} break; - case 144: /* having_opt ::= */ - case 146: /* limit_opt ::= */ yytestcase(yyruleno==146); - case 151: /* where_opt ::= */ yytestcase(yyruleno==151); - case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153); - case 230: /* case_else ::= */ yytestcase(yyruleno==230); - case 231: /* case_operand ::= */ yytestcase(yyruleno==231); - case 250: /* vinto ::= */ yytestcase(yyruleno==250); -{yymsp[1].minor.yy528 = 0;} + case 148: /* having_opt ::= */ + case 150: /* limit_opt ::= */ yytestcase(yyruleno==150); + case 155: /* where_opt ::= */ yytestcase(yyruleno==155); + case 157: /* where_opt_ret ::= */ yytestcase(yyruleno==157); + case 232: /* case_else ::= */ yytestcase(yyruleno==232); + case 233: /* case_operand ::= */ yytestcase(yyruleno==233); + case 252: /* vinto ::= */ yytestcase(yyruleno==252); +{yymsp[1].minor.yy224 = 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 229: /* case_else ::= ELSE expr */ yytestcase(yyruleno==229); - case 249: /* vinto ::= INTO expr */ yytestcase(yyruleno==249); -{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;} + case 149: /* having_opt ::= HAVING expr */ + case 156: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==156); + case 158: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==158); + case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231); + case 251: /* vinto ::= INTO expr */ yytestcase(yyruleno==251); +{yymsp[-1].minor.yy224 = yymsp[0].minor.yy224;} break; - case 147: /* limit_opt ::= LIMIT expr */ -{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);} + case 151: /* limit_opt ::= LIMIT expr */ +{yymsp[-1].minor.yy224 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy224,0);} break; - case 148: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} + case 152: /* limit_opt ::= LIMIT expr OFFSET expr */ +{yymsp[-3].minor.yy224 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy224,yymsp[0].minor.yy224);} break; - case 149: /* limit_opt ::= LIMIT expr COMMA expr */ -{yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,yymsp[-2].minor.yy528);} + case 153: /* limit_opt ::= LIMIT expr COMMA expr */ +{yymsp[-3].minor.yy224 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy224,yymsp[-2].minor.yy224);} break; - case 150: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + case 154: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy131, &yymsp[-1].minor.yy0); - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy131,yymsp[0].minor.yy528,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy493, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy493,yymsp[0].minor.yy224,0,0); } break; - case 155: /* where_opt_ret ::= RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-1].minor.yy528 = 0;} + case 159: /* where_opt_ret ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy586); yymsp[-1].minor.yy224 = 0;} break; - case 156: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-3].minor.yy528 = yymsp[-2].minor.yy528;} + case 160: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy586); yymsp[-3].minor.yy224 = yymsp[-2].minor.yy224;} break; - case 157: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + case 161: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-4].minor.yy0); - sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy322,"set list"); - if( yymsp[-1].minor.yy131 ){ - SrcList *pFromClause = yymsp[-1].minor.yy131; + sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy493, &yymsp[-4].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy586,"set list"); + if( yymsp[-1].minor.yy493 ){ + SrcList *pFromClause = yymsp[-1].minor.yy493; if( pFromClause->nSrc>1 ){ Select *pSubquery; Token as; @@ -174612,92 +173456,92 @@ static YYACTIONTYPE yy_reduce( as.z = 0; pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0); } - yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, pFromClause); + yymsp[-5].minor.yy493 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy493, pFromClause); } - sqlite3Update(pParse,yymsp[-5].minor.yy131,yymsp[-2].minor.yy322,yymsp[0].minor.yy528,yymsp[-6].minor.yy394,0,0,0); + sqlite3Update(pParse,yymsp[-5].minor.yy493,yymsp[-2].minor.yy586,yymsp[0].minor.yy224,yymsp[-6].minor.yy436,0,0,0); } break; - case 158: /* setlist ::= setlist COMMA nm EQ expr */ + case 162: /* setlist ::= setlist COMMA nm EQ expr */ { - yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy528); - sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, 1); + yymsp[-4].minor.yy586 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy586, yymsp[0].minor.yy224); + sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy586, &yymsp[-2].minor.yy0, 1); } break; - case 159: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ + case 163: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ { - yymsp[-6].minor.yy322 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy322, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); + yymsp[-6].minor.yy586 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy586, yymsp[-3].minor.yy600, yymsp[0].minor.yy224); } break; - case 160: /* setlist ::= nm EQ expr */ + case 164: /* setlist ::= nm EQ expr */ { - yylhsminor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy528); - sqlite3ExprListSetName(pParse, yylhsminor.yy322, &yymsp[-2].minor.yy0, 1); + yylhsminor.yy586 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy224); + sqlite3ExprListSetName(pParse, yylhsminor.yy586, &yymsp[-2].minor.yy0, 1); } - yymsp[-2].minor.yy322 = yylhsminor.yy322; + yymsp[-2].minor.yy586 = yylhsminor.yy586; break; - case 161: /* setlist ::= LP idlist RP EQ expr */ + case 165: /* setlist ::= LP idlist RP EQ expr */ { - yymsp[-4].minor.yy322 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); + yymsp[-4].minor.yy586 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy600, yymsp[0].minor.yy224); } break; - case 162: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + case 166: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy131, yymsp[-1].minor.yy47, yymsp[-2].minor.yy254, yymsp[-5].minor.yy394, yymsp[0].minor.yy444); + sqlite3Insert(pParse, yymsp[-3].minor.yy493, yymsp[-1].minor.yy136, yymsp[-2].minor.yy600, yymsp[-5].minor.yy436, yymsp[0].minor.yy6); } break; - case 163: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + case 167: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ { - sqlite3Insert(pParse, yymsp[-4].minor.yy131, 0, yymsp[-3].minor.yy254, yymsp[-6].minor.yy394, 0); + sqlite3Insert(pParse, yymsp[-4].minor.yy493, 0, yymsp[-3].minor.yy600, yymsp[-6].minor.yy436, 0); } break; - case 164: /* upsert ::= */ -{ yymsp[1].minor.yy444 = 0; } + case 168: /* upsert ::= */ +{ yymsp[1].minor.yy6 = 0; } break; - case 165: /* upsert ::= RETURNING selcollist */ -{ yymsp[-1].minor.yy444 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy322); } + case 169: /* upsert ::= RETURNING selcollist */ +{ yymsp[-1].minor.yy6 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy586); } break; - case 166: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ -{ yymsp[-11].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy322,yymsp[-6].minor.yy528,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,yymsp[0].minor.yy444);} + case 170: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ +{ yymsp[-11].minor.yy6 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy586,yymsp[-6].minor.yy224,yymsp[-2].minor.yy586,yymsp[-1].minor.yy224,yymsp[0].minor.yy6);} break; - case 167: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ -{ yymsp[-8].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy322,yymsp[-3].minor.yy528,0,0,yymsp[0].minor.yy444); } + case 171: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ +{ yymsp[-8].minor.yy6 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy586,yymsp[-3].minor.yy224,0,0,yymsp[0].minor.yy6); } break; - case 168: /* upsert ::= ON CONFLICT DO NOTHING returning */ -{ yymsp[-4].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } + case 172: /* upsert ::= ON CONFLICT DO NOTHING returning */ +{ yymsp[-4].minor.yy6 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } break; - case 169: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ -{ yymsp[-7].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,0);} + case 173: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ +{ yymsp[-7].minor.yy6 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy586,yymsp[-1].minor.yy224,0);} break; - case 170: /* returning ::= RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy322);} + case 174: /* returning ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy586);} break; - case 173: /* idlist_opt ::= */ -{yymsp[1].minor.yy254 = 0;} + case 177: /* idlist_opt ::= */ +{yymsp[1].minor.yy600 = 0;} break; - case 174: /* idlist_opt ::= LP idlist RP */ -{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;} + case 178: /* idlist_opt ::= LP idlist RP */ +{yymsp[-2].minor.yy600 = yymsp[-1].minor.yy600;} break; - case 175: /* idlist ::= idlist COMMA nm */ -{yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);} + case 179: /* idlist ::= idlist COMMA nm */ +{yymsp[-2].minor.yy600 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy600,&yymsp[0].minor.yy0);} break; - case 176: /* idlist ::= nm */ -{yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} + case 180: /* idlist ::= nm */ +{yymsp[0].minor.yy600 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} break; - case 177: /* expr ::= LP expr RP */ -{yymsp[-2].minor.yy528 = yymsp[-1].minor.yy528;} + case 181: /* expr ::= LP expr RP */ +{yymsp[-2].minor.yy224 = yymsp[-1].minor.yy224;} break; - case 178: /* expr ::= ID|INDEXED|JOIN_KW */ -{yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 182: /* expr ::= ID|INDEXED|JOIN_KW */ +{yymsp[0].minor.yy224=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 179: /* expr ::= nm DOT nm */ + case 183: /* expr ::= nm DOT nm */ { Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); - yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); + yylhsminor.yy224 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } - yymsp[-2].minor.yy528 = yylhsminor.yy528; + yymsp[-2].minor.yy224 = yylhsminor.yy224; break; - case 180: /* expr ::= nm DOT nm DOT nm */ + case 184: /* 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); @@ -174706,27 +173550,27 @@ static YYACTIONTYPE yy_reduce( if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, 0, temp1); } - yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); + yylhsminor.yy224 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } - yymsp[-4].minor.yy528 = yylhsminor.yy528; + yymsp[-4].minor.yy224 = yylhsminor.yy224; break; - case 181: /* term ::= NULL|FLOAT|BLOB */ - case 182: /* term ::= STRING */ yytestcase(yyruleno==182); -{yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 185: /* term ::= NULL|FLOAT|BLOB */ + case 186: /* term ::= STRING */ yytestcase(yyruleno==186); +{yymsp[0].minor.yy224=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 183: /* term ::= INTEGER */ + case 187: /* term ::= INTEGER */ { - yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); - if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); + yylhsminor.yy224 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); + if( yylhsminor.yy224 ) yylhsminor.yy224->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); } - yymsp[0].minor.yy528 = yylhsminor.yy528; + yymsp[0].minor.yy224 = yylhsminor.yy224; break; - case 184: /* expr ::= VARIABLE */ + case 188: /* expr ::= VARIABLE */ { if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ u32 n = yymsp[0].minor.yy0.n; - yymsp[0].minor.yy528 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy528, n); + yymsp[0].minor.yy224 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy224, n); }else{ /* When doing a nested parse, one can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers @@ -174735,194 +173579,179 @@ static YYACTIONTYPE yy_reduce( assert( t.n>=2 ); if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); - yymsp[0].minor.yy528 = 0; + yymsp[0].minor.yy224 = 0; }else{ - yymsp[0].minor.yy528 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); - if( yymsp[0].minor.yy528 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy528->iTable); + yymsp[0].minor.yy224 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( yymsp[0].minor.yy224 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy224->iTable); } } } break; - case 185: /* expr ::= expr COLLATE ID|STRING */ -{ - yymsp[-2].minor.yy528 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy528, &yymsp[0].minor.yy0, 1); -} - break; - case 186: /* expr ::= CAST LP expr AS typetoken RP */ -{ - yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); - sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy528, yymsp[-3].minor.yy528, 0); -} - break; - case 187: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ + case 189: /* expr ::= expr COLLATE ID|STRING */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy394); + yymsp[-2].minor.yy224 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy224, &yymsp[0].minor.yy0, 1); } - yymsp[-4].minor.yy528 = yylhsminor.yy528; break; - case 188: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ + case 190: /* expr ::= CAST LP expr AS typetoken RP */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy322, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy394); - sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy528, yymsp[-1].minor.yy322); + yymsp[-5].minor.yy224 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); + sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy224, yymsp[-3].minor.yy224, 0); } - yymsp[-7].minor.yy528 = yylhsminor.yy528; break; - case 189: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + case 191: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); + yylhsminor.yy224 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy586, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy436); } - yymsp[-3].minor.yy528 = yylhsminor.yy528; + yymsp[-4].minor.yy224 = yylhsminor.yy224; break; - case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + case 192: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy322, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy394); - sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); + yylhsminor.yy224 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } - yymsp[-5].minor.yy528 = yylhsminor.yy528; + yymsp[-3].minor.yy224 = yylhsminor.yy224; break; - case 191: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ + case 193: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy322, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy394); - sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); - sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy528, yymsp[-2].minor.yy322); + yylhsminor.yy224 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy586, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy436); + sqlite3WindowAttach(pParse, yylhsminor.yy224, yymsp[0].minor.yy591); } - yymsp[-8].minor.yy528 = yylhsminor.yy528; + yymsp[-5].minor.yy224 = yylhsminor.yy224; break; - case 192: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + case 194: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); - sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); + yylhsminor.yy224 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); + sqlite3WindowAttach(pParse, yylhsminor.yy224, yymsp[0].minor.yy591); } - yymsp[-4].minor.yy528 = yylhsminor.yy528; + yymsp[-4].minor.yy224 = yylhsminor.yy224; break; - case 193: /* term ::= CTIME_KW */ + case 195: /* term ::= CTIME_KW */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); + yylhsminor.yy224 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } - yymsp[0].minor.yy528 = yylhsminor.yy528; + yymsp[0].minor.yy224 = yylhsminor.yy224; break; - case 194: /* expr ::= LP nexprlist COMMA expr RP */ + case 196: /* expr ::= LP nexprlist COMMA expr RP */ { - ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528); - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); - if( yymsp[-4].minor.yy528 ){ - yymsp[-4].minor.yy528->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy586, yymsp[-1].minor.yy224); + yymsp[-4].minor.yy224 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( yymsp[-4].minor.yy224 ){ + yymsp[-4].minor.yy224->x.pList = pList; if( ALWAYS(pList->nExpr) ){ - yymsp[-4].minor.yy528->flags |= pList->a[0].pExpr->flags & EP_Propagate; + yymsp[-4].minor.yy224->flags |= pList->a[0].pExpr->flags & EP_Propagate; } }else{ sqlite3ExprListDelete(pParse->db, pList); } } break; - case 195: /* expr ::= expr AND expr */ -{yymsp[-2].minor.yy528=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} + case 197: /* expr ::= expr AND expr */ +{yymsp[-2].minor.yy224=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy224,yymsp[0].minor.yy224);} break; - case 196: /* expr ::= expr OR expr */ - case 197: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==197); - case 198: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==198); - case 199: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==199); - case 200: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==200); - case 201: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==201); - case 202: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==202); -{yymsp[-2].minor.yy528=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} + case 198: /* expr ::= expr OR expr */ + case 199: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==199); + case 200: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==200); + case 201: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==201); + case 202: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==202); + case 203: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==203); + case 204: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==204); +{yymsp[-2].minor.yy224=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy224,yymsp[0].minor.yy224);} break; - case 203: /* likeop ::= NOT LIKE_KW|MATCH */ + case 205: /* likeop ::= NOT LIKE_KW|MATCH */ {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} break; - case 204: /* expr ::= expr likeop expr */ + case 206: /* expr ::= expr likeop expr */ { ExprList *pList; int bNot = yymsp[-1].minor.yy0.n & 0x80000000; yymsp[-1].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy528); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy528); - yymsp[-2].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); - if( bNot ) yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy528, 0); - if( yymsp[-2].minor.yy528 ) yymsp[-2].minor.yy528->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy224); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy224); + yymsp[-2].minor.yy224 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + if( bNot ) yymsp[-2].minor.yy224 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy224, 0); + if( yymsp[-2].minor.yy224 ) yymsp[-2].minor.yy224->flags |= EP_InfixFunc; } break; - case 205: /* expr ::= expr likeop expr ESCAPE expr */ + case 207: /* expr ::= expr likeop expr ESCAPE expr */ { ExprList *pList; int bNot = yymsp[-3].minor.yy0.n & 0x80000000; yymsp[-3].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy528); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); - yymsp[-4].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); - if( bNot ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); - if( yymsp[-4].minor.yy528 ) yymsp[-4].minor.yy528->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy224); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy224); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy224); + yymsp[-4].minor.yy224 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); + if( bNot ) yymsp[-4].minor.yy224 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy224, 0); + if( yymsp[-4].minor.yy224 ) yymsp[-4].minor.yy224->flags |= EP_InfixFunc; } break; - case 206: /* expr ::= expr ISNULL|NOTNULL */ -{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy528,0);} + case 208: /* expr ::= expr ISNULL|NOTNULL */ +{yymsp[-1].minor.yy224 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy224,0);} break; - case 207: /* expr ::= expr NOT NULL */ -{yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy528,0);} + case 209: /* expr ::= expr NOT NULL */ +{yymsp[-2].minor.yy224 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy224,0);} break; - case 208: /* expr ::= expr IS expr */ + case 210: /* expr ::= expr IS expr */ { - yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy528,yymsp[0].minor.yy528); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-2].minor.yy528, TK_ISNULL); + yymsp[-2].minor.yy224 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy224,yymsp[0].minor.yy224); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy224, yymsp[-2].minor.yy224, TK_ISNULL); } break; - case 209: /* expr ::= expr IS NOT expr */ + case 211: /* expr ::= expr IS NOT expr */ { - yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL); + yymsp[-3].minor.yy224 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy224,yymsp[0].minor.yy224); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy224, yymsp[-3].minor.yy224, TK_NOTNULL); } break; - case 210: /* expr ::= expr IS NOT DISTINCT FROM expr */ + case 212: /* expr ::= expr IS NOT DISTINCT FROM expr */ { - yymsp[-5].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy528,yymsp[0].minor.yy528); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-5].minor.yy528, TK_ISNULL); + yymsp[-5].minor.yy224 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy224,yymsp[0].minor.yy224); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy224, yymsp[-5].minor.yy224, TK_ISNULL); } break; - case 211: /* expr ::= expr IS DISTINCT FROM expr */ + case 213: /* expr ::= expr IS DISTINCT FROM expr */ { - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy528,yymsp[0].minor.yy528); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-4].minor.yy528, TK_NOTNULL); + yymsp[-4].minor.yy224 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy224,yymsp[0].minor.yy224); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy224, yymsp[-4].minor.yy224, TK_NOTNULL); } break; - case 212: /* expr ::= NOT expr */ - case 213: /* expr ::= BITNOT expr */ yytestcase(yyruleno==213); -{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/} + case 214: /* expr ::= NOT expr */ + case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215); +{yymsp[-1].minor.yy224 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy224, 0);/*A-overwrites-B*/} break; - case 214: /* expr ::= PLUS|MINUS expr */ + case 216: /* expr ::= PLUS|MINUS expr */ { - yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0); + yymsp[-1].minor.yy224 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy224, 0); /*A-overwrites-B*/ } break; - case 215: /* expr ::= expr PTR expr */ + case 217: /* expr ::= expr PTR expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528); - pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528); - yylhsminor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy224); + pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy224); + yylhsminor.yy224 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); } - yymsp[-2].minor.yy528 = yylhsminor.yy528; + yymsp[-2].minor.yy224 = yylhsminor.yy224; break; - case 216: /* between_op ::= BETWEEN */ - case 219: /* in_op ::= IN */ yytestcase(yyruleno==219); -{yymsp[0].minor.yy394 = 0;} + case 218: /* between_op ::= BETWEEN */ + case 221: /* in_op ::= IN */ yytestcase(yyruleno==221); +{yymsp[0].minor.yy436 = 0;} break; - case 218: /* expr ::= expr between_op expr AND expr */ + case 220: /* expr ::= expr between_op expr AND expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy528, 0); - if( yymsp[-4].minor.yy528 ){ - yymsp[-4].minor.yy528->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy224); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy224); + yymsp[-4].minor.yy224 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy224, 0); + if( yymsp[-4].minor.yy224 ){ + yymsp[-4].minor.yy224->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } - if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + if( yymsp[-3].minor.yy436 ) yymsp[-4].minor.yy224 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy224, 0); } break; - case 221: /* expr ::= expr in_op LP exprlist RP */ + case 223: /* expr ::= expr in_op LP exprlist RP */ { - if( yymsp[-1].minor.yy322==0 ){ + if( yymsp[-1].minor.yy586==0 ){ /* Expressions of the form ** ** expr1 IN () @@ -174931,208 +173760,208 @@ static YYACTIONTYPE yy_reduce( ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ - sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy528); - yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy394 ? "true" : "false"); - if( yymsp[-4].minor.yy528 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy528); - }else{ - Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr; - if( yymsp[-1].minor.yy322->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy528->op!=TK_VECTOR ){ - yymsp[-1].minor.yy322->a[0].pExpr = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy224); + yymsp[-4].minor.yy224 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy436 ? "true" : "false"); + if( yymsp[-4].minor.yy224 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy224); + }else{ + Expr *pRHS = yymsp[-1].minor.yy586->a[0].pExpr; + if( yymsp[-1].minor.yy586->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy224->op!=TK_VECTOR ){ + yymsp[-1].minor.yy586->a[0].pExpr = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy586); pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy528, pRHS); - }else if( yymsp[-1].minor.yy322->nExpr==1 && pRHS->op==TK_SELECT ){ - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pRHS->x.pSelect); + yymsp[-4].minor.yy224 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy224, pRHS); + }else if( yymsp[-1].minor.yy586->nExpr==1 && pRHS->op==TK_SELECT ){ + yymsp[-4].minor.yy224 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy224, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy224, pRHS->x.pSelect); pRHS->x.pSelect = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy586); }else{ - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); - if( yymsp[-4].minor.yy528==0 ){ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); - }else if( yymsp[-4].minor.yy528->pLeft->op==TK_VECTOR ){ - int nExpr = yymsp[-4].minor.yy528->pLeft->x.pList->nExpr; - Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy322); + yymsp[-4].minor.yy224 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy224, 0); + if( yymsp[-4].minor.yy224==0 ){ + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy586); + }else if( yymsp[-4].minor.yy224->pLeft->op==TK_VECTOR ){ + int nExpr = yymsp[-4].minor.yy224->pLeft->x.pList->nExpr; + Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy586); if( pSelectRHS ){ parserDoubleLinkSelect(pParse, pSelectRHS); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelectRHS); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy224, pSelectRHS); } }else{ - yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy322; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528); + yymsp[-4].minor.yy224->x.pList = yymsp[-1].minor.yy586; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy224); } } - if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + if( yymsp[-3].minor.yy436 ) yymsp[-4].minor.yy224 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy224, 0); } } break; - case 222: /* expr ::= LP select RP */ + case 224: /* expr ::= LP select RP */ { - yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); - sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47); + yymsp[-2].minor.yy224 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy224, yymsp[-1].minor.yy136); } break; - case 223: /* expr ::= expr in_op LP select RP */ + case 225: /* expr ::= expr in_op LP select RP */ { - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47); - if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + yymsp[-4].minor.yy224 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy224, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy224, yymsp[-1].minor.yy136); + if( yymsp[-3].minor.yy436 ) yymsp[-4].minor.yy224 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy224, 0); } break; - case 224: /* expr ::= expr in_op nm dbnm paren_exprlist */ + case 226: /* expr ::= expr in_op nm dbnm paren_exprlist */ { SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); - if( yymsp[0].minor.yy322 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy322); - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelect); - if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + if( yymsp[0].minor.yy586 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy586); + yymsp[-4].minor.yy224 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy224, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy224, pSelect); + if( yymsp[-3].minor.yy436 ) yymsp[-4].minor.yy224 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy224, 0); } break; - case 225: /* expr ::= EXISTS LP select RP */ + case 227: /* expr ::= EXISTS LP select RP */ { Expr *p; - p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); - sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47); + p = yymsp[-3].minor.yy224 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy136); } break; - case 226: /* expr ::= CASE case_operand case_exprlist case_else END */ + case 228: /* expr ::= CASE case_operand case_exprlist case_else END */ { - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0); - if( yymsp[-4].minor.yy528 ){ - yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy528 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528) : yymsp[-2].minor.yy322; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528); + yymsp[-4].minor.yy224 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy224, 0); + if( yymsp[-4].minor.yy224 ){ + yymsp[-4].minor.yy224->x.pList = yymsp[-1].minor.yy224 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy586,yymsp[-1].minor.yy224) : yymsp[-2].minor.yy586; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy224); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322); - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy586); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy224); } } break; - case 227: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { - yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); - yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528); + yymsp[-4].minor.yy586 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy586, yymsp[-2].minor.yy224); + yymsp[-4].minor.yy586 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy586, yymsp[0].minor.yy224); } break; - case 228: /* case_exprlist ::= WHEN expr THEN expr */ + case 230: /* case_exprlist ::= WHEN expr THEN expr */ { - yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); - yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528); + yymsp[-3].minor.yy586 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy224); + yymsp[-3].minor.yy586 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy586, yymsp[0].minor.yy224); } break; - case 233: /* nexprlist ::= nexprlist COMMA expr */ -{yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);} + case 235: /* nexprlist ::= nexprlist COMMA expr */ +{yymsp[-2].minor.yy586 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy586,yymsp[0].minor.yy224);} break; - case 234: /* nexprlist ::= expr */ -{yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/} + case 236: /* nexprlist ::= expr */ +{yymsp[0].minor.yy586 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy224); /*A-overwrites-Y*/} break; - case 236: /* paren_exprlist ::= LP exprlist RP */ - case 241: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==241); -{yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;} + case 238: /* paren_exprlist ::= LP exprlist RP */ + case 243: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==243); +{yymsp[-2].minor.yy586 = yymsp[-1].minor.yy586;} break; - case 237: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ { sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, - sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394, - &yymsp[-11].minor.yy0, yymsp[0].minor.yy528, SQLITE_SO_ASC, yymsp[-8].minor.yy394, SQLITE_IDXTYPE_APPDEF); + sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy586, yymsp[-10].minor.yy436, + &yymsp[-11].minor.yy0, yymsp[0].minor.yy224, SQLITE_SO_ASC, yymsp[-8].minor.yy436, SQLITE_IDXTYPE_APPDEF); if( IN_RENAME_OBJECT && pParse->pNewIndex ){ sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); } } break; - case 238: /* uniqueflag ::= UNIQUE */ - case 280: /* raisetype ::= ABORT */ yytestcase(yyruleno==280); -{yymsp[0].minor.yy394 = OE_Abort;} + case 240: /* uniqueflag ::= UNIQUE */ + case 282: /* raisetype ::= ABORT */ yytestcase(yyruleno==282); +{yymsp[0].minor.yy436 = OE_Abort;} break; - case 239: /* uniqueflag ::= */ -{yymsp[1].minor.yy394 = OE_None;} + case 241: /* uniqueflag ::= */ +{yymsp[1].minor.yy436 = OE_None;} break; - case 242: /* eidlist ::= eidlist COMMA nm collate sortorder */ + case 244: /* eidlist ::= eidlist COMMA nm collate sortorder */ { - yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); + yymsp[-4].minor.yy586 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy586, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy436, yymsp[0].minor.yy436); } break; - case 243: /* eidlist ::= nm collate sortorder */ + case 245: /* eidlist ::= nm collate sortorder */ { - yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/ + yymsp[-2].minor.yy586 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy436, yymsp[0].minor.yy436); /*A-overwrites-Y*/ } break; - case 246: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);} + case 248: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy493, yymsp[-1].minor.yy436);} break; - case 247: /* cmd ::= VACUUM vinto */ -{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);} + case 249: /* cmd ::= VACUUM vinto */ +{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy224);} break; - case 248: /* cmd ::= VACUUM nm vinto */ -{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);} + case 250: /* cmd ::= VACUUM nm vinto */ +{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy224);} break; - case 251: /* cmd ::= PRAGMA nm dbnm */ + case 253: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ + case 254: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; - case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ + case 255: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; - case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ + case 256: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; - case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ + case 257: /* 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 258: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + case 260: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ { Token all; all.z = yymsp[-3].minor.yy0.z; all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy137, &all); } break; - case 259: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 261: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy436, yymsp[-4].minor.yy510.a, yymsp[-4].minor.yy510.b, yymsp[-2].minor.yy493, yymsp[0].minor.yy224, yymsp[-10].minor.yy436, yymsp[-8].minor.yy436); yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ } break; - case 260: /* trigger_time ::= BEFORE|AFTER */ -{ yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ } + case 262: /* trigger_time ::= BEFORE|AFTER */ +{ yymsp[0].minor.yy436 = yymsp[0].major; /*A-overwrites-X*/ } break; - case 261: /* trigger_time ::= INSTEAD OF */ -{ yymsp[-1].minor.yy394 = TK_INSTEAD;} + case 263: /* trigger_time ::= INSTEAD OF */ +{ yymsp[-1].minor.yy436 = TK_INSTEAD;} break; - case 262: /* trigger_time ::= */ -{ yymsp[1].minor.yy394 = TK_BEFORE; } + case 264: /* trigger_time ::= */ +{ yymsp[1].minor.yy436 = TK_BEFORE; } break; - case 263: /* trigger_event ::= DELETE|INSERT */ - case 264: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==264); -{yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;} + case 265: /* trigger_event ::= DELETE|INSERT */ + case 266: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==266); +{yymsp[0].minor.yy510.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy510.b = 0;} break; - case 265: /* trigger_event ::= UPDATE OF idlist */ -{yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;} + case 267: /* trigger_event ::= UPDATE OF idlist */ +{yymsp[-2].minor.yy510.a = TK_UPDATE; yymsp[-2].minor.yy510.b = yymsp[0].minor.yy600;} break; - case 266: /* when_clause ::= */ - case 285: /* key_opt ::= */ yytestcase(yyruleno==285); -{ yymsp[1].minor.yy528 = 0; } + case 268: /* when_clause ::= */ + case 287: /* key_opt ::= */ yytestcase(yyruleno==287); +{ yymsp[1].minor.yy224 = 0; } break; - case 267: /* when_clause ::= WHEN expr */ - case 286: /* key_opt ::= KEY expr */ yytestcase(yyruleno==286); -{ yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; } + case 269: /* when_clause ::= WHEN expr */ + case 288: /* key_opt ::= KEY expr */ yytestcase(yyruleno==288); +{ yymsp[-1].minor.yy224 = yymsp[0].minor.yy224; } break; - case 268: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 270: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { - assert( yymsp[-2].minor.yy33!=0 ); - yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33; - yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33; + assert( yymsp[-2].minor.yy137!=0 ); + yymsp[-2].minor.yy137->pLast->pNext = yymsp[-1].minor.yy137; + yymsp[-2].minor.yy137->pLast = yymsp[-1].minor.yy137; } break; - case 269: /* trigger_cmd_list ::= trigger_cmd SEMI */ + case 271: /* trigger_cmd_list ::= trigger_cmd SEMI */ { - assert( yymsp[-1].minor.yy33!=0 ); - yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33; + assert( yymsp[-1].minor.yy137!=0 ); + yymsp[-1].minor.yy137->pLast = yymsp[-1].minor.yy137; } break; - case 270: /* trnm ::= nm DOT nm */ + case 272: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, @@ -175140,367 +173969,375 @@ static YYACTIONTYPE yy_reduce( "statements within triggers"); } break; - case 271: /* tridxby ::= INDEXED BY nm */ + case 273: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 272: /* tridxby ::= NOT INDEXED */ + case 274: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 273: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ -{yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);} - yymsp[-8].minor.yy33 = yylhsminor.yy33; + case 275: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ +{yylhsminor.yy137 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy493, yymsp[-3].minor.yy586, yymsp[-1].minor.yy224, yymsp[-7].minor.yy436, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy594);} + yymsp[-8].minor.yy137 = yylhsminor.yy137; break; - case 274: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + case 276: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ { - yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/ + yylhsminor.yy137 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy600,yymsp[-2].minor.yy136,yymsp[-6].minor.yy436,yymsp[-1].minor.yy6,yymsp[-7].minor.yy594,yymsp[0].minor.yy594);/*yylhsminor.yy137-overwrites-yymsp[-6].minor.yy436*/ } - yymsp[-7].minor.yy33 = yylhsminor.yy33; + yymsp[-7].minor.yy137 = yylhsminor.yy137; break; - case 275: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -{yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);} - yymsp[-5].minor.yy33 = yylhsminor.yy33; + case 277: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ +{yylhsminor.yy137 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy224, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy594);} + yymsp[-5].minor.yy137 = yylhsminor.yy137; break; - case 276: /* trigger_cmd ::= scanpt select scanpt */ -{yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/} - yymsp[-2].minor.yy33 = yylhsminor.yy33; + case 278: /* trigger_cmd ::= scanpt select scanpt */ +{yylhsminor.yy137 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy136, yymsp[-2].minor.yy594, yymsp[0].minor.yy594); /*yylhsminor.yy137-overwrites-yymsp[-1].minor.yy136*/} + yymsp[-2].minor.yy137 = yylhsminor.yy137; break; - case 277: /* expr ::= RAISE LP IGNORE RP */ + case 279: /* expr ::= RAISE LP IGNORE RP */ { - yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); - if( yymsp[-3].minor.yy528 ){ - yymsp[-3].minor.yy528->affExpr = OE_Ignore; + yymsp[-3].minor.yy224 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); + if( yymsp[-3].minor.yy224 ){ + yymsp[-3].minor.yy224->affExpr = OE_Ignore; } } break; - case 278: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 280: /* expr ::= RAISE LP raisetype COMMA nm RP */ { - yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); - if( yymsp[-5].minor.yy528 ) { - yymsp[-5].minor.yy528->affExpr = (char)yymsp[-3].minor.yy394; + yymsp[-5].minor.yy224 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); + if( yymsp[-5].minor.yy224 ) { + yymsp[-5].minor.yy224->affExpr = (char)yymsp[-3].minor.yy436; } } break; - case 279: /* raisetype ::= ROLLBACK */ -{yymsp[0].minor.yy394 = OE_Rollback;} + case 281: /* raisetype ::= ROLLBACK */ +{yymsp[0].minor.yy436 = OE_Rollback;} break; - case 281: /* raisetype ::= FAIL */ -{yymsp[0].minor.yy394 = OE_Fail;} + case 283: /* raisetype ::= FAIL */ +{yymsp[0].minor.yy436 = OE_Fail;} break; - case 282: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 284: /* cmd ::= DROP TRIGGER ifexists fullname */ { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy493,yymsp[-1].minor.yy436); } break; - case 283: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 285: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { - sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528); + sqlite3Attach(pParse, yymsp[-3].minor.yy224, yymsp[-1].minor.yy224, yymsp[0].minor.yy224); } break; - case 284: /* cmd ::= DETACH database_kw_opt expr */ + case 286: /* cmd ::= DETACH database_kw_opt expr */ { - sqlite3Detach(pParse, yymsp[0].minor.yy528); + sqlite3Detach(pParse, yymsp[0].minor.yy224); } break; - case 287: /* cmd ::= REINDEX */ + case 289: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 288: /* cmd ::= REINDEX nm dbnm */ + case 290: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 289: /* cmd ::= ANALYZE */ + case 291: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 290: /* cmd ::= ANALYZE nm dbnm */ + case 292: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 291: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 293: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy493,&yymsp[0].minor.yy0); } break; - case 292: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + case 294: /* 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 293: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + case 295: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ { - sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0); + sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy493, &yymsp[0].minor.yy0); } break; - case 294: /* add_column_fullname ::= fullname */ + case 296: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy493); } break; - case 295: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + case 297: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ { - sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy493, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 296: /* cmd ::= create_vtab */ + case 298: /* cmd ::= ALTER TABLE fullname ALTER COLUMNKW columnname TO columnname carglist */ +{ + libsqlAlterAlterColumn(pParse, yymsp[-6].minor.yy493, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0); +} + break; + case 299: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 297: /* cmd ::= create_vtab LP vtabarglist RP */ + case 300: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 298: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + case 301: /* 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.yy394); + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy436); } break; - case 299: /* vtabarg ::= */ + case 302: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 300: /* vtabargtoken ::= ANY */ - case 301: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==301); - case 302: /* lp ::= LP */ yytestcase(yyruleno==302); + case 303: /* vtabargtoken ::= ANY */ + case 304: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==304); + case 305: /* lp ::= LP */ yytestcase(yyruleno==305); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; - case 303: /* with ::= WITH wqlist */ - case 304: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==304); -{ sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); } + case 306: /* with ::= WITH wqlist */ + case 307: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==307); +{ sqlite3WithPush(pParse, yymsp[0].minor.yy19, 1); } break; - case 305: /* wqas ::= AS */ -{yymsp[0].minor.yy516 = M10d_Any;} + case 308: /* wqas ::= AS */ +{yymsp[0].minor.yy480 = M10d_Any;} break; - case 306: /* wqas ::= AS MATERIALIZED */ -{yymsp[-1].minor.yy516 = M10d_Yes;} + case 309: /* wqas ::= AS MATERIALIZED */ +{yymsp[-1].minor.yy480 = M10d_Yes;} break; - case 307: /* wqas ::= AS NOT MATERIALIZED */ -{yymsp[-2].minor.yy516 = M10d_No;} + case 310: /* wqas ::= AS NOT MATERIALIZED */ +{yymsp[-2].minor.yy480 = M10d_No;} break; - case 308: /* wqitem ::= nm eidlist_opt wqas LP select RP */ + case 311: /* wqitem ::= nm eidlist_opt wqas LP select RP */ { - yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/ + yymsp[-5].minor.yy615 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy586, yymsp[-1].minor.yy136, yymsp[-3].minor.yy480); /*A-overwrites-X*/ } break; - case 309: /* wqlist ::= wqitem */ + case 312: /* wqlist ::= wqitem */ { - yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/ + yymsp[0].minor.yy19 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy615); /*A-overwrites-X*/ } break; - case 310: /* wqlist ::= wqlist COMMA wqitem */ + case 313: /* wqlist ::= wqlist COMMA wqitem */ { - yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385); + yymsp[-2].minor.yy19 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy19, yymsp[0].minor.yy615); } break; - case 311: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ + case 314: /* windowdefn_list ::= windowdefn */ +{ yylhsminor.yy591 = yymsp[0].minor.yy591; } + yymsp[0].minor.yy591 = yylhsminor.yy591; + break; + case 315: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ { - assert( yymsp[0].minor.yy41!=0 ); - sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41); - yymsp[0].minor.yy41->pNextWin = yymsp[-2].minor.yy41; - yylhsminor.yy41 = yymsp[0].minor.yy41; + assert( yymsp[0].minor.yy591!=0 ); + sqlite3WindowChain(pParse, yymsp[0].minor.yy591, yymsp[-2].minor.yy591); + yymsp[0].minor.yy591->pNextWin = yymsp[-2].minor.yy591; + yylhsminor.yy591 = yymsp[0].minor.yy591; } - yymsp[-2].minor.yy41 = yylhsminor.yy41; + yymsp[-2].minor.yy591 = yylhsminor.yy591; break; - case 312: /* windowdefn ::= nm AS LP window RP */ + case 316: /* windowdefn ::= nm AS LP window RP */ { - if( ALWAYS(yymsp[-1].minor.yy41) ){ - yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); + if( ALWAYS(yymsp[-1].minor.yy591) ){ + yymsp[-1].minor.yy591->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); } - yylhsminor.yy41 = yymsp[-1].minor.yy41; + yylhsminor.yy591 = yymsp[-1].minor.yy591; } - yymsp[-4].minor.yy41 = yylhsminor.yy41; + yymsp[-4].minor.yy591 = yylhsminor.yy591; break; - case 313: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + case 317: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ { - yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0); + yymsp[-4].minor.yy591 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy591, yymsp[-2].minor.yy586, yymsp[-1].minor.yy586, 0); } break; - case 314: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + case 318: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ { - yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0); + yylhsminor.yy591 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy591, yymsp[-2].minor.yy586, yymsp[-1].minor.yy586, &yymsp[-5].minor.yy0); } - yymsp[-5].minor.yy41 = yylhsminor.yy41; + yymsp[-5].minor.yy591 = yylhsminor.yy591; break; - case 315: /* window ::= ORDER BY sortlist frame_opt */ + case 319: /* window ::= ORDER BY sortlist frame_opt */ { - yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0); + yymsp[-3].minor.yy591 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy591, 0, yymsp[-1].minor.yy586, 0); } break; - case 316: /* window ::= nm ORDER BY sortlist frame_opt */ + case 320: /* window ::= nm ORDER BY sortlist frame_opt */ { - yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); + yylhsminor.yy591 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy591, 0, yymsp[-1].minor.yy586, &yymsp[-4].minor.yy0); } - yymsp[-4].minor.yy41 = yylhsminor.yy41; + yymsp[-4].minor.yy591 = yylhsminor.yy591; break; - case 317: /* window ::= nm frame_opt */ + case 321: /* window ::= frame_opt */ + case 340: /* filter_over ::= over_clause */ yytestcase(yyruleno==340); { - yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0); + yylhsminor.yy591 = yymsp[0].minor.yy591; } - yymsp[-1].minor.yy41 = yylhsminor.yy41; + yymsp[0].minor.yy591 = yylhsminor.yy591; break; - case 318: /* frame_opt ::= */ + case 322: /* window ::= nm frame_opt */ { - yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); + yylhsminor.yy591 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy591, 0, 0, &yymsp[-1].minor.yy0); } + yymsp[-1].minor.yy591 = yylhsminor.yy591; break; - case 319: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + case 323: /* frame_opt ::= */ { - yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516); + yymsp[1].minor.yy591 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); } - yymsp[-2].minor.yy41 = yylhsminor.yy41; break; - case 320: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + case 324: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ { - yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516); + yylhsminor.yy591 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy436, yymsp[-1].minor.yy537.eType, yymsp[-1].minor.yy537.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy480); } - yymsp[-5].minor.yy41 = yylhsminor.yy41; + yymsp[-2].minor.yy591 = yylhsminor.yy591; break; - case 322: /* frame_bound_s ::= frame_bound */ - case 324: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==324); -{yylhsminor.yy595 = yymsp[0].minor.yy595;} - yymsp[0].minor.yy595 = yylhsminor.yy595; + case 325: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ +{ + yylhsminor.yy591 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy436, yymsp[-3].minor.yy537.eType, yymsp[-3].minor.yy537.pExpr, yymsp[-1].minor.yy537.eType, yymsp[-1].minor.yy537.pExpr, yymsp[0].minor.yy480); +} + yymsp[-5].minor.yy591 = yylhsminor.yy591; + break; + case 327: /* frame_bound_s ::= frame_bound */ + case 329: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==329); +{yylhsminor.yy537 = yymsp[0].minor.yy537;} + yymsp[0].minor.yy537 = yylhsminor.yy537; break; - case 323: /* frame_bound_s ::= UNBOUNDED PRECEDING */ - case 325: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==325); - case 327: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==327); -{yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;} - yymsp[-1].minor.yy595 = yylhsminor.yy595; + case 328: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 330: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==330); + case 332: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==332); +{yylhsminor.yy537.eType = yymsp[-1].major; yylhsminor.yy537.pExpr = 0;} + yymsp[-1].minor.yy537 = yylhsminor.yy537; break; - case 326: /* frame_bound ::= expr PRECEDING|FOLLOWING */ -{yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;} - yymsp[-1].minor.yy595 = yylhsminor.yy595; + case 331: /* frame_bound ::= expr PRECEDING|FOLLOWING */ +{yylhsminor.yy537.eType = yymsp[0].major; yylhsminor.yy537.pExpr = yymsp[-1].minor.yy224;} + yymsp[-1].minor.yy537 = yylhsminor.yy537; break; - case 328: /* frame_exclude_opt ::= */ -{yymsp[1].minor.yy516 = 0;} + case 333: /* frame_exclude_opt ::= */ +{yymsp[1].minor.yy480 = 0;} break; - case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ -{yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;} + case 334: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ +{yymsp[-1].minor.yy480 = yymsp[0].minor.yy480;} break; - case 330: /* frame_exclude ::= NO OTHERS */ - case 331: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==331); -{yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/} + case 335: /* frame_exclude ::= NO OTHERS */ + case 336: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==336); +{yymsp[-1].minor.yy480 = yymsp[-1].major; /*A-overwrites-X*/} break; - case 332: /* frame_exclude ::= GROUP|TIES */ -{yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/} + case 337: /* frame_exclude ::= GROUP|TIES */ +{yymsp[0].minor.yy480 = yymsp[0].major; /*A-overwrites-X*/} break; - case 333: /* window_clause ::= WINDOW windowdefn_list */ -{ yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; } + case 338: /* window_clause ::= WINDOW windowdefn_list */ +{ yymsp[-1].minor.yy591 = yymsp[0].minor.yy591; } break; - case 334: /* filter_over ::= filter_clause over_clause */ + case 339: /* filter_over ::= filter_clause over_clause */ { - if( yymsp[0].minor.yy41 ){ - yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528; + if( yymsp[0].minor.yy591 ){ + yymsp[0].minor.yy591->pFilter = yymsp[-1].minor.yy224; }else{ - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy224); } - yylhsminor.yy41 = yymsp[0].minor.yy41; + yylhsminor.yy591 = yymsp[0].minor.yy591; } - yymsp[-1].minor.yy41 = yylhsminor.yy41; + yymsp[-1].minor.yy591 = yylhsminor.yy591; break; - case 335: /* filter_over ::= over_clause */ + case 341: /* filter_over ::= filter_clause */ { - yylhsminor.yy41 = yymsp[0].minor.yy41; -} - yymsp[0].minor.yy41 = yylhsminor.yy41; - break; - case 336: /* filter_over ::= filter_clause */ -{ - yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yylhsminor.yy41 ){ - yylhsminor.yy41->eFrmType = TK_FILTER; - yylhsminor.yy41->pFilter = yymsp[0].minor.yy528; + yylhsminor.yy591 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yylhsminor.yy591 ){ + yylhsminor.yy591->eFrmType = TK_FILTER; + yylhsminor.yy591->pFilter = yymsp[0].minor.yy224; }else{ - sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy528); + sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy224); } } - yymsp[0].minor.yy41 = yylhsminor.yy41; + yymsp[0].minor.yy591 = yylhsminor.yy591; break; - case 337: /* over_clause ::= OVER LP window RP */ + case 342: /* over_clause ::= OVER LP window RP */ { - yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41; - assert( yymsp[-3].minor.yy41!=0 ); + yymsp[-3].minor.yy591 = yymsp[-1].minor.yy591; + assert( yymsp[-3].minor.yy591!=0 ); } break; - case 338: /* over_clause ::= OVER nm */ + case 343: /* over_clause ::= OVER nm */ { - yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yymsp[-1].minor.yy41 ){ - yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); + yymsp[-1].minor.yy591 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yymsp[-1].minor.yy591 ){ + yymsp[-1].minor.yy591->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); } } break; - case 339: /* filter_clause ::= FILTER LP WHERE expr RP */ -{ yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; } + case 344: /* filter_clause ::= FILTER LP WHERE expr RP */ +{ yymsp[-4].minor.yy224 = yymsp[-1].minor.yy224; } break; default: - /* (340) input ::= cmdlist */ yytestcase(yyruleno==340); - /* (341) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==341); - /* (342) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=342); - /* (343) ecmd ::= SEMI */ yytestcase(yyruleno==343); - /* (344) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==344); - /* (345) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=345); - /* (346) trans_opt ::= */ yytestcase(yyruleno==346); - /* (347) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==347); - /* (348) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==348); - /* (349) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==349); - /* (350) savepoint_opt ::= */ yytestcase(yyruleno==350); - /* (351) cmd ::= create_table create_table_args */ yytestcase(yyruleno==351); - /* (352) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=352); - /* (353) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==353); - /* (354) columnlist ::= columnname carglist */ yytestcase(yyruleno==354); - /* (355) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==355); - /* (356) nm ::= STRING */ yytestcase(yyruleno==356); - /* (357) typetoken ::= typename */ yytestcase(yyruleno==357); - /* (358) typename ::= ID|STRING */ yytestcase(yyruleno==358); - /* (359) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=359); - /* (360) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=360); - /* (361) carglist ::= carglist ccons */ yytestcase(yyruleno==361); - /* (362) carglist ::= */ yytestcase(yyruleno==362); - /* (363) ccons ::= NULL onconf */ yytestcase(yyruleno==363); - /* (364) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==364); - /* (365) ccons ::= AS generated */ yytestcase(yyruleno==365); - /* (366) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==366); - /* (367) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==367); - /* (368) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=368); - /* (369) tconscomma ::= */ yytestcase(yyruleno==369); - /* (370) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=370); - /* (371) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=371); - /* (372) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=372); - /* (373) oneselect ::= values */ yytestcase(yyruleno==373); - /* (374) sclp ::= selcollist COMMA */ yytestcase(yyruleno==374); - /* (375) as ::= ID|STRING */ yytestcase(yyruleno==375); - /* (376) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=376); - /* (377) returning ::= */ yytestcase(yyruleno==377); - /* (378) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=378); - /* (379) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==379); - /* (380) case_operand ::= expr */ yytestcase(yyruleno==380); - /* (381) exprlist ::= nexprlist */ yytestcase(yyruleno==381); - /* (382) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=382); - /* (383) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=383); - /* (384) nmnum ::= ON */ yytestcase(yyruleno==384); - /* (385) nmnum ::= DELETE */ yytestcase(yyruleno==385); - /* (386) nmnum ::= DEFAULT */ yytestcase(yyruleno==386); - /* (387) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==387); - /* (388) foreach_clause ::= */ yytestcase(yyruleno==388); - /* (389) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==389); - /* (390) trnm ::= nm */ yytestcase(yyruleno==390); - /* (391) tridxby ::= */ yytestcase(yyruleno==391); - /* (392) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==392); - /* (393) database_kw_opt ::= */ yytestcase(yyruleno==393); - /* (394) kwcolumn_opt ::= */ yytestcase(yyruleno==394); - /* (395) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==395); - /* (396) vtabarglist ::= vtabarg */ yytestcase(yyruleno==396); - /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==397); - /* (398) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==398); - /* (399) anylist ::= */ yytestcase(yyruleno==399); - /* (400) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==400); - /* (401) anylist ::= anylist ANY */ yytestcase(yyruleno==401); - /* (402) with ::= */ yytestcase(yyruleno==402); - /* (403) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=403); - /* (404) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=404); + /* (345) input ::= cmdlist */ yytestcase(yyruleno==345); + /* (346) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==346); + /* (347) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=347); + /* (348) ecmd ::= SEMI */ yytestcase(yyruleno==348); + /* (349) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==349); + /* (350) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=350); + /* (351) trans_opt ::= */ yytestcase(yyruleno==351); + /* (352) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==352); + /* (353) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==353); + /* (354) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==354); + /* (355) savepoint_opt ::= */ yytestcase(yyruleno==355); + /* (356) cmd ::= create_table create_table_args */ yytestcase(yyruleno==356); + /* (357) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=357); + /* (358) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==358); + /* (359) columnlist ::= columnname carglist */ yytestcase(yyruleno==359); + /* (360) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==360); + /* (361) nm ::= STRING */ yytestcase(yyruleno==361); + /* (362) typetoken ::= typename */ yytestcase(yyruleno==362); + /* (363) typename ::= ID|STRING */ yytestcase(yyruleno==363); + /* (364) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=364); + /* (365) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=365); + /* (366) carglist ::= carglist ccons */ yytestcase(yyruleno==366); + /* (367) carglist ::= */ yytestcase(yyruleno==367); + /* (368) ccons ::= NULL onconf */ yytestcase(yyruleno==368); + /* (369) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==369); + /* (370) ccons ::= AS generated */ yytestcase(yyruleno==370); + /* (371) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==371); + /* (372) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==372); + /* (373) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=373); + /* (374) tconscomma ::= */ yytestcase(yyruleno==374); + /* (375) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=375); + /* (376) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=376); + /* (377) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=377); + /* (378) oneselect ::= values */ yytestcase(yyruleno==378); + /* (379) sclp ::= selcollist COMMA */ yytestcase(yyruleno==379); + /* (380) as ::= ID|STRING */ yytestcase(yyruleno==380); + /* (381) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=381); + /* (382) returning ::= */ yytestcase(yyruleno==382); + /* (383) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=383); + /* (384) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==384); + /* (385) case_operand ::= expr */ yytestcase(yyruleno==385); + /* (386) exprlist ::= nexprlist */ yytestcase(yyruleno==386); + /* (387) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=387); + /* (388) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=388); + /* (389) nmnum ::= ON */ yytestcase(yyruleno==389); + /* (390) nmnum ::= DELETE */ yytestcase(yyruleno==390); + /* (391) nmnum ::= DEFAULT */ yytestcase(yyruleno==391); + /* (392) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==392); + /* (393) foreach_clause ::= */ yytestcase(yyruleno==393); + /* (394) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==394); + /* (395) trnm ::= nm */ yytestcase(yyruleno==395); + /* (396) tridxby ::= */ yytestcase(yyruleno==396); + /* (397) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==397); + /* (398) database_kw_opt ::= */ yytestcase(yyruleno==398); + /* (399) kwcolumn_opt ::= */ yytestcase(yyruleno==399); + /* (400) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==400); + /* (401) vtabarglist ::= vtabarg */ yytestcase(yyruleno==401); + /* (402) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==402); + /* (403) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==403); + /* (404) anylist ::= */ yytestcase(yyruleno==404); + /* (405) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==405); + /* (406) anylist ::= anylist ANY */ yytestcase(yyruleno==406); + /* (407) with ::= */ yytestcase(yyruleno==407); break; /********** End reduce actions ************************************************/ }; @@ -176007,21 +174844,21 @@ const unsigned char ebcdicToAscii[] = { ** is substantially reduced. This is important for embedded applications ** on platforms with limited memory. */ -/* Hash score: 231 */ -/* zKWText[] encodes 1007 bytes of keyword text in 667 bytes */ +/* Hash score: 236 */ +/* zKWText[] encodes 1032 bytes of keyword text in 687 bytes */ /* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */ /* ABLEFTHENDEFERRABLELSEXCLUDELETEMPORARYISNULLSAVEPOINTERSECT */ -/* IESNOTNULLIKEXCEPTRANSACTIONATURALTERAISEXCLUSIVEXISTS */ -/* CONSTRAINTOFFSETRIGGERANGENERATEDETACHAVINGLOBEGINNEREFERENCES */ -/* UNIQUERYWITHOUTERELEASEATTACHBETWEENOTHINGROUPSCASCADEFAULT */ -/* CASECOLLATECREATECURRENT_DATEIMMEDIATEJOINSERTMATCHPLANALYZE */ -/* PRAGMATERIALIZEDEFERREDISTINCTUPDATEVALUESVIRTUALWAYSWHENWHERE */ -/* CURSIVEABORTAFTERENAMEANDROPARTITIONAUTOINCREMENTCASTCOLUMN */ -/* COMMITCONFLICTCROSSCURRENT_TIMESTAMPRECEDINGFAILASTFILTER */ -/* EPLACEFIRSTFOLLOWINGFROMFULLIMITIFORDERESTRICTOTHERSOVER */ -/* ETURNINGRIGHTROLLBACKROWSUNBOUNDEDUNIONUSINGVACUUMVIEWINDOWBY */ -/* INITIALLYPRIMARY */ -static const char zKWText[666] = { +/* IESNOTNULLANGUAGENERATEDETACHAVINGLOBEGINNERAISEXCEPT */ +/* RANSACTIONATURALTERANGEXCLUSIVEXISTSCONSTRAINTOFFSETRIGGER */ +/* EFERENCESPLANALYZEUNIQUERYWITHOUTERELEASEATTACHBETWEENOTHING */ +/* ROUPSCASCADEFAULTCASECOLLATECREATECURRENT_DATEIMMEDIATEJOIN */ +/* SERTLIKEMATCHPRAGMATERIALIZEDEFERREDISTINCTUPDATEVALUESVIRTUAL */ +/* WAYSWHENWHERECURSIVEABORTAFTERANDOMAUTOINCREMENTCASTCOLUMN */ +/* COMMITCONFLICTCROSSCURRENT_TIMESTAMPARTITIONDROPRECEDINGFAIL */ +/* ASTFILTERENAMEFIRSTFOLLOWINGFROMFULLIMITFUNCTIONIFORDEREPLACE */ +/* OTHERSOVERESTRICTRETURNINGRIGHTROLLBACKROWSUNBOUNDEDUNIONUSING */ +/* VACUUMVIEWINDOWBYINITIALLYPRIMARY */ +static const char zKWText[686] = { 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H', 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G', 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A', @@ -176029,100 +174866,102 @@ static const char zKWText[666] = { 'E','R','R','A','B','L','E','L','S','E','X','C','L','U','D','E','L','E', 'T','E','M','P','O','R','A','R','Y','I','S','N','U','L','L','S','A','V', 'E','P','O','I','N','T','E','R','S','E','C','T','I','E','S','N','O','T', - 'N','U','L','L','I','K','E','X','C','E','P','T','R','A','N','S','A','C', - 'T','I','O','N','A','T','U','R','A','L','T','E','R','A','I','S','E','X', - 'C','L','U','S','I','V','E','X','I','S','T','S','C','O','N','S','T','R', - 'A','I','N','T','O','F','F','S','E','T','R','I','G','G','E','R','A','N', - 'G','E','N','E','R','A','T','E','D','E','T','A','C','H','A','V','I','N', - 'G','L','O','B','E','G','I','N','N','E','R','E','F','E','R','E','N','C', - 'E','S','U','N','I','Q','U','E','R','Y','W','I','T','H','O','U','T','E', - 'R','E','L','E','A','S','E','A','T','T','A','C','H','B','E','T','W','E', - 'E','N','O','T','H','I','N','G','R','O','U','P','S','C','A','S','C','A', - 'D','E','F','A','U','L','T','C','A','S','E','C','O','L','L','A','T','E', - 'C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A','T','E', - 'I','M','M','E','D','I','A','T','E','J','O','I','N','S','E','R','T','M', - 'A','T','C','H','P','L','A','N','A','L','Y','Z','E','P','R','A','G','M', - 'A','T','E','R','I','A','L','I','Z','E','D','E','F','E','R','R','E','D', - 'I','S','T','I','N','C','T','U','P','D','A','T','E','V','A','L','U','E', - 'S','V','I','R','T','U','A','L','W','A','Y','S','W','H','E','N','W','H', - 'E','R','E','C','U','R','S','I','V','E','A','B','O','R','T','A','F','T', - 'E','R','E','N','A','M','E','A','N','D','R','O','P','A','R','T','I','T', - 'I','O','N','A','U','T','O','I','N','C','R','E','M','E','N','T','C','A', - 'S','T','C','O','L','U','M','N','C','O','M','M','I','T','C','O','N','F', - 'L','I','C','T','C','R','O','S','S','C','U','R','R','E','N','T','_','T', - 'I','M','E','S','T','A','M','P','R','E','C','E','D','I','N','G','F','A', - 'I','L','A','S','T','F','I','L','T','E','R','E','P','L','A','C','E','F', - 'I','R','S','T','F','O','L','L','O','W','I','N','G','F','R','O','M','F', - 'U','L','L','I','M','I','T','I','F','O','R','D','E','R','E','S','T','R', - 'I','C','T','O','T','H','E','R','S','O','V','E','R','E','T','U','R','N', - 'I','N','G','R','I','G','H','T','R','O','L','L','B','A','C','K','R','O', - 'W','S','U','N','B','O','U','N','D','E','D','U','N','I','O','N','U','S', - 'I','N','G','V','A','C','U','U','M','V','I','E','W','I','N','D','O','W', - 'B','Y','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R','Y', + 'N','U','L','L','A','N','G','U','A','G','E','N','E','R','A','T','E','D', + 'E','T','A','C','H','A','V','I','N','G','L','O','B','E','G','I','N','N', + 'E','R','A','I','S','E','X','C','E','P','T','R','A','N','S','A','C','T', + 'I','O','N','A','T','U','R','A','L','T','E','R','A','N','G','E','X','C', + 'L','U','S','I','V','E','X','I','S','T','S','C','O','N','S','T','R','A', + 'I','N','T','O','F','F','S','E','T','R','I','G','G','E','R','E','F','E', + 'R','E','N','C','E','S','P','L','A','N','A','L','Y','Z','E','U','N','I', + 'Q','U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A', + 'S','E','A','T','T','A','C','H','B','E','T','W','E','E','N','O','T','H', + 'I','N','G','R','O','U','P','S','C','A','S','C','A','D','E','F','A','U', + 'L','T','C','A','S','E','C','O','L','L','A','T','E','C','R','E','A','T', + 'E','C','U','R','R','E','N','T','_','D','A','T','E','I','M','M','E','D', + 'I','A','T','E','J','O','I','N','S','E','R','T','L','I','K','E','M','A', + 'T','C','H','P','R','A','G','M','A','T','E','R','I','A','L','I','Z','E', + 'D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','U','P','D', + 'A','T','E','V','A','L','U','E','S','V','I','R','T','U','A','L','W','A', + 'Y','S','W','H','E','N','W','H','E','R','E','C','U','R','S','I','V','E', + 'A','B','O','R','T','A','F','T','E','R','A','N','D','O','M','A','U','T', + 'O','I','N','C','R','E','M','E','N','T','C','A','S','T','C','O','L','U', + 'M','N','C','O','M','M','I','T','C','O','N','F','L','I','C','T','C','R', + 'O','S','S','C','U','R','R','E','N','T','_','T','I','M','E','S','T','A', + 'M','P','A','R','T','I','T','I','O','N','D','R','O','P','R','E','C','E', + 'D','I','N','G','F','A','I','L','A','S','T','F','I','L','T','E','R','E', + 'N','A','M','E','F','I','R','S','T','F','O','L','L','O','W','I','N','G', + 'F','R','O','M','F','U','L','L','I','M','I','T','F','U','N','C','T','I', + 'O','N','I','F','O','R','D','E','R','E','P','L','A','C','E','O','T','H', + 'E','R','S','O','V','E','R','E','S','T','R','I','C','T','R','E','T','U', + 'R','N','I','N','G','R','I','G','H','T','R','O','L','L','B','A','C','K', + 'R','O','W','S','U','N','B','O','U','N','D','E','D','U','N','I','O','N', + 'U','S','I','N','G','V','A','C','U','U','M','V','I','E','W','I','N','D', + 'O','W','B','Y','I','N','I','T','I','A','L','L','Y','P','R','I','M','A', + 'R','Y', }; /* aKWHash[i] is the hash value for the i-th keyword */ static const unsigned char aKWHash[127] = { - 84, 92, 134, 82, 105, 29, 0, 0, 94, 0, 85, 72, 0, - 53, 35, 86, 15, 0, 42, 97, 54, 89, 135, 19, 0, 0, - 140, 0, 40, 129, 0, 22, 107, 0, 9, 0, 0, 123, 80, - 0, 78, 6, 0, 65, 103, 147, 0, 136, 115, 0, 0, 48, - 0, 90, 24, 0, 17, 0, 27, 70, 23, 26, 5, 60, 142, - 110, 122, 0, 73, 91, 71, 145, 61, 120, 74, 0, 49, 0, - 11, 41, 0, 113, 0, 0, 0, 109, 10, 111, 116, 125, 14, - 50, 124, 0, 100, 0, 18, 121, 144, 56, 130, 139, 88, 83, - 37, 30, 126, 0, 0, 108, 51, 131, 128, 0, 34, 0, 0, - 132, 0, 98, 38, 39, 0, 20, 45, 117, 93, + 86, 93, 137, 84, 116, 29, 0, 0, 95, 0, 88, 74, 0, + 60, 35, 64, 15, 0, 49, 98, 61, 90, 138, 19, 40, 0, + 143, 0, 87, 134, 0, 22, 106, 0, 9, 0, 0, 124, 82, + 0, 80, 6, 0, 67, 104, 150, 0, 139, 114, 0, 0, 55, + 0, 91, 24, 0, 17, 0, 27, 72, 23, 26, 5, 44, 145, + 109, 123, 0, 75, 92, 73, 148, 45, 121, 76, 0, 56, 0, + 11, 48, 0, 112, 0, 0, 0, 108, 10, 110, 115, 126, 14, + 128, 125, 0, 101, 0, 18, 131, 147, 54, 132, 142, 89, 85, + 37, 30, 127, 0, 0, 107, 58, 133, 130, 0, 34, 0, 0, + 135, 0, 99, 38, 39, 0, 20, 52, 118, 94, }; /* 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, - 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, - 138, 0, 133, 0, 0, 36, 0, 0, 28, 77, 0, 0, 0, - 0, 59, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 69, 0, 0, 0, 0, 0, 146, 3, 0, 58, 0, 1, - 75, 0, 0, 0, 31, 0, 0, 0, 0, 0, 127, 0, 104, - 0, 64, 66, 63, 0, 0, 0, 0, 0, 46, 0, 16, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 101, 0, - 112, 21, 7, 67, 0, 79, 96, 118, 0, 0, 68, 0, 0, - 99, 44, 0, 55, 0, 76, 0, 95, 32, 33, 57, 25, 0, - 102, 0, 0, 87, +static const unsigned char aKWNext[151] = {0, + 0, 0, 0, 0, 4, 0, 50, 0, 0, 105, 113, 0, 0, + 0, 2, 0, 0, 146, 0, 0, 0, 13, 0, 0, 0, 0, + 144, 0, 0, 120, 59, 0, 0, 140, 12, 0, 0, 46, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 36, + 0, 47, 28, 79, 0, 0, 0, 0, 43, 0, 0, 0, 0, + 0, 0, 0, 71, 0, 0, 0, 0, 0, 149, 3, 0, 42, + 0, 1, 77, 0, 0, 0, 31, 0, 141, 103, 0, 129, 0, + 117, 0, 66, 68, 63, 0, 0, 0, 0, 0, 53, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 102, 0, 8, + 0, 111, 21, 7, 0, 0, 81, 97, 119, 0, 57, 0, 70, + 69, 0, 100, 0, 51, 0, 62, 0, 78, 0, 96, 32, 33, + 41, 25, 0, 122, 0, 0, 65, }; /* aKWLen[i] is the length (in bytes) of the i-th keyword */ -static const unsigned char aKWLen[148] = {0, +static const unsigned char aKWLen[151] = {0, 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, - 4, 6, 11, 6, 2, 7, 5, 5, 9, 6, 10, 4, 6, - 2, 3, 7, 5, 9, 6, 6, 4, 5, 5, 10, 6, 5, - 7, 4, 5, 7, 6, 7, 7, 6, 5, 7, 3, 7, 4, - 7, 6, 12, 9, 4, 6, 5, 4, 7, 6, 12, 8, 8, - 2, 6, 6, 7, 6, 4, 5, 9, 5, 5, 6, 3, 4, - 9, 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 9, - 4, 4, 6, 7, 5, 9, 4, 4, 5, 2, 5, 8, 6, - 4, 9, 5, 8, 4, 3, 9, 5, 5, 6, 4, 6, 2, - 2, 9, 3, 7, + 8, 9, 6, 6, 4, 5, 5, 5, 6, 11, 6, 2, 7, + 5, 5, 9, 6, 10, 4, 6, 2, 3, 7, 10, 4, 7, + 6, 5, 7, 4, 5, 7, 6, 7, 7, 6, 5, 7, 3, + 7, 4, 7, 6, 12, 9, 4, 6, 4, 5, 6, 12, 8, + 8, 2, 6, 6, 7, 6, 4, 5, 9, 5, 5, 6, 3, + 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 9, 4, + 9, 4, 4, 6, 6, 5, 9, 4, 4, 5, 8, 2, 5, + 7, 6, 4, 8, 9, 5, 8, 4, 3, 9, 5, 5, 6, + 4, 6, 2, 2, 9, 3, 7, }; /* 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[151] = {0, 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, - 129, 132, 137, 142, 146, 147, 152, 156, 160, 168, 174, 181, 184, - 184, 187, 189, 195, 198, 206, 211, 216, 219, 222, 226, 236, 239, - 244, 244, 248, 252, 259, 265, 271, 277, 277, 283, 284, 288, 295, - 299, 306, 312, 324, 333, 335, 341, 346, 348, 355, 359, 370, 377, - 378, 385, 391, 397, 402, 408, 412, 415, 424, 429, 433, 439, 441, - 444, 453, 455, 457, 466, 470, 476, 482, 490, 495, 495, 495, 511, - 520, 523, 527, 532, 539, 544, 553, 557, 560, 565, 567, 571, 579, - 585, 588, 597, 602, 610, 610, 614, 623, 628, 633, 639, 642, 645, - 648, 650, 655, 659, + 129, 135, 143, 148, 153, 156, 159, 163, 167, 172, 177, 181, 182, + 187, 191, 195, 203, 209, 216, 219, 219, 222, 224, 230, 240, 242, + 249, 252, 257, 257, 261, 265, 272, 278, 284, 290, 290, 296, 297, + 301, 308, 312, 319, 325, 337, 346, 348, 354, 358, 363, 367, 378, + 385, 386, 393, 399, 405, 410, 416, 420, 423, 432, 437, 441, 442, + 447, 449, 451, 460, 464, 470, 476, 484, 489, 489, 489, 505, 514, + 517, 526, 529, 533, 538, 544, 549, 558, 562, 565, 570, 578, 580, + 584, 591, 597, 600, 608, 617, 622, 630, 630, 634, 643, 648, 653, + 659, 662, 665, 668, 670, 675, 679, }; /* aKWCode[i] is the parser symbol code for the i-th keyword */ -static const unsigned char aKWCode[148] = {0, +static const unsigned char aKWCode[151] = {0, 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, @@ -176130,29 +174969,29 @@ static const unsigned char aKWCode[148] = {0, TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE, TK_EXCLUDE, TK_DELETE, TK_TEMP, TK_TEMP, TK_OR, TK_ISNULL, TK_NULLS, TK_SAVEPOINT, TK_INTERSECT, TK_TIES, - TK_NOTNULL, TK_NOT, TK_NO, TK_NULL, TK_LIKE_KW, - TK_EXCEPT, TK_TRANSACTION,TK_ACTION, TK_ON, TK_JOIN_KW, - TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_CONSTRAINT, - TK_INTO, TK_OFFSET, TK_OF, TK_SET, TK_TRIGGER, - TK_RANGE, TK_GENERATED, TK_DETACH, TK_HAVING, TK_LIKE_KW, - TK_BEGIN, TK_JOIN_KW, TK_REFERENCES, TK_UNIQUE, TK_QUERY, - TK_WITHOUT, TK_WITH, TK_JOIN_KW, TK_RELEASE, TK_ATTACH, - TK_BETWEEN, TK_NOTHING, TK_GROUPS, TK_GROUP, TK_CASCADE, - TK_ASC, TK_DEFAULT, TK_CASE, TK_COLLATE, TK_CREATE, - TK_CTIME_KW, TK_IMMEDIATE, TK_JOIN, TK_INSERT, TK_MATCH, - TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_MATERIALIZED, TK_DEFERRED, - TK_DISTINCT, TK_IS, TK_UPDATE, TK_VALUES, TK_VIRTUAL, - TK_ALWAYS, TK_WHEN, TK_WHERE, TK_RECURSIVE, TK_ABORT, - TK_AFTER, TK_RENAME, TK_AND, TK_DROP, TK_PARTITION, - TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, - TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, - TK_CURRENT, TK_PRECEDING, TK_FAIL, TK_LAST, TK_FILTER, - TK_REPLACE, TK_FIRST, TK_FOLLOWING, TK_FROM, TK_JOIN_KW, - TK_LIMIT, TK_IF, TK_ORDER, TK_RESTRICT, TK_OTHERS, - TK_OVER, TK_RETURNING, TK_JOIN_KW, TK_ROLLBACK, TK_ROWS, - TK_ROW, TK_UNBOUNDED, TK_UNION, TK_USING, TK_VACUUM, - TK_VIEW, TK_WINDOW, TK_DO, TK_BY, TK_INITIALLY, - TK_ALL, TK_PRIMARY, + TK_NOTNULL, TK_NOT, TK_NO, TK_NULL, TK_LANGUAGE, + TK_GENERATED, TK_DETACH, TK_HAVING, TK_LIKE_KW, TK_BEGIN, + TK_JOIN_KW, TK_RAISE, TK_EXCEPT, TK_TRANSACTION,TK_ACTION, + TK_ON, TK_JOIN_KW, TK_ALTER, TK_RANGE, TK_EXCLUSIVE, + TK_EXISTS, TK_CONSTRAINT, TK_INTO, TK_OFFSET, TK_OF, + TK_SET, TK_TRIGGER, TK_REFERENCES, TK_PLAN, TK_ANALYZE, + TK_UNIQUE, TK_QUERY, TK_WITHOUT, TK_WITH, TK_JOIN_KW, + TK_RELEASE, TK_ATTACH, TK_BETWEEN, TK_NOTHING, TK_GROUPS, + TK_GROUP, TK_CASCADE, TK_ASC, TK_DEFAULT, TK_CASE, + TK_COLLATE, TK_CREATE, TK_CTIME_KW, TK_IMMEDIATE, TK_JOIN, + TK_INSERT, TK_LIKE_KW, TK_MATCH, TK_PRAGMA, TK_MATERIALIZED, + TK_DEFERRED, TK_DISTINCT, TK_IS, TK_UPDATE, TK_VALUES, + TK_VIRTUAL, TK_ALWAYS, TK_WHEN, TK_WHERE, TK_RECURSIVE, + TK_ABORT, TK_AFTER, TK_RANDOM, TK_AND, TK_AUTOINCR, + TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, TK_COMMIT, + TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, TK_CURRENT, + TK_PARTITION, TK_DROP, TK_PRECEDING, TK_FAIL, TK_LAST, + TK_FILTER, TK_RENAME, TK_FIRST, TK_FOLLOWING, TK_FROM, + TK_JOIN_KW, TK_LIMIT, TK_FUNCTION, TK_IF, TK_ORDER, + TK_REPLACE, TK_OTHERS, TK_OVER, TK_RESTRICT, TK_RETURNING, + TK_JOIN_KW, TK_ROLLBACK, TK_ROWS, TK_ROW, TK_UNBOUNDED, + TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_WINDOW, + TK_DO, TK_BY, TK_INITIALLY, TK_ALL, TK_PRIMARY, }; /* Hash table decoded: ** 0: INSERT @@ -176165,7 +175004,7 @@ static const unsigned char aKWCode[148] = {0, ** 7: ** 8: VALUES WITHOUT ** 9: -** 10: MATCH +** 10: MATCH RANDOM ** 11: NOTHING ** 12: ** 13: OF @@ -176179,7 +175018,7 @@ static const unsigned char aKWCode[148] = {0, ** 21: MATERIALIZED IF ** 22: ROWS ** 23: SELECT -** 24: +** 24: LANGUAGE ** 25: ** 26: VACUUM SAVEPOINT ** 27: @@ -176246,7 +175085,7 @@ static const unsigned char aKWCode[148] = {0, ** 88: CURRENT AFTER ALTER ** 89: FULL FAIL CONFLICT ** 90: EXPLAIN -** 91: CONSTRAINT +** 91: FUNCTION CONSTRAINT ** 92: FROM ALWAYS ** 93: ** 94: ABORT @@ -176289,182 +175128,186 @@ 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]; i>0; i=aKWNext[i]){ + 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 +#define SQLITE_N_KEYWORD 150 SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){ if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR; i++; @@ -176766,7 +175609,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); - testcase( z[0]=='9' ); testcase( z[0]=='.' ); + testcase( z[0]=='9' ); *tokenType = TK_INTEGER; #ifndef SQLITE_OMIT_HEX_INTEGER if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ @@ -176838,8 +175681,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 @@ -177618,20 +176460,30 @@ 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 #ifdef SQLITE_ENABLE_STMTVTAB SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*); #endif -#ifdef SQLITE_EXTRA_AUTOEXT -int SQLITE_EXTRA_AUTOEXT(sqlite3*); -#endif + /* ** An array of pointers to extension initializer functions for ** 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 @@ -177660,9 +176512,6 @@ static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = { #ifdef SQLITE_ENABLE_BYTECODE_VTAB sqlite3VdbeBytecodeVtabInit, #endif -#ifdef SQLITE_EXTRA_AUTOEXT - SQLITE_EXTRA_AUTOEXT, -#endif }; #ifndef SQLITE_AMALGAMATION @@ -177670,6 +176519,7 @@ static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = { ** contains the text of SQLITE_VERSION macro. */ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; +const char libsql_version[] = LIBSQL_VERSION; #endif /* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns @@ -177677,6 +176527,8 @@ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; */ SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; } +const char *libsql_libversion(void){ return LIBSQL_VERSION; } + /* IMPLEMENTATION-OF: R-25063-23286 The sqlite3_sourceid() function returns a ** pointer to a string constant whose value is the same as the ** SQLITE_SOURCE_ID C preprocessor macro. Except if SQLite is built using @@ -177736,32 +176588,6 @@ SQLITE_API char *sqlite3_temp_directory = 0; */ SQLITE_API char *sqlite3_data_directory = 0; -/* -** Determine whether or not high-precision (long double) floating point -** math works correctly on CPU currently running. -*/ -static SQLITE_NOINLINE int hasHighPrecisionDouble(int rc){ - if( sizeof(LONGDOUBLE_TYPE)<=8 ){ - /* If the size of "long double" is not more than 8, then - ** high-precision math is not possible. */ - return 0; - }else{ - /* Just because sizeof(long double)>8 does not mean that the underlying - ** hardware actually supports high-precision floating point. For example, - ** clearing the 0x100 bit in the floating-point control word on Intel - ** processors will make long double work like double, even though long - ** double takes up more space. The only way to determine if long double - ** actually works is to run an experiment. */ - LONGDOUBLE_TYPE a, b, c; - rc++; - a = 1.0+rc*0.1; - b = 1.0e+18+rc*25.0; - c = a+b; - return b!=c; - } -} - - /* ** Initialize SQLite. ** @@ -177957,12 +176783,6 @@ SQLITE_API int sqlite3_initialize(void){ } #endif - /* Experimentally determine if high-precision floating point is - ** available. */ -#ifndef SQLITE_OMIT_WSD - sqlite3Config.bUseLongDouble = hasHighPrecisionDouble(rc); -#endif - return rc; } @@ -178533,10 +177353,6 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3 *db){ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ va_list ap; int rc; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif sqlite3_mutex_enter(db->mutex); va_start(ap, op); switch( op ){ @@ -178761,7 +177577,7 @@ SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *db){ ** copies of a single function are created when create_function() is called ** with SQLITE_ANY as the encoding. */ -static void functionDestroy(sqlite3 *db, FuncDef *p){ +void functionDestroy(sqlite3 *db, FuncDef *p){ FuncDestructor *pDestructor; assert( (p->funcFlags & SQLITE_FUNC_BUILTIN)==0 ); pDestructor = p->u.pDestructor; @@ -178837,6 +177653,10 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){ db->trace.xV2(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0); } + if (db->xCloseCallback) { + db->xCloseCallback(db->pCloseArg, db); + } + /* Force xDisconnect calls on all virtual tables */ disconnectAllVtab(db); @@ -178866,17 +177686,14 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){ } #endif - while( db->pDbData ){ - DbClientData *p = db->pDbData; - db->pDbData = p->pNext; - assert( p->pData!=0 ); - if( p->xDestructor ) p->xDestructor(p->pData); - sqlite3_free(p); - } - /* Convert the connection into a zombie and then close it. */ db->eOpenState = SQLITE_STATE_ZOMBIE; +#ifdef LIBSQL_ENABLE_WASM_RUNTIME + if (db->wasm.engine) { + libsql_wasm_engine_free(db->wasm.engine); + } +#endif sqlite3LeaveMutexAndCloseZombie(db); return SQLITE_OK; } @@ -179291,9 +178108,9 @@ static int sqliteDefaultBusyCallback( void *ptr, /* Database connection */ int count /* Number of times table has been busy */ ){ -#if SQLITE_OS_WIN || !defined(HAVE_NANOSLEEP) || HAVE_NANOSLEEP +#if SQLITE_OS_WIN || HAVE_USLEEP /* This case is for systems that have support for sleeping for fractions of - ** a second. Examples: All windows systems, unix systems with nanosleep() */ + ** a second. Examples: All windows systems, unix systems with usleep() */ static const u8 delays[] = { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; static const u8 totals[] = @@ -179491,7 +178308,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc( assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| - SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE); + SQLITE_SUBTYPE|SQLITE_INNOCUOUS); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But @@ -179948,12 +178765,6 @@ SQLITE_API void *sqlite3_preupdate_hook( void *pArg /* First callback argument */ ){ void *pRet; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( db==0 ){ - return 0; - } -#endif sqlite3_mutex_enter(db->mutex); pRet = db->pPreUpdateArg; db->xPreUpdateCallback = xCallback; @@ -179963,6 +178774,24 @@ SQLITE_API void *sqlite3_preupdate_hook( } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ +/* +** Register a callback to be invoked when the connection is closed. +*/ +void *libsql_close_hook( + sqlite3 *db, /* Attach the hook to this connection */ + void(*xCallback)( /* Callback function */ + void*,sqlite3*), + void *pArg /* First callback argument */ +){ + void *pRet; + sqlite3_mutex_enter(db->mutex); + pRet = db->pCloseArg; + db->xCloseCallback = xCallback; + db->pCloseArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +} + /* ** Register a function to be invoked prior to each autovacuum that ** determines the number of pages to vacuum. @@ -180100,7 +178929,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( if( eModeSQLITE_CHECKPOINT_TRUNCATE ){ /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint ** mode: */ - return SQLITE_MISUSE_BKPT; + return SQLITE_MISUSE; } sqlite3_mutex_enter(db->mutex); @@ -180534,6 +179363,12 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ return oldLimit; /* IMP: R-53341-35419 */ } +#ifdef SQLITE_OMIT_WAL +libsql_wal_methods* libsql_wal_methods_find(const char *zName) { + return NULL; +} +#endif + /* ** This function is used to parse both URIs and non-URI filenames passed by the ** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database @@ -180554,6 +179389,8 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ ** and is in the same format as names created using sqlite3_create_filename(). ** The caller must invoke sqlite3_free_filename() (not sqlite3_free()!) on ** the value returned in *pzFile to avoid a memory leak. +** *ppWal is set to point to WAL methods that should be used to open +** the database file. ** ** If an error occurs, then an SQLite error code is returned and *pzErrMsg ** may be set to point to a buffer containing an English language error @@ -180562,15 +179399,18 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ */ SQLITE_PRIVATE int sqlite3ParseUri( const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ + const char *zDefaultWal, /* WAL module to use if no "wal=xxx" query option */ const char *zUri, /* Nul-terminated URI to parse */ unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ sqlite3_vfs **ppVfs, /* OUT: VFS to use */ + libsql_wal_methods **ppWal, /* OUT: WAL module to use */ char **pzFile, /* OUT: Filename component of URI */ char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ ){ int rc = SQLITE_OK; unsigned int flags = *pFlags; const char *zVfs = zDefaultVfs; + const char *zWal = zDefaultWal; char *zFile; char c; int nUri = sqlite3Strlen30(zUri); @@ -180690,8 +179530,8 @@ SQLITE_PRIVATE int sqlite3ParseUri( memset(zFile+iOut, 0, 4); /* end-of-options + empty journal filenames */ /* Check if there were any options specified that should be interpreted - ** here. Options that are interpreted here include "vfs" and those that - ** correspond to flags that may be passed to the sqlite3_open_v2() + ** here. Options that are interpreted here include "vfs", "wal", and those + ** that correspond to flags that may be passed to the sqlite3_open_v2() ** method. */ zOpt = &zFile[sqlite3Strlen30(zFile)+1]; while( zOpt[0] ){ @@ -180701,6 +179541,8 @@ SQLITE_PRIVATE int sqlite3ParseUri( if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ zVfs = zVal; + }else if( nOpt==3 && memcmp("wal", zOpt, 3)==0 ){ + zWal = zVal; }else{ struct OpenMode { const char *z; @@ -180783,6 +179625,11 @@ SQLITE_PRIVATE int sqlite3ParseUri( *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs); rc = SQLITE_ERROR; } + *ppWal = libsql_wal_methods_find(zWal); + if( *ppWal==NULL ){ + *pzErrMsg = sqlite3_mprintf("no such WAL module: %s", zWal); + rc = SQLITE_ERROR; + } parse_uri_out: if( rc!=SQLITE_OK ){ sqlite3_free_filename(zFile); @@ -180819,7 +179666,9 @@ static int openDatabase( const char *zFilename, /* Database filename UTF-8 encoded */ sqlite3 **ppDb, /* OUT: Returned database handle */ unsigned int flags, /* Operational flags */ - const char *zVfs /* Name of the VFS to use */ + const char *zVfs, /* Name of the VFS to use */ + const char *zWal, /* Name of WAL module to use */ + void* pWalMethodsData /* Pointer to the user data*/ ){ sqlite3 *db; /* Store allocated handle here */ int rc; /* Return code */ @@ -180879,6 +179728,7 @@ static int openDatabase( /* Allocate the sqlite data structure */ db = sqlite3MallocZero( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; + db->pWalMethodsData = pWalMethodsData; if( isThreadsafe #ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS || sqlite3GlobalConfig.bCoreMutex @@ -180937,7 +179787,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) @@ -181046,7 +179896,7 @@ static int openDatabase( if( ((1<<(flags&7)) & 0x46)==0 ){ rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */ }else{ - rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); + rc = sqlite3ParseUri(zVfs, zWal, zFilename, &flags, &db->pVfs, &db->pWalMethods, &zOpen, &zErrMsg); } if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); @@ -181062,7 +179912,7 @@ static int openDatabase( #endif /* Open the backend database driver */ - rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, + rc = sqlite3BtreeOpen(db->pVfs, db->pWalMethods, zOpen, db, &db->aDb[0].pBt, 0, flags | SQLITE_OPEN_MAIN_DB); if( rc!=SQLITE_OK ){ if( rc==SQLITE_IOERR_NOMEM ){ @@ -181140,6 +179990,10 @@ static int openDatabase( setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, sqlite3GlobalConfig.nLookaside); + if (strcmp("default", libsql_wal_methods_name(db->pWalMethods)) != 0) { + sqlite3_exec(db, "pragma journal_mode=wal", NULL, NULL, NULL); + } + sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); opendb_out: @@ -181177,7 +180031,7 @@ SQLITE_API int sqlite3_open( sqlite3 **ppDb ){ return openDatabase(zFilename, ppDb, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL, NULL, NULL); } SQLITE_API int sqlite3_open_v2( const char *filename, /* Database filename (UTF-8) */ @@ -181185,7 +180039,28 @@ SQLITE_API int sqlite3_open_v2( int flags, /* Flags */ const char *zVfs /* Name of VFS module to use */ ){ - return openDatabase(filename, ppDb, (unsigned int)flags, zVfs); + return openDatabase(filename, ppDb, (unsigned int)flags, zVfs, NULL, NULL); +} + +int libsql_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs, /* Name of VFS module to use, NULL for default */ + const char *zWal /* Name of WAL module to use */ +) { + return openDatabase(filename, ppDb, (unsigned int)flags, zVfs, zWal, NULL); +} + +int libsql_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs, /* Name of VFS module to use, NULL for default */ + const char *zWal, /* Name of WAL module to use */ + void* pWalMethodsData /* User data, passed to the libsql_wal struct*/ +) { + return openDatabase(filename, ppDb, (unsigned int)flags, zVfs, zWal, pWalMethodsData); } #ifndef SQLITE_OMIT_UTF16 @@ -181214,7 +180089,7 @@ SQLITE_API int sqlite3_open16( zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8); if( zFilename8 ){ rc = openDatabase(zFilename8, ppDb, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL, NULL, NULL); assert( *ppDb || rc==SQLITE_NOMEM ); if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){ SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE; @@ -181337,69 +180212,6 @@ SQLITE_API int sqlite3_collation_needed16( } #endif /* SQLITE_OMIT_UTF16 */ -/* -** Find existing client data. -*/ -SQLITE_API void *sqlite3_get_clientdata(sqlite3 *db, const char *zName){ - DbClientData *p; - sqlite3_mutex_enter(db->mutex); - for(p=db->pDbData; p; p=p->pNext){ - if( strcmp(p->zName, zName)==0 ){ - void *pResult = p->pData; - sqlite3_mutex_leave(db->mutex); - return pResult; - } - } - sqlite3_mutex_leave(db->mutex); - return 0; -} - -/* -** Add new client data to a database connection. -*/ -SQLITE_API int sqlite3_set_clientdata( - sqlite3 *db, /* Attach client data to this connection */ - const char *zName, /* Name of the client data */ - void *pData, /* The client data itself */ - void (*xDestructor)(void*) /* Destructor */ -){ - DbClientData *p, **pp; - sqlite3_mutex_enter(db->mutex); - pp = &db->pDbData; - for(p=db->pDbData; p && strcmp(p->zName,zName); p=p->pNext){ - pp = &p->pNext; - } - if( p ){ - assert( p->pData!=0 ); - if( p->xDestructor ) p->xDestructor(p->pData); - if( pData==0 ){ - *pp = p->pNext; - sqlite3_free(p); - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; - } - }else if( pData==0 ){ - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; - }else{ - size_t n = strlen(zName); - p = sqlite3_malloc64( sizeof(DbClientData)+n+1 ); - if( p==0 ){ - if( xDestructor ) xDestructor(pData); - sqlite3_mutex_leave(db->mutex); - return SQLITE_NOMEM; - } - memcpy(p->zName, zName, n+1); - p->pNext = db->pDbData; - db->pDbData = p; - } - p->pData = pData; - p->xDestructor = xDestructor; - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} - - #ifndef SQLITE_OMIT_DEPRECATED /* ** This function is now an anachronism. It used to be used to recover from a @@ -181535,7 +180347,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]; @@ -181665,6 +180477,11 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo }else if( op==SQLITE_FCNTL_DATA_VERSION ){ *(unsigned int*)pArg = sqlite3PagerDataVersion(pPager); rc = SQLITE_OK; +#ifndef SQLITE_OMIT_WAL + }else if( op==SQLITE_FCNTL_WAL_METHODS_POINTER ){ + *(libsql_wal_methods**)pArg = sqlite3PagerWalMethods(pPager); + rc = SQLITE_OK; +#endif }else if( op==SQLITE_FCNTL_RESERVE_BYTES ){ int iNew = *(int*)pArg; *(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree); @@ -181749,28 +180566,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){ } #endif - /* sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, sqlite3 *db, int b); - ** - ** If b is true, then activate the SQLITE_FkNoAction setting. If b is - ** false then clearn that setting. If the SQLITE_FkNoAction setting is - ** abled, all foreign key ON DELETE and ON UPDATE actions behave as if - ** they were NO ACTION, regardless of how they are defined. - ** - ** NB: One must usually run "PRAGMA writable_schema=RESET" after - ** using this test-control, before it will take full effect. failing - ** to reset the schema can result in some unexpected behavior. - */ - case SQLITE_TESTCTRL_FK_NO_ACTION: { - sqlite3 *db = va_arg(ap, sqlite3*); - int b = va_arg(ap, int); - if( b ){ - db->flags |= SQLITE_FkNoAction; - }else{ - db->flags &= ~SQLITE_FkNoAction; - } - break; - } - /* ** sqlite3_test_control(BITVEC_TEST, size, program) ** @@ -181877,12 +180672,10 @@ SQLITE_API int sqlite3_test_control(int op, ...){ sqlite3ShowSrcList(0); sqlite3ShowWith(0); sqlite3ShowUpsert(0); -#ifndef SQLITE_OMIT_TRIGGER sqlite3ShowTriggerStep(0); sqlite3ShowTriggerStepList(0); sqlite3ShowTrigger(0); sqlite3ShowTriggerList(0); -#endif #ifndef SQLITE_OMIT_WINDOWFUNC sqlite3ShowWindow(0); sqlite3ShowWinFunc(0); @@ -181999,7 +180792,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); @@ -182153,7 +180946,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: { @@ -182189,23 +180982,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } -#if !defined(SQLITE_OMIT_WSD) - /* 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 = hasHighPrecisionDouble(b); - if( b>=0 ) sqlite3Config.bUseLongDouble = b>0; - rc = sqlite3Config.bUseLongDouble!=0; - break; - } -#endif - #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) @@ -182506,7 +181282,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, @@ -182613,7 +181389,7 @@ SQLITE_API int sqlite3_compileoption_used(const char *zOptName){ int nOpt; const char **azCompileOpt; -#ifdef SQLITE_ENABLE_API_ARMOR +#if SQLITE_ENABLE_API_ARMOR if( zOptName==0 ){ (void)SQLITE_MISUSE_BKPT; return 0; @@ -182808,9 +181584,6 @@ SQLITE_API int sqlite3_unlock_notify( ){ int rc = SQLITE_OK; -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif sqlite3_mutex_enter(db->mutex); enterMutex(); @@ -183832,7 +182605,6 @@ struct Fts3Table { int nPgsz; /* Page size for host database */ char *zSegmentsTbl; /* Name of %_segments table */ sqlite3_blob *pSegments; /* Blob handle open on %_segments table */ - int iSavepoint; /* ** The following array of hash tables is used to buffer pending index @@ -184576,7 +183348,6 @@ static void fts3DeclareVtab(int *pRc, Fts3Table *p){ zLanguageid = (p->zLanguageid ? p->zLanguageid : "__langid"); sqlite3_vtab_config(p->db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); - sqlite3_vtab_config(p->db, SQLITE_VTAB_INNOCUOUS); /* Create a list of user columns for the virtual table */ zCols = sqlite3_mprintf("%Q, ", p->azColumn[0]); @@ -187826,8 +186597,6 @@ static int fts3RenameMethod( rc = sqlite3Fts3PendingTermsFlush(p); } - p->bIgnoreSavepoint = 1; - if( p->zContentTbl==0 ){ fts3DbExec(&rc, db, "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';", @@ -187855,8 +186624,6 @@ static int fts3RenameMethod( "ALTER TABLE %Q.'%q_segdir' RENAME TO '%q_segdir';", p->zDb, p->zName, zName ); - - p->bIgnoreSavepoint = 0; return rc; } @@ -187867,28 +186634,12 @@ static int fts3RenameMethod( */ static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ int rc = SQLITE_OK; - Fts3Table *pTab = (Fts3Table*)pVtab; - assert( pTab->inTransaction ); - assert( pTab->mxSavepoint<=iSavepoint ); - TESTONLY( pTab->mxSavepoint = iSavepoint ); - - if( pTab->bIgnoreSavepoint==0 ){ - if( fts3HashCount(&pTab->aIndex[0].hPending)>0 ){ - char *zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", - pTab->zDb, pTab->zName, pTab->zName - ); - if( zSql ){ - pTab->bIgnoreSavepoint = 1; - rc = sqlite3_exec(pTab->db, zSql, 0, 0, 0); - pTab->bIgnoreSavepoint = 0; - sqlite3_free(zSql); - }else{ - rc = SQLITE_NOMEM; - } - } - if( rc==SQLITE_OK ){ - pTab->iSavepoint = iSavepoint+1; - } + UNUSED_PARAMETER(iSavepoint); + assert( ((Fts3Table *)pVtab)->inTransaction ); + assert( ((Fts3Table *)pVtab)->mxSavepoint <= iSavepoint ); + TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint ); + if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){ + rc = fts3SyncMethod(pVtab); } return rc; } @@ -187899,11 +186650,12 @@ static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ ** This is a no-op. */ static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ - Fts3Table *pTab = (Fts3Table*)pVtab; - assert( pTab->inTransaction ); - assert( pTab->mxSavepoint >= iSavepoint ); - TESTONLY( pTab->mxSavepoint = iSavepoint-1 ); - pTab->iSavepoint = iSavepoint; + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); + UNUSED_PARAMETER(iSavepoint); + UNUSED_PARAMETER(pVtab); + assert( p->inTransaction ); + assert( p->mxSavepoint >= iSavepoint ); + TESTONLY( p->mxSavepoint = iSavepoint-1 ); return SQLITE_OK; } @@ -187913,13 +186665,11 @@ static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ ** Discard the contents of the pending terms table. */ static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ - Fts3Table *pTab = (Fts3Table*)pVtab; + Fts3Table *p = (Fts3Table*)pVtab; UNUSED_PARAMETER(iSavepoint); - assert( pTab->inTransaction ); - TESTONLY( pTab->mxSavepoint = iSavepoint ); - if( (iSavepoint+1)<=pTab->iSavepoint ){ - sqlite3Fts3PendingTermsClear(pTab); - } + assert( p->inTransaction ); + TESTONLY( p->mxSavepoint = iSavepoint ); + sqlite3Fts3PendingTermsClear(p); return SQLITE_OK; } @@ -187938,49 +186688,8 @@ static int fts3ShadowName(const char *zName){ return 0; } -/* -** Implementation of the xIntegrity() method on the FTS3/FTS4 virtual -** table. -*/ -static int fts3Integrity( - sqlite3_vtab *pVtab, /* The virtual table to be checked */ - const char *zSchema, /* Name of schema in which pVtab lives */ - const char *zTabname, /* Name of the pVTab table */ - int isQuick, /* True if this is a quick_check */ - char **pzErr /* Write error message here */ -){ - Fts3Table *p = (Fts3Table*)pVtab; - char *zSql; - int rc; - char *zErr = 0; - - assert( pzErr!=0 ); - assert( *pzErr==0 ); - UNUSED_PARAMETER(isQuick); - zSql = sqlite3_mprintf( - "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", - zSchema, zTabname, zTabname); - if( zSql==0 ){ - return SQLITE_NOMEM; - } - rc = sqlite3_exec(p->db, zSql, 0, 0, &zErr); - sqlite3_free(zSql); - if( (rc&0xff)==SQLITE_CORRUPT ){ - *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", - p->bFts4 ? 4 : 3, zSchema, zTabname); - }else if( rc!=SQLITE_OK ){ - *pzErr = sqlite3_mprintf("unable to validate the inverted index for" - " FTS%d table %s.%s: %s", - p->bFts4 ? 4 : 3, zSchema, zTabname, zErr); - } - sqlite3_free(zErr); - return SQLITE_OK; -} - - - static const sqlite3_module fts3Module = { - /* iVersion */ 4, + /* iVersion */ 3, /* xCreate */ fts3CreateMethod, /* xConnect */ fts3ConnectMethod, /* xBestIndex */ fts3BestIndexMethod, @@ -188004,7 +186713,6 @@ static const sqlite3_module fts3Module = { /* xRelease */ fts3ReleaseMethod, /* xRollbackTo */ fts3RollbackToMethod, /* xShadowName */ fts3ShadowName, - /* xIntegrity */ fts3Integrity, }; /* @@ -190680,8 +189388,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0, /* xShadowName */ - 0 /* xIntegrity */ + 0 /* xShadowName */ }; int rc; /* Return code */ @@ -194247,8 +192954,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash, void(*xDestr 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0, /* xShadowName */ - 0 /* xIntegrity */ + 0 /* xShadowName */ }; int rc; /* Return code */ @@ -197589,6 +196295,7 @@ SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ rc = fts3SegmentMerge(p, p->iPrevLangid, i, FTS3_SEGCURSOR_PENDING); if( rc==SQLITE_DONE ) rc = SQLITE_OK; } + sqlite3Fts3PendingTermsClear(p); /* Determine the auto-incr-merge setting if unknown. If enabled, ** estimate the number of leaf blocks of content to be written @@ -197610,10 +196317,6 @@ SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ rc = sqlite3_reset(pStmt); } } - - if( rc==SQLITE_OK ){ - sqlite3Fts3PendingTermsClear(p); - } return rc; } @@ -198245,8 +196948,6 @@ static int fts3AppendToNode( blobGrowBuffer(pPrev, nTerm, &rc); if( rc!=SQLITE_OK ) return rc; - assert( pPrev!=0 ); - assert( pPrev->a!=0 ); nPrefix = fts3PrefixCompress(pPrev->a, pPrev->n, zTerm, nTerm); nSuffix = nTerm - nPrefix; @@ -198303,13 +197004,9 @@ static int fts3IncrmergeAppend( nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; /* If the current block is not empty, and if adding this term/doclist - ** to the current block would make it larger than Fts3Table.nNodeSize bytes, - ** and if there is still room for another leaf page, write this block out to - ** the database. */ - if( pLeaf->block.n>0 - && (pLeaf->block.n + nSpace)>p->nNodeSize - && pLeaf->iBlock < (pWriter->iStart + pWriter->nLeafEst) - ){ + ** to the current block would make it larger than Fts3Table.nNodeSize + ** bytes, write this block out to the database. */ + if( pLeaf->block.n>0 && (pLeaf->block.n + nSpace)>p->nNodeSize ){ rc = fts3WriteSegment(p, pLeaf->iBlock, pLeaf->block.a, pLeaf->block.n); pWriter->nWork++; @@ -198620,7 +197317,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){ @@ -198641,7 +197337,7 @@ static int fts3IncrmergeLoad( rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock,0); blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc - ); + ); if( rc==SQLITE_OK ){ memcpy(pNode->block.a, aBlock, nBlock); pNode->block.n = nBlock; @@ -199491,7 +198187,7 @@ static u64 fts3ChecksumIndex( int rc; u64 cksum = 0; - if( *pRc ) return 0; + assert( *pRc==SQLITE_OK ); memset(&filter, 0, sizeof(filter)); memset(&csr, 0, sizeof(csr)); @@ -199706,11 +198402,8 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ rc = fts3DoIncrmerge(p, &zVal[6]); }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){ rc = fts3DoAutoincrmerge(p, &zVal[10]); - }else if( nVal==5 && 0==sqlite3_strnicmp(zVal, "flush", 5) ){ - rc = sqlite3Fts3PendingTermsFlush(p); - } #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - else{ + }else{ int v; if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ v = atoi(&zVal[9]); @@ -199728,8 +198421,8 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ if( v>=4 && v<=FTS3_MERGE_COUNT && (v&1)==0 ) p->nMergeCount = v; rc = SQLITE_OK; } - } #endif + } return rc; } @@ -202670,51 +201363,25 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ ** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). */ static const char jsonIsSpace[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; #define fast_isspace(x) (jsonIsSpace[(unsigned char)x]) -/* -** Characters that are special to JSON. Control charaters, -** '"' and '\\'. -*/ -static const char jsonIsOk[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 -}; - - #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST) # define VVA(X) #else @@ -202725,7 +201392,6 @@ static const char jsonIsOk[256] = { 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 @@ -202741,26 +201407,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" */ @@ -202769,87 +201425,52 @@ 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 */ +#define JNODE_JSON5 0x80 /* Node contains JSON5 enhancements */ -/* 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 */ 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 */ }; /* @@ -202882,14 +201503,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){ @@ -202906,7 +201529,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; @@ -202915,12 +201538,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; @@ -202928,36 +201551,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, ...){ @@ -202971,36 +201571,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 '{'. */ @@ -203008,8 +201583,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 @@ -203023,16 +201597,11 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ p->zBuf[p->nUsed++] = '"'; for(i=0; izBuf[p->nUsed++] = c; - }else if( c=='"' || c=='\\' ){ + if( c=='"' || c=='\\' ){ json_simple_escape: if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; p->zBuf[p->nUsed++] = '\\'; - p->zBuf[p->nUsed++] = c; - }else if( c=='\'' ){ - p->zBuf[p->nUsed++] = c; - }else{ + }else if( c<=0x1f ){ static const char aSpecial[] = { 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 @@ -203043,7 +201612,6 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ assert( aSpecial['\n']=='n' ); assert( aSpecial['\r']=='r' ); assert( aSpecial['\t']=='t' ); - assert( c>=0 && czBuf[p->nUsed++] = 'u'; p->zBuf[p->nUsed++] = '0'; p->zBuf[p->nUsed++] = '0'; - p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4]; - p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf]; + p->zBuf[p->nUsed++] = '0' + (c>>4); + c = "0123456789abcdef"[c&0xf]; } + p->zBuf[p->nUsed++] = c; } p->zBuf[p->nUsed++] = '"'; assert( p->nUsednAlloc ); @@ -203072,35 +201641,29 @@ static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){ zIn++; N -= 2; while( N>0 ){ - for(i=0; i0 ){ - jsonAppendRawNZ(p, zIn, i); + jsonAppendRaw(p, zIn, i); zIn += i; N -= i; if( N==0 ) break; } - if( zIn[0]=='"' ){ - jsonAppendRawNZ(p, "\\\"", 2); - zIn++; - N--; - continue; - } assert( zIn[0]=='\\' ); switch( (u8)zIn[1] ){ case '\'': jsonAppendChar(p, '\''); break; case 'v': - jsonAppendRawNZ(p, "\\u0009", 6); + jsonAppendRaw(p, "\\u0009", 6); break; case 'x': - jsonAppendRawNZ(p, "\\u00", 4); - jsonAppendRawNZ(p, &zIn[2], 2); + jsonAppendRaw(p, "\\u00", 4); + jsonAppendRaw(p, &zIn[2], 2); zIn += 2; N -= 2; break; case '0': - jsonAppendRawNZ(p, "\\u0000", 6); + jsonAppendRaw(p, "\\u0000", 6); break; case '\r': if( zIn[2]=='\n' ){ @@ -203118,7 +201681,7 @@ static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){ N -= 2; break; default: - jsonAppendRawNZ(p, zIn, 2); + jsonAppendRaw(p, zIn, 2); break; } zIn += 2; @@ -203148,12 +201711,11 @@ static void jsonAppendNormalizedInt(JsonString *p, const char *zIn, u32 N){ jsonPrintf(100,p,"%lld",i); }else{ assert( rc==2 ); - jsonAppendRawNZ(p, "9.0e999", 7); + jsonAppendRaw(p, "9.0e999", 7); } return; } - assert( N>0 ); - jsonAppendRawNZ(p, zIn, N); + jsonAppendRaw(p, zIn, N); } /* @@ -203185,7 +201747,7 @@ static void jsonAppendNormalizedReal(JsonString *p, const char *zIn, u32 N){ } } if( N>0 ){ - jsonAppendRawNZ(p, zIn, N); + jsonAppendRaw(p, zIn, N); } } @@ -203201,7 +201763,7 @@ static void jsonAppendValue( ){ switch( sqlite3_value_type(pValue) ){ case SQLITE_NULL: { - jsonAppendRawNZ(p, "null", 4); + jsonAppendRaw(p, "null", 4); break; } case SQLITE_FLOAT: { @@ -203237,25 +201799,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, - 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 ); } /************************************************************************** @@ -203280,73 +201832,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); } /* @@ -203355,38 +201854,32 @@ 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: { @@ -203402,8 +201895,7 @@ static void jsonRenderNode( }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); + jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); } break; } @@ -203412,8 +201904,7 @@ static void jsonRenderNode( if( pNode->jnFlags & JNODE_JSON5 ){ jsonAppendNormalizedReal(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; } @@ -203422,8 +201913,7 @@ static void jsonRenderNode( 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; } @@ -203432,16 +201922,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, ']'); @@ -203452,18 +201941,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, '}'); @@ -203473,30 +201961,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 */ - int omitSubtype /* Do not call sqlite3_result_subtype() */ + 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); - if( !omitSubtype ) sqlite3_result_subtype(pCtx, JSON_SUBTYPE); - } + jsonInit(&s, pCtx); + jsonRenderNode(pNode, &s, aReplace); + jsonResult(&s); + sqlite3_result_subtype(pCtx, JSON_SUBTYPE); } /* @@ -203534,10 +202010,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 */ - int omitSubtype /* Do not call sqlite3_result_subtype() */ + sqlite3_value **aReplace /* Array of replacement values */ ){ switch( pNode->eType ){ default: { @@ -203559,6 +202034,7 @@ static void jsonReturn( int bNeg = 0; const char *z; + assert( pNode->eU==1 ); z = pNode->u.zJContent; if( z[0]=='-' ){ z++; bNeg = 1; } @@ -203683,7 +202159,7 @@ static void jsonReturn( } case JSON_ARRAY: case JSON_OBJECT: { - jsonReturnJson(pParse, pNode, pCtx, 0, omitSubtype); + jsonReturnJson(pNode, pCtx, aReplace); break; } } @@ -203705,12 +202181,6 @@ static int jsonParseAddNode(JsonParse*,u32,u32,const char*); #endif -/* -** Add a single node to pParse->aNode 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 */ @@ -203727,7 +202197,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); @@ -203745,13 +202215,10 @@ 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); } - assert( pParse->aNode!=0 ); p = &pParse->aNode[pParse->nNode]; - assert( p!=0 ); p->eType = (u8)(eType & 0xff); p->jnFlags = (u8)(eType >> 8); VVA( p->eU = zContent ? 1 : 0 ); @@ -203760,52 +202227,6 @@ static int jsonParseAddNode( 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 */ -){ - assert( aNode!=0 ); - assert( nNode>=1 ); - 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 */ @@ -203972,7 +202393,7 @@ static const struct NanInfName { ** ** Special return values: ** -** 0 End of input +** 0 End if input ** -1 Syntax error ** -2 '}' seen ** -3 ']' seen @@ -204147,12 +202568,15 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ jnFlags = 0; parse_string: cDelim = z[i]; - for(j=i+1; 1; j++){ - if( jsonIsOk[(unsigned char)z[j]] ) continue; + 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 */ + pParse->iErr = j; + return -1; + } + if( c=='\\' ){ c = z[++j]; if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' || c=='n' || c=='r' || c=='t' @@ -204172,11 +202596,10 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ pParse->iErr = j; return -1; } - }else if( c<=0x1f ){ - /* Control characters are not allowed in strings */ - pParse->iErr = j; - return -1; + }else if( c==cDelim ){ + break; } + j++; } jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]); return j+1; @@ -204412,18 +202835,20 @@ static int jsonParseValue(JsonParse *pParse, u32 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 ){ @@ -204452,7 +202877,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. */ @@ -204502,49 +202926,35 @@ 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. +** If an error occurs and pErrCtx==0 then return the Parse object with +** JsonParse.nErr non-zero. If the caller invokes this routine with +** pErrCtx==0 and it gets back a JsonParse with nErr!=0, then the caller +** is responsible for invoking jsonParseFree() on the returned value. +** But the caller may invoke jsonParseFree() *only* if pParse->nErr!=0. */ 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) - ){ - 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 + && memcmp(p->zJson,zJson,nJson)==0 ){ p->nErr = 0; - p->useMod = 1; pMatch = p; }else if( p->iHoldiHold; @@ -204579,44 +202977,28 @@ 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,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) ){ + p->zJson = (char*)&p[1]; + memcpy((char*)p->zJson, zJson, nJson+1); + if( jsonParse(p, pErrCtx, p->zJson) ){ if( pErrCtx==0 ){ p->nErr = 1; - assert( p->nJPRef==1 ); /* Caller will own the new JsonParse object p */ return p; } - jsonParseFree(p); + 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); @@ -204667,31 +203049,9 @@ static JsonNode *jsonLookupStep( ){ u32 i, j, nKey; const char *zKey; - JsonNode *pRoot; - if( pParse->oom ) return 0; - pRoot = &pParse->aNode[iRoot]; - if( pRoot->jnFlags & (JNODE_REPLACE|JNODE_REMOVE) && pParse->useMod ){ - while( (pRoot->jnFlags & JNODE_REPLACE)!=0 ){ - 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; - } - } - if( pRoot->jnFlags & JNODE_REMOVE ){ - return 0; - } - } + 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++; @@ -204725,16 +203085,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; @@ -204743,7 +203101,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; @@ -204764,13 +203122,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; } @@ -204798,17 +203155,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( i==0 && j<=pRoot->n ) break; 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; } @@ -204818,14 +203171,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 ); } @@ -204952,90 +203304,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, 0); + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + jsonParseFindParents(&x); + jsonInit(&s, ctx); + for(i=0; inNode ); if( argc==2 ){ @@ -205132,16 +203441,9 @@ static void jsonArrayLengthFunc( return; } if( pNode->eType==JSON_ARRAY ){ - while( 1 /*exit-by-break*/ ){ - i = 1; - while( i<=pNode->n ){ - if( (pNode[i].jnFlags & JNODE_REMOVE)==0 ) 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); @@ -205188,7 +203490,7 @@ 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 */ @@ -205206,11 +203508,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); } @@ -205221,14 +203523,15 @@ static void jsonExtractFunc( } if( pNode ){ if( flags & JSON_JSON ){ - jsonReturnJson(p, pNode, ctx, 0, 0); + jsonReturnJson(pNode, ctx, 0); }else{ - jsonReturn(p, pNode, ctx, 1); + 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, 0); + if( p->nErr==0 && pNode ) jsonReturn(pNode, ctx, 0); } }else{ /* Two or more PATH arguments results in a JSON array with each @@ -205242,9 +203545,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 ){ @@ -205289,38 +203592,45 @@ static JsonNode *jsonMergePatch( 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; + 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; @@ -205336,28 +203646,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; - assert( pX->hasMod==0 ); - pX->hasMod = 1; - pY = jsonParseCached(ctx, argv[1], ctx, 1); - if( pY==0 ) return; - pX->useMod = 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, 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); } @@ -205413,120 +203720,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, 0); + 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 = sqlite3_malloc64( n+1 ); - int k; - if( zCopy ){ - memcpy(zCopy, z, n); - zCopy[n] = 0; - 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); } /* @@ -205540,7 +203753,7 @@ static void jsonReplaceFunc( int argc, sqlite3_value **argv ){ - JsonParse *pParse; /* The parse */ + JsonParse x; /* The parse */ JsonNode *pNode; const char *zPath; u32 i; @@ -205550,22 +203763,28 @@ static void jsonReplaceFunc( jsonWrongNumArgs(ctx, "replace"); return; } - pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); - if( pParse==0 ) return; - pParse->nJPRef++; + 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, 0); + 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); - jsonParseFree(pParse); + jsonParseReset(&x); } @@ -205586,7 +203805,7 @@ static void jsonSetFunc( int argc, sqlite3_value **argv ){ - JsonParse *pParse; /* The parse */ + JsonParse x; /* The parse */ JsonNode *pNode; const char *zPath; u32 i; @@ -205598,27 +203817,33 @@ static void jsonSetFunc( jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); return; } - pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); - if( pParse==0 ) return; - pParse->nJPRef++; + 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, 0); + 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: - jsonParseFree(pParse); + jsonParseReset(&x); } /* @@ -205637,7 +203862,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]); @@ -205663,19 +203888,13 @@ static void jsonValidFunc( ){ JsonParse *p; /* The parse */ UNUSED_PARAMETER(argc); - if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ -#ifdef SQLITE_LEGACY_JSON_VALID - /* Incorrect legacy behavior was to return FALSE for a NULL input */ - sqlite3_result_int(ctx, 0); -#endif - return; - } - p = jsonParseCached(ctx, argv[0], 0, 0); + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + p = jsonParseCached(ctx, argv, 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)); + sqlite3_result_int(ctx, p->nErr==0 && p->hasNonstd==0); if( p->nErr ) jsonParseFree(p); } } @@ -205716,7 +203935,7 @@ static void jsonErrorFunc( JsonParse *p; /* The parse */ UNUSED_PARAMETER(argc); if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - p = jsonParseCached(ctx, argv[0], 0, 0); + p = jsonParseCached(ctx, argv, 0); if( p==0 || p->oom ){ sqlite3_result_error_nomem(ctx); sqlite3_free(p); @@ -205725,7 +203944,7 @@ static void jsonErrorFunc( }else{ int n = 1; u32 i; - const char *z = (const char*)sqlite3_value_text(argv[0]); + const char *z = p->zJson; for(i=0; iiErr && ALWAYS(z[i]); i++){ if( (z[i]&0xc0)!=0x80 ) n++; } @@ -205773,8 +203992,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 : - sqlite3RCStrUnref); + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); @@ -205815,7 +204033,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; @@ -205882,8 +204100,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 : - sqlite3RCStrUnref); + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); @@ -205994,6 +204211,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; @@ -206131,7 +204349,7 @@ static int jsonEachColumn( case JEACH_KEY: { if( p->i==0 ) break; if( p->eType==JSON_OBJECT ){ - jsonReturn(&p->sParse, pThis, ctx, 0); + jsonReturn(pThis, ctx, 0); }else if( p->eType==JSON_ARRAY ){ u32 iKey; if( p->bRecursive ){ @@ -206147,7 +204365,7 @@ static int jsonEachColumn( } case JEACH_VALUE: { if( pThis->jnFlags & JNODE_LABEL ) pThis++; - jsonReturn(&p->sParse, pThis, ctx, 0); + jsonReturn(pThis, ctx, 0); break; } case JEACH_TYPE: { @@ -206158,7 +204376,7 @@ static int jsonEachColumn( case JEACH_ATOM: { if( pThis->jnFlags & JNODE_LABEL ) pThis++; if( pThis->eType>=JSON_ARRAY ) break; - jsonReturn(&p->sParse, pThis, ctx, 0); + jsonReturn(pThis, ctx, 0); break; } case JEACH_ID: { @@ -206313,19 +204531,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], 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); @@ -206410,8 +204620,7 @@ static sqlite3_module jsonEachModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0, /* xShadowName */ - 0 /* xIntegrity */ + 0 /* xShadowName */ }; /* The methods of the json_tree virtual table. */ @@ -206439,8 +204648,7 @@ static sqlite3_module jsonTreeModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0, /* xShadowName */ - 0 /* xIntegrity */ + 0 /* xShadowName */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ #endif /* !defined(SQLITE_OMIT_JSON) */ @@ -206451,43 +204659,34 @@ static sqlite3_module jsonTreeModule = { SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ #ifndef SQLITE_OMIT_JSON static FuncDef aJsonFunc[] = { - /* calls sqlite3_result_subtype() */ - /* | */ - /* Uses cache ______ | __ calls sqlite3_value_subtype() */ - /* | | | */ - /* Num args _________ | | | ___ Flags */ - /* | | | | | */ - /* | | | | | */ - JFUNCTION(json, 1, 1, 1, 0, 0, jsonRemoveFunc), - JFUNCTION(json_array, -1, 0, 1, 1, 0, jsonArrayFunc), - JFUNCTION(json_array_length, 1, 1, 0, 0, 0, jsonArrayLengthFunc), - JFUNCTION(json_array_length, 2, 1, 0, 0, 0, jsonArrayLengthFunc), - JFUNCTION(json_error_position,1, 1, 0, 0, 0, jsonErrorFunc), - JFUNCTION(json_extract, -1, 1, 1, 0, 0, jsonExtractFunc), - JFUNCTION(->, 2, 1, 1, 0, JSON_JSON, jsonExtractFunc), - JFUNCTION(->>, 2, 1, 0, 0, JSON_SQL, jsonExtractFunc), - JFUNCTION(json_insert, -1, 1, 1, 1, 0, jsonSetFunc), - JFUNCTION(json_object, -1, 0, 1, 1, 0, jsonObjectFunc), - JFUNCTION(json_patch, 2, 1, 1, 0, 0, jsonPatchFunc), - JFUNCTION(json_quote, 1, 0, 1, 1, 0, jsonQuoteFunc), - JFUNCTION(json_remove, -1, 1, 1, 0, 0, jsonRemoveFunc), - JFUNCTION(json_replace, -1, 1, 1, 1, 0, jsonReplaceFunc), - JFUNCTION(json_set, -1, 1, 1, 1, JSON_ISSET, jsonSetFunc), - JFUNCTION(json_type, 1, 1, 0, 0, 0, jsonTypeFunc), - JFUNCTION(json_type, 2, 1, 0, 0, 0, jsonTypeFunc), - JFUNCTION(json_valid, 1, 1, 0, 0, 0, jsonValidFunc), -#ifdef SQLITE_DEBUG - JFUNCTION(json_parse, 1, 1, 1, 0, 0, jsonParseFunc), - JFUNCTION(json_test1, 1, 1, 0, 1, 0, jsonTest1Func), + JFUNCTION(json, 1, 0, jsonRemoveFunc), + 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), + JFUNCTION(json_insert, -1, 0, jsonSetFunc), + JFUNCTION(json_object, -1, 0, jsonObjectFunc), + JFUNCTION(json_patch, 2, 0, jsonPatchFunc), + JFUNCTION(json_quote, 1, 0, jsonQuoteFunc), + JFUNCTION(json_remove, -1, 0, jsonRemoveFunc), + JFUNCTION(json_replace, -1, 0, jsonReplaceFunc), + JFUNCTION(json_set, -1, JSON_ISSET, jsonSetFunc), + JFUNCTION(json_type, 1, 0, jsonTypeFunc), + JFUNCTION(json_type, 2, 0, jsonTypeFunc), + JFUNCTION(json_valid, 1, 0, jsonValidFunc), +#if SQLITE_DEBUG + JFUNCTION(json_parse, 1, 0, jsonParseFunc), + JFUNCTION(json_test1, 1, 0, jsonTest1Func), #endif WAGGREGATE(json_group_array, 1, 0, 0, jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, - SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| - SQLITE_DETERMINISTIC), + SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), WAGGREGATE(json_group_object, 2, 0, 0, jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, - SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| - SQLITE_DETERMINISTIC) + SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC) }; sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc)); #endif @@ -206614,11 +204813,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 */ @@ -206684,7 +204878,6 @@ struct Rtree { int iDepth; /* Current depth of the r-tree structure */ char *zDb; /* Name of database containing r-tree table */ char *zName; /* Name of r-tree table */ - char *zNodeName; /* Name of the %_node table */ u32 nBusy; /* Current number of users of this structure */ i64 nRowEst; /* Estimated number of rows in this table */ u32 nCursor; /* Number of open cursors */ @@ -206697,6 +204890,7 @@ struct Rtree { ** headed by the node (leaf nodes have RtreeNode.iNode==0). */ RtreeNode *pDeleted; + int iReinsertHeight; /* Height of sub-trees Reinsert() has run on */ /* Blob I/O on xxx_node */ sqlite3_blob *pNodeBlob; @@ -206993,20 +205187,15 @@ struct RtreeMatchArg { ** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined ** at run-time. */ -#ifndef SQLITE_BYTEORDER /* Replicate changes at tag-20230904a */ -# if defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ -# define SQLITE_BYTEORDER 4321 -# elif defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ -# define SQLITE_BYTEORDER 1234 -# elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 -# define SQLITE_BYTEORDER 4321 -# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ +#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(__ARMEB__) || defined(__AARCH64EB__) -# define SQLITE_BYTEORDER 4321 +# define SQLITE_BYTEORDER 1234 +# elif defined(sparc) || defined(__ppc__) || \ + defined(__ARMEB__) || defined(__AARCH64EB__) +# define SQLITE_BYTEORDER 4321 # else # define SQLITE_BYTEORDER 0 # endif @@ -207030,7 +205219,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 @@ -207084,7 +205273,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 @@ -207255,9 +205444,11 @@ static int nodeAcquire( } } if( pRtree->pNodeBlob==0 ){ - rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, pRtree->zNodeName, - "data", iNode, 0, + char *zTab = sqlite3_mprintf("%s_node", pRtree->zName); + if( zTab==0 ) return SQLITE_NOMEM; + rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, zTab, "data", iNode, 0, &pRtree->pNodeBlob); + sqlite3_free(zTab); } if( rc ){ nodeBlobReset(pRtree); @@ -207810,7 +206001,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 */ @@ -207863,7 +206054,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 */ @@ -208440,7 +206631,7 @@ static int rtreeFilter( #else p->u.rValue = (double)iVal; if( iVal>=((sqlite3_int64)1)<<48 - || 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; @@ -208598,12 +206789,8 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ pIdxInfo->idxNum = 2; pIdxInfo->needToFreeIdxStr = 1; - if( iIdx>0 ){ - pIdxInfo->idxStr = sqlite3_malloc( iIdx+1 ); - if( pIdxInfo->idxStr==0 ){ - return SQLITE_NOMEM; - } - memcpy(pIdxInfo->idxStr, zIdxStr, iIdx+1); + if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){ + return SQLITE_NOMEM; } nRow = pRtree->nRowEst >> (iIdx/2); @@ -208682,22 +206869,31 @@ static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ */ static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ int ii; - if( pRtree->eCoordType==RTREE_COORD_INT32 ){ - for(ii=0; iinDim2; ii+=2){ - RtreeCoord *a1 = &p1->aCoord[ii]; - RtreeCoord *a2 = &p2->aCoord[ii]; - if( a2[0].ia1[1].i ) return 0; - } - }else{ - for(ii=0; iinDim2; ii+=2){ - RtreeCoord *a1 = &p1->aCoord[ii]; - RtreeCoord *a2 = &p2->aCoord[ii]; - if( a2[0].fa1[1].f ) return 0; + int isInt = (pRtree->eCoordType==RTREE_COORD_INT32); + for(ii=0; iinDim2; ii+=2){ + RtreeCoord *a1 = &p1->aCoord[ii]; + RtreeCoord *a2 = &p2->aCoord[ii]; + if( (!isInt && (a2[0].fa1[1].f)) + || ( isInt && (a2[0].ia1[1].i)) + ){ + return 0; } } return 1; } +/* +** Return the amount cell p would grow by if it were unioned with pCell. +*/ +static RtreeDValue cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){ + RtreeDValue area; + RtreeCell cell; + memcpy(&cell, p, sizeof(RtreeCell)); + area = cellArea(pRtree, &cell); + cellUnion(pRtree, &cell, pCell); + return (cellArea(pRtree, &cell)-area); +} + static RtreeDValue cellOverlap( Rtree *pRtree, RtreeCell *p, @@ -208744,52 +206940,38 @@ static int ChooseLeaf( for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ int iCell; sqlite3_int64 iBest = 0; - int bFound = 0; + RtreeDValue fMinGrowth = RTREE_ZERO; RtreeDValue fMinArea = RTREE_ZERO; + int nCell = NCELL(pNode); + RtreeCell cell; RtreeNode *pChild = 0; - /* First check to see if there is are any cells in pNode that completely - ** contains pCell. If two or more cells in pNode completely contain pCell - ** then pick the smallest. + RtreeCell *aCell = 0; + + /* Select the child node which will be enlarged the least if pCell + ** is inserted into it. Resolve ties by choosing the entry with + ** the smallest area. */ for(iCell=0; iCell1 ){ + int iLeft = 0; + int iRight = 0; + + int nLeft = nIdx/2; + int nRight = nIdx-nLeft; + int *aLeft = aIdx; + int *aRight = &aIdx[nLeft]; + + SortByDistance(aLeft, nLeft, aDistance, aSpare); + SortByDistance(aRight, nRight, aDistance, aSpare); + + memcpy(aSpare, aLeft, sizeof(int)*nLeft); + aLeft = aSpare; + + while( iLeftnDim; iDim++){ + aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]); + aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]); + } + } + for(iDim=0; iDimnDim; iDim++){ + aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2)); + } + + for(ii=0; iinDim; iDim++){ + RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) - + DCOORD(aCell[ii].aCoord[iDim*2])); + aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); + } + } + + SortByDistance(aOrder, nCell, aDistance, aSpare); + nodeZero(pRtree, pNode); + + for(ii=0; rc==SQLITE_OK && ii<(nCell-(RTREE_MINCELLS(pRtree)+1)); ii++){ + RtreeCell *p = &aCell[aOrder[ii]]; + nodeInsertCell(pRtree, pNode, p); + if( p->iRowid==pCell->iRowid ){ + if( iHeight==0 ){ + rc = rowidWrite(pRtree, p->iRowid, pNode->iNode); + }else{ + rc = parentWrite(pRtree, p->iRowid, pNode->iNode); + } + } + } + if( rc==SQLITE_OK ){ + rc = fixBoundingBox(pRtree, pNode); + } + for(; rc==SQLITE_OK && iiiNode currently contains + ** the height of the sub-tree headed by the cell. + */ + RtreeNode *pInsert; + RtreeCell *p = &aCell[aOrder[ii]]; + rc = ChooseLeaf(pRtree, p, iHeight, &pInsert); + if( rc==SQLITE_OK ){ + int rc2; + rc = rtreeInsertCell(pRtree, pInsert, p, iHeight); + rc2 = nodeRelease(pRtree, pInsert); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + + sqlite3_free(aCell); + return rc; +} + /* ** Insert cell pCell into node pNode. Node pNode is the head of a ** subtree iHeight high (leaf nodes have iHeight==0). @@ -209366,7 +207720,12 @@ static int rtreeInsertCell( } } if( nodeInsertCell(pRtree, pNode, pCell) ){ - rc = SplitNode(pRtree, pNode, pCell, iHeight); + if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){ + rc = SplitNode(pRtree, pNode, pCell, iHeight); + }else{ + pRtree->iReinsertHeight = iHeight; + rc = Reinsert(pRtree, pNode, pCell, iHeight); + } }else{ rc = AdjustTree(pRtree, pNode, pCell); if( ALWAYS(rc==SQLITE_OK) ){ @@ -209709,6 +208068,7 @@ static int rtreeUpdate( } if( rc==SQLITE_OK ){ int rc2; + pRtree->iReinsertHeight = -1; rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); rc2 = nodeRelease(pRtree, pLeaf); if( rc==SQLITE_OK ){ @@ -209849,11 +208209,8 @@ static int rtreeShadowName(const char *zName){ return 0; } -/* Forward declaration */ -static int rtreeIntegrity(sqlite3_vtab*, const char*, const char*, int, char**); - static sqlite3_module rtreeModule = { - 4, /* iVersion */ + 3, /* iVersion */ rtreeCreate, /* xCreate - create a table */ rtreeConnect, /* xConnect - connect to an existing table */ rtreeBestIndex, /* xBestIndex - Determine search strategy */ @@ -209876,8 +208233,7 @@ static sqlite3_module rtreeModule = { rtreeSavepoint, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - rtreeShadowName, /* xShadowName */ - rtreeIntegrity /* xIntegrity */ + rtreeShadowName /* xShadowName */ }; static int rtreeSqlInit( @@ -210133,27 +208489,22 @@ static int rtreeInit( } sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); - sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); - /* Allocate the sqlite3_vtab structure */ nDb = (int)strlen(argv[1]); nName = (int)strlen(argv[2]); - pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName*2+8); + pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2); if( !pRtree ){ return SQLITE_NOMEM; } - memset(pRtree, 0, sizeof(Rtree)+nDb+nName*2+8); + memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); pRtree->nBusy = 1; pRtree->base.pModule = &rtreeModule; pRtree->zDb = (char *)&pRtree[1]; pRtree->zName = &pRtree->zDb[nDb+1]; - pRtree->zNodeName = &pRtree->zName[nName+1]; pRtree->eCoordType = (u8)eCoordType; memcpy(pRtree->zDb, argv[1], nDb); memcpy(pRtree->zName, argv[2], nName); - memcpy(pRtree->zNodeName, argv[2], nName); - memcpy(&pRtree->zNodeName[nName], "_node", 6); /* Create/Connect to the underlying relational database schema. If @@ -210650,6 +209001,7 @@ static int rtreeCheckTable( ){ RtreeCheck check; /* Common context for various routines */ sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */ + int bEnd = 0; /* True if transaction should be closed */ int nAux = 0; /* Number of extra columns. */ /* Initialize the context object */ @@ -210658,6 +209010,14 @@ static int rtreeCheckTable( check.zDb = zDb; check.zTab = zTab; + /* If there is not already an open transaction, open one now. This is + ** to ensure that the queries run as part of this integrity-check operate + ** on a consistent snapshot. */ + if( sqlite3_get_autocommit(db) ){ + check.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0); + bEnd = 1; + } + /* Find the number of auxiliary columns */ if( check.rc==SQLITE_OK ){ pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); @@ -210698,34 +209058,15 @@ static int rtreeCheckTable( sqlite3_finalize(check.aCheckMapping[0]); sqlite3_finalize(check.aCheckMapping[1]); + /* If one was opened, close the transaction */ + if( bEnd ){ + int rc = sqlite3_exec(db, "END", 0, 0, 0); + if( check.rc==SQLITE_OK ) check.rc = rc; + } *pzReport = check.zReport; return check.rc; } -/* -** Implementation of the xIntegrity method for Rtree. -*/ -static int rtreeIntegrity( - sqlite3_vtab *pVtab, /* The virtual table to check */ - const char *zSchema, /* Schema in which the virtual table lives */ - const char *zName, /* Name of the virtual table */ - int isQuick, /* True for a quick_check */ - char **pzErr /* Write results here */ -){ - Rtree *pRtree = (Rtree*)pVtab; - int rc; - assert( pzErr!=0 && *pzErr==0 ); - UNUSED_PARAMETER(zSchema); - UNUSED_PARAMETER(zName); - UNUSED_PARAMETER(isQuick); - rc = rtreeCheckTable(pRtree->db, pRtree->zDb, pRtree->zName, pzErr); - if( rc==SQLITE_OK && *pzErr ){ - *pzErr = sqlite3_mprintf("In RTree %s.%s:\n%z", - pRtree->zDb, pRtree->zName, *pzErr); - } - return rc; -} - /* ** Usage: ** @@ -212047,28 +210388,24 @@ static int geopolyInit( (void)pAux; sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); - sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); /* Allocate the sqlite3_vtab structure */ nDb = strlen(argv[1]); nName = strlen(argv[2]); - pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName*2+8); + pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2); if( !pRtree ){ return SQLITE_NOMEM; } - memset(pRtree, 0, sizeof(Rtree)+nDb+nName*2+8); + memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); pRtree->nBusy = 1; pRtree->base.pModule = &rtreeModule; pRtree->zDb = (char *)&pRtree[1]; pRtree->zName = &pRtree->zDb[nDb+1]; - pRtree->zNodeName = &pRtree->zName[nName+1]; pRtree->eCoordType = RTREE_COORD_REAL32; pRtree->nDim = 2; pRtree->nDim2 = 4; memcpy(pRtree->zDb, argv[1], nDb); memcpy(pRtree->zName, argv[2], nName); - memcpy(pRtree->zNodeName, argv[2], nName); - memcpy(&pRtree->zNodeName[nName], "_node", 6); /* Create/Connect to the underlying relational database schema. If @@ -212482,6 +210819,7 @@ static int geopolyUpdate( } if( rc==SQLITE_OK ){ int rc2; + pRtree->iReinsertHeight = -1; rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); rc2 = nodeRelease(pRtree, pLeaf); if( rc==SQLITE_OK ){ @@ -212578,8 +210916,7 @@ static sqlite3_module geopolyModule = { rtreeSavepoint, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - rtreeShadowName, /* xShadowName */ - rtreeIntegrity /* xIntegrity */ + rtreeShadowName /* xShadowName */ }; static int sqlite3_geopoly_init(sqlite3 *db){ @@ -220593,8 +218930,7 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0, /* xShadowName */ - 0 /* xIntegrity */ + 0 /* xShadowName */ }; return sqlite3_create_module(db, "dbstat", &dbstat_module, 0); } @@ -221031,8 +219367,7 @@ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0, /* xShadowName */ - 0 /* xIntegrity */ + 0 /* xShadowName */ }; return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0); } @@ -221163,18 +219498,6 @@ struct sqlite3_changeset_iter { ** The data associated with each hash-table entry is a structure containing ** a subset of the initial values that the modified row contained at the ** start of the session. Or no initial values if the row was inserted. -** -** pDfltStmt: -** This is only used by the sqlite3changegroup_xxx() APIs, not by -** regular sqlite3_session objects. It is a SELECT statement that -** selects the default value for each table column. For example, -** if the table is -** -** CREATE TABLE xx(a DEFAULT 1, b, c DEFAULT 'abc') -** -** then this variable is the compiled version of: -** -** SELECT 1, NULL, 'abc' */ struct SessionTable { SessionTable *pNext; @@ -221183,12 +219506,10 @@ struct SessionTable { int bStat1; /* True if this is sqlite_stat1 */ int bRowid; /* True if this table uses rowid for PK */ const char **azCol; /* Column names */ - const char **azDflt; /* Default value expressions */ u8 *abPK; /* Array of primary key flags */ int nEntry; /* Total number of entries in hash table */ int nChange; /* Size of apChange[] array */ SessionChange **apChange; /* Hash table buckets */ - sqlite3_stmt *pDfltStmt; }; /* @@ -221357,7 +219678,6 @@ struct SessionTable { struct SessionChange { u8 op; /* One of UPDATE, DELETE, INSERT */ u8 bIndirect; /* True if this change is "indirect" */ - u16 nRecordField; /* Number of fields in aRecord[] */ int nMaxSize; /* Max size of eventual changeset record */ int nRecord; /* Number of bytes in buffer aRecord[] */ u8 *aRecord; /* Buffer containing old.* record */ @@ -221383,7 +219703,7 @@ static int sessionVarintLen(int iVal){ ** Read a varint value from aBuf[] into *piVal. Return the number of ** bytes read. */ -static int sessionVarintGet(const u8 *aBuf, int *piVal){ +static int sessionVarintGet(u8 *aBuf, int *piVal){ return getVarint32(aBuf, *piVal); } @@ -221646,11 +219966,9 @@ static int sessionPreupdateHash( ** Return the number of bytes of space occupied by the value (including ** the type byte). */ -static int sessionSerialLen(const u8 *a){ - int e; +static int sessionSerialLen(u8 *a){ + int e = *a; int n; - assert( a!=0 ); - e = *a; if( e==0 || e==0xFF ) return 1; if( e==SQLITE_NULL ) return 1; if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9; @@ -221952,7 +220270,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 */ @@ -222055,14 +220372,13 @@ static int sessionGrowHash( ** ** For example, if the table is declared as: ** -** CREATE TABLE tbl1(w, x DEFAULT 'abc', y, z, PRIMARY KEY(w, z)); +** CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z)); ** -** Then the five output variables are populated as follows: +** Then the four output variables are populated as follows: ** ** *pnCol = 4 ** *pzTab = "tbl1" ** *pazCol = {"w", "x", "y", "z"} -** *pazDflt = {NULL, 'abc', NULL, NULL} ** *pabPK = {1, 0, 0, 1} ** ** All returned buffers are part of the same single allocation, which must @@ -222076,7 +220392,6 @@ 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 */ - const char ***pazDflt, /* OUT: Array of default value expressions */ u8 **pabPK, /* OUT: Array of booleans - true for PK col */ int *pbRowid /* OUT: True if only PK is a rowid */ ){ @@ -222089,18 +220404,11 @@ static int sessionTableInfo( int i; u8 *pAlloc = 0; char **azCol = 0; - char **azDflt = 0; u8 *abPK = 0; int bRowid = 0; /* Set to true to use rowid as PK */ assert( pazCol && pabPK ); - *pazCol = 0; - *pabPK = 0; - *pnCol = 0; - if( pzTab ) *pzTab = 0; - if( pazDflt ) *pazDflt = 0; - nThis = sqlite3Strlen30(zThis); if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){ rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0); @@ -222114,28 +220422,39 @@ static int sessionTableInfo( }else if( rc==SQLITE_ERROR ){ zPragma = sqlite3_mprintf(""); }else{ + *pazCol = 0; + *pabPK = 0; + *pnCol = 0; + if( pzTab ) *pzTab = 0; return rc; } }else{ zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); } if( !zPragma ){ + *pazCol = 0; + *pabPK = 0; + *pnCol = 0; + if( pzTab ) *pzTab = 0; return SQLITE_NOMEM; } rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0); sqlite3_free(zPragma); if( rc!=SQLITE_OK ){ + *pazCol = 0; + *pabPK = 0; + *pnCol = 0; + if( pzTab ) *pzTab = 0; return rc; } nByte = nThis + 1; bRowid = (pbRowid!=0); while( SQLITE_ROW==sqlite3_step(pStmt) ){ - nByte += sqlite3_column_bytes(pStmt, 1); /* name */ - nByte += sqlite3_column_bytes(pStmt, 4); /* dflt_value */ + nByte += sqlite3_column_bytes(pStmt, 1); nDbCol++; - if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; /* pk */ + if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; } if( nDbCol==0 ) bRowid = 0; nDbCol += bRowid; @@ -222143,18 +220462,15 @@ static int sessionTableInfo( rc = sqlite3_reset(pStmt); if( rc==SQLITE_OK ){ - nByte += nDbCol * (sizeof(const char *)*2 + sizeof(u8) + 1 + 1); + nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1); pAlloc = sessionMalloc64(pSession, nByte); if( pAlloc==0 ){ rc = SQLITE_NOMEM; - }else{ - memset(pAlloc, 0, nByte); } } if( rc==SQLITE_OK ){ azCol = (char **)pAlloc; - azDflt = (char**)&azCol[nDbCol]; - pAlloc = (u8 *)&azDflt[nDbCol]; + pAlloc = (u8 *)&azCol[nDbCol]; abPK = (u8 *)pAlloc; pAlloc = &abPK[nDbCol]; if( pzTab ){ @@ -222174,21 +220490,11 @@ static int sessionTableInfo( } while( SQLITE_ROW==sqlite3_step(pStmt) ){ int nName = sqlite3_column_bytes(pStmt, 1); - int nDflt = sqlite3_column_bytes(pStmt, 4); const unsigned char *zName = sqlite3_column_text(pStmt, 1); - const unsigned char *zDflt = sqlite3_column_text(pStmt, 4); - if( zName==0 ) break; memcpy(pAlloc, zName, nName+1); azCol[i] = (char *)pAlloc; pAlloc += nName+1; - if( zDflt ){ - memcpy(pAlloc, zDflt, nDflt+1); - azDflt[i] = (char *)pAlloc; - pAlloc += nDflt+1; - }else{ - azDflt[i] = 0; - } abPK[i] = sqlite3_column_int(pStmt, 5); i++; } @@ -222199,11 +220505,14 @@ static int sessionTableInfo( ** free any allocation made. An error code will be returned in this case. */ if( rc==SQLITE_OK ){ - *pazCol = (const char**)azCol; - if( pazDflt ) *pazDflt = (const char**)azDflt; + *pazCol = (const char **)azCol; *pabPK = abPK; *pnCol = nDbCol; }else{ + *pazCol = 0; + *pabPK = 0; + *pnCol = 0; + if( pzTab ) *pzTab = 0; sessionFree(pSession, azCol); } if( pbRowid ) *pbRowid = bRowid; @@ -222212,9 +220521,10 @@ static int sessionTableInfo( } /* -** This function is called to initialize the SessionTable.nCol, azCol[] -** abPK[] and azDflt[] members of SessionTable object pTab. If these -** fields are already initilialized, this function is a no-op. +** This function is only called from within a pre-update handler for a +** write to table pTab, part of session pSession. If this is the first +** write to this table, initalize the SessionTable.nCol, azCol[] and +** abPK[] arrays accordingly. ** ** If an error occurs, an error code is stored in sqlite3_session.rc and ** non-zero returned. Or, if no error occurs but the table has no primary @@ -222222,22 +220532,15 @@ static int sessionTableInfo( ** indicate that updates on this table should be ignored. SessionTable.abPK ** is set to NULL in this case. */ -static int sessionInitTable( - sqlite3_session *pSession, /* Optional session handle */ - SessionTable *pTab, /* Table object to initialize */ - sqlite3 *db, /* Database handle to read schema from */ - const char *zDb /* Name of db - "main", "temp" etc. */ -){ - int rc = SQLITE_OK; - +static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ if( pTab->nCol==0 ){ u8 *abPK; assert( pTab->azCol==0 || pTab->abPK==0 ); - rc = sessionTableInfo(pSession, db, zDb, - pTab->zName, &pTab->nCol, 0, &pTab->azCol, &pTab->azDflt, &abPK, - ((pSession==0 || pSession->bImplicitPK) ? &pTab->bRowid : 0) + pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, + pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK, + (pSession->bImplicitPK ? &pTab->bRowid : 0) ); - if( rc==SQLITE_OK ){ + if( pSession->rc==SQLITE_OK ){ int i; for(i=0; inCol; i++){ if( abPK[i] ){ @@ -222249,321 +220552,14 @@ static int sessionInitTable( pTab->bStat1 = 1; } - if( pSession && pSession->bEnableSize ){ + if( pSession->bEnableSize ){ pSession->nMaxChangesetSize += ( 1 + sessionVarintLen(pTab->nCol) + pTab->nCol + strlen(pTab->zName)+1 ); } } } - - if( pSession ){ - pSession->rc = rc; - return (rc || pTab->abPK==0); - } - return rc; -} - -/* -** Re-initialize table object pTab. -*/ -static int sessionReinitTable(sqlite3_session *pSession, SessionTable *pTab){ - int nCol = 0; - const char **azCol = 0; - const char **azDflt = 0; - u8 *abPK = 0; - int bRowid = 0; - - assert( pSession->rc==SQLITE_OK ); - - pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, - pTab->zName, &nCol, 0, &azCol, &azDflt, &abPK, - (pSession->bImplicitPK ? &bRowid : 0) - ); - if( pSession->rc==SQLITE_OK ){ - if( pTab->nCol>nCol || pTab->bRowid!=bRowid ){ - pSession->rc = SQLITE_SCHEMA; - }else{ - int ii; - int nOldCol = pTab->nCol; - for(ii=0; iinCol ){ - if( pTab->abPK[ii]!=abPK[ii] ){ - pSession->rc = SQLITE_SCHEMA; - } - }else if( abPK[ii] ){ - pSession->rc = SQLITE_SCHEMA; - } - } - - if( pSession->rc==SQLITE_OK ){ - const char **a = pTab->azCol; - pTab->azCol = azCol; - pTab->nCol = nCol; - pTab->azDflt = azDflt; - pTab->abPK = abPK; - azCol = a; - } - if( pSession->bEnableSize ){ - pSession->nMaxChangesetSize += (nCol - nOldCol); - pSession->nMaxChangesetSize += sessionVarintLen(nCol); - pSession->nMaxChangesetSize -= sessionVarintLen(nOldCol); - } - } - } - - sqlite3_free((char*)azCol); - return pSession->rc; -} - -/* -** Session-change object (*pp) contains an old.* record with fewer than -** nCol fields. This function updates it with the default values for -** the missing fields. -*/ -static void sessionUpdateOneChange( - sqlite3_session *pSession, /* For memory accounting */ - int *pRc, /* IN/OUT: Error code */ - SessionChange **pp, /* IN/OUT: Change object to update */ - int nCol, /* Number of columns now in table */ - sqlite3_stmt *pDflt /* SELECT */ -){ - SessionChange *pOld = *pp; - - while( pOld->nRecordFieldnRecordField; - int eType = sqlite3_column_type(pDflt, iField); - switch( eType ){ - case SQLITE_NULL: - nIncr = 1; - break; - case SQLITE_INTEGER: - case SQLITE_FLOAT: - nIncr = 9; - break; - default: { - int n = sqlite3_column_bytes(pDflt, iField); - nIncr = 1 + sessionVarintLen(n) + n; - assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); - break; - } - } - - nByte = nIncr + (sizeof(SessionChange) + pOld->nRecord); - pNew = sessionMalloc64(pSession, nByte); - if( pNew==0 ){ - *pRc = SQLITE_NOMEM; - return; - }else{ - memcpy(pNew, pOld, sizeof(SessionChange)); - pNew->aRecord = (u8*)&pNew[1]; - memcpy(pNew->aRecord, pOld->aRecord, pOld->nRecord); - pNew->aRecord[pNew->nRecord++] = (u8)eType; - switch( eType ){ - case SQLITE_INTEGER: { - i64 iVal = sqlite3_column_int64(pDflt, iField); - sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal); - pNew->nRecord += 8; - break; - } - - case SQLITE_FLOAT: { - double rVal = sqlite3_column_double(pDflt, iField); - i64 iVal = 0; - memcpy(&iVal, &rVal, sizeof(rVal)); - sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal); - pNew->nRecord += 8; - break; - } - - case SQLITE_TEXT: { - int n = sqlite3_column_bytes(pDflt, iField); - const char *z = (const char*)sqlite3_column_text(pDflt, iField); - pNew->nRecord += sessionVarintPut(&pNew->aRecord[pNew->nRecord], n); - memcpy(&pNew->aRecord[pNew->nRecord], z, n); - pNew->nRecord += n; - break; - } - - case SQLITE_BLOB: { - int n = sqlite3_column_bytes(pDflt, iField); - const u8 *z = (const u8*)sqlite3_column_blob(pDflt, iField); - pNew->nRecord += sessionVarintPut(&pNew->aRecord[pNew->nRecord], n); - memcpy(&pNew->aRecord[pNew->nRecord], z, n); - pNew->nRecord += n; - break; - } - - default: - assert( eType==SQLITE_NULL ); - break; - } - - sessionFree(pSession, pOld); - *pp = pOld = pNew; - pNew->nRecordField++; - pNew->nMaxSize += nIncr; - if( pSession ){ - pSession->nMaxChangesetSize += nIncr; - } - } - } -} - -/* -** Ensure that there is room in the buffer to append nByte bytes of data. -** If not, use sqlite3_realloc() to grow the buffer so that there is. -** -** If successful, return zero. Otherwise, if an OOM condition is encountered, -** set *pRc to SQLITE_NOMEM and return non-zero. -*/ -static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){ -#define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1) - i64 nReq = p->nBuf + nByte; - if( *pRc==SQLITE_OK && nReq>p->nAlloc ){ - u8 *aNew; - i64 nNew = p->nAlloc ? p->nAlloc : 128; - - do { - nNew = nNew*2; - }while( nNewSESSION_MAX_BUFFER_SZ ){ - nNew = SESSION_MAX_BUFFER_SZ; - if( nNewaBuf, nNew); - if( 0==aNew ){ - *pRc = SQLITE_NOMEM; - }else{ - p->aBuf = aNew; - p->nAlloc = nNew; - } - } - return (*pRc!=SQLITE_OK); -} - - -/* -** This function is a no-op if *pRc is other than SQLITE_OK when it is -** called. Otherwise, append a string to the buffer. All bytes in the string -** up to (but not including) the nul-terminator are written to the buffer. -** -** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before -** returning. -*/ -static void sessionAppendStr( - SessionBuffer *p, - const char *zStr, - int *pRc -){ - int nStr = sqlite3Strlen30(zStr); - if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ - memcpy(&p->aBuf[p->nBuf], zStr, nStr); - p->nBuf += nStr; - p->aBuf[p->nBuf] = 0x00; - } -} - -/* -** Format a string using printf() style formatting and then append it to the -** buffer using sessionAppendString(). -*/ -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); - } -} - -/* -** Prepare a statement against database handle db that SELECTs a single -** row containing the default values for each column in table pTab. For -** example, if pTab is declared as: -** -** CREATE TABLE pTab(a PRIMARY KEY, b DEFAULT 123, c DEFAULT 'abcd'); -** -** Then this function prepares and returns the SQL statement: -** -** SELECT NULL, 123, 'abcd'; -*/ -static int sessionPrepareDfltStmt( - sqlite3 *db, /* Database handle */ - SessionTable *pTab, /* Table to prepare statement for */ - sqlite3_stmt **ppStmt /* OUT: Statement handle */ -){ - SessionBuffer sql = {0,0,0}; - int rc = SQLITE_OK; - const char *zSep = " "; - int ii = 0; - - *ppStmt = 0; - sessionAppendPrintf(&sql, &rc, "SELECT"); - for(ii=0; iinCol; ii++){ - const char *zDflt = pTab->azDflt[ii] ? pTab->azDflt[ii] : "NULL"; - sessionAppendPrintf(&sql, &rc, "%s%s", zSep, zDflt); - zSep = ", "; - } - if( rc==SQLITE_OK ){ - rc = sqlite3_prepare_v2(db, (const char*)sql.aBuf, -1, ppStmt, 0); - } - sqlite3_free(sql.aBuf); - - return rc; -} - -/* -** Table pTab has one or more existing change-records with old.* records -** with fewer than pTab->nCol columns. This function updates all such -** change-records with the default values for the missing columns. -*/ -static int sessionUpdateChanges(sqlite3_session *pSession, SessionTable *pTab){ - sqlite3_stmt *pStmt = 0; - int rc = pSession->rc; - - rc = sessionPrepareDfltStmt(pSession->db, pTab, &pStmt); - if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ - int ii = 0; - SessionChange **pp = 0; - for(ii=0; iinChange; ii++){ - for(pp=&pTab->apChange[ii]; *pp; pp=&((*pp)->pNext)){ - if( (*pp)->nRecordField!=pTab->nCol ){ - sessionUpdateOneChange(pSession, &rc, pp, pTab->nCol, pStmt); - } - } - } - } - - pSession->rc = rc; - rc = sqlite3_finalize(pStmt); - if( pSession->rc==SQLITE_OK ) pSession->rc = rc; - return pSession->rc; + return (pSession->rc || pTab->abPK==0); } /* @@ -222726,22 +220722,16 @@ static void sessionPreupdateOneChange( int iHash; int bNull = 0; int rc = SQLITE_OK; - int nExpect = 0; SessionStat1Ctx stat1 = {{0,0,0,0,0},0}; if( pSession->rc ) return; /* Load table details if required */ - if( sessionInitTable(pSession, pTab, pSession->db, pSession->zDb) ) return; + if( sessionInitTable(pSession, pTab) ) return; /* Check the number of columns in this xPreUpdate call matches the ** number of columns in the table. */ - nExpect = pSession->hook.xCount(pSession->hook.pCtx); - if( (pTab->nCol-pTab->bRowid)nCol-pTab->bRowid)!=nExpect ){ + if( (pTab->nCol-pTab->bRowid)!=pSession->hook.xCount(pSession->hook.pCtx) ){ pSession->rc = SQLITE_SCHEMA; return; } @@ -222818,7 +220808,7 @@ static void sessionPreupdateOneChange( } /* Allocate the change object */ - pC = (SessionChange*)sessionMalloc64(pSession, nByte); + pC = (SessionChange *)sessionMalloc64(pSession, nByte); if( !pC ){ rc = SQLITE_NOMEM; goto error_out; @@ -222851,7 +220841,6 @@ static void sessionPreupdateOneChange( if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){ pC->bIndirect = 1; } - pC->nRecordField = pTab->nCol; pC->nRecord = nByte; pC->op = op; pC->pNext = pTab->apChange[iHash]; @@ -223231,7 +221220,7 @@ SQLITE_API int sqlite3session_diff( /* Locate and if necessary initialize the target table object */ rc = sessionFindTable(pSession, zTbl, &pTo); if( pTo==0 ) goto diff_out; - if( sessionInitTable(pSession, pTo, pSession->db, pSession->zDb) ){ + if( sessionInitTable(pSession, pTo) ){ rc = pSession->rc; goto diff_out; } @@ -223244,7 +221233,7 @@ SQLITE_API int sqlite3session_diff( int bRowid = 0; u8 *abPK; const char **azCol = 0; - rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, 0, &abPK, + rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK, pSession->bImplicitPK ? &bRowid : 0 ); if( rc==SQLITE_OK ){ @@ -223359,7 +221348,6 @@ static void sessionDeleteTable(sqlite3_session *pSession, SessionTable *pList){ sessionFree(pSession, p); } } - sqlite3_finalize(pTab->pDfltStmt); sessionFree(pSession, (char*)pTab->azCol); /* cast works around VC++ bug */ sessionFree(pSession, pTab->apChange); sessionFree(pSession, pTab); @@ -223394,7 +221382,7 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){ /* Assert that all allocations have been freed and then free the ** session object itself. */ - // assert( pSession->nMalloc==0 ); + assert( pSession->nMalloc==0 ); sqlite3_free(pSession); } @@ -223465,6 +221453,48 @@ SQLITE_API int sqlite3session_attach( return rc; } +/* +** Ensure that there is room in the buffer to append nByte bytes of data. +** If not, use sqlite3_realloc() to grow the buffer so that there is. +** +** If successful, return zero. Otherwise, if an OOM condition is encountered, +** set *pRc to SQLITE_NOMEM and return non-zero. +*/ +static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){ +#define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1) + i64 nReq = p->nBuf + nByte; + if( *pRc==SQLITE_OK && nReq>p->nAlloc ){ + u8 *aNew; + i64 nNew = p->nAlloc ? p->nAlloc : 128; + + do { + nNew = nNew*2; + }while( nNewSESSION_MAX_BUFFER_SZ ){ + nNew = SESSION_MAX_BUFFER_SZ; + if( nNewaBuf, nNew); + if( 0==aNew ){ + *pRc = SQLITE_NOMEM; + }else{ + p->aBuf = aNew; + p->nAlloc = nNew; + } + } + return (*pRc!=SQLITE_OK); +} + /* ** Append the value passed as the second argument to the buffer passed ** as the first. @@ -223533,6 +221563,27 @@ static void sessionAppendBlob( } } +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. Otherwise, append a string to the buffer. All bytes in the string +** up to (but not including) the nul-terminator are written to the buffer. +** +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before +** returning. +*/ +static void sessionAppendStr( + SessionBuffer *p, + const char *zStr, + int *pRc +){ + int nStr = sqlite3Strlen30(zStr); + if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ + memcpy(&p->aBuf[p->nBuf], zStr, nStr); + p->nBuf += nStr; + p->aBuf[p->nBuf] = 0x00; + } +} + /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is ** called. Otherwise, append the string representation of integer iVal @@ -223551,6 +221602,27 @@ 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 @@ -224041,16 +222113,26 @@ static int sessionGenerateChangeset( for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ const char *zName = pTab->zName; + int nCol = 0; /* Number of columns in table */ + u8 *abPK = 0; /* Primary key array */ + const char **azCol = 0; /* Table columns */ int i; /* Used to iterate through hash buckets */ sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ int nRewind = buf.nBuf; /* Initial size of write buffer */ int nNoop; /* Size of buffer after writing tbl header */ - int nOldCol = pTab->nCol; + int bRowid = 0; /* Check the table schema is still Ok. */ - rc = sessionReinitTable(pSession, pTab); - if( rc==SQLITE_OK && pTab->nCol!=nOldCol ){ - rc = sessionUpdateChanges(pSession, pTab); + rc = sessionTableInfo( + 0, db, pSession->zDb, 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 = SQLITE_SCHEMA; } /* Write a table header */ @@ -224058,8 +222140,8 @@ static int sessionGenerateChangeset( /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ - rc = sessionSelectStmt(db, 0, pSession->zDb, - zName, pTab->bRowid, pTab->nCol, pTab->azCol, pTab->abPK, &pSel + rc = sessionSelectStmt( + db, 0, pSession->zDb, zName, bRowid, nCol, azCol, abPK, &pSel ); } @@ -224068,22 +222150,22 @@ static int sessionGenerateChangeset( SessionChange *p; /* Used to iterate through changes */ for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ - rc = sessionSelectBind(pSel, pTab->nCol, pTab->abPK, p); + rc = sessionSelectBind(pSel, nCol, abPK, p); if( rc!=SQLITE_OK ) continue; if( sqlite3_step(pSel)==SQLITE_ROW ){ if( p->op==SQLITE_INSERT ){ int iCol; sessionAppendByte(&buf, SQLITE_INSERT, &rc); sessionAppendByte(&buf, p->bIndirect, &rc); - for(iCol=0; iColnCol; iCol++){ + for(iCol=0; iColabPK!=0 ); - rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, pTab->abPK); + assert( abPK!=0 ); /* Because sessionSelectStmt() returned ok */ + rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK); } }else if( p->op!=SQLITE_INSERT ){ - rc = sessionAppendDelete(&buf, bPatchset, p, pTab->nCol,pTab->abPK); + rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK); } if( rc==SQLITE_OK ){ rc = sqlite3_reset(pSel); @@ -224108,6 +222190,7 @@ static int sessionGenerateChangeset( if( buf.nBuf==nNoop ){ buf.nBuf = nRewind; } + sqlite3_free((char*)azCol); /* cast works around VC++ bug */ } } @@ -224531,19 +222614,15 @@ static int sessionReadRecord( } } if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - if( (pIn->nData-pIn->iNext)<8 ){ - rc = SQLITE_CORRUPT_BKPT; + sqlite3_int64 v = sessionGetI64(aVal); + if( eType==SQLITE_INTEGER ){ + sqlite3VdbeMemSetInt64(apOut[i], v); }else{ - sqlite3_int64 v = sessionGetI64(aVal); - if( eType==SQLITE_INTEGER ){ - sqlite3VdbeMemSetInt64(apOut[i], v); - }else{ - double d; - memcpy(&d, &v, 8); - sqlite3VdbeMemSetDouble(apOut[i], d); - } - pIn->iNext += 8; + double d; + memcpy(&d, &v, 8); + sqlite3VdbeMemSetDouble(apOut[i], d); } + pIn->iNext += 8; } } } @@ -226236,7 +224315,7 @@ static int sessionChangesetApply( sqlite3changeset_pk(pIter, &abPK, 0); rc = sessionTableInfo(0, db, "main", zNew, - &sApply.nCol, &zTab, &sApply.azCol, 0, &sApply.abPK, &sApply.bRowid + &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK, &sApply.bRowid ); if( rc!=SQLITE_OK ) break; for(i=0; iflags & SQLITE_FkNoAction; - - if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ - db->flags |= ((u64)SQLITE_FkNoAction); - db->aDb[0].pSchema->schema_cookie -= 32; - } - if( rc==SQLITE_OK ){ rc = sessionChangesetApply( db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags ); } - - if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){ - assert( db->flags & SQLITE_FkNoAction ); - db->flags &= ~((u64)SQLITE_FkNoAction); - db->aDb[0].pSchema->schema_cookie -= 32; - } return rc; } @@ -226473,9 +224539,6 @@ struct sqlite3_changegroup { int rc; /* Error code */ int bPatch; /* True to accumulate patchsets */ SessionTable *pList; /* List of tables in current patch */ - - sqlite3 *db; /* Configured by changegroup_schema() */ - char *zDb; /* Configured by changegroup_schema() */ }; /* @@ -226496,7 +224559,6 @@ static int sessionChangeMerge( ){ SessionChange *pNew = 0; int rc = SQLITE_OK; - assert( aRec!=0 ); if( !pExist ){ pNew = (SessionChange *)sqlite3_malloc64(sizeof(SessionChange) + nRec); @@ -226662,114 +224724,6 @@ static int sessionChangeMerge( return rc; } -/* -** Check if a changeset entry with nCol columns and the PK array passed -** as the final argument to this function is compatible with SessionTable -** pTab. If so, return 1. Otherwise, if they are incompatible in some way, -** return 0. -*/ -static int sessionChangesetCheckCompat( - SessionTable *pTab, - int nCol, - u8 *abPK -){ - if( pTab->azCol && nColnCol ){ - int ii; - for(ii=0; iinCol; ii++){ - u8 bPK = (ii < nCol) ? abPK[ii] : 0; - if( pTab->abPK[ii]!=bPK ) return 0; - } - return 1; - } - return (pTab->nCol==nCol && 0==memcmp(abPK, pTab->abPK, nCol)); -} - -static int sessionChangesetExtendRecord( - sqlite3_changegroup *pGrp, - SessionTable *pTab, - int nCol, - int op, - const u8 *aRec, - int nRec, - SessionBuffer *pOut -){ - int rc = SQLITE_OK; - int ii = 0; - - assert( pTab->azCol ); - assert( nColnCol ); - - pOut->nBuf = 0; - if( op==SQLITE_INSERT || (op==SQLITE_DELETE && pGrp->bPatch==0) ){ - /* Append the missing default column values to the record. */ - sessionAppendBlob(pOut, aRec, nRec, &rc); - if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){ - rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt); - } - for(ii=nCol; rc==SQLITE_OK && iinCol; ii++){ - int eType = sqlite3_column_type(pTab->pDfltStmt, ii); - sessionAppendByte(pOut, eType, &rc); - switch( eType ){ - case SQLITE_FLOAT: - case SQLITE_INTEGER: { - i64 iVal; - if( eType==SQLITE_INTEGER ){ - iVal = sqlite3_column_int64(pTab->pDfltStmt, ii); - }else{ - double rVal = sqlite3_column_int64(pTab->pDfltStmt, ii); - memcpy(&iVal, &rVal, sizeof(i64)); - } - if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){ - sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); - } - break; - } - - case SQLITE_BLOB: - case SQLITE_TEXT: { - int n = sqlite3_column_bytes(pTab->pDfltStmt, ii); - sessionAppendVarint(pOut, n, &rc); - if( eType==SQLITE_TEXT ){ - const u8 *z = (const u8*)sqlite3_column_text(pTab->pDfltStmt, ii); - sessionAppendBlob(pOut, z, n, &rc); - }else{ - const u8 *z = (const u8*)sqlite3_column_blob(pTab->pDfltStmt, ii); - sessionAppendBlob(pOut, z, n, &rc); - } - break; - } - - default: - assert( eType==SQLITE_NULL ); - break; - } - } - }else if( op==SQLITE_UPDATE ){ - /* Append missing "undefined" entries to the old.* record. And, if this - ** is an UPDATE, to the new.* record as well. */ - int iOff = 0; - if( pGrp->bPatch==0 ){ - for(ii=0; iinCol-nCol); ii++){ - sessionAppendByte(pOut, 0x00, &rc); - } - } - - sessionAppendBlob(pOut, &aRec[iOff], nRec-iOff, &rc); - for(ii=0; ii<(pTab->nCol-nCol); ii++){ - sessionAppendByte(pOut, 0x00, &rc); - } - }else{ - assert( op==SQLITE_DELETE && pGrp->bPatch ); - sessionAppendBlob(pOut, aRec, nRec, &rc); - } - - return rc; -} - /* ** Add all changes in the changeset traversed by the iterator passed as ** the first argument to the changegroup hash tables. @@ -226783,7 +224737,6 @@ static int sessionChangesetToHash( int nRec; int rc = SQLITE_OK; SessionTable *pTab = 0; - SessionBuffer rec = {0, 0, 0}; while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){ const char *zNew; @@ -226795,9 +224748,6 @@ static int sessionChangesetToHash( SessionChange *pExist = 0; SessionChange **pp; - /* Ensure that only changesets, or only patchsets, but not a mixture - ** of both, are being combined. It is an error to try to combine a - ** changeset and a patchset. */ if( pGrp->pList==0 ){ pGrp->bPatch = pIter->bPatchset; }else if( pIter->bPatchset!=pGrp->bPatch ){ @@ -226830,38 +224780,18 @@ static int sessionChangesetToHash( pTab->zName = (char*)&pTab->abPK[nCol]; memcpy(pTab->zName, zNew, nNew+1); - if( pGrp->db ){ - pTab->nCol = 0; - rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb); - if( rc ){ - assert( pTab->azCol==0 ); - sqlite3_free(pTab); - break; - } - } - /* The new object must be linked on to the end of the list, not ** simply added to the start of it. This is to ensure that the ** tables within the output of sqlite3changegroup_output() are in ** the right order. */ for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext); *ppTab = pTab; - } - - if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ + }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){ rc = SQLITE_SCHEMA; break; } } - if( nColnCol ){ - assert( pGrp->db ); - rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, &rec); - if( rc ) break; - aRec = rec.aBuf; - nRec = rec.nBuf; - } - if( sessionGrowHash(0, pIter->bPatchset, pTab) ){ rc = SQLITE_NOMEM; break; @@ -226899,7 +224829,6 @@ static int sessionChangesetToHash( } } - sqlite3_free(rec.aBuf); if( rc==SQLITE_OK ) rc = pIter->rc; return rc; } @@ -226986,31 +224915,6 @@ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp){ return rc; } -/* -** Provide a database schema to the changegroup object. -*/ -SQLITE_API int sqlite3changegroup_schema( - sqlite3_changegroup *pGrp, - sqlite3 *db, - const char *zDb -){ - int rc = SQLITE_OK; - - if( pGrp->pList || pGrp->db ){ - /* Cannot add a schema after one or more calls to sqlite3changegroup_add(), - ** or after sqlite3changegroup_schema() has already been called. */ - rc = SQLITE_MISUSE; - }else{ - pGrp->zDb = sqlite3_mprintf("%s", zDb); - if( pGrp->zDb==0 ){ - rc = SQLITE_NOMEM; - }else{ - pGrp->db = db; - } - } - return rc; -} - /* ** Add the changeset currently stored in buffer pData, size nData bytes, ** to changeset-group p. @@ -227074,7 +224978,6 @@ SQLITE_API int sqlite3changegroup_output_strm( */ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ if( pGrp ){ - sqlite3_free(pGrp->zDb); sessionDeleteTable(0, pGrp->pList); sqlite3_free(pGrp); } @@ -227782,7 +225685,7 @@ struct Fts5PhraseIter { ** See xPhraseFirstColumn above. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ void *(*xUserData)(Fts5Context*); @@ -228011,8 +225914,8 @@ struct Fts5ExtensionApi { ** as separate queries of the FTS index are required for each synonym. ** ** When using methods (2) or (3), it is important that the tokenizer only -** provide synonyms when tokenizing document text (method (3)) or query -** text (method (2)), not both. Doing so will not cause any errors, but is +** provide synonyms when tokenizing document text (method (2)) or query +** text (method (3)), not both. Doing so will not cause any errors, but is ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; @@ -228060,7 +225963,7 @@ struct fts5_api { int (*xCreateTokenizer)( fts5_api *pApi, const char *zName, - void *pUserData, + void *pContext, fts5_tokenizer *pTokenizer, void (*xDestroy)(void*) ); @@ -228069,7 +225972,7 @@ struct fts5_api { int (*xFindTokenizer)( fts5_api *pApi, const char *zName, - void **ppUserData, + void **ppContext, fts5_tokenizer *pTokenizer ); @@ -228077,7 +225980,7 @@ struct fts5_api { int (*xCreateFunction)( fts5_api *pApi, const char *zName, - void *pUserData, + void *pContext, fts5_extension_function xFunction, void (*xDestroy)(void*) ); @@ -228249,10 +226152,6 @@ typedef struct Fts5Config Fts5Config; ** attempt to merge together. A value of 1 sets the object to use the ** compile time default. Zero disables auto-merge altogether. ** -** bContentlessDelete: -** True if the contentless_delete option was present in the CREATE -** VIRTUAL TABLE statement. -** ** zContent: ** ** zContentRowid: @@ -228287,7 +226186,6 @@ struct Fts5Config { int nPrefix; /* Number of prefix indexes */ int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */ int eContent; /* An FTS5_CONTENT value */ - int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */ char *zContent; /* content table */ char *zContentRowid; /* "content_rowid=" option value */ int bColumnsize; /* "columnsize=" option value (dflt==1) */ @@ -228309,7 +226207,6 @@ struct Fts5Config { char *zRank; /* Name of rank function */ char *zRankArgs; /* Arguments to rank function */ int bSecureDelete; /* 'secure-delete' */ - int nDeleteMerge; /* 'deletemerge' */ /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */ char **pzErrmsg; @@ -228632,9 +226529,6 @@ static int sqlite3Fts5IndexReset(Fts5Index *p); static int sqlite3Fts5IndexLoadConfig(Fts5Index *p); -static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin); -static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid); - /* ** End of interface to code in fts5_index.c. **************************************************************************/ @@ -228719,11 +226613,6 @@ static int sqlite3Fts5HashWrite( */ static void sqlite3Fts5HashClear(Fts5Hash*); -/* -** Return true if the hash is empty, false otherwise. -*/ -static int sqlite3Fts5HashIsEmpty(Fts5Hash*); - static int sqlite3Fts5HashQuery( Fts5Hash*, /* Hash table to query */ int nPre, @@ -228745,7 +226634,6 @@ static void sqlite3Fts5HashScanEntry(Fts5Hash *, ); - /* ** End of interface to code in fts5_hash.c. **************************************************************************/ @@ -228989,8 +226877,7 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); #define FTS5_STAR 15 /* This file is automatically generated by Lemon from input grammar -** source file "fts5parse.y". -*/ +** source file "fts5parse.y". */ /* ** 2000-05-29 ** @@ -230580,19 +228467,15 @@ static int fts5CInstIterInit( */ typedef struct HighlightContext HighlightContext; struct HighlightContext { - /* Constant parameters to fts5HighlightCb() */ + CInstIter iter; /* Coalesced Instance Iterator */ + int iPos; /* Current token offset in zIn[] */ int iRangeStart; /* First token to include */ int iRangeEnd; /* If non-zero, last token to include */ const char *zOpen; /* Opening highlight */ const char *zClose; /* Closing highlight */ const char *zIn; /* Input text */ int nIn; /* Size of input text in bytes */ - - /* Variables modified by fts5HighlightCb() */ - CInstIter iter; /* Coalesced Instance Iterator */ - int iPos; /* Current token offset in zIn[] */ - int iOff; /* Have copied up to this offset in zIn[] */ - int bOpen; /* True if highlight is open */ + int iOff; /* Current offset within zIn[] */ char *zOut; /* Output value */ }; @@ -230625,8 +228508,8 @@ static int fts5HighlightCb( int tflags, /* Mask of FTS5_TOKEN_* flags */ const char *pToken, /* Buffer containing token */ int nToken, /* Size of token in bytes */ - int iStartOff, /* Start byte offset of token */ - int iEndOff /* End byte offset of token */ + int iStartOff, /* Start offset of token */ + int iEndOff /* End offset of token */ ){ HighlightContext *p = (HighlightContext*)pContext; int rc = SQLITE_OK; @@ -230642,47 +228525,30 @@ static int fts5HighlightCb( if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff; } - /* If the parenthesis is open, and this token is not part of the current - ** phrase, and the starting byte offset of this token is past the point - ** that has currently been copied into the output buffer, close the - ** parenthesis. */ - if( p->bOpen - && (iPos<=p->iter.iStart || p->iter.iStart<0) - && iStartOff>p->iOff - ){ - fts5HighlightAppend(&rc, p, p->zClose, -1); - p->bOpen = 0; - } - - /* If this is the start of a new phrase, and the highlight is not open: - ** - ** * copy text from the input up to the start of the phrase, and - ** * open the highlight. - */ - if( iPos==p->iter.iStart && p->bOpen==0 ){ + if( iPos==p->iter.iStart ){ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iStartOff - p->iOff); fts5HighlightAppend(&rc, p, p->zOpen, -1); p->iOff = iStartOff; - p->bOpen = 1; } if( iPos==p->iter.iEnd ){ - if( p->bOpen==0 ){ - assert( p->iRangeEnd>=0 ); + if( p->iRangeEnd>=0 && p->iter.iStartiRangeStart ){ fts5HighlightAppend(&rc, p, p->zOpen, -1); - p->bOpen = 1; } fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); + fts5HighlightAppend(&rc, p, p->zClose, -1); p->iOff = iEndOff; - if( rc==SQLITE_OK ){ rc = fts5CInstIterNext(&p->iter); } } - if( 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 ){ + fts5HighlightAppend(&rc, p, p->zClose, -1); + } } return rc; @@ -230723,9 +228589,6 @@ static void fts5HighlightFunction( if( rc==SQLITE_OK ){ rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); } - if( ctx.bOpen ){ - fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); - } fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff); if( rc==SQLITE_OK ){ @@ -231004,9 +228867,6 @@ static void fts5SnippetFunction( if( rc==SQLITE_OK ){ rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); } - if( ctx.bOpen ){ - fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); - } if( ctx.iRangeEnd>=(nColSize-1) ){ fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff); }else{ @@ -231645,8 +229505,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) @@ -231977,16 +229835,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"); @@ -232231,28 +230079,6 @@ static int sqlite3Fts5ConfigParse( sqlite3_free(zTwo); } - /* We only allow contentless_delete=1 if the table is indeed contentless. */ - if( rc==SQLITE_OK - && pRet->bContentlessDelete - && 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. */ @@ -232547,18 +230373,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; @@ -232607,7 +230421,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 ){ @@ -235131,7 +232944,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; @@ -235237,8 +233050,6 @@ static char *fts5ExprPrintTcl( if( zRet==0 ) return 0; } - }else if( pExpr->eType==0 ){ - zRet = sqlite3_mprintf("{}"); }else{ char const *zOp = 0; int i; @@ -235500,14 +233311,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**); @@ -236224,8 +234035,10 @@ static Fts5HashEntry *fts5HashEntryMerge( } /* -** Link all tokens from hash table iHash into a list in sorted order. The -** tokens are not removed from the hash table. +** Extract all tokens from hash table iHash and link them into a list +** in sorted order. The hash table is cleared before returning. It is +** the responsibility of the caller to free the elements of the returned +** list. */ static int fts5HashEntrySort( Fts5Hash *pHash, @@ -236265,6 +234078,7 @@ static int fts5HashEntrySort( pList = fts5HashEntryMerge(pList, ap[i]); } + pHash->nEntry = 0; sqlite3_free(ap); *ppSorted = pList; return SQLITE_OK; @@ -236318,28 +234132,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; @@ -236428,24 +234220,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: ** @@ -236453,7 +234227,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. ** @@ -236462,12 +234236,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, @@ -236482,12 +234256,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. @@ -236603,38 +234371,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 */ /* @@ -236668,7 +234404,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; } @@ -236704,12 +234439,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 */ @@ -236724,8 +234453,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 */ @@ -236760,23 +234487,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 */ @@ -236786,7 +234501,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 */ @@ -236875,13 +234589,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 */ @@ -236890,8 +234597,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*); @@ -237021,60 +234726,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. ** @@ -237302,17 +234953,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( @@ -237423,19 +235067,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); @@ -237486,14 +235122,6 @@ static int fts5StructureDecode( 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; @@ -237504,9 +235132,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); @@ -237719,7 +235344,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)); @@ -237728,12 +235352,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); @@ -237747,17 +235368,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); } } @@ -238280,23 +235893,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 @@ -238338,7 +235934,6 @@ static void fts5SegIterInit( pIter->iPgidxOff = pIter->pLeaf->szLeaf+1; fts5SegIterLoadTerm(p, pIter, 0); fts5SegIterLoadNPos(p, pIter); - fts5SegIterAllocTombstone(p, pIter); } } @@ -239040,7 +236635,6 @@ static void fts5SegIterSeekInit( } fts5SegIterSetNext(p, pIter); - fts5SegIterAllocTombstone(p, pIter); /* Either: ** @@ -239091,14 +236685,6 @@ static void fts5SegIterHashInit( pLeaf->p = (u8*)pList; } } - - /* The call to sqlite3Fts5HashScanInit() causes the hash table to - ** fill the size field of all existing position lists. This means they - ** can no longer be appended to. Since the only scenario in which they - ** can be appended to is if the previous operation on this table was - ** a DELETE, by clearing the Fts5Index.bDelete flag we can avoid this - ** possibility altogether. */ - p->bDelete = 0; }else{ p->rc = sqlite3Fts5HashQuery(p->pHash, sizeof(Fts5Data), (const char*)pTerm, nTerm, (void**)&pLeaf, &nList @@ -239129,20 +236715,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)); @@ -239284,6 +236855,7 @@ static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){ assert_nc( i2!=0 ); pRes->bTermEq = 1; if( p1->iRowid==p2->iRowid ){ + p1->bDel = p2->bDel; return i2; } res = ((p1->iRowid > p2->iRowid)==pIter->bRev) ? -1 : +1; @@ -239487,84 +237059,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. ** @@ -239602,9 +237096,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; } @@ -239636,9 +237128,7 @@ static void fts5MultiIterNext2( } fts5AssertMultiIterSetup(p, pIter); - }while( (fts5MultiIterIsEmpty(p, pIter) || fts5MultiIterIsDeleted(pIter)) - && (p->rc==SQLITE_OK) - ); + }while( fts5MultiIterIsEmpty(p, pIter) ); } } @@ -239651,7 +237141,7 @@ static Fts5Iter *fts5MultiIterAlloc( int nSeg ){ Fts5Iter *pNew; - i64 nSlot; /* Power of two >= nSeg */ + int nSlot; /* Power of two >= nSeg */ for(nSlot=2; nSlotbSkipEmpty && 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]; @@ -240373,9 +237861,7 @@ static void fts5IndexDiscardData(Fts5Index *p){ if( p->pHash ){ sqlite3Fts5HashClear(p->pHash); p->nPendingData = 0; - p->nPendingRow = 0; } - p->nContentlessDelete = 0; } /* @@ -240776,7 +238262,7 @@ static void fts5WriteAppendPoslistData( const u8 *a = aData; int n = nData; - assert( p->pConfig->pgsz>0 || p->rc!=SQLITE_OK ); + assert( p->pConfig->pgsz>0 ); while( p->rc==SQLITE_OK && (pPage->buf.n + pPage->pgidx.n + n)>=p->pConfig->pgsz ){ @@ -241012,12 +238498,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); @@ -241077,11 +238557,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 */ @@ -241107,43 +238584,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_nc( 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. ** @@ -241163,15 +238603,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; } @@ -241180,18 +238619,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; @@ -241376,13 +238819,9 @@ static void fts5SecureDeleteOverflow( 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; + i1 += fts5GetVarint32(&aPg[i1], iFirst); i2 = sqlite3Fts5PutVarint(aIdx, iFirst-nShift); if( i1nn ){ memcpy(&aIdx[i2], &aPg[i1], pLeaf->nn-i1); @@ -241427,6 +238866,7 @@ static void fts5DoSecureDelete( int iPgIdx = pSeg->pLeaf->szLeaf; u64 iDelta = 0; + u64 iNextDelta = 0; int iNextOff = 0; int iOff = 0; int nIdx = 0; @@ -241434,6 +238874,8 @@ static void fts5DoSecureDelete( 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; @@ -241458,21 +238900,10 @@ static void fts5DoSecureDelete( ** This block sets the following variables: ** ** iStart: - ** The offset of the first byte of the rowid or delta-rowid - ** value for the doclist entry being removed. - ** ** iDelta: - ** The value of the rowid or delta-rowid value for the doclist - ** entry being removed. - ** - ** iNextOff: - ** The offset of the next entry following the position list - ** for the one being removed. If the position list for this - ** entry overflows onto the next leaf page, this value will be - ** greater than pLeaf->szLeaf. */ { - int iSOP; /* Start-Of-Position-list */ + int iSOP; if( pSeg->iLeafPgno==pSeg->iTermLeafPgno ){ iStart = pSeg->iTermLeafOffset; }else{ @@ -241508,81 +238939,47 @@ static void fts5DoSecureDelete( } iOff = iStart; - - /* If the position-list for the entry being removed flows over past - ** the end of this page, delete the portion of the position-list on the - ** next page and beyond. - ** - ** Set variable bLastInDoclist to true if this entry happens - ** to be the last rowid in the doclist for its term. */ if( iNextOff>=iPgIdx ){ int pgno = pSeg->iLeafPgno+1; fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); iNextOff = iPgIdx; - } - - if( pSeg->bDel==0 ){ - if( iNextOff!=iPgIdx ){ - /* Loop through the page-footer. If iNextOff (offset of the - ** entry following the one we are removing) is equal to the - ** offset of a key on this page, then the entry is the last - ** in its doclist. */ - int iKeyOff = 0; - for(iIdx=0; iIdxbDel ){ - iOff += sqlite3Fts5PutVarint(&aPg[iOff], iDelta); - aPg[iOff++] = 0x01; - }else if( bLastInDoclist==0 ){ + if( bLastInDoclist==0 ){ if( iNextOff!=iPgIdx ){ - u64 iNextDelta = 0; iNextOff += fts5GetVarint(&aPg[iNextOff], &iNextDelta); iOff += sqlite3Fts5PutVarint(&aPg[iOff], iDelta + iNextDelta); } }else if( - pSeg->iLeafPgno==pSeg->iTermLeafPgno - && iStart==pSeg->iTermLeafOffset + iStart==pSeg->iTermLeafOffset && 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; - int iKeyOff = 0; - - /* Set iKeyOff to the offset of the term that will be removed - the - ** last offset in the footer that is not greater than iStart. */ - for(iIdx=0; iIdx(u32)iStart ) break; iKeyOff += iVal; } - assert_nc( iKey>=1 ); - /* Set iDelKeyOff to the value of the footer entry to remove from - ** the page. */ iDelKeyOff = iOff = iKeyOff; - if( iNextOff!=iPgIdx ){ - /* This is the only position-list associated with the term, and there - ** is another term following it on this page. So the subsequent term - ** needs to be moved to replace the term associated with the entry - ** being removed. */ int nPrefix = 0; int nSuffix = 0; int nPrefix2 = 0; @@ -241607,9 +239004,7 @@ static void fts5DoSecureDelete( iOff += sqlite3Fts5PutVarint(&aPg[iOff], nPrefix); } iOff += sqlite3Fts5PutVarint(&aPg[iOff], nSuffix); - if( nPrefix2>pSeg->term.n ){ - p->rc = FTS5_CORRUPT; - }else if( nPrefix2>nPrefix ){ + if( nPrefix2>nPrefix ){ memcpy(&aPg[iOff], &pSeg->term.p[nPrefix], nPrefix2-nPrefix); iOff += (nPrefix2-nPrefix); } @@ -241619,88 +239014,80 @@ static void fts5DoSecureDelete( } } }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; + 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); + 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); + fts5DataWrite(p, iId, pTerm->p, iTermOff+nTermIdx); + if( nTermIdx==0 ){ + fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iTermLeafPgno); + } } + fts5DataRelease(pTerm); } - fts5DataRelease(pTerm); } - } - /* Assuming no error has occurred, this block does final edits to the - ** leaf page before writing it back to disk. Input variables are: - ** - ** nPg: Total initial size of leaf page. - ** iPgIdx: Initial offset of page footer. - ** - ** iOff: Offset to move data to - ** iNextOff: Offset to move data from - */ - if( p->rc==SQLITE_OK ){ - const int nMove = nPg - iNextOff; /* Number of bytes to move */ - int nShift = iNextOff - iOff; /* Distance to move them */ + if( p->rc==SQLITE_OK ){ + const int nMove = nPg - iNextOff; + int nShift = 0; - int iPrevKeyOut = 0; - int iKeyIn = 0; + memmove(&aPg[iOff], &aPg[iNextOff], nMove); + iPgIdx -= (iNextOff - iOff); + nPg = iPgIdx; + fts5PutU16(&aPg[2], iPgIdx); - memmove(&aPg[iOff], &aPg[iNextOff], nMove); - iPgIdx -= nShift; - 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; + } + } - for(iIdx=0; iIdxiOff ? nShift : 0)); - nPg += sqlite3Fts5PutVarint(&aPg[nPg], iKeyOut - iPrevKeyOut); - iPrevKeyOut = iKeyOut; + if( iPgIdx==nPg && nIdx>0 && pSeg->iLeafPgno!=1 ){ + fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iLeafPgno); } - } - 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); } - - assert_nc( nPg>4 || fts5GetU16(aPg)==0 ); - fts5DataWrite(p, FTS5_SEGMENT_ROWID(iSegid,pSeg->iLeafPgno), aPg, nPg); - } - sqlite3_free(aIdx); + sqlite3_free(aIdx); } /* @@ -241754,198 +239141,184 @@ 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( 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 */ - 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 || 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++; + if( iOffrc!=SQLITE_OK || pDoclist[iOff]==0x01 ){ + iOff++; + continue; + } } + } - if( p->rc==SQLITE_OK && bTermWritten==0 ){ - fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); - bTermWritten = 1; - assert( p->rc!=SQLITE_OK || writer.bFirstRowidInPage==0 ); - } + if( p->rc==SQLITE_OK && bTermWritten==0 ){ + fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); + bTermWritten = 1; + assert( p->rc!=SQLITE_OK || writer.bFirstRowidInPage==0 ); + } - 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{ - u64 iRowidDelta = (u64)iRowid - (u64)iPrev; - pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowidDelta); - } - if( p->rc!=SQLITE_OK ) break; - assert( pBuf->n<=pBuf->nSpace ); - iPrev = iRowid; + 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); + } + if( p->rc!=SQLITE_OK ) break; + assert( pBuf->n<=pBuf->nSpace ); + iPrev = iRowid; - 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 bDel = 0; - int nPos = 0; - int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDel); - if( bDel && bSecureDelete ){ - fts5BufferAppendVarint(&p->rc, pBuf, nPos*2); - iOff += nCopy; - nCopy = nPos; - }else{ - 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); } - 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); + + 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; + pStruct->nSegment++; + } + fts5StructurePromote(p, 0, pStruct); } } - fts5IndexAutomerge(p, &pStruct, pgnoLast + p->nContentlessDelete); + fts5IndexAutomerge(p, &pStruct, pgnoLast); fts5IndexCrisismerge(p, &pStruct); fts5StructureWrite(p, pStruct); fts5StructureRelease(pStruct); @@ -241956,15 +239329,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 ); + p->nPendingData = 0; fts5FlushOneHash(p); - if( p->rc==SQLITE_OK ){ - sqlite3Fts5HashClear(p->pHash); - p->nPendingData = 0; - p->nPendingRow = 0; - p->nContentlessDelete = 0; - } } } @@ -241980,22 +239348,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; } @@ -242011,7 +239374,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 ){ @@ -242042,9 +239404,7 @@ static int sqlite3Fts5IndexOptimize(Fts5Index *p){ assert( p->rc==SQLITE_OK ); fts5IndexFlush(p); - assert( p->rc!=SQLITE_OK || p->nContentlessDelete==0 ); pStruct = fts5StructureRead(p); - assert( p->rc!=SQLITE_OK || pStruct!=0 ); fts5StructureInvalidate(p); if( pStruct ){ @@ -242073,10 +239433,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); @@ -242084,7 +239441,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 ){ @@ -242598,9 +239955,6 @@ static int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){ p->iWriteRowid = iRowid; p->bDelete = bDelete; - if( bDelete==0 ){ - p->nPendingRow++; - } return fts5IndexReturn(p); } @@ -242638,9 +239992,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); @@ -243032,347 +240383,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); -} /************************************************************************* ************************************************************************** @@ -243924,14 +240934,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 */ @@ -243947,16 +240956,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 ){ @@ -243966,16 +240972,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, @@ -243990,22 +240994,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. ** @@ -244030,9 +241028,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. ** @@ -244055,9 +241053,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 @@ -244074,9 +241072,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 @@ -244109,9 +241107,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. @@ -244152,9 +241150,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(). */ @@ -244165,7 +241163,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 */ @@ -244188,7 +241185,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 ){ @@ -244207,28 +241204,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; iiszLeaf ){ - rc = FTS5_CORRUPT; - }else{ - fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff); - } + + fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff); iOff = iTermOff; if( iOffestimatedCost = (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; - Fts5Structure *p = pCsr->pStruct; - - assert( pCsr->pStruct ); - pCsr->iSeg++; - pCsr->iRowid++; - while( pCsr->iLevelnLevel && pCsr->iSeg>=p->aLevel[pCsr->iLevel].nSeg ){ - pCsr->iLevel++; - pCsr->iSeg = 0; - } - if( pCsr->iLevel>=p->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 @@ -244664,7 +241408,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 ); @@ -244681,37 +241425,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 */ - 0 /* xIntegrity */ - }; - rc = sqlite3_create_module(db, "fts5_structure", &fts5structure_module, 0); - } return rc; #else return SQLITE_OK; @@ -244847,8 +241560,6 @@ struct Fts5FullTable { Fts5Storage *pStorage; /* Document store */ Fts5Global *pGlobal; /* Global (connection wide) data */ Fts5Cursor *pSortCsr; /* Sort data from this cursor */ - int iSavepoint; /* Successful xSavepoint()+1 */ - int bInSavepoint; #ifdef SQLITE_DEBUG struct Fts5TransactionState ts; #endif @@ -245137,13 +241848,6 @@ static int fts5InitVtab( pConfig->pzErrmsg = 0; } - if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ - rc = sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, (int)1); - } - if( rc==SQLITE_OK ){ - rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); - } - if( rc!=SQLITE_OK ){ fts5FreeVtab(pTab); pTab = 0; @@ -246068,9 +242772,6 @@ static int fts5FilterMethod( pCsr->iFirstRowid = fts5GetRowidLimit(pRowidGe, SMALLEST_INT64); } - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); - if( rc!=SQLITE_OK ) goto filter_out; - if( pTab->pSortCsr ){ /* If pSortCsr is non-NULL, then this call is being made as part of ** processing for a "... MATCH ORDER BY rank" query (ePlan is @@ -246093,7 +242794,6 @@ static int fts5FilterMethod( pCsr->pExpr = pTab->pSortCsr->pExpr; rc = fts5CursorFirst(pTab, pCsr, bDesc); }else if( pCsr->pExpr ){ - assert( rc==SQLITE_OK ); rc = fts5CursorParseRank(pConfig, pCsr, pRank); if( rc==SQLITE_OK ){ if( bOrderByRank ){ @@ -246265,7 +242965,6 @@ static int fts5SpecialInsert( Fts5Config *pConfig = pTab->p.pConfig; int rc = SQLITE_OK; int bError = 0; - int bLoadConfig = 0; if( 0==sqlite3_stricmp("delete-all", zCmd) ){ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ @@ -246277,7 +242976,6 @@ static int fts5SpecialInsert( }else{ rc = sqlite3Fts5StorageDeleteAll(pTab->pStorage); } - bLoadConfig = 1; }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){ if( pConfig->eContent==FTS5_CONTENT_NONE ){ fts5SetVtabError(pTab, @@ -246287,7 +242985,6 @@ static int fts5SpecialInsert( }else{ rc = sqlite3Fts5StorageRebuild(pTab->pStorage); } - bLoadConfig = 1; }else if( 0==sqlite3_stricmp("optimize", zCmd) ){ rc = sqlite3Fts5StorageOptimize(pTab->pStorage); }else if( 0==sqlite3_stricmp("merge", zCmd) ){ @@ -246300,8 +242997,6 @@ static int fts5SpecialInsert( }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){ pConfig->bPrefixIndex = sqlite3_value_int(pVal); #endif - }else if( 0==sqlite3_stricmp("flush", zCmd) ){ - rc = sqlite3Fts5FlushToDisk(&pTab->p); }else{ rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); if( rc==SQLITE_OK ){ @@ -246315,12 +243010,6 @@ static int fts5SpecialInsert( } } } - - if( rc==SQLITE_OK && bLoadConfig ){ - pTab->p.pConfig->iCookie--; - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); - } - return rc; } @@ -246379,6 +243068,7 @@ static int fts5UpdateMethod( 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 ); @@ -246407,14 +243097,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]); } @@ -246431,7 +243114,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); } @@ -246439,12 +243122,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 - they are both supported if the CREATE - ** VIRTUAL TABLE statement contained "contentless_delete=1". */ - if( eType0==SQLITE_INTEGER - && pConfig->eContent==FTS5_CONTENT_NONE - && 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 @@ -246468,8 +243147,7 @@ static int fts5UpdateMethod( } else if( eType0!=SQLITE_INTEGER ){ - /* An INSERT statement. If the conflict-mode is REPLACE, first remove - ** the current entry (if any). */ + /* If this is a REPLACE, first remove the current entry (if any) */ if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); @@ -246532,7 +243210,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; } @@ -247299,12 +243978,6 @@ static int fts5ColumnMethod( sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); } pConfig->pzErrmsg = 0; - }else if( pConfig->bContentlessDelete && sqlite3_vtab_nochange(pCtx) ){ - char *zErr = sqlite3_mprintf("cannot UPDATE a subset of " - "columns on fts5 contentless-delete table: %s", pConfig->zName - ); - sqlite3_result_error(pCtx, zErr, -1); - sqlite3_free(zErr); } return rc; } @@ -247343,12 +244016,8 @@ static int fts5RenameMethod( sqlite3_vtab *pVtab, /* Virtual table handle */ const char *zName /* New name of table */ ){ - int rc; Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - pTab->bInSavepoint = 1; - rc = sqlite3Fts5StorageRename(pTab->pStorage, zName); - pTab->bInSavepoint = 0; - return rc; + return sqlite3Fts5StorageRename(pTab->pStorage, zName); } static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){ @@ -247362,29 +244031,9 @@ static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){ ** Flush the contents of the pending-terms table to disk. */ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ - Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - int rc = SQLITE_OK; - char *zSql = 0; - fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); - - if( pTab->bInSavepoint==0 ){ - zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", - pTab->p.pConfig->zDb, pTab->p.pConfig->zName, pTab->p.pConfig->zName - ); - if( zSql ){ - pTab->bInSavepoint = 1; - rc = sqlite3_exec(pTab->p.pConfig->db, zSql, 0, 0, 0); - pTab->bInSavepoint = 0; - sqlite3_free(zSql); - }else{ - rc = SQLITE_NOMEM; - } - if( rc==SQLITE_OK ){ - pTab->iSavepoint = iSavepoint+1; - } - } - - return rc; + UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ + fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_SAVEPOINT, iSavepoint); + return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); } /* @@ -247393,16 +244042,9 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ ** This is a no-op. */ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ - Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - int rc = SQLITE_OK; - fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint); - if( (iSavepoint+1)iSavepoint ){ - rc = sqlite3Fts5FlushToDisk(&pTab->p); - if( rc==SQLITE_OK ){ - pTab->iSavepoint = iSavepoint; - } - } - return rc; + UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ + fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_RELEASE, iSavepoint); + return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); } /* @@ -247412,14 +244054,11 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ */ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - int rc = SQLITE_OK; + UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); fts5TripCursors(pTab); pTab->p.pConfig->pgsz = 0; - if( (iSavepoint+1)<=pTab->iSavepoint ){ - rc = sqlite3Fts5StorageRollback(pTab->pStorage); - } - return rc; + return sqlite3Fts5StorageRollback(pTab->pStorage); } /* @@ -247621,7 +244260,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2023-05-23 11:47:56 cec49c7d93362f527f0b4744cd1ae95d44a79671d49d69baa77fda70be29f7e8", -1, SQLITE_TRANSIENT); } /* @@ -247639,46 +244278,9 @@ static int fts5ShadowName(const char *zName){ return 0; } -/* -** Run an integrity check on the FTS5 data structures. Return a string -** if anything is found amiss. Return a NULL pointer if everything is -** OK. -*/ -static int fts5Integrity( - sqlite3_vtab *pVtab, /* the FTS5 virtual table to check */ - const char *zSchema, /* Name of schema in which this table lives */ - const char *zTabname, /* Name of the table itself */ - int isQuick, /* True if this is a quick-check */ - char **pzErr /* Write error message here */ -){ - Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - Fts5Config *pConfig = pTab->p.pConfig; - char *zSql; - char *zErr = 0; - int rc; - assert( pzErr!=0 && *pzErr==0 ); - UNUSED_PARAM(isQuick); - zSql = sqlite3_mprintf( - "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", - zSchema, zTabname, pConfig->zName); - if( zSql==0 ) return SQLITE_NOMEM; - rc = sqlite3_exec(pConfig->db, zSql, 0, 0, &zErr); - sqlite3_free(zSql); - if( (rc&0xff)==SQLITE_CORRUPT ){ - *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s", - zSchema, zTabname); - }else if( rc!=SQLITE_OK ){ - *pzErr = sqlite3_mprintf("unable to validate the inverted index for" - " FTS5 table %s.%s: %s", - zSchema, zTabname, zErr); - } - sqlite3_free(zErr); - return SQLITE_OK; -} - static int fts5Init(sqlite3 *db){ static const sqlite3_module fts5Mod = { - /* iVersion */ 4, + /* iVersion */ 3, /* xCreate */ fts5CreateMethod, /* xConnect */ fts5ConnectMethod, /* xBestIndex */ fts5BestIndexMethod, @@ -247701,8 +244303,7 @@ static int fts5Init(sqlite3 *db){ /* xSavepoint */ fts5SavepointMethod, /* xRelease */ fts5ReleaseMethod, /* xRollbackTo */ fts5RollbackToMethod, - /* xShadowName */ fts5ShadowName, - /* xIntegrity */ fts5Integrity + /* xShadowName */ fts5ShadowName }; int rc; @@ -247872,10 +244473,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 */ @@ -247923,19 +244524,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; @@ -248125,11 +244713,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( @@ -248206,7 +244792,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; @@ -248222,6 +244808,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; @@ -248258,37 +244845,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: @@ -248309,17 +244865,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; @@ -248383,15 +244932,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 */ @@ -248979,9 +245520,7 @@ static int sqlite3Fts5StorageSync(Fts5Storage *p){ i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db); if( p->bTotalsValid ){ rc = fts5StorageSaveTotals(p); - if( rc==SQLITE_OK ){ - p->bTotalsValid = 0; - } + p->bTotalsValid = 0; } if( rc==SQLITE_OK ){ rc = sqlite3Fts5IndexSync(p->pIndex); @@ -252349,8 +248888,7 @@ static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){ /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0, - /* xIntegrity */ 0 + /* xShadowName */ 0 }; void *p = (void*)pGlobal; @@ -252679,7 +249217,6 @@ static sqlite3_module stmtModule = { 0, /* xRelease */ 0, /* xRollbackTo */ 0, /* xShadowName */ - 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -252712,6 +249249,223 @@ SQLITE_API int sqlite3_stmt_init( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ +/************** Begin file wasmedge_bindings.c *******************************/ +#if defined(LIBSQL_ENABLE_WASM_RUNTIME) && defined(LIBSQL_ENABLE_WASM_RUNTIME_WASMEDGE) + +/* #include "sqliteInt.h" */ +/* #include "wasm_bindings.h" */ +#include + +void libsql_run_wasm(libsql_wasm_udf_api *api, sqlite3_context *context, libsql_wasm_engine_t *engine, + libsql_wasm_module_t *module, const char *func_name, int argc, sqlite3_value **argv) { + + WasmEdge_VMContext *ctx = (WasmEdge_VMContext *)module; + + + WasmEdge_Result res = WasmEdge_VMInstantiate(ctx); + if (!WasmEdge_ResultOK(res)) { + sqlite3_result_error(context, "Instantiation failed", -1); + return; + } + + const WasmEdge_ModuleInstanceContext* instance_ctx = WasmEdge_VMGetActiveModule(ctx); + WasmEdge_String mem_name = WasmEdge_StringCreateByCString("memory"); + WasmEdge_MemoryInstanceContext* mem_ctx = WasmEdge_ModuleInstanceFindMemory(instance_ctx, mem_name); + WasmEdge_StringDelete(mem_name); + + WasmEdge_Value params[argc]; + WasmEdge_Value results[1]; + WasmEdge_Value malloc_param[1]; + + int mem_size = WasmEdge_MemoryInstanceGetPageSize(mem_ctx) * 65536; + int mem_offset = mem_size; + + for (unsigned i = 0; i < argc; ++i) { + u8 type = sqlite3_value_type(argv[i]); + switch (type) { + case SQLITE_INTEGER: + params[i] = WasmEdge_ValueGenI64(sqlite3_value_int(argv[i])); + break; + case SQLITE_FLOAT: + params[i] = WasmEdge_ValueGenI64(sqlite3_value_double(argv[i])); + break; + case SQLITE_TEXT: { + int text_len = sqlite3_value_bytes(argv[i]); + const char *text = sqlite3_value_text(argv[i]); + + malloc_param[0] = WasmEdge_ValueGenI32(text_len + 2); + WasmEdge_String wasmedge_func_name = WasmEdge_StringCreateByCString("libsql_malloc"); + res = WasmEdge_VMExecute(ctx, wasmedge_func_name, malloc_param, 1, results, 1); + WasmEdge_StringDelete(wasmedge_func_name); + if (!WasmEdge_ResultOK(res)) { + sqlite3_result_error(context, "Execution failed", -1); + return; + } + mem_offset = WasmEdge_ValueGetI32(results[0]); + + u8 *data = WasmEdge_MemoryInstanceGetPointer(mem_ctx, mem_offset, text_len + 2); + data[0] = type; + memcpy(data + 1, text, text_len); + data[1 + text_len] = '\0'; + params[i] = WasmEdge_ValueGenI32(mem_offset); + break; + } + case SQLITE_BLOB: { + int blob_len = sqlite3_value_bytes(argv[i]); + const void *blob = sqlite3_value_blob(argv[i]); + + malloc_param[0] = WasmEdge_ValueGenI32(blob_len + 5); + WasmEdge_String wasmedge_func_name = WasmEdge_StringCreateByCString("libsql_malloc"); + res = WasmEdge_VMExecute(ctx, wasmedge_func_name, malloc_param, 1, results, 1); + WasmEdge_StringDelete(wasmedge_func_name); + if (!WasmEdge_ResultOK(res)) { + sqlite3_result_error(context, "Execution failed", -1); + return; + } + mem_offset = WasmEdge_ValueGetI32(results[0]); + + u8 *data = WasmEdge_MemoryInstanceGetPointer(mem_ctx, mem_offset, blob_len + 5); + data[0] = type; + sqlite3Put4byte(data + 1, blob_len); + memcpy(data + 1 + 4, blob, blob_len); + params[i] = WasmEdge_ValueGenI32(mem_offset); + break; + } + case SQLITE_NULL: + + malloc_param[0] = WasmEdge_ValueGenI32(1); + WasmEdge_String wasmedge_func_name = WasmEdge_StringCreateByCString("libsql_malloc"); + res = WasmEdge_VMExecute(ctx, wasmedge_func_name, malloc_param, 1, results, 1); + WasmEdge_StringDelete(wasmedge_func_name); + if (!WasmEdge_ResultOK(res)) { + sqlite3_result_error(context, "Execution failed", -1); + return; + } + mem_offset = WasmEdge_ValueGetI32(results[0]); + + u8 *data = WasmEdge_MemoryInstanceGetPointer(mem_ctx, mem_offset, 1); + data[0] = type; + params[i] = WasmEdge_ValueGenI32(mem_offset); + break; + } + } + + WasmEdge_String wasmedge_func_name = WasmEdge_StringCreateByCString(func_name); + res = WasmEdge_VMExecute(ctx, wasmedge_func_name, params, argc, results, 1); + if (!WasmEdge_ResultOK(res)) { + sqlite3_result_error(context, "Execution failed", -1); + WasmEdge_StringDelete(wasmedge_func_name); + return; + } + WasmEdge_StringDelete(wasmedge_func_name); + + switch (results[0].Type) { + case WasmEdge_ValType_I64: + sqlite3_result_int(context, WasmEdge_ValueGetI64(results[0])); + break; + case WasmEdge_ValType_F64: + sqlite3_result_double(context, WasmEdge_ValueGetF64(results[0])); + break; + case WasmEdge_ValType_I32: { + int type_offset = WasmEdge_ValueGetI32(results[0]); + char *type_ptr = WasmEdge_MemoryInstanceGetPointer(mem_ctx, type_offset, 1); + if (!type_ptr) { + sqlite3_result_error(context, "Unexpected end of Wasm memory when trying to fetch results", -1); + return; + } + char type = *type_ptr; + switch (type) { + case SQLITE_TEXT: { + const char *wasm_result = type_ptr + 1; + size_t wasm_result_len = strlen(wasm_result); + char *result = sqlite3Malloc(wasm_result_len + 1); + if (!result) { + sqlite3_result_error_nomem(context); + return; + } + memcpy(result, wasm_result, wasm_result_len); + sqlite3_result_text(context, result, wasm_result_len, sqlite3_free); + break; + } + case SQLITE_BLOB: { + void *wasm_result = type_ptr + 1; + int wasm_result_len = sqlite3Get4byte(wasm_result); + wasm_result += 4; + if (wasm_result_len > 2*1024*1024) { + sqlite3_result_error_nomem(context); + return; + } + char *result = sqlite3Malloc(wasm_result_len); + if (!result) { + sqlite3_result_error_nomem(context); + return; + } + memcpy(result, wasm_result, wasm_result_len); + sqlite3_result_blob(context, result, wasm_result_len, sqlite3_free); + break; + } + case SQLITE_NULL: + sqlite3_result_null(context); + break; + default: + sqlite3_result_error(context, "Wasm function returned malformed result type", -1); + } + } + break; + default: + fprintf(stderr, "res %d\n", results[0].Type); + sqlite3_result_error(context, "Wasm function returned an unsupported result type", -1); + } +} + +void libsql_free_wasm_module(void *ctx) { + WasmEdge_VMDelete(*(WasmEdge_VMContext **)ctx); +} + +libsql_wasm_engine_t *libsql_wasm_engine_new() { + WasmEdge_PluginLoadWithDefaultPaths(); + return NULL; +} + +void libsql_wasm_engine_free(libsql_wasm_engine_t *eng) { +} + +libsql_wasm_module_t *libsql_compile_wasm_module(libsql_wasm_engine_t* engine, const char *pSrcBody, int nBody, + void *(*alloc_err_buf)(unsigned long long), char **err_msg_buf) { + + if (nBody < 4 || memcmp(pSrcBody, "\0asm", 4) != 0) { + *err_msg_buf = sqlite3_mprintf("Magic header was not detected. " + "WasmEdge backend supports compiled binary Wasm format only. " + "If you passed WAT source, please transform it with wat2wasm or any similar tool"); + return NULL; + } + + WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate(); + WasmEdge_ConfigureAddHostRegistration(ConfCxt, WasmEdge_HostRegistration_Wasi); + WasmEdge_ConfigureAddHostRegistration(ConfCxt, WasmEdge_HostRegistration_WasiNN); + + WasmEdge_VMContext *ctx = WasmEdge_VMCreate(ConfCxt, NULL); + WasmEdge_ConfigureDelete(ConfCxt); + + WasmEdge_Result res = WasmEdge_VMLoadWasmFromBuffer(ctx, (const uint8_t *)pSrcBody, nBody); + if (!WasmEdge_ResultOK(res)) { + *err_msg_buf = sqlite3_mprintf("Compilation failed: %s", WasmEdge_ResultGetMessage(res)); + return NULL; + } + res = WasmEdge_VMValidate(ctx); + if (!WasmEdge_ResultOK(res)) { + *err_msg_buf = sqlite3_mprintf("Validation failed: %s", WasmEdge_ResultGetMessage(res)); + return NULL; + } + return (libsql_wasm_module_t*)ctx; +} + +void libsql_wasm_free_msg_buf(char *err_msg_buf) { + sqlite3_free(err_msg_buf); +} + +#endif +/************** End of wasmedge_bindings.c ***********************************/ /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } /************************** End of sqlite3.c ******************************/ diff --git a/c_src/sqlite3.h b/c_src/sqlite3.h index ef0237b..2281aa4 100644 --- a/c_src/sqlite3.h +++ b/c_src/sqlite3.h @@ -89,6 +89,9 @@ extern "C" { #ifndef SQLITE_SYSAPI # define SQLITE_SYSAPI #endif +#ifndef LIBSQL_API +# define LIBSQL_API +#endif /* ** These no-op macros are used in front of interfaces to mark those @@ -146,9 +149,11 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.44.2" -#define SQLITE_VERSION_NUMBER 3044002 -#define SQLITE_SOURCE_ID "2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f" +#define SQLITE_VERSION "3.43.0" +#define SQLITE_VERSION_NUMBER 3043000 +#define SQLITE_SOURCE_ID "2023-05-23 11:47:56 cec49c7d93362f527f0b4744cd1ae95d44a79671d49d69baa77fda70be29alt1" + +#define LIBSQL_VERSION "0.2.2" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -187,6 +192,8 @@ SQLITE_API const char *sqlite3_libversion(void); SQLITE_API const char *sqlite3_sourceid(void); SQLITE_API int sqlite3_libversion_number(void); +SQLITE_API const char *libsql_libversion(void); + /* ** CAPI3REF: Run-Time Library Compilation Options Diagnostics ** @@ -528,7 +535,6 @@ SQLITE_API int sqlite3_exec( #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) #define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) -#define SQLITE_IOERR_IN_PAGE (SQLITE_IOERR | (34<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) @@ -1007,6 +1013,13 @@ struct sqlite3_io_methods { ** ^When there are multiple VFS shims in the stack, this opcode finds the ** upper-most shim only. ** +**
    4. [[SQLITE_FCNTL_WAL_METHODS_POINTER]] +** ^The [SQLITE_FCNTL_WAL_METHODS_POINTER] opcode finds a pointer to the top-level +** WAL methods currently in use. ^(The argument X in +** sqlite3_file_control(db,SQLITE_FCNTL_WAL_METHODS_POINTER,X) must be +** of type "[libsql_wal_methods] **". This opcodes will set *X +** to a pointer to the top-level WAL methods.)^ +** **
    5. [[SQLITE_FCNTL_PRAGMA]] ** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] ** file control is sent to the open [sqlite3_file] object corresponding @@ -1191,7 +1204,7 @@ struct sqlite3_io_methods { ** by clients within the current process, only within other processes. ** **
    6. [[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. ** **
    7. [[SQLITE_FCNTL_RESET_CACHE]] @@ -1243,6 +1256,9 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 +// libSQL extension +#define SQLITE_FCNTL_WAL_METHODS_POINTER 129 + /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE @@ -1271,6 +1287,16 @@ typedef struct sqlite3_mutex sqlite3_mutex; */ typedef struct sqlite3_api_routines sqlite3_api_routines; +/* +** CAPI3REF: Loadable Extension Thunk +** +** A pointer to the opaque libsql_api_routines structure is passed as +** the fourth parameter to entry points of [loadable extensions]. This +** structure must be typedefed in order to work around compiler warnings +** on some platforms. +*/ +typedef struct libsql_api_routines libsql_api_routines; + /* ** CAPI3REF: File Name ** @@ -2127,7 +2153,7 @@ struct sqlite3_mem_methods { ** is stored in each sorted record and the required column values loaded ** from the database as records are returned in sorted order. The default ** value for this option is to never use this optimization. Specifying a -** negative value for this option restores the default behavior. +** negative value for this option restores the default behaviour. ** This option is only available if SQLite is compiled with the ** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. ** @@ -2302,7 +2328,7 @@ struct sqlite3_mem_methods { ** database handle, SQLite checks if this will mean that there are now no ** connections at all to the database. If so, it performs a checkpoint ** operation before closing the connection. This option may be used to -** override this behavior. The first parameter passed to this operation +** override this behaviour. The first parameter passed to this operation ** is an integer - positive to disable checkpoints-on-close, or zero (the ** default) to enable them, and negative to leave the setting unchanged. ** The second parameter is a pointer to an integer @@ -2455,7 +2481,7 @@ 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]] @@ -2736,7 +2762,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*); @@ -3390,10 +3415,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 @@ -3750,6 +3773,24 @@ SQLITE_API int sqlite3_open_v2( int flags, /* Flags */ const char *zVfs /* Name of VFS module to use */ ); +SQLITE_API int libsql_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs, /* Name of VFS module to use, NULL for default */ + const char *zWal /* Name of WAL module to use */ +); + +SQLITE_API int libsql_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs, /* Name of VFS module to use, NULL for default */ + const char *zWal, /* Name of WAL module to use */ + void* pWalMethodsData /* User data, passed to the libsql_wal struct*/ +); + +SQLITE_API LIBSQL_API int libsql_try_initialize_wasm_func_table(sqlite3 *db); /* ** CAPI3REF: Obtain Values For URI Parameters @@ -3762,7 +3803,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()]. **
    @@ -3875,7 +3916,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 @@ -3955,7 +3996,6 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language ** text that describes the error, as either UTF-8 or UTF-16 respectively. -** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by @@ -4423,41 +4463,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 [sqlite3_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 @@ -4621,7 +4626,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 @@ -5326,7 +5331,6 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); */ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); - /* ** CAPI3REF: Create Or Redefine SQL Functions ** KEYWORDS: {function creation routines} @@ -5537,7 +5541,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. **

    @@ -5573,27 +5577,13 @@ SQLITE_API int sqlite3_create_window_function( ** ** ** [[SQLITE_SUBTYPE]]

    SQLITE_SUBTYPE
    -** The SQLITE_SUBTYPE flag indicates to SQLite that a function might call +** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. -** This flag instructs SQLite to omit some corner-case optimizations that -** might disrupt the operation of the [sqlite3_value_subtype()] function, -** causing it to return zero rather than the correct subtype(). -** SQL functions that invokes [sqlite3_value_subtype()] should have this -** property. If the SQLITE_SUBTYPE property is omitted, then the return -** value from [sqlite3_value_subtype()] might sometimes be zero even though -** a non-zero subtype was specified by the function argument expression. -** -** [[SQLITE_RESULT_SUBTYPE]]
    SQLITE_RESULT_SUBTYPE
    -** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call -** [sqlite3_result_subtype()] to cause a sub-type to be associated with its -** result. -** Every function that invokes [sqlite3_result_subtype()] should have this -** property. If it does not, then the call to [sqlite3_result_subtype()] -** might become a no-op if the function is used as term in an -** [expression index]. On the other hand, SQL functions that never invoke -** [sqlite3_result_subtype()] should avoid setting this property, as the -** purpose of this property is to disable certain optimizations that are -** incompatible with subtypes. +** Specifying this flag makes no difference for scalar or aggregate user +** functions. However, if it is not specified for a user-defined window +** function, then any sub-types belonging to arguments passed to the window +** function may be discarded before the window function is called (i.e. +** sqlite3_value_subtype() will always return 0). **
    ** */ @@ -5601,7 +5591,6 @@ SQLITE_API int sqlite3_create_window_function( #define SQLITE_DIRECTONLY 0x000080000 #define SQLITE_SUBTYPE 0x000100000 #define SQLITE_INNOCUOUS 0x000200000 -#define SQLITE_RESULT_SUBTYPE 0x001000000 /* ** CAPI3REF: Deprecated Functions @@ -5798,12 +5787,6 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*); ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. -** -** Every [application-defined SQL function] that invoke this interface -** should include the [SQLITE_SUBTYPE] property in the text -** encoding argument when the function is [sqlite3_create_function|registered]. -** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() -** might return zero instead of the upstream subtype in some corner cases. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); @@ -5902,56 +5885,48 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** METHOD: sqlite3_context ** ** These functions may be used by (non-aggregate) SQL functions to -** associate auxiliary data with argument values. If the same argument -** value is passed to multiple invocations of the same SQL function during -** query execution, under some circumstances the associated auxiliary data -** might be preserved. An example of where this might be useful is in a -** regular-expression matching function. The compiled version of the regular -** expression can be stored as auxiliary data associated with the pattern string. +** associate metadata with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated metadata may be preserved. An example +** of where this might be useful is in a regular-expression matching +** function. The compiled version of the regular expression can be stored as +** metadata associated with the pattern string. ** Then as long as the pattern string remains the same, ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** -** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata ** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument ** value to the application-defined function. ^N is zero for the left-most -** function argument. ^If there is no auxiliary data +** function argument. ^If there is no metadata ** associated with the function argument, the sqlite3_get_auxdata(C,N) interface ** returns a NULL pointer. ** -** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the -** N-th argument of the application-defined function. ^Subsequent +** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th +** argument of the application-defined function. ^Subsequent ** calls to sqlite3_get_auxdata(C,N) return P from the most recent -** sqlite3_set_auxdata(C,N,P,X) call if the auxiliary data is still valid or -** NULL if the auxiliary data has been discarded. +** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or +** NULL if the metadata has been discarded. ** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, ** SQLite will invoke the destructor function X with parameter P exactly -** once, when the auxiliary data is discarded. -** SQLite is free to discard the auxiliary data at any time, including:
      +** once, when the metadata is discarded. +** SQLite is free to discard the metadata at any time, including:
        **
      • ^(when the corresponding function parameter changes)^, or **
      • ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the ** SQL statement)^, or **
      • ^(when sqlite3_set_auxdata() is invoked again on the same ** parameter)^, or **
      • ^(during the original sqlite3_set_auxdata() call when a memory -** allocation error occurs.)^ -**
      • ^(during the original sqlite3_set_auxdata() call if the function -** is evaluated during query planning instead of during query execution, -** as sometimes happens with [SQLITE_ENABLE_STAT4].)^
      +** allocation error occurs.)^
    ** -** Note the last two bullets in particular. The destructor X in +** Note the last bullet in particular. The destructor X in ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() ** should be called near the end of the function implementation and the ** function implementation should not make any use of P after -** sqlite3_set_auxdata() has been called. Furthermore, a call to -** sqlite3_get_auxdata() that occurs immediately after a corresponding call -** to sqlite3_set_auxdata() might still return NULL if an out-of-memory -** condition occurred during the sqlite3_set_auxdata() call or if the -** function is being evaluated during query planning rather than during -** query execution. -** -** ^(In practice, auxiliary data is preserved between function calls for +** sqlite3_set_auxdata() has been called. +** +** ^(In practice, metadata is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** @@ -5961,67 +5936,10 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** ** These routines must be called from the same thread in which ** the SQL function is running. -** -** See also: [sqlite3_get_clientdata()] and [sqlite3_set_clientdata()]. */ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); -/* -** CAPI3REF: Database Connection Client Data -** METHOD: sqlite3 -** -** These functions are used to associate one or more named pointers -** with a [database connection]. -** A call to sqlite3_set_clientdata(D,N,P,X) causes the pointer P -** to be attached to [database connection] D using name N. Subsequent -** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P -** or a NULL pointer if there were no prior calls to -** sqlite3_set_clientdata() with the same values of D and N. -** Names are compared using strcmp() and are thus case sensitive. -** -** If P and X are both non-NULL, then the destructor X is invoked with -** argument P on the first of the following occurrences: -**
      -**
    • An out-of-memory error occurs during the call to -** sqlite3_set_clientdata() which attempts to register pointer P. -**
    • A subsequent call to sqlite3_set_clientdata(D,N,P,X) is made -** with the same D and N parameters. -**
    • The database connection closes. SQLite does not make any guarantees -** about the order in which destructors are called, only that all -** destructors will be called exactly once at some point during the -** database connection closing process. -**
    -** -** SQLite does not do anything with client data other than invoke -** destructors on the client data at the appropriate time. The intended -** use for client data is to provide a mechanism for wrapper libraries -** to store additional information about an SQLite database connection. -** -** There is no limit (other than available memory) on the number of different -** client data pointers (with different names) that can be attached to a -** single database connection. However, the implementation is optimized -** for the case of having only one or two different client data names. -** Applications and wrapper libraries are discouraged from using more than -** one client data name each. -** -** There is no way to enumerate the client data pointers -** associated with a database connection. The N parameter can be thought -** of as a secret key such that only code that knows the secret key is able -** to access the associated data. -** -** Security Warning: These interfaces should not be exposed in scripting -** languages or in other circumstances where it might be possible for an -** an attacker to invoke them. Any agent that can invoke these interfaces -** can probably also take control of the process. -** -** Database connection client data is only available for SQLite -** version 3.44.0 ([dateof:3.44.0]) and later. -** -** See also: [sqlite3_set_auxdata()] and [sqlite3_get_auxdata()]. -*/ -SQLITE_API void *sqlite3_get_clientdata(sqlite3*,const char*); -SQLITE_API int sqlite3_set_clientdata(sqlite3*, const char*, void*, void(*)(void*)); /* ** CAPI3REF: Constants Defining Special Destructor Behavior @@ -6223,20 +6141,6 @@ SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); ** higher order bits are discarded. ** The number of subtype bytes preserved by SQLite might increase ** in future releases of SQLite. -** -** Every [application-defined SQL function] that invokes this interface -** should include the [SQLITE_RESULT_SUBTYPE] property in its -** text encoding argument when the SQL function is -** [sqlite3_create_function|registered]. If the [SQLITE_RESULT_SUBTYPE] -** property is omitted from the function that invokes sqlite3_result_subtype(), -** then in some cases the sqlite3_result_subtype() might fail to set -** the result subtype. -** -** If SQLite is compiled with -DSQLITE_STRICT_SUBTYPE=1, then any -** SQL function that invokes the sqlite3_result_subtype() interface -** and that does not have the SQLITE_RESULT_SUBTYPE property will raise -** an error. Future versions of SQLite might enable -DSQLITE_STRICT_SUBTYPE=1 -** by default. */ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); @@ -6668,7 +6572,7 @@ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); /* -** CAPI3REF: Allowed return values from sqlite3_txn_state() +** CAPI3REF: Allowed return values from [sqlite3_txn_state()] ** KEYWORDS: {transaction state} ** ** These constants define the current transaction state of a database file. @@ -6800,7 +6704,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** ^Each call to the sqlite3_autovacuum_pages() interface overrides all ** previous invocations for that database connection. ^If the callback ** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer, -** then the autovacuum steps callback is canceled. The return value +** then the autovacuum steps callback is cancelled. The return value ** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might ** be some other error code if something goes wrong. The current ** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other @@ -7319,10 +7223,9 @@ struct sqlite3_module { /* The methods above are in versions 1 and 2 of the sqlite_module object. ** Those below are for version 3 and greater. */ int (*xShadowName)(const char*); - /* The methods above are in versions 1 through 3 of the sqlite_module object. - ** Those below are for version 4 and greater. */ - int (*xIntegrity)(sqlite3_vtab *pVTab, const char *zSchema, - const char *zTabName, int mFlags, char **pzErr); + /* The methods below relate to features contributed by the community and + ** are available for version 700 and greater. */ + int (*xPreparedSql)(sqlite3_vtab_cursor*, const char*); }; /* @@ -7810,7 +7713,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); ** code is returned and the transaction rolled back. ** ** Calling this function with an argument that is not a NULL pointer or an -** open blob handle results in undefined behavior. ^Calling this routine +** open blob handle results in undefined behaviour. ^Calling this routine ** with a null pointer (such as would be returned by a failed call to ** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function ** is passed a valid open blob handle, the values returned by the @@ -7938,6 +7841,34 @@ SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); +/* +** CAPI3REF: Virtual WAL Methods +** +** Virtual WAL methods can be redefined in order to change the default +** behavior of the write-ahead log. +** Methods can be registered and unregistered. +** The following interfaces are provided. +** +** ^The libsql_wal_methods_find() interface returns a pointer +** to the methods given their identifier. +** ^Names are case sensitive. +** ^Names are zero-terminated UTF-8 strings. +** ^If there is no match, a NULL pointer is returned. +** ^If zName is NULL then the default implementation is returned. +** +** ^New WAL methods are registered with libsql_wal_methods_register(). +** ^Same methods can be registered multiple times without injury. +** +** ^Unregister WAL methods with the libsql_wal_methods_unregister() interface. +*/ +typedef struct libsql_wal_methods libsql_wal_methods; +SQLITE_API libsql_wal_methods *libsql_wal_methods_find(const char *zName); +SQLITE_API int libsql_wal_methods_register(libsql_wal_methods*); +SQLITE_API int libsql_wal_methods_unregister(libsql_wal_methods*); + +SQLITE_API libsql_wal_methods *libsql_wal_methods_next(libsql_wal_methods *w); +SQLITE_API const char *libsql_wal_methods_name(libsql_wal_methods *w); + /* ** CAPI3REF: Mutexes ** @@ -8290,7 +8221,6 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SAVE 5 #define SQLITE_TESTCTRL_PRNG_RESTORE 6 #define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */ -#define SQLITE_TESTCTRL_FK_NO_ACTION 7 #define SQLITE_TESTCTRL_BITVEC_TEST 8 #define SQLITE_TESTCTRL_FAULT_INSTALL 9 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 @@ -8319,8 +8249,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 @@ -8860,6 +8789,14 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED. ** ** +** +** [[LIBSQL_STMTSTATUS_ROWS_READ]] +** [[LIBSQL_STMTSTATUS_ROWS_WRITTEN]] +**
    LIBSQL_STMTSTATUS_ROWS_READ
    +** LIBSQL_STMTSTATUS_ROWS_WRITTEN
    +**
    ^LIBSQL_STMTSTATUS_ROWS_READ is the number of rows read when executing +** this statement. LIBSQL_STMTSTATUS_ROWS_WRITTEN value is the number of +** rows written. */ #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 #define SQLITE_STMTSTATUS_SORT 2 @@ -8871,6 +8808,10 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); #define SQLITE_STMTSTATUS_FILTER_HIT 8 #define SQLITE_STMTSTATUS_MEMUSED 99 +#define LIBSQL_STMTSTATUS_BASE 1024 +#define LIBSQL_STMTSTATUS_ROWS_READ LIBSQL_STMTSTATUS_BASE + 1 +#define LIBSQL_STMTSTATUS_ROWS_WRITTEN LIBSQL_STMTSTATUS_BASE + 2 + /* ** CAPI3REF: Custom Page Cache Object ** @@ -9776,7 +9717,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. **
    @@ -9966,7 +9907,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 @@ -10395,7 +10336,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 @@ -10424,6 +10365,22 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *); #endif +/* +** CAPI3REF: The close hook. +** METHOD: sqlite3 +** +** ^The [libsql_close_hook()] interface registers a callback function +** that is invoked prior to closing the database connection. +** ^At most one close hook may be registered at a time on a single +** [database connection]; each call to [libsql_close_hook()] overrides +** the previous setting. +** ^The close hook is disabled by invoking [libsql_close_hook()] +** with a NULL pointer as the second parameter. +** ^The third parameter to [libsql_close_hook()] is passed through as +** the first parameter to callbacks. +*/ +SQLITE_API void *libsql_close_hook(sqlite3 *db, void (*xClose)(void *pCtx, sqlite3 *db), void *arg); + /* ** CAPI3REF: Low-level system error code ** METHOD: sqlite3 @@ -10656,13 +10613,6 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c ** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy ** of the database exists. ** -** After the call, if the SQLITE_SERIALIZE_NOCOPY bit had been set, -** the returned buffer content will remain accessible and unchanged -** until either the next write operation on the connection or when -** the connection is closed, and applications must not modify the -** buffer. If the bit had been clear, the returned buffer will not -** be accessed by SQLite after the call. -** ** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the ** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory ** allocation error occurs. @@ -10711,9 +10661,6 @@ SQLITE_API unsigned char *sqlite3_serialize( ** SQLite will try to increase the buffer size using sqlite3_realloc64() ** if writes on the database cause it to grow larger than M bytes. ** -** Applications must not modify the buffer P or invalidate it before -** the database connection D is closed. -** ** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the ** database is currently in a read transaction or is involved in a backup ** operation. @@ -10722,13 +10669,6 @@ SQLITE_API unsigned char *sqlite3_serialize( ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the ** function returns SQLITE_ERROR. ** -** The deserialized database should not be in [WAL mode]. If the database -** is in WAL mode, then any attempt to use the database file will result -** in an [SQLITE_CANTOPEN] error. The application can set the -** [file format version numbers] (bytes 18 and 19) of the input database P -** to 0x01 prior to invoking sqlite3_deserialize(D,S,P,N,M,F) to force the -** database file into rollback mode and work around this limitation. -** ** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the ** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then ** [sqlite3_free()] is invoked on argument P prior to returning. @@ -11801,18 +11741,6 @@ SQLITE_API int sqlite3changeset_concat( ); -/* -** CAPI3REF: Upgrade the Schema of a Changeset/Patchset -*/ -SQLITE_API int sqlite3changeset_upgrade( - sqlite3 *db, - const char *zDb, - int nIn, const void *pIn, /* Input changeset */ - int *pnOut, void **ppOut /* OUT: Inverse of input */ -); - - - /* ** CAPI3REF: Changegroup Handle ** @@ -11859,38 +11787,6 @@ typedef struct sqlite3_changegroup sqlite3_changegroup; */ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp); -/* -** CAPI3REF: Add a Schema to a Changegroup -** METHOD: sqlite3_changegroup_schema -** -** This method may be used to optionally enforce the rule that the changesets -** added to the changegroup handle must match the schema of database zDb -** ("main", "temp", or the name of an attached database). If -** sqlite3changegroup_add() is called to add a changeset that is not compatible -** with the configured schema, SQLITE_SCHEMA is returned and the changegroup -** object is left in an undefined state. -** -** A changeset schema is considered compatible with the database schema in -** the same way as for sqlite3changeset_apply(). Specifically, for each -** table in the changeset, there exists a database table with: -** -**
      -**
    • The name identified by the changeset, and -**
    • at least as many columns as recorded in the changeset, and -**
    • the primary key columns in the same position as recorded in -** the changeset. -**
    -** -** The output of the changegroup object always has the same schema as the -** database nominated using this function. In cases where changesets passed -** to sqlite3changegroup_add() have fewer columns than the corresponding table -** in the database schema, these are filled in using the default column -** values from the database schema. This makes it possible to combined -** changesets that have different numbers of columns for a single table -** within a changegroup, provided that they are otherwise compatible. -*/ -SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const char *zDb); - /* ** CAPI3REF: Add A Changeset To A Changegroup ** METHOD: sqlite3_changegroup @@ -11959,18 +11855,13 @@ SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const c ** If the new changeset contains changes to a table that is already present ** in the changegroup, then the number of columns and the position of the ** primary key columns for the table must be consistent. If this is not the -** case, this function fails with SQLITE_SCHEMA. Except, if the changegroup -** object has been configured with a database schema using the -** sqlite3changegroup_schema() API, then it is possible to combine changesets -** with different numbers of columns for a single table, provided that -** they are otherwise compatible. -** -** If the input changeset appears to be corrupt and the corruption is -** detected, SQLITE_CORRUPT is returned. Or, if an out-of-memory condition -** occurs during processing, this function returns SQLITE_NOMEM. +** case, this function fails with SQLITE_SCHEMA. If the input changeset +** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is +** returned. Or, if an out-of-memory condition occurs during processing, this +** function returns SQLITE_NOMEM. In all cases, if an error occurs the state +** of the final contents of the changegroup is undefined. ** -** In all cases, if an error occurs the state of the final contents of the -** changegroup is undefined. If no error occurs, SQLITE_OK is returned. +** If no error occurs, SQLITE_OK is returned. */ SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); @@ -12235,17 +12126,10 @@ SQLITE_API int sqlite3changeset_apply_v2( **
  • an insert change if all fields of the conflicting row match ** the row being inserted. ** -** -**
    SQLITE_CHANGESETAPPLY_FKNOACTION
    -** If this flag it set, then all foreign key constraints in the target -** database behave as if they were declared with "ON UPDATE NO ACTION ON -** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL -** or SET DEFAULT. */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 #define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 -#define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008 /* ** CAPI3REF: Constants Passed To The Conflict Handler @@ -12986,7 +12870,7 @@ struct Fts5PhraseIter { ** See xPhraseFirstColumn above. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ void *(*xUserData)(Fts5Context*); @@ -13215,8 +13099,8 @@ struct Fts5ExtensionApi { ** as separate queries of the FTS index are required for each synonym. ** ** When using methods (2) or (3), it is important that the tokenizer only -** provide synonyms when tokenizing document text (method (3)) or query -** text (method (2)), not both. Doing so will not cause any errors, but is +** provide synonyms when tokenizing document text (method (2)) or query +** text (method (3)), not both. Doing so will not cause any errors, but is ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; @@ -13264,7 +13148,7 @@ struct fts5_api { int (*xCreateTokenizer)( fts5_api *pApi, const char *zName, - void *pUserData, + void *pContext, fts5_tokenizer *pTokenizer, void (*xDestroy)(void*) ); @@ -13273,7 +13157,7 @@ struct fts5_api { int (*xFindTokenizer)( fts5_api *pApi, const char *zName, - void **ppUserData, + void **ppContext, fts5_tokenizer *pTokenizer ); @@ -13281,7 +13165,7 @@ struct fts5_api { int (*xCreateFunction)( fts5_api *pApi, const char *zName, - void *pUserData, + void *pContext, fts5_extension_function xFunction, void (*xDestroy)(void*) ); @@ -13298,3 +13182,335 @@ struct fts5_api { #endif /* _FTS5_H */ /******** End of fts5.h *********/ +/******** Begin file page_header.h *********/ +// SPDX-License-Identifier: MIT + +#ifndef LIBSQL_PAGE_HEADER_H +#define LIBSQL_PAGE_HEADER_H + +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +typedef struct Pager Pager; +typedef struct libsql_pghdr PgHdr; +typedef struct PCache PCache; + +/* +** Every page in the cache is controlled by an instance of the following +** structure. +*/ +struct libsql_pghdr { + sqlite3_pcache_page *pPage; /* Pcache object page handle */ + void *pData; /* Page data */ + void *pExtra; /* Extra content */ + PCache *pCache; /* PRIVATE: Cache that owns this page */ + PgHdr *pDirty; /* Transient list of dirty sorted by pgno */ + Pager *pPager; /* The pager this page is part of */ + unsigned int pgno; /* Page number for this page */ + unsigned int pageHash; /* Hash of page content */ + unsigned short flags; /* PGHDR flags defined below */ + + /********************************************************************** + ** Elements above, except pCache, are public. All that follow are + ** private to pcache.c and should not be accessed by other modules. + ** pCache is grouped with the public elements for efficiency. + */ + unsigned long long nRef; /* Number of users of this page */ + PgHdr *pDirtyNext; /* Next element in list of dirty pages */ + PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ + /* NB: pDirtyNext and pDirtyPrev are undefined if the + ** PgHdr object is not dirty */ +}; + +typedef struct libsql_pghdr libsql_pghdr; + +#endif // LIBSQL_PAGE_HEADER_H + +/******** End of page_header.h *********/ +/******** Begin file wal.h *********/ +/* +** 2010 February 1 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface to the write-ahead logging +** system. Refer to the comments below and the header comment attached to +** the implementation of each function in log.c for further details. +*/ + +#ifndef SQLITE_WAL_H +#define SQLITE_WAL_H + + +/* Macros for extracting appropriate sync flags for either transaction +** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)): +*/ +#define WAL_SYNC_FLAGS(X) ((X)&0x03) +#define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03) + +#define WAL_SAVEPOINT_NDATA 4 + +/* Connection to a write-ahead log (WAL) file. +** There is one object of this type for each pager. +*/ +typedef struct libsql_wal libsql_wal; + +typedef struct libsql_wal_methods { + int iVersion; /* Current version is 1, versioning is here for backward compatibility */ + /* Open and close a connection to a write-ahead log. */ + int (*xOpen)(sqlite3_vfs*, sqlite3_file* , const char*, int no_shm_mode, long long max_size, struct libsql_wal_methods*, libsql_wal**); + int (*xClose)(libsql_wal*, sqlite3* db, int sync_flags, int nBuf, unsigned char *zBuf); + + /* Set the limiting size of a WAL file. */ + void (*xLimit)(libsql_wal*, long long limit); + + /* Used by readers to open (lock) and close (unlock) a snapshot. A + ** snapshot is like a read-transaction. It is the state of the database + ** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and + ** preserves the current state even if the other threads or processes + ** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the + ** transaction and releases the lock. + */ + int (*xBeginReadTransaction)(libsql_wal *, int *); + void (*xEndReadTransaction)(libsql_wal *); + + /* Read a page from the write-ahead log, if it is present. */ + int (*xFindFrame)(libsql_wal *, unsigned int, unsigned int *); + int (*xReadFrame)(libsql_wal *, unsigned int, int, unsigned char *); + + /* If the WAL is not empty, return the size of the database. */ + unsigned int (*xDbsize)(libsql_wal *pWal); + + /* Obtain or release the WRITER lock. */ + int (*xBeginWriteTransaction)(libsql_wal *pWal); + int (*xEndWriteTransaction)(libsql_wal *pWal); + + /* Undo any frames written (but not committed) to the log */ + int (*xUndo)(libsql_wal *pWal, int (*xUndo)(void *, unsigned int), void *pUndoCtx); + + /* Return an integer that records the current (uncommitted) write + ** position in the WAL */ + void (*xSavepoint)(libsql_wal *pWal, unsigned int *aWalData); + + /* Move the write position of the WAL back to iFrame. Called in + ** response to a ROLLBACK TO command. */ + int (*xSavepointUndo)(libsql_wal *pWal, unsigned int *aWalData); + + /* Write a frame or frames to the log. */ + int (*xFrames)(libsql_wal *pWal, int, libsql_pghdr *, unsigned int, int, int); + + /* Copy pages from the log to the database file */ + int (*xCheckpoint)( + libsql_wal *pWal, /* Write-ahead log connection */ + sqlite3 *db, /* Check this handle's interrupt flag */ + int eMode, /* One of PASSIVE, FULL and RESTART */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags to sync db file with (or 0) */ + int nBuf, /* Size of buffer nBuf */ + unsigned char *zBuf, /* Temporary buffer to use */ + int *pnLog, /* OUT: Number of frames in WAL */ + int *pnCkpt /* OUT: Number of backfilled frames in WAL */ + ); + + /* Return the value to pass to a sqlite3_wal_hook callback, the + ** number of frames in the WAL at the point of the last commit since + ** sqlite3WalCallback() was called. If no commits have occurred since + ** the last call, then return 0. + */ + int (*xCallback)(libsql_wal *pWal); + + /* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released) + ** by the pager layer on the database file. + */ + int (*xExclusiveMode)(libsql_wal *pWal, int op); + + /* Return true if the argument is non-NULL and the WAL module is using + ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the + ** WAL module is using shared-memory, return false. + */ + int (*xHeapMemory)(libsql_wal *pWal); + + // Only needed with SQLITE_ENABLE_SNAPSHOT, but part of the ABI + int (*xSnapshotGet)(libsql_wal *pWal, sqlite3_snapshot **ppSnapshot); + void (*xSnapshotOpen)(libsql_wal *pWal, sqlite3_snapshot *pSnapshot); + int (*xSnapshotRecover)(libsql_wal *pWal); + int (*xSnapshotCheck)(libsql_wal *pWal, sqlite3_snapshot *pSnapshot); + void (*xSnapshotUnlock)(libsql_wal *pWal); + + // Only needed with SQLITE_ENABLE_ZIPVFS, but part of the ABI + /* If the WAL file is not empty, return the number of bytes of content + ** stored in each frame (i.e. the db page-size when the WAL was created). + */ + int (*xFramesize)(libsql_wal *pWal); + + + /* Return the sqlite3_file object for the WAL file */ + sqlite3_file *(*xFile)(libsql_wal *pWal); + + // Only needed with SQLITE_ENABLE_SETLK_TIMEOUT + int (*xWriteLock)(libsql_wal *pWal, int bLock); + + void (*xDb)(libsql_wal *pWal, sqlite3 *db); + + /* Return the WAL pathname length based on the owning pager's pathname len. + ** For WAL implementations not based on a single file, 0 should be returned. */ + int (*xPathnameLen)(int origPathname); + + /* Get the WAL pathname to given buffer. Assumes that the buffer can hold + ** at least xPathnameLen bytes. For WAL implementations not based on a single file, + ** this operation can safely be a no-op. + ** */ + void (*xGetWalPathname)(char *buf, const char *orig, int orig_len); + + /* + ** This optional callback gets called before the main database file which owns + ** the WAL file is open. It is a good place for initialization routines, as WAL + ** is otherwise open lazily. + */ + int (*xPreMainDbOpen)(libsql_wal_methods *methods, const char *main_db_path); + + /* True if the implementation relies on shared memory routines (e.g. locks) */ + int bUsesShm; + + const char *zName; + struct libsql_wal_methods *pNext; +} libsql_wal_methods; + +libsql_wal_methods* libsql_wal_methods_find(const char *zName); + +/* Object declarations */ +typedef struct WalIndexHdr WalIndexHdr; +typedef struct WalIterator WalIterator; +typedef struct WalCkptInfo WalCkptInfo; + + +/* +** The following object holds a copy of the wal-index header content. +** +** The actual header in the wal-index consists of two copies of this +** object followed by one instance of the WalCkptInfo object. +** For all versions of SQLite through 3.10.0 and probably beyond, +** the locking bytes (WalCkptInfo.aLock) start at offset 120 and +** the total header size is 136 bytes. +** +** The szPage value can be any power of 2 between 512 and 32768, inclusive. +** Or it can be 1 to represent a 65536-byte page. The latter case was +** added in 3.7.1 when support for 64K pages was added. +*/ +struct WalIndexHdr { + unsigned int iVersion; /* Wal-index version */ + unsigned int unused; /* Unused (padding) field */ + unsigned int iChange; /* Counter incremented each transaction */ + unsigned char isInit; /* 1 when initialized */ + unsigned char bigEndCksum; /* True if checksums in WAL are big-endian */ + unsigned short szPage; /* Database page size in bytes. 1==64K */ + unsigned int mxFrame; /* Index of last valid frame in the WAL */ + unsigned int nPage; /* Size of database in pages */ + unsigned int aFrameCksum[2]; /* Checksum of last frame in log */ + unsigned int aSalt[2]; /* Two salt values copied from WAL header */ + unsigned int aCksum[2]; /* Checksum over all prior fields */ +}; + +/* +** An open write-ahead log file is represented by an instance of the +** following object. +*/ +struct libsql_wal { + sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ + sqlite3_file *pDbFd; /* File handle for the database file */ + sqlite3_file *pWalFd; /* File handle for WAL file */ + unsigned int iCallback; /* Value to pass to log callback (or 0) */ + long long mxWalSize; /* Truncate WAL to this size upon reset */ + int nWiData; /* Size of array apWiData */ + int szFirstBlock; /* Size of first block written to WAL file */ + volatile unsigned int **apWiData; /* Pointer to wal-index content in memory */ + unsigned int szPage; /* Database page size */ + short readLock; /* Which read lock is being held. -1 for none */ + unsigned char syncFlags; /* Flags to use to sync header writes */ + unsigned char exclusiveMode; /* Non-zero if connection is in exclusive mode */ + unsigned char writeLock; /* True if in a write transaction */ + unsigned char ckptLock; /* True if holding a checkpoint lock */ + unsigned char readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ + unsigned char truncateOnCommit; /* True to truncate WAL file on commit */ + unsigned char syncHeader; /* Fsync the WAL header if true */ + unsigned char padToSectorBoundary; /* Pad transactions out to the next sector */ + unsigned char bShmUnreliable; /* SHM content is read-only and unreliable */ + WalIndexHdr hdr; /* Wal-index header for current transaction */ + unsigned int minFrame; /* Ignore wal frames before this one */ + unsigned int iReCksum; /* On commit, recalculate checksums from here */ + const char *zWalName; /* Name of WAL file */ + unsigned int nCkpt; /* Checkpoint sequence counter in the wal-header */ + unsigned char lockError; /* True if a locking error has occurred */ + WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ + sqlite3 *db; + libsql_wal_methods *pMethods; /* Virtual methods for interacting with WAL */ + void *pMethodsData; /* Optional context for private use of libsql_wal_methods */ +}; + +typedef struct libsql_wal libsql_wal; + +#endif /* SQLITE_WAL_H */ + +/******** End of wal.h *********/ +/******** Begin file wasm_bindings.h *********/ +/* SPDX-License-Identifier: MIT */ +#ifdef LIBSQL_ENABLE_WASM_RUNTIME + +#ifndef LIBSQL_WASM_BINDINGS_H +#define LIBSQL_WASM_BINDINGS_H + +typedef struct libsql_wasm_engine_t libsql_wasm_engine_t; +typedef struct libsql_wasm_module_t libsql_wasm_module_t; + +typedef struct libsql_wasm_udf_api { + int (*libsql_value_type)(sqlite3_value*); + int (*libsql_value_int)(sqlite3_value*); + double (*libsql_value_double)(sqlite3_value*); + const unsigned char *(*libsql_value_text)(sqlite3_value*); + const void *(*libsql_value_blob)(sqlite3_value*); + int (*libsql_value_bytes)(sqlite3_value*); + void (*libsql_result_error)(sqlite3_context*, const char*, int); + void (*libsql_result_error_nomem)(sqlite3_context*); + void (*libsql_result_int)(sqlite3_context*, int); + void (*libsql_result_double)(sqlite3_context*, double); + void (*libsql_result_text)(sqlite3_context*, const char*, int, void(*)(void*)); + void (*libsql_result_blob)(sqlite3_context*, const void*, int, void(*)(void*)); + void (*libsql_result_null)(sqlite3_context*); + void *(*libsql_malloc)(int); + void (*libsql_free)(void *); +} libsql_wasm_udf_api; + +/* +** Runs a WebAssembly user-defined function. +** Additional data can be accessed via sqlite3_user_data(context) +*/ +SQLITE_API void libsql_run_wasm(struct libsql_wasm_udf_api *api, sqlite3_context *context, + libsql_wasm_engine_t *engine, libsql_wasm_module_t *module, const char *func_name, int argc, sqlite3_value **argv); + +/* +** Compiles a WebAssembly module. Can accept both .wat and binary Wasm format, depending on the implementation. +** err_msg_buf needs to be deallocated with libsql_free_wasm_module. +*/ +SQLITE_API libsql_wasm_module_t *libsql_compile_wasm_module(libsql_wasm_engine_t* engine, const char *pSrcBody, int nBody, + void *(*alloc_err_buf)(unsigned long long), char **err_msg_buf); + +/* +** Frees a module allocated with libsql_compile_wasm_module +*/ +SQLITE_API void libsql_free_wasm_module(void *module); + +/* +** Creates a new wasm engine +*/ +SQLITE_API libsql_wasm_engine_t *libsql_wasm_engine_new(); +SQLITE_API void libsql_wasm_engine_free(libsql_wasm_engine_t *); + +#endif //LIBSQL_WASM_BINDINGS_H +#endif //LIBSQL_ENABLE_WASM_RUNTIME + +/******** End of wasm_bindings.h *********/