Index: src/sqlite3.c ================================================================== --- src/sqlite3.c +++ src/sqlite3.c @@ -1,8 +1,8 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.41.0. By combining all the individual C code files into this +** version 3.39.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 ** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. @@ -450,13 +450,13 @@ ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.41.0" -#define SQLITE_VERSION_NUMBER 3041000 -#define SQLITE_SOURCE_ID "2023-02-06 16:23:52 5dde07a91dcf99b9c9a418b4e2178f66eef4cffd4799538a419674314a7530f9" +#define SQLITE_VERSION "3.39.0" +#define SQLITE_VERSION_NUMBER 3039000 +#define SQLITE_SOURCE_ID "2022-06-22 18:51:47 83ff1a28e3e7a99fa90d5079897d76529c4256eed859bf7cb98b860fbedfdc5b" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** @@ -867,11 +867,10 @@ #define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8)) #define SQLITE_CONSTRAINT_PINNED (SQLITE_CONSTRAINT |(11<<8)) #define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT |(12<<8)) #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) -#define SQLITE_NOTICE_RBU (SQLITE_NOTICE | (3<<8)) #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) #define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */ @@ -975,21 +974,17 @@ /* ** CAPI3REF: File Locking Levels ** ** SQLite uses one of these integer values as the second ** argument to calls it makes to the xLock() and xUnlock() methods -** of an [sqlite3_io_methods] object. These values are ordered from -** lest restrictive to most restrictive. -** -** The argument to xLock() is always SHARED or higher. The argument to -** xUnlock is either SHARED or NONE. +** of an [sqlite3_io_methods] object. */ -#define SQLITE_LOCK_NONE 0 /* xUnlock() only */ -#define SQLITE_LOCK_SHARED 1 /* xLock() or xUnlock() */ -#define SQLITE_LOCK_RESERVED 2 /* xLock() only */ -#define SQLITE_LOCK_PENDING 3 /* xLock() only */ -#define SQLITE_LOCK_EXCLUSIVE 4 /* xLock() only */ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 /* ** CAPI3REF: Synchronization Type Flags ** ** When SQLite invokes the xSync() method of an @@ -1063,18 +1058,11 @@ **
  • [SQLITE_LOCK_SHARED], **
  • [SQLITE_LOCK_RESERVED], **
  • [SQLITE_LOCK_PENDING], or **
  • [SQLITE_LOCK_EXCLUSIVE]. ** -** xLock() upgrades the database file lock. In other words, xLock() moves the -** database file lock in the direction NONE toward EXCLUSIVE. The argument to -** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never -** SQLITE_LOCK_NONE. If the database file lock is already at or above the -** requested lock, then the call to xLock() is a no-op. -** xUnlock() downgrades the database file lock to either SHARED or NONE. -* If the lock is already at or below the requested lock state, then the call -** to xUnlock() is a no-op. +** xLock() increases the lock. xUnlock() decreases the lock. ** The xCheckReservedLock() method checks whether any database connection, ** either in this process or in some other process, is holding a RESERVED, ** PENDING, or EXCLUSIVE lock on the file. It returns true ** if such a lock exists and false otherwise. ** @@ -1175,12 +1163,13 @@ **
  • [[SQLITE_FCNTL_LOCKSTATE]] ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This ** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) -** into an integer that the pArg argument points to. -** This capability is only available if SQLite is compiled with [SQLITE_DEBUG]. +** into an integer that the pArg argument points to. This capability +** is used during testing and is only available when the SQLITE_TEST +** compile-time option is used. ** **
  • [[SQLITE_FCNTL_SIZE_HINT]] ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS ** layer a hint of how large the database file will grow to be during the ** current transaction. This hint is not guaranteed to be accurate but it @@ -1497,16 +1486,10 @@ ** by clients within the current process, only within other processes. ** ** **
  • [[SQLITE_FCNTL_CKSM_FILE]] ** Used by the cksmvfs VFS module only. -** -**
  • [[SQLITE_FCNTL_RESET_CACHE]] -** If there is currently no transaction open on the database, and the -** database is not a temp db, then this file-control purges the contents -** of the in-memory page cache. If there is an open transaction, or if -** the db is a temp-db, it is a no-op, not an error. ** */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 @@ -1545,11 +1528,10 @@ #define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 -#define SQLITE_FCNTL_RESET_CACHE 42 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO @@ -1575,30 +1557,10 @@ ** structure must be typedefed in order to work around compiler warnings ** on some platforms. */ typedef struct sqlite3_api_routines sqlite3_api_routines; -/* -** CAPI3REF: File Name -** -** Type [sqlite3_filename] is used by SQLite to pass filenames to the -** xOpen method of a [VFS]. It may be cast to (const char*) and treated -** as a normal, nul-terminated, UTF-8 buffer containing the filename, but -** may also be passed to special APIs such as: -** -** -*/ -typedef const char *sqlite3_filename; - /* ** CAPI3REF: OS Interface Object ** ** An instance of the sqlite3_vfs object defines the interface between ** the SQLite core and the underlying operating system. The "vfs" @@ -1773,11 +1735,11 @@ int szOsFile; /* Size of subclassed sqlite3_file */ int mxPathname; /* Maximum file pathname length */ sqlite3_vfs *pNext; /* Next registered VFS */ const char *zName; /* Name of this virtual file system */ void *pAppData; /* Pointer to application-specific data */ - int (*xOpen)(sqlite3_vfs*, sqlite3_filename zName, sqlite3_file*, + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, int flags, int *pOutFlags); int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); @@ -2489,11 +2451,11 @@ ** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally ** rounded down to the next smaller multiple of 8. ^(The lookaside memory ** configuration for a database connection can only be changed when that ** connection is not currently using lookaside memory, or in other words ** when the "current value" returned by -** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero. +** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. ** Any attempt to change the lookaside memory configuration when lookaside ** memory is in use leaves the configuration unchanged and returns ** [SQLITE_BUSY].)^ ** ** [[SQLITE_DBCONFIG_ENABLE_FKEY]] @@ -2639,16 +2601,12 @@ **
  • sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); **
  • [sqlite3_exec](db, "[VACUUM]", 0, 0, 0); **
  • sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); ** ** Because resetting a database is destructive and irreversible, the -** process requires the use of this obscure API and multiple steps to -** help ensure that it does not happen by accident. Because this -** feature must be capable of resetting corrupt databases, and -** shutting down virtual tables may require access to that corrupt -** storage, the library must abandon any installed virtual tables -** without calling their xDestroy() methods. +** process requires the use of this obscure API and multiple steps to help +** ensure that it does not happen by accident. ** ** [[SQLITE_DBCONFIG_DEFENSIVE]]
    SQLITE_DBCONFIG_DEFENSIVE
    **
    The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the ** "defensive" flag for a database connection. When the defensive ** flag is enabled, language features that allow ordinary SQL to @@ -2655,11 +2613,10 @@ ** deliberately corrupt the database file are disabled. The disabled ** features include but are not limited to the following: ** **
    ** @@ -2983,16 +2940,12 @@ ** that are started after the running statement count reaches zero are ** not effected by the sqlite3_interrupt(). ** ^A call to sqlite3_interrupt(D) that occurs when there are no running ** SQL statements is a no-op and has no effect on SQL statements ** that are started after the sqlite3_interrupt() call returns. -** -** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether -** or not an interrupt is currently in effect for [database connection] D. */ SQLITE_API void sqlite3_interrupt(sqlite3*); -SQLITE_API int sqlite3_is_interrupted(sqlite3*); /* ** CAPI3REF: Determine If An SQL Statement Is Complete ** ** These routines are useful during command-line input to determine if the @@ -3606,12 +3559,12 @@ ** ** [[SQLITE_TRACE_PROFILE]]
    SQLITE_TRACE_PROFILE
    **
    ^An SQLITE_TRACE_PROFILE callback provides approximately the same ** information as is provided by the [sqlite3_profile()] callback. ** ^The P argument is a pointer to the [prepared statement] and the -** X argument points to a 64-bit integer which is approximately -** the number of nanoseconds that the prepared statement took to run. +** X argument points to a 64-bit integer which is the estimated of +** the number of nanosecond that the prepared statement took to run. ** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. ** ** [[SQLITE_TRACE_ROW]]
    SQLITE_TRACE_ROW
    **
    ^An SQLITE_TRACE_ROW callback is invoked whenever a prepared ** statement generates a single row of result. @@ -3670,11 +3623,11 @@ ** CAPI3REF: Query Progress Callbacks ** METHOD: sqlite3 ** ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback ** function X to be invoked periodically during long running calls to -** [sqlite3_step()] and [sqlite3_prepare()] and similar for +** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for ** database connection D. An example use for this ** interface is to keep a GUI updated during a large query. ** ** ^The parameter P is passed through as the only parameter to the ** callback function X. ^The parameter N is the approximate number of @@ -3695,17 +3648,10 @@ ** The progress handler callback must not do anything that will modify ** the database connection that invoked the progress handler. ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** -** The progress handler callback would originally only be invoked from the -** bytecode engine. It still might be invoked during [sqlite3_prepare()] -** and similar because those routines might force a reparse of the schema -** which involves running the bytecode engine. However, beginning with -** SQLite version 3.41.0, the progress handler callback might also be -** invoked directly from [sqlite3_prepare()] while analyzing and generating -** code for complex queries. */ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection @@ -3738,22 +3684,17 @@ ** sqlite3_open_v2() must include, at a minimum, one of the following ** three flag combinations:)^ ** **
    ** ^(
    [SQLITE_OPEN_READONLY]
    -**
    The database is opened in read-only mode. If the database does -** not already exist, an error is returned.
    )^ +**
    The database is opened in read-only mode. If the database does not +** already exist, an error is returned.
    )^ ** ** ^(
    [SQLITE_OPEN_READWRITE]
    -**
    The database is opened for reading and writing if possible, or -** reading only if the file is write protected by the operating -** system. In either case the database must already exist, otherwise -** an error is returned. For historical reasons, if opening in -** read-write mode fails due to OS-level permissions, an attempt is -** made to open it in read-only mode. [sqlite3_db_readonly()] can be -** used to determine whether the database is actually -** read-write.
    )^ +**
    The database is opened for reading and writing if possible, or reading +** only if the file is write protected by the operating system. In either +** case the database must already exist, otherwise an error is returned.
    )^ ** ** ^(
    [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
    **
    The database is opened for reading and writing, and is created if ** it does not already exist. This is the behavior that is always used for ** sqlite3_open() and sqlite3_open16().
    )^ @@ -3787,13 +3728,10 @@ ** ** ^(
    [SQLITE_OPEN_SHAREDCACHE]
    **
    The database is opened [shared cache] enabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ -** The [use of shared cache mode is discouraged] and hence shared cache -** capabilities may be omitted from many builds of SQLite. In such cases, -** this option is a no-op. ** ** ^(
    [SQLITE_OPEN_PRIVATECACHE]
    **
    The database is opened [shared cache] disabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ @@ -3805,11 +3743,11 @@ ** connection as soon as the connection is created. In addition to setting ** the extended result code mode, this flag also causes [sqlite3_open_v2()] ** to return an extended result code.
    ** ** [[OPEN_NOFOLLOW]] ^(
    [SQLITE_OPEN_NOFOLLOW]
    -**
    The database filename is not allowed to contain a symbolic link
    +**
    The database filename is not allowed to be a symbolic link
    **
    )^ ** ** If the 3rd parameter to sqlite3_open_v2() is not one of the ** required combinations shown above optionally combined with other ** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] @@ -4064,14 +4002,14 @@ ** it has access to all the same query parameters as were found on the ** main database file. ** ** See the [URI filename] documentation for additional information. */ -SQLITE_API const char *sqlite3_uri_parameter(sqlite3_filename z, const char *zParam); -SQLITE_API int sqlite3_uri_boolean(sqlite3_filename z, const char *zParam, int bDefault); -SQLITE_API sqlite3_int64 sqlite3_uri_int64(sqlite3_filename, const char*, sqlite3_int64); -SQLITE_API const char *sqlite3_uri_key(sqlite3_filename z, int N); +SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); +SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); +SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N); /* ** CAPI3REF: Translate filenames ** ** These routines are available to [VFS|custom VFS implementations] for @@ -4096,13 +4034,13 @@ ** In all of the above, if F is not the name of a database, journal or WAL ** filename passed into the VFS from the SQLite core and F is not the ** return value from [sqlite3_db_filename()], then the result is ** undefined and is likely a memory access violation. */ -SQLITE_API const char *sqlite3_filename_database(sqlite3_filename); -SQLITE_API const char *sqlite3_filename_journal(sqlite3_filename); -SQLITE_API const char *sqlite3_filename_wal(sqlite3_filename); +SQLITE_API const char *sqlite3_filename_database(const char*); +SQLITE_API const char *sqlite3_filename_journal(const char*); +SQLITE_API const char *sqlite3_filename_wal(const char*); /* ** CAPI3REF: Database File Corresponding To A Journal ** ** ^If X is the name of a rollback or WAL-mode journal file that is @@ -4164,18 +4102,18 @@ ** used again after sqlite3_free_filename(Y) has been called. This means ** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y, ** then the corresponding [sqlite3_module.xClose() method should also be ** invoked prior to calling sqlite3_free_filename(Y). */ -SQLITE_API sqlite3_filename sqlite3_create_filename( +SQLITE_API char *sqlite3_create_filename( const char *zDatabase, const char *zJournal, const char *zWal, int nParam, const char **azParam ); -SQLITE_API void sqlite3_free_filename(sqlite3_filename); +SQLITE_API void sqlite3_free_filename(char*); /* ** CAPI3REF: Error Codes And Messages ** METHOD: sqlite3 ** @@ -5730,25 +5668,14 @@ ** [[SQLITE_DIRECTONLY]]
    SQLITE_DIRECTONLY
    ** The SQLITE_DIRECTONLY flag means that the function may only be invoked ** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in ** schema structures such as [CHECK constraints], [DEFAULT clauses], ** [expression indexes], [partial indexes], or [generated columns]. -**

    -** The SQLITE_DIRECTONLY flag is recommended for any -** [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 surreptiously -** modified to invoke the application-defined function in ways that are -** harmful. -**

    -** Some people say it is good practice to set SQLITE_DIRECTONLY on all -** [application-defined SQL functions], regardless of whether or not they -** are security sensitive, as doing so prevents those functions from being used -** inside of the database schema, and thus ensures that the database -** can be inspected and modified using generic tools (such as the [CLI]) -** that do not have access to the application-defined functions. +** The SQLITE_DIRECTONLY flags is a security feature which is recommended +** for all [application-defined SQL functions], and especially for functions +** that have side-effects or that could potentially leak sensitive +** information. **

    ** ** [[SQLITE_INNOCUOUS]]
    SQLITE_INNOCUOUS
    ** The SQLITE_INNOCUOUS flag means that the function is unlikely ** to cause problems even if misused. An innocuous function should have @@ -5950,32 +5877,10 @@ SQLITE_API int sqlite3_value_type(sqlite3_value*); SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); SQLITE_API int sqlite3_value_nochange(sqlite3_value*); SQLITE_API int sqlite3_value_frombind(sqlite3_value*); -/* -** CAPI3REF: Report the internal text encoding state of an sqlite3_value object -** METHOD: sqlite3_value -** -** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8], -** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current text encoding -** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X) -** returns something other than SQLITE_TEXT, then the return value from -** sqlite3_value_encoding(X) is meaningless. ^Calls to -** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)], -** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or -** [sqlite3_value_bytes16(X)] might change the encoding of the value X and -** thus change the return from subsequent calls to sqlite3_value_encoding(X). -** -** This routine is intended for used by applications that test and validate -** the SQLite implementation. This routine is inquiring about the opaque -** internal state of an [sqlite3_value] object. Ordinary applications should -** not need to know what the internal state of an sqlite3_value object is and -** hence should not need to use this interface. -*/ -SQLITE_API int sqlite3_value_encoding(sqlite3_value*); - /* ** CAPI3REF: Finding The Subtype Of SQL Values ** METHOD: sqlite3_value ** ** The sqlite3_value_subtype(V) function returns the subtype for @@ -6024,11 +5929,11 @@ ** In those cases, sqlite3_aggregate_context() might be called for the ** first time from within xFinal().)^ ** ** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer ** when first called if N is less than or equal to zero or if a memory -** allocation error occurs. +** allocate error occurs. ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is ** determined by the N parameter on first successful call. Changing the ** value of N in any subsequent call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory @@ -6229,14 +6134,13 @@ ** application-defined function to be a text string in an encoding ** specified by the fifth (and last) parameter, which must be one ** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. ** ^SQLite takes the text result from the application from ** the 2nd parameter of the sqlite3_result_text* interfaces. -** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces -** other than sqlite3_result_text64() is negative, then SQLite computes -** the string length itself by searching the 2nd parameter for the first -** zero character. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is negative, then SQLite takes result text from the 2nd parameter +** through the first zero character. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would @@ -6682,11 +6586,11 @@ ** CAPI3REF: Return The Schema Name For A Database Connection ** METHOD: sqlite3 ** ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name ** for the N-th database on database connection D, or a NULL pointer of N is -** out of range. An N value of 0 means the main database file. An N of 1 is +** out of range. An N alue of 0 means the main database file. An N of 1 is ** the "temp" schema. Larger values of N correspond to various ATTACH-ed ** databases. ** ** Space to hold the string that is returned by sqlite3_db_name() is managed ** by SQLite itself. The string might be deallocated by any operation that @@ -6728,11 +6632,11 @@ **
  • [sqlite3_filename_database()] **
  • [sqlite3_filename_journal()] **
  • [sqlite3_filename_wal()] ** */ -SQLITE_API sqlite3_filename sqlite3_db_filename(sqlite3 *db, const char *zDbName); +SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Determine if a database is read-only ** METHOD: sqlite3 ** @@ -6865,11 +6769,11 @@ ** ** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback ** function C that is invoked prior to each autovacuum of the database ** file. ^The callback is passed a copy of the generic data pointer (P), ** the schema-name of the attached database that is being autovacuumed, -** the size of the database file in pages, the number of free pages, +** the the size of the database file in pages, the number of free pages, ** and the number of bytes per page, respectively. The callback should ** return the number of free pages that should be removed by the ** autovacuum. ^If the callback returns zero, then no autovacuum happens. ** ^If the value returned is greater than or equal to the number of ** free pages, then a complete autovacuum happens. @@ -6986,15 +6890,10 @@ ** ^(This routine enables or disables the sharing of the database cache ** and schema data structures between [database connection | connections] ** to the same database. Sharing is enabled if the argument is true ** and disabled if the argument is false.)^ ** -** This interface is omitted if SQLite is compiled with -** [-DSQLITE_OMIT_SHARED_CACHE]. The [-DSQLITE_OMIT_SHARED_CACHE] -** compile-time option is recommended because the -** [use of shared cache mode is discouraged]. -** ** ^Cache sharing is enabled and disabled for an entire process. ** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). ** In prior versions of SQLite, ** sharing was enabled or disabled for each thread separately. ** @@ -7089,11 +6988,11 @@ ** ^Setting the heap limits to zero disables the heap limiter mechanism. ** ** ^The soft heap limit may not be greater than the hard heap limit. ** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N) ** is invoked with a value of N that is greater than the hard heap limit, -** the soft heap limit is set to the value of the hard heap limit. +** the the soft heap limit is set to the value of the hard heap limit. ** ^The soft heap limit is automatically enabled whenever the hard heap ** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and ** the soft heap limit is outside the range of 1..N, then the soft heap ** limit is set to N. ^Invoking sqlite3_soft_heap_limit64(0) when the ** hard heap limit is enabled makes the soft heap limit equal to the @@ -7350,10 +7249,19 @@ ** ^This interface disables all automatic extensions previously ** registered using [sqlite3_auto_extension()]. */ SQLITE_API void sqlite3_reset_auto_extension(void); +/* +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + /* ** Structures used by the virtual table interface */ typedef struct sqlite3_vtab sqlite3_vtab; typedef struct sqlite3_index_info sqlite3_index_info; @@ -7468,14 +7376,14 @@ ** checked separately in byte code. If the omit flag is change to true, then ** the constraint may or may not be checked in byte code. In other words, ** when the omit flag is true there is no guarantee that the constraint will ** not be checked again using byte code.)^ ** -** ^The idxNum and idxStr values are recorded and passed into the +** ^The idxNum and idxPtr values are recorded and passed into the ** [xFilter] method. -** ^[sqlite3_free()] is used to free idxStr if and only if -** needToFreeIdxStr is true. +** ^[sqlite3_free()] is used to free idxPtr if and only if +** needToFreeIdxPtr is true. ** ** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in ** the correct order to satisfy the ORDER BY clause so that no separate ** sorting step is required. ** @@ -7591,11 +7499,11 @@ ** ** The collating sequence to be used for comparison can be found using ** the [sqlite3_vtab_collation()] interface. For most real-world virtual ** tables, the collating sequence of constraints does not matter (for example ** because the constraints are numeric) and so the sqlite3_vtab_collation() -** interface is not commonly needed. +** interface is no commonly needed. */ #define SQLITE_INDEX_CONSTRAINT_EQ 2 #define SQLITE_INDEX_CONSTRAINT_GT 4 #define SQLITE_INDEX_CONSTRAINT_LE 8 #define SQLITE_INDEX_CONSTRAINT_LT 16 @@ -7749,10 +7657,20 @@ ** the new function is not good for anything by itself. Its only ** purpose is to be a placeholder function that can be overloaded ** by a [virtual table]. */ SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ /* ** CAPI3REF: A Handle To An Open BLOB ** KEYWORDS: {BLOB handle} {BLOB handles} ** @@ -9365,11 +9283,11 @@ ** sqlite3_backup_init() is called and before the corresponding call to ** sqlite3_backup_finish(). SQLite does not currently check to see ** if the application incorrectly accesses the destination [database connection] ** and so no error code is reported, but the operations may malfunction ** nevertheless. Use of the destination database connection while a -** backup is in progress might also cause a mutex deadlock. +** backup is in progress might also also cause a mutex deadlock. ** ** If running in [shared cache mode], the application must ** guarantee that the shared cache used by the destination database ** is not accessed while the backup is running. In practice this means ** that the application must guarantee that the disk file being @@ -9793,11 +9711,11 @@ ** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the ** meaning of each of these checkpoint modes. */ #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ -#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */ +#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ /* ** CAPI3REF: Virtual Table Interface Configuration ** @@ -9953,11 +9871,11 @@ ** statement that was passed into [sqlite3_declare_vtab()], then the ** name of that alternative collating sequence is returned. **
  • Otherwise, "BINARY" is returned. ** */ -SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); +SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); /* ** CAPI3REF: Determine if a virtual table query is DISTINCT ** METHOD: sqlite3_index_info ** @@ -10110,17 +10028,18 @@ ** [xFilter|xFilter() method] of a [virtual table] implementation. ** The result of invoking these interfaces from any other context ** is undefined and probably harmful. ** ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or -** sqlite3_vtab_in_next(X,P) should be one of the parameters to the +** sqlite3_vtab_in_next(X,P) must be one of the parameters to the ** xFilter method which invokes these routines, and specifically ** a parameter that was previously selected for all-at-once IN constraint ** processing use the [sqlite3_vtab_in()] interface in the ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not ** an xFilter argument that was selected for all-at-once IN constraint -** processing, then these routines return [SQLITE_ERROR].)^ +** processing, then these routines return [SQLITE_MISUSE])^ or perhaps +** exhibit some other undefined or harmful behavior. ** ** ^(Use these routines to access all values on the right-hand side ** of the IN constraint using code like the following: ** **

    @@ -10221,14 +10140,10 @@
     **
     ** When the value returned to V is a string, space to hold that string is
     ** managed by the prepared statement S and will be automatically freed when
     ** S is finalized.
     **
    -** Not all values are available for all query elements. When a value is
    -** not available, the output variable is set to -1 if the value is numeric,
    -** or to NULL if it is a string (SQLITE_SCANSTAT_NAME).
    -**
     ** 
    ** [[SQLITE_SCANSTAT_NLOOP]]
    SQLITE_SCANSTAT_NLOOP
    **
    ^The [sqlite3_int64] variable pointed to by the V parameter will be ** set to the total number of times that the X-th loop has run.
    ** @@ -10252,44 +10167,30 @@ ** [[SQLITE_SCANSTAT_EXPLAIN]]
    SQLITE_SCANSTAT_EXPLAIN
    **
    ^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] ** description for the X-th loop. ** -** [[SQLITE_SCANSTAT_SELECTID]]
    SQLITE_SCANSTAT_SELECTID
    +** [[SQLITE_SCANSTAT_SELECTID]]
    SQLITE_SCANSTAT_SELECT
    **
    ^The "int" variable pointed to by the V parameter will be set to the -** id for the X-th query plan element. The id value is unique within the -** statement. The select-id is the same value as is output in the first -** column of an [EXPLAIN QUERY PLAN] query. +** "select-id" for the X-th loop. The select-id identifies which query or +** subquery the loop is part of. The main query has a select-id of zero. +** The select-id is the same value as is output in the first column +** of an [EXPLAIN QUERY PLAN] query. **
    -** -** [[SQLITE_SCANSTAT_PARENTID]]
    SQLITE_SCANSTAT_PARENTID
    -**
    The "int" variable pointed to by the V parameter will be set to the -** the id of the parent of the current query element, if applicable, or -** to zero if the query element has no parent. This is the same value as -** returned in the second column of an [EXPLAIN QUERY PLAN] query. -** -** [[SQLITE_SCANSTAT_NCYCLE]]
    SQLITE_SCANSTAT_NCYCLE
    -**
    The sqlite3_int64 output value is set to the number of cycles, -** according to the processor time-stamp counter, that elapsed while the -** query element was being processed. This value is not available for -** all query elements - if it is unavailable the output variable is -** set to -1. */ #define SQLITE_SCANSTAT_NLOOP 0 #define SQLITE_SCANSTAT_NVISIT 1 #define SQLITE_SCANSTAT_EST 2 #define SQLITE_SCANSTAT_NAME 3 #define SQLITE_SCANSTAT_EXPLAIN 4 #define SQLITE_SCANSTAT_SELECTID 5 -#define SQLITE_SCANSTAT_PARENTID 6 -#define SQLITE_SCANSTAT_NCYCLE 7 /* ** CAPI3REF: Prepared Statement Scan Status ** METHOD: sqlite3_stmt ** -** These interfaces return information about the predicted and measured +** This interface returns information about the predicted and measured ** performance for pStmt. Advanced applications can use this ** interface to compare the predicted and the measured performance and ** issue warnings and/or rerun [ANALYZE] if discrepancies are found. ** ** Since this interface is expected to be rarely used, it is only @@ -10296,51 +10197,32 @@ ** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS] ** compile-time option. ** ** The "iScanStatusOp" parameter determines which status information to return. ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior -** of this interface is undefined. ^The requested measurement is written into -** a variable pointed to by the "pOut" parameter. -** -** The "flags" parameter must be passed a mask of flags. At present only -** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX -** is specified, then status information is available for all elements -** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If -** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements -** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of -** the EXPLAIN QUERY PLAN output) are available. Invoking API -** sqlite3_stmt_scanstatus() is equivalent to calling -** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. -** -** Parameter "idx" identifies the specific query element to retrieve statistics -** for. Query elements are numbered starting from zero. A value of -1 may be -** to query for statistics regarding the entire query. ^If idx is out of range -** - less than -1 or greater than or equal to the total number of query -** elements used to implement the statement - a non-zero value is returned and -** the variable that pOut points to is unchanged. +** of this interface is undefined. +** ^The requested measurement is written into a variable pointed to by +** the "pOut" parameter. +** Parameter "idx" identifies the specific loop to retrieve statistics for. +** Loops are numbered starting from zero. ^If idx is out of range - less than +** zero or greater than or equal to the total number of loops used to implement +** the statement - a non-zero value is returned and the variable that pOut +** points to is unchanged. +** +** ^Statistics might not be available for all loops in all statements. ^In cases +** where there exist loops with no available statistics, this function behaves +** as if the loop did not exist - it returns non-zero and leave the variable +** that pOut points to unchanged. ** ** See also: [sqlite3_stmt_scanstatus_reset()] */ SQLITE_API int sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ void *pOut /* Result written here */ ); -SQLITE_API int sqlite3_stmt_scanstatus_v2( - sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ - int idx, /* Index of loop to report on */ - int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ - int flags, /* Mask of flags defined below */ - void *pOut /* Result written here */ -); - -/* -** CAPI3REF: Prepared Statement Scan Status -** KEYWORDS: {scan status flags} -*/ -#define SQLITE_SCANSTAT_COMPLEX 0x0001 /* ** CAPI3REF: Zero Scan-Status Counters ** METHOD: sqlite3_stmt ** @@ -10427,14 +10309,10 @@ ** seventh parameter is the final rowid value of the row being inserted ** or updated. The value of the seventh parameter passed to the callback ** function is not defined for operations on WITHOUT ROWID tables, or for ** DELETE operations on rowid tables. ** -** ^The sqlite3_update_hook(D,C,P) function returns the P argument from -** the previous call on the same [database connection] D, or NULL for -** the first call on D. -** ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces ** provide additional information about a preupdate event. These routines ** may only be called from within a preupdate callback. Invoking any of ** these routines from outside of a preupdate callback or with a @@ -13264,21 +13142,16 @@ /******** End of fts5.h *********/ /************** End of sqlite3.h *********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ -/* -** Reuse the STATIC_LRU for mutex access to sqlite3_temp_directory. -*/ -#define SQLITE_MUTEX_STATIC_TEMPDIR SQLITE_MUTEX_STATIC_VFS1 - /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build */ #if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H) -#include "sqlite_cfg.h" +#include "config.h" #define SQLITECONFIG_H 1 #endif /************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/ /************** Begin file sqliteLimit.h *************************************/ @@ -14541,13 +14414,13 @@ ** Except, if SQLITE_4_BYTE_ALIGNED_MALLOC is defined, then the ** underlying malloc() implementation might return us 4-byte aligned ** pointers. In that case, only verify 4-byte alignment. */ #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC -# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0) +# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0) #else -# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) +# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0) #endif /* ** Disable MMAP on platforms where it is known to not work */ @@ -14597,42 +14470,19 @@ #endif #if defined(SQLITE_DEBUG) \ && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE) \ || defined(SQLITE_ENABLE_TREETRACE)) # define TREETRACE_ENABLED 1 -# define TREETRACE(K,P,S,X) \ +# define SELECTTRACE(K,P,S,X) \ if(sqlite3TreeTrace&(K)) \ sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ sqlite3DebugPrintf X #else -# define TREETRACE(K,P,S,X) +# define SELECTTRACE(K,P,S,X) # define TREETRACE_ENABLED 0 #endif -/* TREETRACE flag meanings: -** -** 0x00000001 Beginning and end of SELECT processing -** 0x00000002 WHERE clause processing -** 0x00000004 Query flattener -** 0x00000008 Result-set wildcard expansion -** 0x00000010 Query name resolution -** 0x00000020 Aggregate analysis -** 0x00000040 Window functions -** 0x00000080 Generated column names -** 0x00000100 Move HAVING terms into WHERE -** 0x00000200 Count-of-view optimization -** 0x00000400 Compound SELECT processing -** 0x00000800 Drop superfluous ORDER BY -** 0x00001000 LEFT JOIN simplifies to JOIN -** 0x00002000 Constant propagation -** 0x00004000 Push-down optimization -** 0x00008000 After all FROM-clause analysis -** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing -** 0x00020000 Transform DISTINCT into GROUP BY -** 0x00040000 SELECT tree dump after all code has been generated -*/ - /* ** Macros for "wheretrace" */ SQLITE_PRIVATE u32 sqlite3WhereTrace; #if defined(SQLITE_DEBUG) \ @@ -14641,40 +14491,10 @@ # define WHERETRACE_ENABLED 1 #else # define WHERETRACE(K,X) #endif -/* -** Bits for the sqlite3WhereTrace mask: -** -** (---any--) Top-level block structure -** 0x-------F High-level debug messages -** 0x----FFF- More detail -** 0xFFFF---- Low-level debug messages -** -** 0x00000001 Code generation -** 0x00000002 Solver -** 0x00000004 Solver costs -** 0x00000008 WhereLoop inserts -** -** 0x00000010 Display sqlite3_index_info xBestIndex calls -** 0x00000020 Range an equality scan metrics -** 0x00000040 IN operator decisions -** 0x00000080 WhereLoop cost adjustements -** 0x00000100 -** 0x00000200 Covering index decisions -** 0x00000400 OR optimization -** 0x00000800 Index scanner -** 0x00001000 More details associated with code generation -** 0x00002000 -** 0x00004000 Show all WHERE terms at key points -** 0x00008000 Show the full SELECT statement at key places -** -** 0x00010000 Show more detail when printing WHERE terms -** 0x00020000 Show WHERE terms returned from whereScanNext() -*/ - /* ** An instance of the following structure is used to store the busy-handler ** callback for a given sqlite handle. ** @@ -14810,11 +14630,10 @@ typedef struct FuncDestructor FuncDestructor; typedef struct FuncDef FuncDef; typedef struct FuncDefHash FuncDefHash; typedef struct IdList IdList; typedef struct Index Index; -typedef struct IndexedExpr IndexedExpr; typedef struct IndexSample IndexSample; typedef struct KeyClass KeyClass; typedef struct KeyInfo KeyInfo; typedef struct Lookaside Lookaside; typedef struct LookasideSlot LookasideSlot; @@ -14876,11 +14695,10 @@ #define MASKBIT(n) (((Bitmask)1)<<(n)) #define MASKBIT64(n) (((u64)1)<<(n)) #define MASKBIT32(n) (((unsigned int)1)<<(n)) #define SMASKBIT32(n) ((n)<=31?((unsigned int)1)<<(n):0) #define ALLBITS ((Bitmask)-1) -#define TOPBIT (((Bitmask)1)<<(BMS-1)) /* A VList object records a mapping between parameters/variables/wildcards ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer ** variable number associated with that parameter. See the format description ** on the sqlite3VListAdd() routine for more information. A VList is really @@ -14891,335 +14709,10 @@ /* ** Defer sourcing vdbe.h and btree.h until after the "u8" and ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque ** pointer types (i.e. FuncDef) defined above. */ -/************** Include os.h in the middle of sqliteInt.h ********************/ -/************** Begin file os.h **********************************************/ -/* -** 2001 September 16 -** -** 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 (together with is companion C source-code file -** "os.c") attempt to abstract the underlying operating system so that -** the SQLite library will work on both POSIX and windows systems. -** -** This header file is #include-ed by sqliteInt.h and thus ends up -** being included by every source file. -*/ -#ifndef _SQLITE_OS_H_ -#define _SQLITE_OS_H_ - -/* -** Attempt to automatically detect the operating system and setup the -** necessary pre-processor macros for it. -*/ -/************** Include os_setup.h in the middle of os.h *********************/ -/************** Begin file os_setup.h ****************************************/ -/* -** 2013 November 25 -** -** 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 file contains pre-processor directives related to operating system -** detection and/or setup. -*/ -#ifndef SQLITE_OS_SETUP_H -#define SQLITE_OS_SETUP_H - -/* -** Figure out if we are dealing with Unix, Windows, or some other operating -** system. -** -** After the following block of preprocess macros, all of -** -** SQLITE_OS_KV -** SQLITE_OS_OTHER -** SQLITE_OS_UNIX -** SQLITE_OS_WIN -** -** will defined to either 1 or 0. One of them will be 1. The others will be 0. -** If none of the macros are initially defined, then select either -** SQLITE_OS_UNIX or SQLITE_OS_WIN depending on the target platform. -** -** If SQLITE_OS_OTHER=1 is specified at compile-time, then the application -** must provide its own VFS implementation together with sqlite3_os_init() -** and sqlite3_os_end() routines. -*/ -#if !defined(SQLITE_OS_KV) && !defined(SQLITE_OS_OTHER) && \ - !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_WIN) -# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ - defined(__MINGW32__) || defined(__BORLANDC__) -# define SQLITE_OS_WIN 1 -# define SQLITE_OS_UNIX 0 -# else -# define SQLITE_OS_WIN 0 -# define SQLITE_OS_UNIX 1 -# endif -#endif -#if SQLITE_OS_OTHER+1>1 -# undef SQLITE_OS_KV -# define SQLITE_OS_KV 0 -# undef SQLITE_OS_UNIX -# define SQLITE_OS_UNIX 0 -# undef SQLITE_OS_WIN -# define SQLITE_OS_WIN 0 -#endif -#if SQLITE_OS_KV+1>1 -# undef SQLITE_OS_OTHER -# define SQLITE_OS_OTHER 0 -# undef SQLITE_OS_UNIX -# define SQLITE_OS_UNIX 0 -# undef SQLITE_OS_WIN -# define SQLITE_OS_WIN 0 -# define SQLITE_OMIT_LOAD_EXTENSION 1 -# define SQLITE_OMIT_WAL 1 -# define SQLITE_OMIT_DEPRECATED 1 -# undef SQLITE_TEMP_STORE -# define SQLITE_TEMP_STORE 3 /* Always use memory for temporary storage */ -# define SQLITE_DQS 0 -# define SQLITE_OMIT_SHARED_CACHE 1 -# define SQLITE_OMIT_AUTOINIT 1 -#endif -#if SQLITE_OS_UNIX+1>1 -# undef SQLITE_OS_KV -# define SQLITE_OS_KV 0 -# undef SQLITE_OS_OTHER -# define SQLITE_OS_OTHER 0 -# undef SQLITE_OS_WIN -# define SQLITE_OS_WIN 0 -#endif -#if SQLITE_OS_WIN+1>1 -# undef SQLITE_OS_KV -# define SQLITE_OS_KV 0 -# undef SQLITE_OS_OTHER -# define SQLITE_OS_OTHER 0 -# undef SQLITE_OS_UNIX -# define SQLITE_OS_UNIX 0 -#endif - - -#endif /* SQLITE_OS_SETUP_H */ - -/************** End of os_setup.h ********************************************/ -/************** Continuing where we left off in os.h *************************/ - -/* If the SET_FULLSYNC macro is not defined above, then make it -** a no-op -*/ -#ifndef SET_FULLSYNC -# define SET_FULLSYNC(x,y) -#endif - -/* Maximum pathname length. Note: FILENAME_MAX defined by stdio.h -*/ -#ifndef SQLITE_MAX_PATHLEN -# define SQLITE_MAX_PATHLEN FILENAME_MAX -#endif - -/* Maximum number of symlinks that will be resolved while trying to -** expand a filename in xFullPathname() in the VFS. -*/ -#ifndef SQLITE_MAX_SYMLINK -# define SQLITE_MAX_SYMLINK 200 -#endif - -/* -** The default size of a disk sector -*/ -#ifndef SQLITE_DEFAULT_SECTOR_SIZE -# define SQLITE_DEFAULT_SECTOR_SIZE 4096 -#endif - -/* -** Temporary files are named starting with this prefix followed by 16 random -** alphanumeric characters, and no file extension. They are stored in the -** OS's standard temporary file directory, and are deleted prior to exit. -** If sqlite is being embedded in another program, you may wish to change the -** prefix to reflect your program's name, so that if your program exits -** prematurely, old temporary files can be easily identified. This can be done -** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line. -** -** 2006-10-31: The default prefix used to be "sqlite_". But then -** Mcafee started using SQLite in their anti-virus product and it -** started putting files with the "sqlite" name in the c:/temp folder. -** This annoyed many windows users. Those users would then do a -** Google search for "sqlite", find the telephone numbers of the -** developers and call to wake them up at night and complain. -** For this reason, the default name prefix is changed to be "sqlite" -** spelled backwards. So the temp files are still identified, but -** anybody smart enough to figure out the code is also likely smart -** enough to know that calling the developer will not help get rid -** of the file. -*/ -#ifndef SQLITE_TEMP_FILE_PREFIX -# define SQLITE_TEMP_FILE_PREFIX "etilqs_" -#endif - -/* -** The following values may be passed as the second argument to -** sqlite3OsLock(). The various locks exhibit the following semantics: -** -** SHARED: Any number of processes may hold a SHARED lock simultaneously. -** RESERVED: A single process may hold a RESERVED lock on a file at -** any time. Other processes may hold and obtain new SHARED locks. -** PENDING: A single process may hold a PENDING lock on a file at -** any one time. Existing SHARED locks may persist, but no new -** SHARED locks may be obtained by other processes. -** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. -** -** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a -** process that requests an EXCLUSIVE lock may actually obtain a PENDING -** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to -** sqlite3OsLock(). -*/ -#define NO_LOCK 0 -#define SHARED_LOCK 1 -#define RESERVED_LOCK 2 -#define PENDING_LOCK 3 -#define EXCLUSIVE_LOCK 4 - -/* -** File Locking Notes: (Mostly about windows but also some info for Unix) -** -** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because -** those functions are not available. So we use only LockFile() and -** UnlockFile(). -** -** LockFile() prevents not just writing but also reading by other processes. -** A SHARED_LOCK is obtained by locking a single randomly-chosen -** byte out of a specific range of bytes. The lock byte is obtained at -** random so two separate readers can probably access the file at the -** same time, unless they are unlucky and choose the same lock byte. -** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range. -** There can only be one writer. A RESERVED_LOCK is obtained by locking -** a single byte of the file that is designated as the reserved lock byte. -** A PENDING_LOCK is obtained by locking a designated byte different from -** the RESERVED_LOCK byte. -** -** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, -** which means we can use reader/writer locks. When reader/writer locks -** are used, the lock is placed on the same range of bytes that is used -** for probabilistic locking in Win95/98/ME. Hence, the locking scheme -** will support two or more Win95 readers or two or more WinNT readers. -** But a single Win95 reader will lock out all WinNT readers and a single -** WinNT reader will lock out all other Win95 readers. -** -** The following #defines specify the range of bytes used for locking. -** SHARED_SIZE is the number of bytes available in the pool from which -** a random byte is selected for a shared lock. The pool of bytes for -** shared locks begins at SHARED_FIRST. -** -** The same locking strategy and -** byte ranges are used for Unix. This leaves open the possibility of having -** clients on win95, winNT, and unix all talking to the same shared file -** and all locking correctly. To do so would require that samba (or whatever -** tool is being used for file sharing) implements locks correctly between -** windows and unix. I'm guessing that isn't likely to happen, but by -** using the same locking range we are at least open to the possibility. -** -** Locking in windows is manditory. For this reason, we cannot store -** actual data in the bytes used for locking. The pager never allocates -** the pages involved in locking therefore. SHARED_SIZE is selected so -** that all locks will fit on a single page even at the minimum page size. -** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE -** is set high so that we don't have to allocate an unused page except -** for very large databases. But one should test the page skipping logic -** by setting PENDING_BYTE low and running the entire regression suite. -** -** Changing the value of PENDING_BYTE results in a subtly incompatible -** file format. Depending on how it is changed, you might not notice -** the incompatibility right away, even running a full regression test. -** The default location of PENDING_BYTE is the first byte past the -** 1GB boundary. -** -*/ -#ifdef SQLITE_OMIT_WSD -# define PENDING_BYTE (0x40000000) -#else -# define PENDING_BYTE sqlite3PendingByte -#endif -#define RESERVED_BYTE (PENDING_BYTE+1) -#define SHARED_FIRST (PENDING_BYTE+2) -#define SHARED_SIZE 510 - -/* -** Wrapper around OS specific sqlite3_os_init() function. -*/ -SQLITE_PRIVATE int sqlite3OsInit(void); - -/* -** Functions for accessing sqlite3_file methods -*/ -SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file*); -SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); -SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); -SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size); -SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int); -SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); -SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int); -SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int); -SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); -SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*); -SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*); -#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 -SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); -SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); -#ifndef SQLITE_OMIT_WAL -SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); -SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); -SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); -SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); -#endif /* SQLITE_OMIT_WAL */ -SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); -SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *); - - -/* -** Functions for accessing sqlite3_vfs methods -*/ -SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); -SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int); -SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut); -SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); -#ifndef SQLITE_OMIT_LOAD_EXTENSION -SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); -SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *); -SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); -SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); -#endif /* SQLITE_OMIT_LOAD_EXTENSION */ -SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); -SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); -SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*); -SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); - -/* -** Convenience functions for opening and closing files using -** sqlite3_malloc() to obtain space for the file-handle structure. -*/ -SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); -SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *); - -#endif /* _SQLITE_OS_H_ */ - -/************** End of os.h **************************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ /************** Include pager.h in the middle of sqliteInt.h *****************/ /************** Begin file pager.h *******************************************/ /* ** 2001 September 15 ** @@ -15651,11 +15144,11 @@ ** to prefetch content from remote machines - to provide those ** implementations with limits on what needs to be prefetched and thereby ** reduce network bandwidth. ** ** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by -** standard SQLite. The other hints are provided for extensions that use +** standard SQLite. The other hints are provided for extentions that use ** the SQLite parser and code generator but substitute their own storage ** engine. */ #define BTREE_HINT_RANGE 0 /* Range constraints on queries */ @@ -15797,19 +15290,11 @@ SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*); SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*); -SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( - sqlite3 *db, /* Database connection that is running the check */ - Btree *p, /* The btree to be checked */ - Pgno *aRoot, /* An array of root pages numbers for individual trees */ - int nRoot, /* Number of entries in aRoot[] */ - int mxErr, /* Stop reporting errors after this many */ - int *pnErr, /* OUT: Write number of errors seen to this variable */ - char **pzOut /* OUT: Write the error message string here */ -); +SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,Pgno*aRoot,int nRoot,int,int*); SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor*); #ifndef SQLITE_OMIT_INCRBLOB SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*); @@ -15844,12 +15329,10 @@ SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); #endif SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor*, BtCursor*, i64); -SQLITE_PRIVATE void sqlite3BtreeClearCache(Btree*); - /* ** If we are not using shared cache, then there is no need to ** use mutexes to access the BtShared structures. So make the ** Enter and Leave procedures no-ops. */ @@ -15962,18 +15445,18 @@ #endif } p4; #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS char *zComment; /* Comment to improve readability */ #endif +#ifdef VDBE_PROFILE + u32 cnt; /* Number of times this instruction was executed */ + u64 cycles; /* Total time spent executing this instruction */ +#endif #ifdef SQLITE_VDBE_COVERAGE u32 iSrcLine; /* Source-code line that generated this opcode ** with flags in the upper 8 bits */ #endif -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) - u64 nExec; - u64 nCycle; -#endif }; typedef struct VdbeOp VdbeOp; /* @@ -16070,67 +15553,67 @@ #define OP_Checkpoint 3 #define OP_JournalMode 4 #define OP_Vacuum 5 #define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */ #define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */ -#define OP_Init 8 /* jump, synopsis: Start at P2 */ -#define OP_Goto 9 /* jump */ -#define OP_Gosub 10 /* jump */ -#define OP_InitCoroutine 11 /* jump */ -#define OP_Yield 12 /* jump */ -#define OP_MustBeInt 13 /* jump */ -#define OP_Jump 14 /* jump */ -#define OP_Once 15 /* jump */ -#define OP_If 16 /* jump */ -#define OP_IfNot 17 /* jump */ -#define OP_IsType 18 /* jump, synopsis: if typeof(P1.P3) in P5 goto P2 */ +#define OP_Goto 8 /* jump */ +#define OP_Gosub 9 /* jump */ +#define OP_InitCoroutine 10 /* jump */ +#define OP_Yield 11 /* jump */ +#define OP_MustBeInt 12 /* jump */ +#define OP_Jump 13 /* jump */ +#define OP_Once 14 /* jump */ +#define OP_If 15 /* jump */ +#define OP_IfNot 16 /* jump */ +#define OP_IsNullOrType 17 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */ +#define OP_IfNullRow 18 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ -#define OP_IfNullRow 20 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ -#define OP_SeekLT 21 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekLE 22 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekGE 23 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekGT 24 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IfNotOpen 25 /* jump, synopsis: if( !csr[P1] ) goto P2 */ -#define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */ -#define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */ -#define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */ -#define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekRowid 30 /* jump, synopsis: intkey=r[P3] */ -#define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */ -#define OP_Last 32 /* jump */ -#define OP_IfSmaller 33 /* jump */ -#define OP_SorterSort 34 /* jump */ -#define OP_Sort 35 /* jump */ -#define OP_Rewind 36 /* jump */ -#define OP_SorterNext 37 /* jump */ -#define OP_Prev 38 /* jump */ -#define OP_Next 39 /* jump */ -#define OP_IdxLE 40 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IdxGT 41 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IdxLT 42 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekLT 20 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekLE 21 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekGE 22 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekGT 23 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IfNotOpen 24 /* jump, synopsis: if( !csr[P1] ) goto P2 */ +#define OP_IfNoHope 25 /* jump, synopsis: key=r[P3@P4] */ +#define OP_NoConflict 26 /* jump, synopsis: key=r[P3@P4] */ +#define OP_NotFound 27 /* jump, synopsis: key=r[P3@P4] */ +#define OP_Found 28 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekRowid 29 /* jump, synopsis: intkey=r[P3] */ +#define OP_NotExists 30 /* jump, synopsis: intkey=r[P3] */ +#define OP_Last 31 /* jump */ +#define OP_IfSmaller 32 /* jump */ +#define OP_SorterSort 33 /* jump */ +#define OP_Sort 34 /* jump */ +#define OP_Rewind 35 /* jump */ +#define OP_SorterNext 36 /* jump */ +#define OP_Prev 37 /* jump */ +#define OP_Next 38 /* jump */ +#define OP_IdxLE 39 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxGT 40 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxLT 41 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxGE 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_Program 48 /* jump */ -#define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ +#define OP_RowSetRead 45 /* jump, synopsis: r[P3]=rowset(P1) */ +#define OP_RowSetTest 46 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ +#define OP_Program 47 /* jump */ +#define OP_FkIfZero 48 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ +#define OP_IfPos 49 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, 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_IncrVacuum 62 /* jump */ -#define OP_VNext 63 /* jump */ -#define OP_Filter 64 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ +#define OP_IfNotZero 59 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ +#define OP_DecrJumpZero 60 /* jump, synopsis: if (--r[P1])==0 goto P2 */ +#define OP_IncrVacuum 61 /* jump */ +#define OP_VNext 62 /* jump */ +#define OP_Filter 63 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ +#define OP_Init 64 /* jump, synopsis: Start at P2 */ #define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */ #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */ #define OP_Return 67 #define OP_EndCoroutine 68 #define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */ @@ -16260,34 +15743,33 @@ #define OPFLG_IN1 0x02 /* in1: P1 is an input */ #define OPFLG_IN2 0x04 /* in2: P2 is an input */ #define OPFLG_IN3 0x08 /* in3: P3 is an input */ #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ -#define OPFLG_NCYCLE 0x40 /* ncycle:Cycles count against P1 */ #define OPFLG_INITIALIZER {\ -/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\ -/* 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, 0x01, 0x01, 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,\ +/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\ +/* 8 */ 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03,\ +/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x09, 0x09, 0x09, 0x09,\ +/* 24 */ 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01,\ +/* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ +/* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\ +/* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ +/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\ /* 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,\ +/* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00,\ +/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 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, 0x00, 0x00, 0x50,\ -/* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\ +/* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\ +/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\ +/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ +/* 136 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\ /* 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, 0x50, 0x40,\ +/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\ /* 176 */ 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00,\ /* 184 */ 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 @@ -16338,24 +15820,18 @@ # define sqlite3VdbeVerifyAbortable(A,B) # define sqlite3VdbeNoJumpsOutsideSubrtn(A,B,C,D) #endif SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno); #ifndef SQLITE_OMIT_EXPLAIN -SQLITE_PRIVATE int sqlite3VdbeExplain(Parse*,u8,const char*,...); +SQLITE_PRIVATE void sqlite3VdbeExplain(Parse*,u8,const char*,...); SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse*); SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse*); # define ExplainQueryPlan(P) sqlite3VdbeExplain P -# ifdef SQLITE_ENABLE_STMT_SCANSTATUS -# define ExplainQueryPlan2(V,P) (V = sqlite3VdbeExplain P) -# else -# define ExplainQueryPlan2(V,P) ExplainQueryPlan(P) -# endif # define ExplainQueryPlanPop(P) sqlite3VdbeExplainPop(P) # define ExplainQueryPlanParent(P) sqlite3VdbeExplainParent(P) #else # define ExplainQueryPlan(P) -# define ExplainQueryPlan2(V,P) # define ExplainQueryPlanPop(P) # define ExplainQueryPlanParent(P) 0 # define sqlite3ExplainBreakpoint(A,B) /*no-op*/ #endif #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) @@ -16367,11 +15843,10 @@ SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8); SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1); SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3); SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u16 P5); -SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe*, int); SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr); SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr); SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe*, int addr); SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); #ifdef SQLITE_DEBUG @@ -16382,11 +15857,10 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type); SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); -SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetLastOp(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*); SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); @@ -16524,16 +15998,12 @@ # define VDBE_OFFSET_LINENO(x) 0 #endif #ifdef SQLITE_ENABLE_STMT_SCANSTATUS SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*); -SQLITE_PRIVATE void sqlite3VdbeScanStatusRange(Vdbe*, int, int, int); -SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters(Vdbe*, int, int, int); #else -# define sqlite3VdbeScanStatus(a,b,c,d,e,f) -# define sqlite3VdbeScanStatusRange(a,b,c,d) -# define sqlite3VdbeScanStatusCounters(a,b,c,d) +# define sqlite3VdbeScanStatus(a,b,c,d,e) #endif #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); #endif @@ -16734,10 +16204,301 @@ #endif #endif /* _PCACHE_H_ */ /************** End of pcache.h **********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include os.h in the middle of sqliteInt.h ********************/ +/************** Begin file os.h **********************************************/ +/* +** 2001 September 16 +** +** 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 (together with is companion C source-code file +** "os.c") attempt to abstract the underlying operating system so that +** the SQLite library will work on both POSIX and windows systems. +** +** This header file is #include-ed by sqliteInt.h and thus ends up +** being included by every source file. +*/ +#ifndef _SQLITE_OS_H_ +#define _SQLITE_OS_H_ + +/* +** Attempt to automatically detect the operating system and setup the +** necessary pre-processor macros for it. +*/ +/************** Include os_setup.h in the middle of os.h *********************/ +/************** Begin file os_setup.h ****************************************/ +/* +** 2013 November 25 +** +** 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 file contains pre-processor directives related to operating system +** detection and/or setup. +*/ +#ifndef SQLITE_OS_SETUP_H +#define SQLITE_OS_SETUP_H + +/* +** Figure out if we are dealing with Unix, Windows, or some other operating +** system. +** +** After the following block of preprocess macros, all of SQLITE_OS_UNIX, +** SQLITE_OS_WIN, and SQLITE_OS_OTHER will defined to either 1 or 0. One of +** the three will be 1. The other two will be 0. +*/ +#if defined(SQLITE_OS_OTHER) +# if SQLITE_OS_OTHER==1 +# undef SQLITE_OS_UNIX +# define SQLITE_OS_UNIX 0 +# undef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# else +# undef SQLITE_OS_OTHER +# endif +#endif +#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) +# define SQLITE_OS_OTHER 0 +# ifndef SQLITE_OS_WIN +# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ + defined(__MINGW32__) || defined(__BORLANDC__) +# define SQLITE_OS_WIN 1 +# define SQLITE_OS_UNIX 0 +# else +# define SQLITE_OS_WIN 0 +# define SQLITE_OS_UNIX 1 +# endif +# else +# define SQLITE_OS_UNIX 0 +# endif +#else +# ifndef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# endif +#endif + +#endif /* SQLITE_OS_SETUP_H */ + +/************** End of os_setup.h ********************************************/ +/************** Continuing where we left off in os.h *************************/ + +/* If the SET_FULLSYNC macro is not defined above, then make it +** a no-op +*/ +#ifndef SET_FULLSYNC +# define SET_FULLSYNC(x,y) +#endif + +/* Maximum pathname length. Note: FILENAME_MAX defined by stdio.h +*/ +#ifndef SQLITE_MAX_PATHLEN +# define SQLITE_MAX_PATHLEN FILENAME_MAX +#endif + +/* Maximum number of symlinks that will be resolved while trying to +** expand a filename in xFullPathname() in the VFS. +*/ +#ifndef SQLITE_MAX_SYMLINK +# define SQLITE_MAX_SYMLINK 200 +#endif + +/* +** The default size of a disk sector +*/ +#ifndef SQLITE_DEFAULT_SECTOR_SIZE +# define SQLITE_DEFAULT_SECTOR_SIZE 4096 +#endif + +/* +** Temporary files are named starting with this prefix followed by 16 random +** alphanumeric characters, and no file extension. They are stored in the +** OS's standard temporary file directory, and are deleted prior to exit. +** If sqlite is being embedded in another program, you may wish to change the +** prefix to reflect your program's name, so that if your program exits +** prematurely, old temporary files can be easily identified. This can be done +** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line. +** +** 2006-10-31: The default prefix used to be "sqlite_". But then +** Mcafee started using SQLite in their anti-virus product and it +** started putting files with the "sqlite" name in the c:/temp folder. +** This annoyed many windows users. Those users would then do a +** Google search for "sqlite", find the telephone numbers of the +** developers and call to wake them up at night and complain. +** For this reason, the default name prefix is changed to be "sqlite" +** spelled backwards. So the temp files are still identified, but +** anybody smart enough to figure out the code is also likely smart +** enough to know that calling the developer will not help get rid +** of the file. +*/ +#ifndef SQLITE_TEMP_FILE_PREFIX +# define SQLITE_TEMP_FILE_PREFIX "etilqs_" +#endif + +/* +** The following values may be passed as the second argument to +** sqlite3OsLock(). The various locks exhibit the following semantics: +** +** SHARED: Any number of processes may hold a SHARED lock simultaneously. +** RESERVED: A single process may hold a RESERVED lock on a file at +** any time. Other processes may hold and obtain new SHARED locks. +** PENDING: A single process may hold a PENDING lock on a file at +** any one time. Existing SHARED locks may persist, but no new +** SHARED locks may be obtained by other processes. +** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. +** +** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a +** process that requests an EXCLUSIVE lock may actually obtain a PENDING +** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to +** sqlite3OsLock(). +*/ +#define NO_LOCK 0 +#define SHARED_LOCK 1 +#define RESERVED_LOCK 2 +#define PENDING_LOCK 3 +#define EXCLUSIVE_LOCK 4 + +/* +** File Locking Notes: (Mostly about windows but also some info for Unix) +** +** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because +** those functions are not available. So we use only LockFile() and +** UnlockFile(). +** +** LockFile() prevents not just writing but also reading by other processes. +** A SHARED_LOCK is obtained by locking a single randomly-chosen +** byte out of a specific range of bytes. The lock byte is obtained at +** random so two separate readers can probably access the file at the +** same time, unless they are unlucky and choose the same lock byte. +** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range. +** There can only be one writer. A RESERVED_LOCK is obtained by locking +** a single byte of the file that is designated as the reserved lock byte. +** A PENDING_LOCK is obtained by locking a designated byte different from +** the RESERVED_LOCK byte. +** +** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, +** which means we can use reader/writer locks. When reader/writer locks +** are used, the lock is placed on the same range of bytes that is used +** for probabilistic locking in Win95/98/ME. Hence, the locking scheme +** will support two or more Win95 readers or two or more WinNT readers. +** But a single Win95 reader will lock out all WinNT readers and a single +** WinNT reader will lock out all other Win95 readers. +** +** The following #defines specify the range of bytes used for locking. +** SHARED_SIZE is the number of bytes available in the pool from which +** a random byte is selected for a shared lock. The pool of bytes for +** shared locks begins at SHARED_FIRST. +** +** The same locking strategy and +** byte ranges are used for Unix. This leaves open the possibility of having +** clients on win95, winNT, and unix all talking to the same shared file +** and all locking correctly. To do so would require that samba (or whatever +** tool is being used for file sharing) implements locks correctly between +** windows and unix. I'm guessing that isn't likely to happen, but by +** using the same locking range we are at least open to the possibility. +** +** Locking in windows is manditory. For this reason, we cannot store +** actual data in the bytes used for locking. The pager never allocates +** the pages involved in locking therefore. SHARED_SIZE is selected so +** that all locks will fit on a single page even at the minimum page size. +** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE +** is set high so that we don't have to allocate an unused page except +** for very large databases. But one should test the page skipping logic +** by setting PENDING_BYTE low and running the entire regression suite. +** +** Changing the value of PENDING_BYTE results in a subtly incompatible +** file format. Depending on how it is changed, you might not notice +** the incompatibility right away, even running a full regression test. +** The default location of PENDING_BYTE is the first byte past the +** 1GB boundary. +** +*/ +#ifdef SQLITE_OMIT_WSD +# define PENDING_BYTE (0x40000000) +#else +# define PENDING_BYTE sqlite3PendingByte +#endif +#define RESERVED_BYTE (PENDING_BYTE+1) +#define SHARED_FIRST (PENDING_BYTE+2) +#define SHARED_SIZE 510 + +/* +** Wrapper around OS specific sqlite3_os_init() function. +*/ +SQLITE_PRIVATE int sqlite3OsInit(void); + +/* +** Functions for accessing sqlite3_file methods +*/ +SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file*); +SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); +SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); +SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size); +SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); +SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); +SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*); +SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*); +#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 +SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); +SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); +SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); +#endif /* SQLITE_OMIT_WAL */ +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *); + + +/* +** Functions for accessing sqlite3_vfs methods +*/ +SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); +SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int); +SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut); +SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); +#ifndef SQLITE_OMIT_LOAD_EXTENSION +SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); +SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *); +SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); +SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ +SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); +SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); +SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*); +SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); + +/* +** Convenience functions for opening and closing files using +** sqlite3_malloc() to obtain space for the file-handle structure. +*/ +SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); +SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *); + +#endif /* _SQLITE_OS_H_ */ + +/************** End of os.h **************************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ /************** Include mutex.h in the middle of sqliteInt.h *****************/ /************** Begin file mutex.h *******************************************/ /* ** 2007 August 28 @@ -16980,11 +16741,10 @@ void *pMiddle; /* First byte past end of full-size buffers and ** the first byte of LOOKASIDE_SMALL buffers */ #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ void *pStart; /* First byte of available memory space */ void *pEnd; /* First byte past end of available space */ - void *pTrueEnd; /* True value of pEnd, when db->pnBytesFreed!=0 */ }; struct LookasideSlot { LookasideSlot *pNext; /* Next buffer in the list of free buffers */ }; @@ -17325,12 +17085,10 @@ #define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */ #define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */ #define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ -#define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ -#define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. */ @@ -17411,18 +17169,12 @@ ** SQLITE_FUNC_ANYORDER == NC_OrderAgg == SF_OrderByReqd ** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG ** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG ** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API ** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API -** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS -- opposite meanings!!! +** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS ** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API -** -** 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 tha the function has side effects. -** SQLITE_INNOCUOUS is used by application code and means "not unsafe". -** See multiple instances of tag-20230109-1. */ #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ #define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */ #define SQLITE_FUNC_CASE 0x0008 /* Case-sensitive LIKE-type function */ #define SQLITE_FUNC_EPHEM 0x0010 /* Ephemeral. Delete with VDBE */ @@ -17535,11 +17287,11 @@ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #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, iArg, xFunc) \ - {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|\ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS|\ 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|\ SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ @@ -17727,11 +17479,10 @@ #define SQLITE_AFF_BLOB 0x41 /* 'A' */ #define SQLITE_AFF_TEXT 0x42 /* 'B' */ #define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ #define SQLITE_AFF_REAL 0x45 /* 'E' */ -#define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) /* ** The SQLITE_AFF_MASK values masks off the significant bits of an @@ -17906,11 +17657,11 @@ ** table support is omitted from the build. */ #ifndef SQLITE_OMIT_VIRTUALTABLE # define IsVirtual(X) ((X)->eTabType==TABTYP_VTAB) # define ExprIsVtab(X) \ - ((X)->op==TK_COLUMN && (X)->y.pTab->eTabType==TABTYP_VTAB) + ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->eTabType==TABTYP_VTAB) #else # define IsVirtual(X) 0 # define ExprIsVtab(X) 0 #endif @@ -18123,26 +17874,14 @@ ** Ex1.aCol[], hence Ex2.aiColumn[1]==0. ** ** The Index.onError field determines whether or not the indexed columns ** must be unique and what to do if they are not. When Index.onError=OE_None, ** it means this is not a unique index. Otherwise it is a unique index -** and the value of Index.onError indicates which conflict resolution -** algorithm to employ when an attempt is made to insert a non-unique +** and the value of Index.onError indicate the which conflict resolution +** algorithm to employ whenever an attempt is made to insert a non-unique ** element. ** -** The colNotIdxed bitmask is used in combination with SrcItem.colUsed -** for a fast test to see if an index can serve as a covering index. -** colNotIdxed has a 1 bit for every column of the original table that -** is *not* available in the index. Thus the expression -** "colUsed & colNotIdxed" will be non-zero if the index is not a -** covering index. The most significant bit of of colNotIdxed will always -** be true (note-20221022-a). If a column beyond the 63rd column of the -** table is used, the "colUsed & colNotIdxed" test will always be non-zero -** and we have to assume either that the index is not covering, or use -** an alternative (slower) algorithm to determine whether or not -** the index is covering. -** ** While parsing a CREATE TABLE or CREATE INDEX statement in order to ** generate VDBE code (as opposed to parsing one read from an sqlite_schema ** table as part of parsing an existing database schema), transient instances ** of this structure may be created. In this case the Index.tnum variable is ** used to store the address of a VDBE instruction, not a database page @@ -18174,21 +17913,19 @@ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ - unsigned bHasExpr:1; /* Index contains an expression, either a literal - ** expression, or a reference to a VIRTUAL column */ #ifdef SQLITE_ENABLE_STAT4 int nSample; /* Number of elements in aSample[] */ int nSampleCol; /* Size of IndexSample.anEq[] and so on */ tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ IndexSample *aSample; /* Samples of the left-most key */ tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */ tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */ #endif - Bitmask colNotIdxed; /* Unindexed columns in pTab */ + Bitmask colNotIdxed; /* 0 for unindexed columns in pTab */ }; /* ** Allowed values for Index.idxType */ @@ -18259,19 +17996,20 @@ struct AggInfo { u8 directMode; /* Direct rendering mode means take data directly ** from source tables rather than from accumulators */ u8 useSortingIdx; /* In direct mode, reference the sorting index rather ** than the source table */ - u16 nSortingColumn; /* Number of columns in the sorting index */ int sortingIdx; /* Cursor number of the sorting index */ int sortingIdxPTab; /* Cursor number of pseudo-table */ - int iFirstReg; /* First register in range for aCol[] and aFunc[] */ + int nSortingColumn; /* Number of columns in the sorting index */ + int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */ ExprList *pGroupBy; /* The group by clause */ struct AggInfo_col { /* For each column used in source tables */ Table *pTab; /* Source table */ Expr *pCExpr; /* The original expression */ int iTable; /* Cursor number of the source table */ + int iMem; /* Memory location that acts as accumulator */ i16 iColumn; /* Column number within the source table */ i16 iSorterColumn; /* Column number in the sorting index */ } *aCol; int nColumn; /* Number of used entries in aCol[] */ int nAccumulator; /* Number of columns that show through to the output. @@ -18278,31 +18016,18 @@ ** Additional columns are used only as parameters to ** aggregate functions */ struct AggInfo_func { /* For each aggregate function */ Expr *pFExpr; /* Expression encoding the function */ FuncDef *pFunc; /* The aggregate function implementation */ + int iMem; /* Memory location that acts as accumulator */ int iDistinct; /* Ephemeral table used to enforce DISTINCT */ int iDistAddr; /* Address of OP_OpenEphemeral */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ -#ifdef SQLITE_DEBUG - Select *pSelect; /* SELECT statement that this AggInfo supports */ -#endif }; -/* -** Macros to compute aCol[] and aFunc[] register numbers. -** -** These macros should not be used prior to the call to -** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. -** The assert()s that are part of this macro verify that constraint. -*/ -#define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I)) -#define AggInfoFuncReg(A,I) \ - (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I)) - /* ** The datatype ynVar is a signed integer, either 16-bit or 32-bit. ** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater ** than 32767 we have to make it 32-bit. 16-bit is preferred because ** it uses less memory in the Expr object, which is a big memory user @@ -18464,11 +18189,11 @@ #define EP_xIsSelect 0x001000 /* x.pSelect is valid (otherwise x.pList is) */ #define EP_Skip 0x002000 /* Operator does not contribute to affinity */ #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 */ - /* 0x020000 // Available for reuse */ +#define EP_MemToken 0x020000 /* Need to sqlite3DbFree() Expr.zToken */ #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 */ #define EP_CanBeNull 0x200000 /* Can be null despite NOT NULL constraint */ #define EP_Subquery 0x400000 /* Tree contains a TK_SELECT operator */ @@ -18649,18 +18374,10 @@ /* ** The SrcItem object represents a single term in the FROM clause of a query. ** The SrcList object is mostly an array of SrcItems. ** -** The jointype starts out showing the join type between the current table -** and the next table on the list. The parser builds the list this way. -** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each -** jointype expresses the join between the table and the previous table. -** -** In the colUsed field, the high-order bit (bit 63) is set if the table -** contains more than 63 columns and the 64-th or later column is used. -** ** Union member validity: ** ** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc ** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy ** u2.pIBIndex fg.isIndexedBy && !fg.isCte @@ -18696,18 +18413,18 @@ int iCursor; /* The VDBE cursor number used to access this table */ union { Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ } u3; - Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */ + Bitmask colUsed; /* Bit N (1<" clause */ ExprList *pFuncArg; /* Arguments to table-valued-function */ } u1; union { Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ - CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */ + CteUse *pCteUse; /* CTE Usage info info fg.isCte is true */ } u2; }; /* ** The OnOrUsing object represents either an ON clause or a USING clause. @@ -18717,15 +18434,27 @@ Expr *pOn; /* The ON clause of a join */ IdList *pUsing; /* The USING clause of a join */ }; /* -** This object represents one or more tables that are the source of -** content for an SQL statement. For example, a single SrcList object -** is used to hold the FROM clause of a SELECT statement. SrcList also -** represents the target tables for DELETE, INSERT, and UPDATE statements. +** The following structure describes the FROM clause of a SELECT statement. +** Each table or subquery in the FROM clause is a separate element of +** the SrcList.a[] array. ** +** With the addition of multiple database support, the following structure +** can also be used to describe a particular table such as the table that +** is modified by an INSERT, DELETE, or UPDATE statement. In standard SQL, +** such a table must be a simple name: ID. But in SQLite, the table can +** now be identified by a database name, a dot, then the table name: ID.ID. +** +** The jointype starts out showing the join type between the current table +** and the next table on the list. The parser builds the list this way. +** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each +** jointype expresses the join between the table and the previous table. +** +** In the colUsed field, the high-order bit (bit 63) is set if the table +** contains more than 63 columns and the 64-th or later column is used. */ struct SrcList { int nSrc; /* Number of tables or subqueries in the FROM clause */ u32 nAlloc; /* Number of entries allocated in a[] below */ SrcItem a[1]; /* One entry for each identifier on the list */ @@ -18958,11 +18687,10 @@ #define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */ #define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ -#define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ /* True if S exists and has SF_NestedFrom */ #define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0) /* @@ -19067,11 +18795,11 @@ u8 eDest; /* How to dispose of the results. One of SRT_* above. */ int iSDParm; /* A parameter used by the eDest disposal method */ int iSDParm2; /* A second parameter for the eDest disposal method */ int iSdst; /* Base register where results are written */ int nSdst; /* Number of registers allocated */ - char *zAffSdst; /* Affinity used for SRT_Set */ + char *zAffSdst; /* Affinity used when eDest==SRT_Set */ ExprList *pOrderBy; /* Key columns for SRT_Queue and SRT_DistQueue */ }; /* ** During code generation of statements that do inserts into AUTOINCREMENT @@ -19126,37 +18854,15 @@ # define DbMaskAllZero(M) sqlite3DbMaskAllZero(M) # define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0) #else typedef unsigned int yDbMask; # define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) -# define DbMaskZero(M) ((M)=0) -# define DbMaskSet(M,I) ((M)|=(((yDbMask)1)<<(I))) -# define DbMaskAllZero(M) ((M)==0) -# define DbMaskNonZero(M) ((M)!=0) -#endif - -/* -** For each index X that has as one of its arguments either an expression -** or the name of a virtual generated column, and if X is in scope such that -** the value of the expression can simply be read from the index, then -** there is an instance of this object on the Parse.pIdxExpr list. -** -** During code generation, while generating code to evaluate expressions, -** this list is consulted and if a matching expression is found, the value -** is read from the index rather than being recomputed. -*/ -struct IndexedExpr { - Expr *pExpr; /* The expression contained in the index */ - int iDataCur; /* The data cursor associated with the index */ - int iIdxCur; /* The index cursor */ - int iIdxCol; /* The index column that contains value of pExpr */ - u8 bMaybeNullRow; /* True if we need an OP_IfNullRow check */ - IndexedExpr *pIENext; /* Next in a list of all indexed expressions */ -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - const char *zIdxName; /* Name of index, used only for bytecode comments */ -#endif -}; +# define DbMaskZero(M) (M)=0 +# define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I)) +# define DbMaskAllZero(M) (M)==0 +# define DbMaskNonZero(M) (M)!=0 +#endif /* ** An instance of the ParseCleanup object specifies an operation that ** should be performed after parsing to deallocation resources obtained ** during the parse and which are no longer needed. @@ -19195,11 +18901,11 @@ u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ u8 mayAbort; /* True if statement may throw an ABORT exception */ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ u8 okConstFactor; /* OK to factor out constants */ u8 disableLookaside; /* Number of times lookaside has been disabled */ - u8 prepFlags; /* SQLITE_PREPARE_* flags */ + u8 disableVtab; /* Disable all virtual tables for this parse */ u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ #endif int nRangeReg; /* Size of the temporary register block */ @@ -19212,11 +18918,10 @@ ** of the base register during check-constraint eval */ int nLabel; /* The *negative* of the number of labels used */ int nLabelAlloc; /* Number of slots in aLabel */ int *aLabel; /* Space to hold the labels */ ExprList *pConstExpr;/* Constant expressions */ - IndexedExpr *pIdxEpr;/* List of expressions used by active indexes */ Token constraintName;/* Name of the constraint currently being parsed */ yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ int regRowid; /* Register holding rowid of CREATE TABLE entry */ int regRoot; /* Register holding root page number for new objects */ @@ -19236,13 +18941,10 @@ 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 */ -#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 */ u8 disableTriggers; /* True to disable triggers */ @@ -19651,19 +19353,19 @@ SrcList *pSrcList; /* FROM clause */ struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */ int *aiCol; /* array of column indexes */ struct IdxCover *pIdxCover; /* Check for index coverage */ + struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */ ExprList *pGroupBy; /* GROUP BY clause */ Select *pSelect; /* HAVING to WHERE clause ctx */ struct WindowRewrite *pRewrite; /* Window rewrite context */ struct WhereConst *pConst; /* WHERE clause constants */ struct RenameCtx *pRename; /* RENAME COLUMN context */ struct Table *pTab; /* Table of generated column */ - struct CoveringIndexCheck *pCovIdxCk; /* Check for covering index */ SrcItem *pSrcItem; /* A single FROM clause item */ - DbFixer *pFix; /* See sqlite3FixSelect() */ + DbFixer *pFix; } u; }; /* ** The following structure contains information used by the sqliteFix... @@ -19965,11 +19667,10 @@ SQLITE_PRIVATE void *sqlite3Realloc(void*, u64); SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*); SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*); -SQLITE_PRIVATE void sqlite3DbNNFreeNN(sqlite3*, void*); SQLITE_PRIVATE int sqlite3MallocSize(const void*); SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, const void*); SQLITE_PRIVATE void *sqlite3PageMalloc(int); SQLITE_PRIVATE void sqlite3PageFree(void*); SQLITE_PRIVATE void sqlite3MemSetDefault(void); @@ -19986,18 +19687,16 @@ ** The alloca() routine never returns NULL. This will cause code paths ** that deal with sqlite3StackAlloc() failures to be unreachable. */ #ifdef SQLITE_USE_ALLOCA # define sqlite3StackAllocRaw(D,N) alloca(N) -# define sqlite3StackAllocRawNN(D,N) alloca(N) +# define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N) # define sqlite3StackFree(D,P) -# define sqlite3StackFreeNN(D,P) #else # define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N) -# define sqlite3StackAllocRawNN(D,N) sqlite3DbMallocRawNN(D,N) +# define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N) # define sqlite3StackFree(D,P) sqlite3DbFree(D,P) -# define sqlite3StackFreeNN(D,P) sqlite3DbFreeNN(D,P) #endif /* Do not allow both MEMSYS5 and MEMSYS3 to be defined together. If they ** are, disable MEMSYS3 */ @@ -20078,20 +19777,18 @@ SQLITE_PRIVATE void sqlite3TreeViewColumnList(TreeView*, const Column*, int, u8); SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*); SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); SQLITE_PRIVATE void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8); -#if TREETRACE_ENABLED SQLITE_PRIVATE void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*, const ExprList*,const Expr*, const Trigger*); SQLITE_PRIVATE void sqlite3TreeViewInsert(const With*, const SrcList*, const IdList*, const Select*, const ExprList*, int, const Upsert*, const Trigger*); SQLITE_PRIVATE void sqlite3TreeViewUpdate(const With*, const SrcList*, const ExprList*, const Expr*, int, const ExprList*, const Expr*, const Upsert*, const Trigger*); -#endif #ifndef SQLITE_OMIT_TRIGGER SQLITE_PRIVATE void sqlite3TreeViewTriggerStep(TreeView*, const TriggerStep*, u8, u8); SQLITE_PRIVATE void sqlite3TreeViewTrigger(TreeView*, const Trigger*, u8, u8); #endif #ifndef SQLITE_OMIT_WINDOWFUNC @@ -20116,11 +19813,10 @@ SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*); #endif #endif SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); -SQLITE_PRIVATE void sqlite3ProgressCheck(Parse*); SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int); SQLITE_PRIVATE void sqlite3Dequote(char*); SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*); SQLITE_PRIVATE void sqlite3DequoteToken(Token*); @@ -20174,11 +19870,11 @@ SQLITE_PRIVATE void sqlite3ColumnSetColl(sqlite3*,Column*,const char*zColl); SQLITE_PRIVATE const char *sqlite3ColumnColl(Column*); SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*); SQLITE_PRIVATE void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect); SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); -SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(Parse*,Table*,Select*,char); +SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char); SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *, int); SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*); SQLITE_PRIVATE i16 sqlite3TableColumnToIndex(Index*, i16); #ifdef SQLITE_OMIT_GENERATED_COLUMNS @@ -20493,12 +20189,11 @@ 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*); +SQLITE_PRIVATE void sqlite3Int64ToText(i64,char*); SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8); SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); SQLITE_PRIVATE int sqlite3Atoi(const char*); #ifndef SQLITE_OMIT_UTF16 @@ -20539,17 +20234,15 @@ #define getVarint sqlite3GetVarint #define putVarint sqlite3PutVarint SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*); -SQLITE_PRIVATE char *sqlite3TableAffinityStr(sqlite3*,const Table*); SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2); SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity); SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table*,int); SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr); -SQLITE_PRIVATE int sqlite3ExprDataType(const Expr *pExpr); SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3*); @@ -20562,13 +20255,10 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int); #endif #ifndef SQLITE_OMIT_DESERIALIZE SQLITE_PRIVATE int sqlite3MemdbInit(void); -SQLITE_PRIVATE int sqlite3IsMemdb(const sqlite3_vfs*); -#else -# define sqlite3IsMemdb(X) 0 #endif SQLITE_PRIVATE const char *sqlite3ErrStr(int); SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); @@ -20615,10 +20305,11 @@ #ifndef SQLITE_AMALGAMATION SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; SQLITE_PRIVATE const char sqlite3StrBINARY[]; SQLITE_PRIVATE const unsigned char sqlite3StdTypeLen[]; SQLITE_PRIVATE const char sqlite3StdTypeAffinity[]; +SQLITE_PRIVATE const char sqlite3StdTypeMap[]; SQLITE_PRIVATE const char *sqlite3StdType[]; SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; SQLITE_PRIVATE const unsigned char *sqlite3aLTb; SQLITE_PRIVATE const unsigned char *sqlite3aEQb; SQLITE_PRIVATE const unsigned char *sqlite3aGTb; @@ -20704,11 +20395,11 @@ SQLITE_PRIVATE void sqlite3OomClear(sqlite3*); SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); -SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, i64); +SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, int); SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8); SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*); SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); @@ -21058,20 +20749,10 @@ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt); #endif -#if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) -SQLITE_PRIVATE int sqlite3KvvfsInit(void); -#endif - -#if defined(VDBE_PROFILE) \ - || defined(SQLITE_PERFORMANCE_TRACE) \ - || defined(SQLITE_ENABLE_STMT_SCANSTATUS) -SQLITE_PRIVATE sqlite3_uint64 sqlite3Hwtime(void); -#endif - #endif /* SQLITEINT_H */ /************** End of sqliteInt.h *******************************************/ /************** Begin file os_common.h ***************************************/ /* @@ -21109,10 +20790,105 @@ ** Macros for performance tracing. Normally turned off. Only works ** on i486 hardware. */ #ifdef SQLITE_PERFORMANCE_TRACE +/* +** hwtime.h contains inline assembler code for implementing +** high-performance timing routines. +*/ +/************** Include hwtime.h in the middle of os_common.h ****************/ +/************** Begin file hwtime.h ******************************************/ +/* +** 2008 May 27 +** +** 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 file contains inline asm code for retrieving "high-performance" +** counters for x86 and x86_64 class CPUs. +*/ +#ifndef SQLITE_HWTIME_H +#define SQLITE_HWTIME_H + +/* +** The following routine only works on pentium-class (or newer) processors. +** It uses the RDTSC opcode to read the cycle count value out of the +** processor and returns that value. This can be used for high-res +** profiling. +*/ +#if !defined(__STRICT_ANSI__) && \ + (defined(__GNUC__) || defined(_MSC_VER)) && \ + (defined(i386) || defined(__i386__) || defined(_M_IX86)) + + #if defined(__GNUC__) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + + #elif defined(_MSC_VER) + + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ + __asm { + rdtsc + ret ; return value at EDX:EAX + } + } + + #endif + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long val; + __asm__ __volatile__ ("rdtsc" : "=A" (val)); + return val; + } + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long long retval; + unsigned long junk; + __asm__ __volatile__ ("\n\ + 1: mftbu %1\n\ + mftb %L0\n\ + mftbu %0\n\ + cmpw %0,%1\n\ + bne 1b" + : "=r" (retval), "=r" (junk)); + return retval; + } + +#else + + /* + ** asm() is needed for hardware timing support. Without asm(), + ** disable the sqlite3Hwtime() routine. + ** + ** sqlite3Hwtime() is only used for some obscure debugging + ** and analysis configurations, not in any deliverable, so this + ** should not be a great loss. + */ +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } + +#endif + +#endif /* !defined(SQLITE_HWTIME_H) */ + +/************** End of hwtime.h **********************************************/ +/************** Continuing where we left off in os_common.h ******************/ + static sqlite_uint64 g_start; static sqlite_uint64 g_elapsed; #define TIMER_START g_start=sqlite3Hwtime() #define TIMER_END g_elapsed=sqlite3Hwtime()-g_start #define TIMER_ELAPSED g_elapsed @@ -21204,11 +20980,11 @@ /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build */ #if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H) -/* #include "sqlite_cfg.h" */ +/* #include "config.h" */ #define SQLITECONFIG_H 1 #endif /* These macros are provided to "stringify" the value of the define ** for those options in which the value is meaningful. */ @@ -21369,13 +21145,10 @@ "DISABLE_PAGECACHE_OVERFLOW_STATS", #endif #ifdef SQLITE_DISABLE_SKIPAHEAD_DISTINCT "DISABLE_SKIPAHEAD_DISTINCT", #endif -#ifdef SQLITE_DQS - "DQS=" CTIMEOPT_VAL(SQLITE_DQS), -#endif #ifdef SQLITE_ENABLE_8_3_NAMES "ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES), #endif #ifdef SQLITE_ENABLE_API_ARMOR "ENABLE_API_ARMOR", @@ -21861,10 +21634,13 @@ #ifdef SQLITE_OMIT_WSD "OMIT_WSD", #endif #ifdef SQLITE_OMIT_XFER_OPT "OMIT_XFER_OPT", +#endif +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + "PCACHE_SEPARATE_HEADER", #endif #ifdef SQLITE_PERFORMANCE_TRACE "PERFORMANCE_TRACE", #endif #ifdef SQLITE_POWERSAFE_OVERWRITE @@ -22341,19 +22117,31 @@ ** sqlite3StdTypeLen[] The length (in bytes) of each entry ** in sqlite3StdType[]. ** ** sqlite3StdTypeAffinity[] The affinity associated with each entry ** in sqlite3StdType[]. +** +** sqlite3StdTypeMap[] The type value (as returned from +** sqlite3_column_type() or sqlite3_value_type()) +** for each entry in sqlite3StdType[]. */ SQLITE_PRIVATE const unsigned char sqlite3StdTypeLen[] = { 3, 4, 3, 7, 4, 4 }; SQLITE_PRIVATE const char sqlite3StdTypeAffinity[] = { SQLITE_AFF_NUMERIC, SQLITE_AFF_BLOB, SQLITE_AFF_INTEGER, SQLITE_AFF_INTEGER, SQLITE_AFF_REAL, SQLITE_AFF_TEXT +}; +SQLITE_PRIVATE const char sqlite3StdTypeMap[] = { + 0, + SQLITE_BLOB, + SQLITE_INTEGER, + SQLITE_INTEGER, + SQLITE_FLOAT, + SQLITE_TEXT }; SQLITE_PRIVATE const char *sqlite3StdType[] = { "ANY", "BLOB", "INT", @@ -22553,10 +22341,11 @@ typedef struct VdbeFrame VdbeFrame; struct VdbeFrame { Vdbe *v; /* VM this frame belongs to */ VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */ Op *aOp; /* Program instructions for parent frame */ + i64 *anExec; /* Event counters from parent frame */ Mem *aMem; /* Array of memory cells for parent frame */ VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ u8 *aOnce; /* Bitmask used by OP_Once */ void *token; /* Copy of SubProgram.token */ i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ @@ -22768,23 +22557,14 @@ */ typedef unsigned bft; /* Bit Field Type */ /* The ScanStatus object holds a single value for the ** sqlite3_stmt_scanstatus() interface. -** -** aAddrRange[]: -** This array is used by ScanStatus elements associated with EQP -** notes that make an SQLITE_SCANSTAT_NCYCLE value available. It is -** an array of up to 3 ranges of VM addresses for which the Vdbe.anCycle[] -** values should be summed to calculate the NCYCLE value. Each pair of -** integer addresses is a start and end address (both inclusive) for a range -** instructions. A start value of 0 indicates an empty range. */ typedef struct ScanStatus ScanStatus; struct ScanStatus { int addrExplain; /* OP_Explain for loop */ - int aAddrRange[6]; int addrLoop; /* Address of "loops" counter */ int addrVisit; /* Address of "rows visited" counter */ int iSelectID; /* The "Select-ID" for this loop */ LogEst nEst; /* Estimated output rows per loop */ char *zName; /* Name of table or index */ @@ -22810,11 +22590,11 @@ ** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare() ** is really a pointer to an instance of this structure. */ struct Vdbe { sqlite3 *db; /* The database connection that owns this statement */ - Vdbe **ppVPrev,*pVNext; /* Linked list of VDBEs with the same Vdbe.db */ + Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ Parse *pParse; /* Parsing context used to create this Vdbe */ ynVar nVar; /* Number of entries in aVar[] */ int nMem; /* Number of memory locations currently allocated */ int nCursor; /* Number of slots in apCsr[] */ u32 cacheCtr; /* VdbeCursor row cache generation counter */ @@ -22836,11 +22616,11 @@ Op *aOp; /* Space to hold the virtual machine's program */ int nOp; /* Number of instructions in the program */ int nOpAlloc; /* Slots allocated for aOp[] */ Mem *aColName; /* Column names to return */ - Mem *pResultRow; /* Current output row */ + Mem *pResultSet; /* Pointer to an array of results */ char *zErrMsg; /* Error message written here */ VList *pVList; /* Name of variables */ #ifndef SQLITE_OMIT_TRACE i64 startTime; /* Time when query started - used for profiling */ #endif @@ -22873,10 +22653,11 @@ int nFrame; /* Number of frames in pFrame list */ u32 expmask; /* Binding to these vars invalidates VM */ SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ AuxData *pAuxData; /* Linked list of auxdata allocations */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS + i64 *anExec; /* Number of times each op has been executed */ int nScan; /* Entries in aScan[] */ ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */ #endif }; @@ -23039,12 +22820,10 @@ SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *); SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *); SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); -SQLITE_PRIVATE void sqlite3VdbeValueListFree(void*); - #ifdef SQLITE_DEBUG SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*); SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe*); #else # define sqlite3VdbeIncrWriteCounter(V,C) @@ -23369,12 +23148,10 @@ int i; /* Used to iterate through schemas */ int nByte = 0; /* Used to accumulate return value */ sqlite3BtreeEnterAll(db); db->pnBytesFreed = &nByte; - assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); - db->lookaside.pEnd = db->lookaside.pStart; for(i=0; inDb; i++){ Schema *pSchema = db->aDb[i].pSchema; if( ALWAYS(pSchema!=0) ){ HashElem *p; @@ -23396,11 +23173,10 @@ sqlite3DeleteTable(db, (Table *)sqliteHashData(p)); } } } db->pnBytesFreed = 0; - db->lookaside.pEnd = db->lookaside.pTrueEnd; sqlite3BtreeLeaveAll(db); *pHighwater = 0; *pCurrent = nByte; break; @@ -23414,16 +23190,13 @@ case SQLITE_DBSTATUS_STMT_USED: { struct Vdbe *pVdbe; /* Used to iterate through VMs */ int nByte = 0; /* Used to accumulate return value */ db->pnBytesFreed = &nByte; - assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); - db->lookaside.pEnd = db->lookaside.pStart; - for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pVNext){ + for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ sqlite3VdbeDelete(pVdbe); } - db->lookaside.pEnd = db->lookaside.pTrueEnd; db->pnBytesFreed = 0; *pHighwater = 0; /* IMP: R-64479-57858 */ *pCurrent = nByte; @@ -23755,11 +23528,11 @@ X1 = 36525*(Y+4716)/100; X2 = 306001*(M+1)/10000; p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); p->validJD = 1; if( p->validHMS ){ - p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5); + p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000); if( p->validTZ ){ p->iJD -= p->tz*60000; p->validYMD = 0; p->validHMS = 0; p->validTZ = 0; @@ -24264,11 +24037,11 @@ ** weekday N where 0==Sunday, 1==Monday, and so forth. If the ** date is already on the appropriate weekday, this is a no-op. */ if( sqlite3_strnicmp(z, "weekday ", 8)==0 && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0 - && r>=0.0 && r<7.0 && (n=(int)r)==r ){ + && (n=(int)r)==r && n>=0 && r<7 ){ sqlite3_int64 Z; computeYMD_HMS(p); p->validTZ = 0; p->validJD = 0; computeJD(p); @@ -24945,15 +24718,13 @@ DO_OS_MALLOC_TEST(id); return id->pMethods->xFileSize(id, pSize); } SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){ DO_OS_MALLOC_TEST(id); - assert( lockType>=SQLITE_LOCK_SHARED && lockType<=SQLITE_LOCK_EXCLUSIVE ); return id->pMethods->xLock(id, lockType); } SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){ - assert( lockType==SQLITE_LOCK_NONE || lockType==SQLITE_LOCK_SHARED ); return id->pMethods->xUnlock(id, lockType); } SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ DO_OS_MALLOC_TEST(id); return id->pMethods->xCheckReservedLock(id, pResOut); @@ -25064,11 +24835,10 @@ DO_OS_MALLOC_TEST(0); /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before ** reaching the VFS. */ - assert( zPath || (flags & SQLITE_OPEN_EXCLUSIVE) ); rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x1087f7f, pFlagsOut); assert( rc==SQLITE_OK || pFile->pMethods==0 ); return rc; } SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ @@ -27380,17 +27150,13 @@ int iFullSz; if( n<=mem5.szAtom*2 ){ if( n<=mem5.szAtom ) return mem5.szAtom; return mem5.szAtom*2; } - if( n>0x10000000 ){ - if( n>0x40000000 ) return 0; - if( n>0x20000000 ) return 0x40000000; - return 0x20000000; - } + if( n>0x40000000 ) return 0; for(iFullSz=mem5.szAtom*8; iFullSz=(i64)n ) return iFullSz/2; + if( (iFullSz/2)>=n ) return iFullSz/2; return iFullSz; } /* ** Return the ceiling of the logarithm base 2 of iValue. @@ -29287,38 +29053,22 @@ sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1); } *pp = p; } -/* -** Maximum size of any single memory allocation. -** -** This is not a limit on the total amount of memory used. This is -** a limit on the size parameter to sqlite3_malloc() and sqlite3_realloc(). -** -** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391 -** This provides a 256-byte safety margin for defense against 32-bit -** signed integer overflow bugs when computing memory allocation sizes. -** Paranoid applications might want to reduce the maximum allocation size -** further for an even larger safety margin. 0x3fffffff or 0x0fffffff -** or even smaller would be reasonable upper bounds on the size of a memory -** allocations for most applications. -*/ -#ifndef SQLITE_MAX_ALLOCATION_SIZE -# define SQLITE_MAX_ALLOCATION_SIZE 2147483391 -#endif -#if SQLITE_MAX_ALLOCATION_SIZE>2147483391 -# error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391 -#endif - /* ** Allocate memory. This routine is like sqlite3_malloc() except that it ** assumes the memory subsystem has already been initialized. */ SQLITE_PRIVATE void *sqlite3Malloc(u64 n){ void *p; - if( n==0 || n>SQLITE_MAX_ALLOCATION_SIZE ){ + if( n==0 || n>=0x7fffff00 ){ + /* A memory allocation of a number of bytes which is near the maximum + ** signed integer value might cause an integer overflow inside of the + ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving + ** 255 bytes of overhead. SQLite itself will never use anything near + ** this amount. The only way to reach the limit is with sqlite3_malloc() */ p = 0; }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); mallocWithAlarm((int)n, &p); sqlite3_mutex_leave(mem0.mutex); @@ -29350,11 +29100,11 @@ /* ** TRUE if p is a lookaside memory allocation from db */ #ifndef SQLITE_OMIT_LOOKASIDE static int isLookaside(sqlite3 *db, const void *p){ - return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pTrueEnd); + return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd); } #else #define isLookaside(A,B) 0 #endif @@ -29374,20 +29124,22 @@ #endif } SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, const void *p){ assert( p!=0 ); #ifdef SQLITE_DEBUG - if( db==0 ){ - assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); - assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); - }else if( !isLookaside(db,p) ){ - assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + if( db==0 || !isLookaside(db,p) ){ + if( db==0 ){ + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + }else{ + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + } } #endif if( db ){ - if( ((uptr)p)<(uptr)(db->lookaside.pTrueEnd) ){ + if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ assert( sqlite3_mutex_held(db->mutex) ); return LOOKASIDE_SMALL; } @@ -29439,15 +29191,18 @@ */ SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){ assert( db==0 || sqlite3_mutex_held(db->mutex) ); assert( p!=0 ); if( db ){ + if( db->pnBytesFreed ){ + measureAllocationSize(db, p); + return; + } if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ LookasideSlot *pBuf = (LookasideSlot*)p; - assert( db->pnBytesFreed==0 ); #ifdef SQLITE_DEBUG memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */ #endif pBuf->pNext = db->lookaside.pSmallFree; db->lookaside.pSmallFree = pBuf; @@ -29454,67 +29209,25 @@ return; } #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ LookasideSlot *pBuf = (LookasideSlot*)p; - assert( db->pnBytesFreed==0 ); #ifdef SQLITE_DEBUG memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */ #endif pBuf->pNext = db->lookaside.pFree; db->lookaside.pFree = pBuf; return; } } - if( db->pnBytesFreed ){ - measureAllocationSize(db, p); - return; - } } assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); sqlite3_free(p); } -SQLITE_PRIVATE void sqlite3DbNNFreeNN(sqlite3 *db, void *p){ - assert( db!=0 ); - assert( sqlite3_mutex_held(db->mutex) ); - assert( p!=0 ); - if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ -#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE - if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ - LookasideSlot *pBuf = (LookasideSlot*)p; - assert( db->pnBytesFreed==0 ); -#ifdef SQLITE_DEBUG - memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */ -#endif - pBuf->pNext = db->lookaside.pSmallFree; - db->lookaside.pSmallFree = pBuf; - return; - } -#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ - if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ - LookasideSlot *pBuf = (LookasideSlot*)p; - assert( db->pnBytesFreed==0 ); -#ifdef SQLITE_DEBUG - memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */ -#endif - pBuf->pNext = db->lookaside.pFree; - db->lookaside.pFree = pBuf; - return; - } - } - if( db->pnBytesFreed ){ - measureAllocationSize(db, p); - return; - } - assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - sqlite3MemdebugSetType(p, MEMTYPE_HEAP); - sqlite3_free(p); -} SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ assert( db==0 || sqlite3_mutex_held(db->mutex) ); if( p ) sqlite3DbFreeNN(db, p); } @@ -29810,18 +29523,13 @@ ** SQL statement. Make a copy of this phrase in space obtained form ** sqlite3DbMalloc(). Omit leading and trailing whitespace. */ SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ int n; -#ifdef SQLITE_DEBUG - /* Because of the way the parser works, the span is guaranteed to contain - ** at least one non-space character */ - for(n=0; sqlite3Isspace(zStart[n]); n++){ assert( &zStart[n]0) && sqlite3Isspace(zStart[n-1]) ) n--; return sqlite3DbStrNDup(db, zStart, n); } /* ** Free any prior content in *pz and replace it with a copy of zNew. @@ -29851,17 +29559,12 @@ if( db->nVdbeExec>0 ){ AtomicStore(&db->u1.isInterrupted, 1); } DisableLookaside; if( db->pParse ){ - Parse *pParse; sqlite3ErrorMsg(db->pParse, "out of memory"); db->pParse->rc = SQLITE_NOMEM_BKPT; - for(pParse=db->pParse->pOuterParse; pParse; pParse = pParse->pOuterParse){ - pParse->nErr++; - pParse->rc = SQLITE_NOMEM; - } } } return 0; } @@ -30656,30 +30359,17 @@ buf[3] = 0x80 + (u8)(ch & 0x3f); length = 4; } } if( precision>1 ){ - i64 nPrior = 1; width -= precision-1; if( width>1 && !flag_leftjustify ){ sqlite3_str_appendchar(pAccum, width-1, ' '); width = 0; } - sqlite3_str_append(pAccum, buf, length); - precision--; - while( precision > 1 ){ - i64 nCopyBytes; - if( nPrior > precision-1 ) nPrior = precision - 1; - nCopyBytes = length*nPrior; - if( nCopyBytes + pAccum->nChar >= pAccum->nAlloc ){ - sqlite3StrAccumEnlarge(pAccum, nCopyBytes); - } - if( pAccum->accError ) break; - sqlite3_str_append(pAccum, - &pAccum->zText[pAccum->nChar-nCopyBytes], nCopyBytes); - precision -= nPrior; - nPrior *= 2; + while( precision-- > 1 ){ + sqlite3_str_append(pAccum, buf, length); } } bufpt = buf; flag_altform2 = 1; goto adjust_width_for_utf8; @@ -30736,12 +30426,12 @@ } break; case etSQLESCAPE: /* %q: Escape ' characters */ case etSQLESCAPE2: /* %Q: Escape ' and enclose in '...' */ case etSQLESCAPE3: { /* %w: Escape " characters */ - i64 i, j, k, n; - int needQuote, isnull; + int i, j, k, n, isnull; + int needQuote; char ch; char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */ char *escarg; if( bArgList ){ @@ -30903,13 +30593,13 @@ ** able to accept at least N more bytes of text. ** ** Return the number of bytes of text that StrAccum is able to accept ** after the attempted enlargement. The value returned might be zero. */ -SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, i64 N){ +SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, int N){ char *zNew; - assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */ + assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ if( p->accError ){ testcase(p->accError==SQLITE_TOOBIG); testcase(p->accError==SQLITE_NOMEM); return 0; } @@ -30916,11 +30606,12 @@ if( p->mxAlloc==0 ){ sqlite3StrAccumSetError(p, SQLITE_TOOBIG); return p->nAlloc - p->nChar - 1; }else{ char *zOld = isMalloced(p) ? p->zText : 0; - i64 szNew = p->nChar + N + 1; + i64 szNew = p->nChar; + szNew += (sqlite3_int64)N + 1; if( szNew+p->nChar<=p->mxAlloc ){ /* Force exponential buffer size growth as long as it does not overflow, ** to avoid having to call this routine too often */ szNew += p->nChar; } @@ -30946,12 +30637,11 @@ sqlite3_str_reset(p); sqlite3StrAccumSetError(p, SQLITE_NOMEM); return 0; } } - assert( N>=0 && N<=0x7fffffff ); - return (int)N; + return N; } /* ** Append N copies of character c to the given string buffer. */ @@ -31425,12 +31115,12 @@ int i; sqlite3TreeViewPush(&pView, moreToFollow); sqlite3TreeViewLine(pView, "COLUMNS"); for(i=0; iu2.pCteUse); } if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){ sqlite3_str_appendf(&x, " ON"); } - if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc"); - if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated"); - if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized"); - if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine"); - if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte"); - if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom"); - sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inSrc-1); n = 0; if( pItem->pSelect ) n++; if( pItem->fg.isTabFunc ) n++; @@ -31564,11 +31247,11 @@ if( pItem->pSelect ){ if( pItem->pTab ){ Table *pTab = pItem->pTab; sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); } - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); } if( pItem->fg.isTabFunc ){ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); } @@ -31819,11 +31502,11 @@ if( pExpr==0 ){ sqlite3TreeViewLine(pView, "nil"); sqlite3TreeViewPop(&pView); return; } - if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags || pExpr->pAggInfo ){ + if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){ StrAccum x; sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0); sqlite3_str_appendf(&x, " fg.af=%x.%c", pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n'); if( ExprHasProperty(pExpr, EP_OuterON) ){ @@ -31836,13 +31519,10 @@ sqlite3_str_appendf(&x, " DDL"); } if( ExprHasVVAProperty(pExpr, EP_Immutable) ){ sqlite3_str_appendf(&x, " IMMUTABLE"); } - if( pExpr->pAggInfo!=0 ){ - sqlite3_str_appendf(&x, " agg-column[%d]", pExpr->iAgg); - } sqlite3StrAccumFinish(&x); }else{ zFlgs[0] = 0; } switch( pExpr->op ){ @@ -32334,11 +32014,10 @@ pUpsert = pUpsert->pNextUpsert; } sqlite3TreeViewPop(&pView); } -#if TREETRACE_ENABLED /* ** Generate a human-readable diagram of the data structure that go ** into generating an DELETE statement. */ SQLITE_PRIVATE void sqlite3TreeViewDelete( @@ -32388,13 +32067,11 @@ if( pTrigger ){ sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); } sqlite3TreeViewPop(&pView); } -#endif /* TREETRACE_ENABLED */ -#if TREETRACE_ENABLED /* ** Generate a human-readable diagram of the data structure that go ** into generating an INSERT statement. */ SQLITE_PRIVATE void sqlite3TreeViewInsert( @@ -32458,13 +32135,11 @@ if( pTrigger ){ sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); } sqlite3TreeViewPop(&pView); } -#endif /* TREETRACE_ENABLED */ -#if TREETRACE_ENABLED /* ** Generate a human-readable diagram of the data structure that go ** into generating an UPDATE statement. */ SQLITE_PRIVATE void sqlite3TreeViewUpdate( @@ -32536,11 +32211,10 @@ if( pTrigger ){ sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); } sqlite3TreeViewPop(&pView); } -#endif /* TREETRACE_ENABLED */ #ifndef SQLITE_OMIT_TRIGGER /* ** Show a human-readable graph of a TriggerStep */ @@ -32650,45 +32324,20 @@ /* All threads share a single random number generator. ** This structure is the current state of the generator. */ static SQLITE_WSD struct sqlite3PrngType { - u32 s[16]; /* 64 bytes of chacha20 state */ - u8 out[64]; /* Output bytes */ - u8 n; /* Output bytes remaining */ + unsigned char isInit; /* True if initialized */ + unsigned char i, j; /* State variables */ + unsigned char s[256]; /* State variables */ } sqlite3Prng; - -/* The RFC-7539 ChaCha20 block function -*/ -#define ROTL(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) -#define QR(a, b, c, d) ( \ - a += b, d ^= a, d = ROTL(d,16), \ - c += d, b ^= c, b = ROTL(b,12), \ - a += b, d ^= a, d = ROTL(d, 8), \ - c += d, b ^= c, b = ROTL(b, 7)) -static void chacha_block(u32 *out, const u32 *in){ - int i; - u32 x[16]; - memcpy(x, in, 64); - for(i=0; i<10; i++){ - QR(x[0], x[4], x[ 8], x[12]); - QR(x[1], x[5], x[ 9], x[13]); - QR(x[2], x[6], x[10], x[14]); - QR(x[3], x[7], x[11], x[15]); - QR(x[0], x[5], x[10], x[15]); - QR(x[1], x[6], x[11], x[12]); - QR(x[2], x[7], x[ 8], x[13]); - QR(x[3], x[4], x[ 9], x[14]); - } - for(i=0; i<16; i++) out[i] = x[i]+in[i]; -} - /* ** Return N random bytes. */ SQLITE_API void sqlite3_randomness(int N, void *pBuf){ + unsigned char t; unsigned char *zBuf = pBuf; /* The "wsdPrng" macro will resolve to the pseudo-random number generator ** state vector. If writable static data is unsupported on the target, ** we have to locate the state vector at run-time. In the more common @@ -32714,50 +32363,57 @@ mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG); #endif sqlite3_mutex_enter(mutex); if( N<=0 || pBuf==0 ){ - wsdPrng.s[0] = 0; + wsdPrng.isInit = 0; sqlite3_mutex_leave(mutex); return; } /* Initialize the state of the random number generator once, - ** the first time this routine is called. + ** the first time this routine is called. The seed value does + ** not need to contain a lot of randomness since we are not + ** trying to do secure encryption or anything like that... + ** + ** Nothing in this file or anywhere else in SQLite does any kind of + ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random + ** number generator) not as an encryption device. */ - if( wsdPrng.s[0]==0 ){ + if( !wsdPrng.isInit ){ sqlite3_vfs *pVfs = sqlite3_vfs_find(0); - static const u32 chacha20_init[] = { - 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 - }; - memcpy(&wsdPrng.s[0], chacha20_init, 16); + int i; + char k[256]; + wsdPrng.j = 0; + wsdPrng.i = 0; if( NEVER(pVfs==0) ){ - memset(&wsdPrng.s[4], 0, 44); + memset(k, 0, sizeof(k)); }else{ - sqlite3OsRandomness(pVfs, 44, (char*)&wsdPrng.s[4]); + sqlite3OsRandomness(pVfs, 256, k); } - wsdPrng.s[15] = wsdPrng.s[12]; - wsdPrng.s[12] = 0; - wsdPrng.n = 0; + for(i=0; i<256; i++){ + wsdPrng.s[i] = (u8)i; + } + for(i=0; i<256; i++){ + wsdPrng.j += wsdPrng.s[i] + k[i]; + t = wsdPrng.s[wsdPrng.j]; + wsdPrng.s[wsdPrng.j] = wsdPrng.s[i]; + wsdPrng.s[i] = t; + } + wsdPrng.isInit = 1; } assert( N>0 ); - while( 1 /* exit by break */ ){ - if( N<=wsdPrng.n ){ - memcpy(zBuf, &wsdPrng.out[wsdPrng.n-N], N); - wsdPrng.n -= N; - break; - } - if( wsdPrng.n>0 ){ - memcpy(zBuf, wsdPrng.out, wsdPrng.n); - N -= wsdPrng.n; - zBuf += wsdPrng.n; - } - wsdPrng.s[12]++; - chacha_block((u32*)wsdPrng.out, wsdPrng.s); - wsdPrng.n = 64; - } + do{ + wsdPrng.i++; + t = wsdPrng.s[wsdPrng.i]; + wsdPrng.j += t; + wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j]; + wsdPrng.s[wsdPrng.j] = t; + t += wsdPrng.s[wsdPrng.i]; + *(zBuf++) = wsdPrng.s[t]; + }while( --N ); sqlite3_mutex_leave(mutex); } #ifndef SQLITE_UNTESTABLE /* @@ -33778,30 +33434,10 @@ va_end(ap); sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); } } -/* -** Check for interrupts and invoke progress callback. -*/ -SQLITE_PRIVATE void sqlite3ProgressCheck(Parse *p){ - sqlite3 *db = p->db; - if( AtomicLoad(&db->u1.isInterrupted) ){ - p->nErr++; - p->rc = SQLITE_INTERRUPT; - } -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - if( db->xProgress && (++p->nProgressSteps)>=db->nProgressOps ){ - if( db->xProgress(db->pProgressArg) ){ - p->nErr++; - p->rc = SQLITE_INTERRUPT; - } - p->nProgressSteps = 0; - } -#endif -} - /* ** Add an error message to pParse->zErrMsg and increment pParse->nErr. ** ** This function should be used to report any error that occurs while ** compiling an SQL statement (i.e. within sqlite3_prepare()). The @@ -33813,11 +33449,11 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ char *zMsg; va_list ap; sqlite3 *db = pParse->db; assert( db!=0 ); - assert( db->pParse==pParse || db->pParse->pToplevel==pParse ); + assert( db->pParse==pParse ); db->errByteOffset = -2; va_start(ap, zFormat); zMsg = sqlite3VMPrintf(db, zFormat, ap); va_end(ap); if( db->errByteOffset<-1 ) db->errByteOffset = -1; @@ -34255,18 +33891,15 @@ #if defined(_MSC_VER) #pragma warning(default : 4756) #endif /* -** Render an signed 64-bit integer as text. Store the result in zOut[] and -** return the length of the string that was stored, in bytes. The value -** returned does not include the zero terminator at the end of the output -** string. +** Render an signed 64-bit integer as text. Store the result in zOut[]. ** ** The caller must ensure that zOut[] is at least 21 bytes in size. */ -SQLITE_PRIVATE int sqlite3Int64ToText(i64 v, char *zOut){ +SQLITE_PRIVATE void sqlite3Int64ToText(i64 v, char *zOut){ int i; u64 x; char zTemp[22]; if( v<0 ){ x = (v==SMALLEST_INT64) ? ((u64)1)<<63 : (u64)-v; @@ -34279,11 +33912,10 @@ zTemp[i--] = (x%10) + '0'; x = x/10; }while( x ); if( v<0 ) zTemp[i--] = '-'; memcpy(zOut, &zTemp[i+1], sizeof(zTemp)-1-i); - return sizeof(zTemp)-2-i; } /* ** Compare the 19-character string zNum against the text representation ** value 2^63: 9223372036854775808. Return negative, zero, or positive @@ -35341,108 +34973,10 @@ i += pIn[i+1]; }while( ifirst; count = pH->count; } if( pHash ) *pHash = h; - while( count ){ + while( count-- ){ assert( elem!=0 ); if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ return elem; } elem = elem->next; - count--; } return &nullElement; } /* Remove a single entry from the hash table given a pointer to that @@ -35734,67 +35267,67 @@ /* 3 */ "Checkpoint" OpHelp(""), /* 4 */ "JournalMode" OpHelp(""), /* 5 */ "Vacuum" OpHelp(""), /* 6 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), /* 7 */ "VUpdate" OpHelp("data=r[P3@P2]"), - /* 8 */ "Init" OpHelp("Start at P2"), - /* 9 */ "Goto" OpHelp(""), - /* 10 */ "Gosub" OpHelp(""), - /* 11 */ "InitCoroutine" OpHelp(""), - /* 12 */ "Yield" OpHelp(""), - /* 13 */ "MustBeInt" OpHelp(""), - /* 14 */ "Jump" OpHelp(""), - /* 15 */ "Once" OpHelp(""), - /* 16 */ "If" OpHelp(""), - /* 17 */ "IfNot" OpHelp(""), - /* 18 */ "IsType" OpHelp("if typeof(P1.P3) in P5 goto P2"), + /* 8 */ "Goto" OpHelp(""), + /* 9 */ "Gosub" OpHelp(""), + /* 10 */ "InitCoroutine" OpHelp(""), + /* 11 */ "Yield" OpHelp(""), + /* 12 */ "MustBeInt" OpHelp(""), + /* 13 */ "Jump" OpHelp(""), + /* 14 */ "Once" OpHelp(""), + /* 15 */ "If" OpHelp(""), + /* 16 */ "IfNot" OpHelp(""), + /* 17 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"), + /* 18 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), - /* 20 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), - /* 21 */ "SeekLT" OpHelp("key=r[P3@P4]"), - /* 22 */ "SeekLE" OpHelp("key=r[P3@P4]"), - /* 23 */ "SeekGE" OpHelp("key=r[P3@P4]"), - /* 24 */ "SeekGT" OpHelp("key=r[P3@P4]"), - /* 25 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), - /* 26 */ "IfNoHope" OpHelp("key=r[P3@P4]"), - /* 27 */ "NoConflict" OpHelp("key=r[P3@P4]"), - /* 28 */ "NotFound" OpHelp("key=r[P3@P4]"), - /* 29 */ "Found" OpHelp("key=r[P3@P4]"), - /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"), - /* 31 */ "NotExists" OpHelp("intkey=r[P3]"), - /* 32 */ "Last" OpHelp(""), - /* 33 */ "IfSmaller" OpHelp(""), - /* 34 */ "SorterSort" OpHelp(""), - /* 35 */ "Sort" OpHelp(""), - /* 36 */ "Rewind" OpHelp(""), - /* 37 */ "SorterNext" OpHelp(""), - /* 38 */ "Prev" OpHelp(""), - /* 39 */ "Next" OpHelp(""), - /* 40 */ "IdxLE" OpHelp("key=r[P3@P4]"), - /* 41 */ "IdxGT" OpHelp("key=r[P3@P4]"), - /* 42 */ "IdxLT" OpHelp("key=r[P3@P4]"), + /* 20 */ "SeekLT" OpHelp("key=r[P3@P4]"), + /* 21 */ "SeekLE" OpHelp("key=r[P3@P4]"), + /* 22 */ "SeekGE" OpHelp("key=r[P3@P4]"), + /* 23 */ "SeekGT" OpHelp("key=r[P3@P4]"), + /* 24 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), + /* 25 */ "IfNoHope" OpHelp("key=r[P3@P4]"), + /* 26 */ "NoConflict" OpHelp("key=r[P3@P4]"), + /* 27 */ "NotFound" OpHelp("key=r[P3@P4]"), + /* 28 */ "Found" OpHelp("key=r[P3@P4]"), + /* 29 */ "SeekRowid" OpHelp("intkey=r[P3]"), + /* 30 */ "NotExists" OpHelp("intkey=r[P3]"), + /* 31 */ "Last" OpHelp(""), + /* 32 */ "IfSmaller" OpHelp(""), + /* 33 */ "SorterSort" OpHelp(""), + /* 34 */ "Sort" OpHelp(""), + /* 35 */ "Rewind" OpHelp(""), + /* 36 */ "SorterNext" OpHelp(""), + /* 37 */ "Prev" OpHelp(""), + /* 38 */ "Next" OpHelp(""), + /* 39 */ "IdxLE" OpHelp("key=r[P3@P4]"), + /* 40 */ "IdxGT" OpHelp("key=r[P3@P4]"), + /* 41 */ "IdxLT" OpHelp("key=r[P3@P4]"), + /* 42 */ "IdxGE" 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"), - /* 48 */ "Program" OpHelp(""), - /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), + /* 45 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), + /* 46 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), + /* 47 */ "Program" OpHelp(""), + /* 48 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), + /* 49 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, 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"), - /* 62 */ "IncrVacuum" OpHelp(""), - /* 63 */ "VNext" OpHelp(""), - /* 64 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), + /* 59 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), + /* 60 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), + /* 61 */ "IncrVacuum" OpHelp(""), + /* 62 */ "VNext" OpHelp(""), + /* 63 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), + /* 64 */ "Init" OpHelp("Start at P2"), /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), /* 67 */ "Return" OpHelp(""), /* 68 */ "EndCoroutine" OpHelp(""), /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), @@ -35919,992 +35452,10 @@ return azName[i]; } #endif /************** End of opcodes.c *********************************************/ -/************** Begin file os_kv.c *******************************************/ -/* -** 2022-09-06 -** -** 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 file contains an experimental VFS layer that operates on a -** Key/Value storage engine where both keys and values must be pure -** text. -*/ -/* #include */ -#if SQLITE_OS_KV || (SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL)) - -/***************************************************************************** -** Debugging logic -*/ - -/* SQLITE_KV_TRACE() is used for tracing calls to kvstorage routines. */ -#if 0 -#define SQLITE_KV_TRACE(X) printf X -#else -#define SQLITE_KV_TRACE(X) -#endif - -/* SQLITE_KV_LOG() is used for tracing calls to the VFS interface */ -#if 0 -#define SQLITE_KV_LOG(X) printf X -#else -#define SQLITE_KV_LOG(X) -#endif - - -/* -** Forward declaration of objects used by this VFS implementation -*/ -typedef struct KVVfsFile KVVfsFile; - -/* A single open file. There are only two files represented by this -** VFS - the database and the rollback journal. -*/ -struct KVVfsFile { - sqlite3_file base; /* IO methods */ - const char *zClass; /* Storage class */ - int isJournal; /* True if this is a journal file */ - unsigned int nJrnl; /* Space allocated for aJrnl[] */ - char *aJrnl; /* Journal content */ - int szPage; /* Last known page size */ - sqlite3_int64 szDb; /* Database file size. -1 means unknown */ - char *aData; /* Buffer to hold page data */ -}; -#define SQLITE_KVOS_SZ 133073 - -/* -** Methods for KVVfsFile -*/ -static int kvvfsClose(sqlite3_file*); -static int kvvfsReadDb(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); -static int kvvfsReadJrnl(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); -static int kvvfsWriteDb(sqlite3_file*,const void*,int iAmt, sqlite3_int64); -static int kvvfsWriteJrnl(sqlite3_file*,const void*,int iAmt, sqlite3_int64); -static int kvvfsTruncateDb(sqlite3_file*, sqlite3_int64 size); -static int kvvfsTruncateJrnl(sqlite3_file*, sqlite3_int64 size); -static int kvvfsSyncDb(sqlite3_file*, int flags); -static int kvvfsSyncJrnl(sqlite3_file*, int flags); -static int kvvfsFileSizeDb(sqlite3_file*, sqlite3_int64 *pSize); -static int kvvfsFileSizeJrnl(sqlite3_file*, sqlite3_int64 *pSize); -static int kvvfsLock(sqlite3_file*, int); -static int kvvfsUnlock(sqlite3_file*, int); -static int kvvfsCheckReservedLock(sqlite3_file*, int *pResOut); -static int kvvfsFileControlDb(sqlite3_file*, int op, void *pArg); -static int kvvfsFileControlJrnl(sqlite3_file*, int op, void *pArg); -static int kvvfsSectorSize(sqlite3_file*); -static int kvvfsDeviceCharacteristics(sqlite3_file*); - -/* -** Methods for sqlite3_vfs -*/ -static int kvvfsOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); -static int kvvfsDelete(sqlite3_vfs*, const char *zName, int syncDir); -static int kvvfsAccess(sqlite3_vfs*, const char *zName, int flags, int *); -static int kvvfsFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); -static void *kvvfsDlOpen(sqlite3_vfs*, const char *zFilename); -static int kvvfsRandomness(sqlite3_vfs*, int nByte, char *zOut); -static int kvvfsSleep(sqlite3_vfs*, int microseconds); -static int kvvfsCurrentTime(sqlite3_vfs*, double*); -static int kvvfsCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); - -static sqlite3_vfs sqlite3OsKvvfsObject = { - 1, /* iVersion */ - sizeof(KVVfsFile), /* szOsFile */ - 1024, /* mxPathname */ - 0, /* pNext */ - "kvvfs", /* zName */ - 0, /* pAppData */ - kvvfsOpen, /* xOpen */ - kvvfsDelete, /* xDelete */ - kvvfsAccess, /* xAccess */ - kvvfsFullPathname, /* xFullPathname */ - kvvfsDlOpen, /* xDlOpen */ - 0, /* xDlError */ - 0, /* xDlSym */ - 0, /* xDlClose */ - kvvfsRandomness, /* xRandomness */ - kvvfsSleep, /* xSleep */ - kvvfsCurrentTime, /* xCurrentTime */ - 0, /* xGetLastError */ - kvvfsCurrentTimeInt64 /* xCurrentTimeInt64 */ -}; - -/* Methods for sqlite3_file objects referencing a database file -*/ -static sqlite3_io_methods kvvfs_db_io_methods = { - 1, /* iVersion */ - kvvfsClose, /* xClose */ - kvvfsReadDb, /* xRead */ - kvvfsWriteDb, /* xWrite */ - kvvfsTruncateDb, /* xTruncate */ - kvvfsSyncDb, /* xSync */ - kvvfsFileSizeDb, /* xFileSize */ - kvvfsLock, /* xLock */ - kvvfsUnlock, /* xUnlock */ - kvvfsCheckReservedLock, /* xCheckReservedLock */ - kvvfsFileControlDb, /* xFileControl */ - kvvfsSectorSize, /* xSectorSize */ - kvvfsDeviceCharacteristics, /* xDeviceCharacteristics */ - 0, /* xShmMap */ - 0, /* xShmLock */ - 0, /* xShmBarrier */ - 0, /* xShmUnmap */ - 0, /* xFetch */ - 0 /* xUnfetch */ -}; - -/* Methods for sqlite3_file objects referencing a rollback journal -*/ -static sqlite3_io_methods kvvfs_jrnl_io_methods = { - 1, /* iVersion */ - kvvfsClose, /* xClose */ - kvvfsReadJrnl, /* xRead */ - kvvfsWriteJrnl, /* xWrite */ - kvvfsTruncateJrnl, /* xTruncate */ - kvvfsSyncJrnl, /* xSync */ - kvvfsFileSizeJrnl, /* xFileSize */ - kvvfsLock, /* xLock */ - kvvfsUnlock, /* xUnlock */ - kvvfsCheckReservedLock, /* xCheckReservedLock */ - kvvfsFileControlJrnl, /* xFileControl */ - kvvfsSectorSize, /* xSectorSize */ - kvvfsDeviceCharacteristics, /* xDeviceCharacteristics */ - 0, /* xShmMap */ - 0, /* xShmLock */ - 0, /* xShmBarrier */ - 0, /* xShmUnmap */ - 0, /* xFetch */ - 0 /* xUnfetch */ -}; - -/****** Storage subsystem **************************************************/ -#include -#include -#include - -/* Forward declarations for the low-level storage engine -*/ -static int kvstorageWrite(const char*, const char *zKey, const char *zData); -static int kvstorageDelete(const char*, const char *zKey); -static int kvstorageRead(const char*, const char *zKey, char *zBuf, int nBuf); -#define KVSTORAGE_KEY_SZ 32 - -/* Expand the key name with an appropriate prefix and put the result -** zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least -** KVSTORAGE_KEY_SZ bytes. -*/ -static void kvstorageMakeKey( - const char *zClass, - const char *zKeyIn, - char *zKeyOut -){ - sqlite3_snprintf(KVSTORAGE_KEY_SZ, zKeyOut, "kvvfs-%s-%s", zClass, zKeyIn); -} - -/* Write content into a key. zClass is the particular namespace of the -** underlying key/value store to use - either "local" or "session". -** -** Both zKey and zData are zero-terminated pure text strings. -** -** Return the number of errors. -*/ -static int kvstorageWrite( - const char *zClass, - const char *zKey, - const char *zData -){ - FILE *fd; - char zXKey[KVSTORAGE_KEY_SZ]; - kvstorageMakeKey(zClass, zKey, zXKey); - fd = fopen(zXKey, "wb"); - if( fd ){ - SQLITE_KV_TRACE(("KVVFS-WRITE %-15s (%d) %.50s%s\n", zXKey, - (int)strlen(zData), zData, - strlen(zData)>50 ? "..." : "")); - fputs(zData, fd); - fclose(fd); - return 0; - }else{ - return 1; - } -} - -/* Delete a key (with its corresponding data) from the key/value -** namespace given by zClass. If the key does not previously exist, -** this routine is a no-op. -*/ -static int kvstorageDelete(const char *zClass, const char *zKey){ - char zXKey[KVSTORAGE_KEY_SZ]; - kvstorageMakeKey(zClass, zKey, zXKey); - unlink(zXKey); - SQLITE_KV_TRACE(("KVVFS-DELETE %-15s\n", zXKey)); - return 0; -} - -/* Read the value associated with a zKey from the key/value namespace given -** by zClass and put the text data associated with that key in the first -** nBuf bytes of zBuf[]. The value might be truncated if zBuf is not large -** enough to hold it all. The value put into zBuf must always be zero -** terminated, even if it gets truncated because nBuf is not large enough. -** -** Return the total number of bytes in the data, without truncation, and -** not counting the final zero terminator. Return -1 if the key does -** not exist. -** -** If nBuf<=0 then this routine simply returns the size of the data without -** actually reading it. -*/ -static int kvstorageRead( - const char *zClass, - const char *zKey, - char *zBuf, - int nBuf -){ - FILE *fd; - struct stat buf; - char zXKey[KVSTORAGE_KEY_SZ]; - kvstorageMakeKey(zClass, zKey, zXKey); - if( access(zXKey, R_OK)!=0 - || stat(zXKey, &buf)!=0 - || !S_ISREG(buf.st_mode) - ){ - SQLITE_KV_TRACE(("KVVFS-READ %-15s (-1)\n", zXKey)); - return -1; - } - if( nBuf<=0 ){ - return (int)buf.st_size; - }else if( nBuf==1 ){ - zBuf[0] = 0; - SQLITE_KV_TRACE(("KVVFS-READ %-15s (%d)\n", zXKey, - (int)buf.st_size)); - return (int)buf.st_size; - } - if( nBuf > buf.st_size + 1 ){ - nBuf = buf.st_size + 1; - } - fd = fopen(zXKey, "rb"); - if( fd==0 ){ - SQLITE_KV_TRACE(("KVVFS-READ %-15s (-1)\n", zXKey)); - return -1; - }else{ - sqlite3_int64 n = fread(zBuf, 1, nBuf-1, fd); - fclose(fd); - zBuf[n] = 0; - SQLITE_KV_TRACE(("KVVFS-READ %-15s (%lld) %.50s%s\n", zXKey, - n, zBuf, n>50 ? "..." : "")); - return (int)n; - } -} - -/* -** An internal level of indirection which enables us to replace the -** kvvfs i/o methods with JavaScript implementations in WASM builds. -** Maintenance reminder: if this struct changes in any way, the JSON -** rendering of its structure must be updated in -** sqlite3_wasm_enum_json(). There are no binary compatibility -** concerns, so it does not need an iVersion member. This file is -** necessarily always compiled together with sqlite3_wasm_enum_json(), -** and JS code dynamically creates the mapping of members based on -** that JSON description. -*/ -typedef struct sqlite3_kvvfs_methods sqlite3_kvvfs_methods; -struct sqlite3_kvvfs_methods { - int (*xRead)(const char *zClass, const char *zKey, char *zBuf, int nBuf); - int (*xWrite)(const char *zClass, const char *zKey, const char *zData); - int (*xDelete)(const char *zClass, const char *zKey); - const int nKeySize; -}; - -/* -** This object holds the kvvfs I/O methods which may be swapped out -** for JavaScript-side implementations in WASM builds. In such builds -** it cannot be const, but in native builds it should be so that -** the compiler can hopefully optimize this level of indirection out. -** That said, kvvfs is intended primarily for use in WASM builds. -** -** Note that this is not explicitly flagged as static because the -** amalgamation build will tag it with SQLITE_PRIVATE. -*/ -#ifndef SQLITE_WASM -const -#endif -SQLITE_PRIVATE sqlite3_kvvfs_methods sqlite3KvvfsMethods = { -kvstorageRead, -kvstorageWrite, -kvstorageDelete, -KVSTORAGE_KEY_SZ -}; - -/****** Utility subroutines ************************************************/ - -/* -** Encode binary into the text encoded used to persist on disk. -** The output text is stored in aOut[], which must be at least -** nData+1 bytes in length. -** -** Return the actual length of the encoded text, not counting the -** zero terminator at the end. -** -** Encoding format -** --------------- -** -** * Non-zero bytes are encoded as upper-case hexadecimal -** -** * A sequence of one or more zero-bytes that are not at the -** beginning of the buffer are encoded as a little-endian -** base-26 number using a..z. "a" means 0. "b" means 1, -** "z" means 25. "ab" means 26. "ac" means 52. And so forth. -** -** * Because there is no overlap between the encoding characters -** of hexadecimal and base-26 numbers, it is always clear where -** one stops and the next begins. -*/ -static int kvvfsEncode(const char *aData, int nData, char *aOut){ - int i, j; - const unsigned char *a = (const unsigned char*)aData; - for(i=j=0; i>4]; - aOut[j++] = "0123456789ABCDEF"[c&0xf]; - }else{ - /* A sequence of 1 or more zeros is stored as a little-endian - ** base-26 number using a..z as the digits. So one zero is "b". - ** Two zeros is "c". 25 zeros is "z", 26 zeros is "ab", 27 is "bb", - ** and so forth. - */ - int k; - for(k=1; i+k0 ){ - aOut[j++] = 'a'+(k%26); - k /= 26; - } - } - } - aOut[j] = 0; - return j; -} - -static const signed char kvvfsHexValue[256] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -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, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 -}; - -/* -** Decode the text encoding back to binary. The binary content is -** written into pOut, which must be at least nOut bytes in length. -** -** The return value is the number of bytes actually written into aOut[]. -*/ -static int kvvfsDecode(const char *a, char *aOut, int nOut){ - int i, j; - int c; - const unsigned char *aIn = (const unsigned char*)a; - i = 0; - j = 0; - while( 1 ){ - c = kvvfsHexValue[aIn[i]]; - if( c<0 ){ - int n = 0; - int mult = 1; - c = aIn[i]; - if( c==0 ) break; - while( c>='a' && c<='z' ){ - n += (c - 'a')*mult; - mult *= 26; - c = aIn[++i]; - } - if( j+n>nOut ) return -1; - memset(&aOut[j], 0, n); - j += n; - if( c==0 || mult==1 ) break; /* progress stalled if mult==1 */ - }else{ - aOut[j] = c<<4; - c = kvvfsHexValue[aIn[++i]]; - if( c<0 ) break; - aOut[j++] += c; - i++; - } - } - return j; -} - -/* -** Decode a complete journal file. Allocate space in pFile->aJrnl -** and store the decoding there. Or leave pFile->aJrnl set to NULL -** if an error is encountered. -** -** The first few characters of the text encoding will be a little-endian -** base-26 number (digits a..z) that is the total number of bytes -** in the decoded journal file image. This base-26 number is followed -** by a single space, then the encoding of the journal. The space -** separator is required to act as a terminator for the base-26 number. -*/ -static void kvvfsDecodeJournal( - KVVfsFile *pFile, /* Store decoding in pFile->aJrnl */ - const char *zTxt, /* Text encoding. Zero-terminated */ - int nTxt /* Bytes in zTxt, excluding zero terminator */ -){ - unsigned int n = 0; - int c, i, mult; - i = 0; - mult = 1; - while( (c = zTxt[i++])>='a' && c<='z' ){ - n += (zTxt[i] - 'a')*mult; - mult *= 26; - } - sqlite3_free(pFile->aJrnl); - pFile->aJrnl = sqlite3_malloc64( n ); - if( pFile->aJrnl==0 ){ - pFile->nJrnl = 0; - return; - } - pFile->nJrnl = n; - n = kvvfsDecode(zTxt+i, pFile->aJrnl, pFile->nJrnl); - if( nnJrnl ){ - sqlite3_free(pFile->aJrnl); - pFile->aJrnl = 0; - pFile->nJrnl = 0; - } -} - -/* -** Read or write the "sz" element, containing the database file size. -*/ -static sqlite3_int64 kvvfsReadFileSize(KVVfsFile *pFile){ - char zData[50]; - zData[0] = 0; - sqlite3KvvfsMethods.xRead(pFile->zClass, "sz", zData, sizeof(zData)-1); - return strtoll(zData, 0, 0); -} -static int kvvfsWriteFileSize(KVVfsFile *pFile, sqlite3_int64 sz){ - char zData[50]; - sqlite3_snprintf(sizeof(zData), zData, "%lld", sz); - return sqlite3KvvfsMethods.xWrite(pFile->zClass, "sz", zData); -} - -/****** sqlite3_io_methods methods ******************************************/ - -/* -** Close an kvvfs-file. -*/ -static int kvvfsClose(sqlite3_file *pProtoFile){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - - SQLITE_KV_LOG(("xClose %s %s\n", pFile->zClass, - pFile->isJournal ? "journal" : "db")); - sqlite3_free(pFile->aJrnl); - sqlite3_free(pFile->aData); - return SQLITE_OK; -} - -/* -** Read from the -journal file. -*/ -static int kvvfsReadJrnl( - sqlite3_file *pProtoFile, - void *zBuf, - int iAmt, - sqlite_int64 iOfst -){ - KVVfsFile *pFile = (KVVfsFile*)pProtoFile; - assert( pFile->isJournal ); - SQLITE_KV_LOG(("xRead('%s-journal',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); - if( pFile->aJrnl==0 ){ - int szTxt = kvstorageRead(pFile->zClass, "jrnl", 0, 0); - char *aTxt; - if( szTxt<=4 ){ - return SQLITE_IOERR; - } - aTxt = sqlite3_malloc64( szTxt+1 ); - if( aTxt==0 ) return SQLITE_NOMEM; - kvstorageRead(pFile->zClass, "jrnl", aTxt, szTxt+1); - kvvfsDecodeJournal(pFile, aTxt, szTxt); - sqlite3_free(aTxt); - if( pFile->aJrnl==0 ) return SQLITE_IOERR; - } - if( iOfst+iAmt>pFile->nJrnl ){ - return SQLITE_IOERR_SHORT_READ; - } - memcpy(zBuf, pFile->aJrnl+iOfst, iAmt); - return SQLITE_OK; -} - -/* -** Read from the database file. -*/ -static int kvvfsReadDb( - sqlite3_file *pProtoFile, - void *zBuf, - int iAmt, - sqlite_int64 iOfst -){ - KVVfsFile *pFile = (KVVfsFile*)pProtoFile; - unsigned int pgno; - int got, n; - char zKey[30]; - char *aData = pFile->aData; - assert( iOfst>=0 ); - assert( iAmt>=0 ); - SQLITE_KV_LOG(("xRead('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); - if( iOfst+iAmt>=512 ){ - if( (iOfst % iAmt)!=0 ){ - return SQLITE_IOERR_READ; - } - if( (iAmt & (iAmt-1))!=0 || iAmt<512 || iAmt>65536 ){ - return SQLITE_IOERR_READ; - } - pFile->szPage = iAmt; - pgno = 1 + iOfst/iAmt; - }else{ - pgno = 1; - } - sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); - got = sqlite3KvvfsMethods.xRead(pFile->zClass, zKey, - aData, SQLITE_KVOS_SZ-1); - if( got<0 ){ - n = 0; - }else{ - aData[got] = 0; - if( iOfst+iAmt<512 ){ - int k = iOfst+iAmt; - aData[k*2] = 0; - n = kvvfsDecode(aData, &aData[2000], SQLITE_KVOS_SZ-2000); - if( n>=iOfst+iAmt ){ - memcpy(zBuf, &aData[2000+iOfst], iAmt); - n = iAmt; - }else{ - n = 0; - } - }else{ - n = kvvfsDecode(aData, zBuf, iAmt); - } - } - if( nzClass, iAmt, iOfst)); - if( iEnd>=0x10000000 ) return SQLITE_FULL; - if( pFile->aJrnl==0 || pFile->nJrnlaJrnl, iEnd); - if( aNew==0 ){ - return SQLITE_IOERR_NOMEM; - } - pFile->aJrnl = aNew; - if( pFile->nJrnlaJrnl+pFile->nJrnl, 0, iOfst-pFile->nJrnl); - } - pFile->nJrnl = iEnd; - } - memcpy(pFile->aJrnl+iOfst, zBuf, iAmt); - return SQLITE_OK; -} - -/* -** Write into the database file. -*/ -static int kvvfsWriteDb( - sqlite3_file *pProtoFile, - const void *zBuf, - int iAmt, - sqlite_int64 iOfst -){ - KVVfsFile *pFile = (KVVfsFile*)pProtoFile; - unsigned int pgno; - char zKey[30]; - char *aData = pFile->aData; - SQLITE_KV_LOG(("xWrite('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); - assert( iAmt>=512 && iAmt<=65536 ); - assert( (iAmt & (iAmt-1))==0 ); - assert( pFile->szPage<0 || pFile->szPage==iAmt ); - pFile->szPage = iAmt; - pgno = 1 + iOfst/iAmt; - sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); - kvvfsEncode(zBuf, iAmt, aData); - if( sqlite3KvvfsMethods.xWrite(pFile->zClass, zKey, aData) ){ - return SQLITE_IOERR; - } - if( iOfst+iAmt > pFile->szDb ){ - pFile->szDb = iOfst + iAmt; - } - return SQLITE_OK; -} - -/* -** Truncate an kvvfs-file. -*/ -static int kvvfsTruncateJrnl(sqlite3_file *pProtoFile, sqlite_int64 size){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - SQLITE_KV_LOG(("xTruncate('%s-journal',%lld)\n", pFile->zClass, size)); - assert( size==0 ); - sqlite3KvvfsMethods.xDelete(pFile->zClass, "jrnl"); - sqlite3_free(pFile->aJrnl); - pFile->aJrnl = 0; - pFile->nJrnl = 0; - return SQLITE_OK; -} -static int kvvfsTruncateDb(sqlite3_file *pProtoFile, sqlite_int64 size){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - if( pFile->szDb>size - && pFile->szPage>0 - && (size % pFile->szPage)==0 - ){ - char zKey[50]; - unsigned int pgno, pgnoMax; - SQLITE_KV_LOG(("xTruncate('%s-db',%lld)\n", pFile->zClass, size)); - pgno = 1 + size/pFile->szPage; - pgnoMax = 2 + pFile->szDb/pFile->szPage; - while( pgno<=pgnoMax ){ - sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); - sqlite3KvvfsMethods.xDelete(pFile->zClass, zKey); - pgno++; - } - pFile->szDb = size; - return kvvfsWriteFileSize(pFile, size) ? SQLITE_IOERR : SQLITE_OK; - } - return SQLITE_IOERR; -} - -/* -** Sync an kvvfs-file. -*/ -static int kvvfsSyncJrnl(sqlite3_file *pProtoFile, int flags){ - int i, n; - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - char *zOut; - SQLITE_KV_LOG(("xSync('%s-journal')\n", pFile->zClass)); - if( pFile->nJrnl<=0 ){ - return kvvfsTruncateJrnl(pProtoFile, 0); - } - zOut = sqlite3_malloc64( pFile->nJrnl*2 + 50 ); - if( zOut==0 ){ - return SQLITE_IOERR_NOMEM; - } - n = pFile->nJrnl; - i = 0; - do{ - zOut[i++] = 'a' + (n%26); - n /= 26; - }while( n>0 ); - zOut[i++] = ' '; - kvvfsEncode(pFile->aJrnl, pFile->nJrnl, &zOut[i]); - i = sqlite3KvvfsMethods.xWrite(pFile->zClass, "jrnl", zOut); - sqlite3_free(zOut); - return i ? SQLITE_IOERR : SQLITE_OK; -} -static int kvvfsSyncDb(sqlite3_file *pProtoFile, int flags){ - return SQLITE_OK; -} - -/* -** Return the current file-size of an kvvfs-file. -*/ -static int kvvfsFileSizeJrnl(sqlite3_file *pProtoFile, sqlite_int64 *pSize){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - SQLITE_KV_LOG(("xFileSize('%s-journal')\n", pFile->zClass)); - *pSize = pFile->nJrnl; - return SQLITE_OK; -} -static int kvvfsFileSizeDb(sqlite3_file *pProtoFile, sqlite_int64 *pSize){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - SQLITE_KV_LOG(("xFileSize('%s-db')\n", pFile->zClass)); - if( pFile->szDb>=0 ){ - *pSize = pFile->szDb; - }else{ - *pSize = kvvfsReadFileSize(pFile); - } - return SQLITE_OK; -} - -/* -** Lock an kvvfs-file. -*/ -static int kvvfsLock(sqlite3_file *pProtoFile, int eLock){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - assert( !pFile->isJournal ); - SQLITE_KV_LOG(("xLock(%s,%d)\n", pFile->zClass, eLock)); - - if( eLock!=SQLITE_LOCK_NONE ){ - pFile->szDb = kvvfsReadFileSize(pFile); - } - return SQLITE_OK; -} - -/* -** Unlock an kvvfs-file. -*/ -static int kvvfsUnlock(sqlite3_file *pProtoFile, int eLock){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - assert( !pFile->isJournal ); - SQLITE_KV_LOG(("xUnlock(%s,%d)\n", pFile->zClass, eLock)); - if( eLock==SQLITE_LOCK_NONE ){ - pFile->szDb = -1; - } - return SQLITE_OK; -} - -/* -** Check if another file-handle holds a RESERVED lock on an kvvfs-file. -*/ -static int kvvfsCheckReservedLock(sqlite3_file *pProtoFile, int *pResOut){ - SQLITE_KV_LOG(("xCheckReservedLock\n")); - *pResOut = 0; - return SQLITE_OK; -} - -/* -** File control method. For custom operations on an kvvfs-file. -*/ -static int kvvfsFileControlJrnl(sqlite3_file *pProtoFile, int op, void *pArg){ - SQLITE_KV_LOG(("xFileControl(%d) on journal\n", op)); - return SQLITE_NOTFOUND; -} -static int kvvfsFileControlDb(sqlite3_file *pProtoFile, int op, void *pArg){ - SQLITE_KV_LOG(("xFileControl(%d) on database\n", op)); - if( op==SQLITE_FCNTL_SYNC ){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - int rc = SQLITE_OK; - SQLITE_KV_LOG(("xSync('%s-db')\n", pFile->zClass)); - if( pFile->szDb>0 && 0!=kvvfsWriteFileSize(pFile, pFile->szDb) ){ - rc = SQLITE_IOERR; - } - return rc; - } - return SQLITE_NOTFOUND; -} - -/* -** Return the sector-size in bytes for an kvvfs-file. -*/ -static int kvvfsSectorSize(sqlite3_file *pFile){ - return 512; -} - -/* -** Return the device characteristic flags supported by an kvvfs-file. -*/ -static int kvvfsDeviceCharacteristics(sqlite3_file *pProtoFile){ - return 0; -} - -/****** sqlite3_vfs methods *************************************************/ - -/* -** Open an kvvfs file handle. -*/ -static int kvvfsOpen( - sqlite3_vfs *pProtoVfs, - const char *zName, - sqlite3_file *pProtoFile, - int flags, - int *pOutFlags -){ - KVVfsFile *pFile = (KVVfsFile*)pProtoFile; - if( zName==0 ) zName = ""; - SQLITE_KV_LOG(("xOpen(\"%s\")\n", zName)); - if( strcmp(zName, "local")==0 - || strcmp(zName, "session")==0 - ){ - pFile->isJournal = 0; - pFile->base.pMethods = &kvvfs_db_io_methods; - }else - if( strcmp(zName, "local-journal")==0 - || strcmp(zName, "session-journal")==0 - ){ - pFile->isJournal = 1; - pFile->base.pMethods = &kvvfs_jrnl_io_methods; - }else{ - return SQLITE_CANTOPEN; - } - if( zName[0]=='s' ){ - pFile->zClass = "session"; - }else{ - pFile->zClass = "local"; - } - pFile->aData = sqlite3_malloc64(SQLITE_KVOS_SZ); - if( pFile->aData==0 ){ - return SQLITE_NOMEM; - } - pFile->aJrnl = 0; - pFile->nJrnl = 0; - pFile->szPage = -1; - pFile->szDb = -1; - return SQLITE_OK; -} - -/* -** Delete the file located at zPath. If the dirSync argument is true, -** ensure the file-system modifications are synced to disk before -** returning. -*/ -static int kvvfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ - if( strcmp(zPath, "local-journal")==0 ){ - sqlite3KvvfsMethods.xDelete("local", "jrnl"); - }else - if( strcmp(zPath, "session-journal")==0 ){ - sqlite3KvvfsMethods.xDelete("session", "jrnl"); - } - return SQLITE_OK; -} - -/* -** Test for access permissions. Return true if the requested permission -** is available, or false otherwise. -*/ -static int kvvfsAccess( - sqlite3_vfs *pProtoVfs, - const char *zPath, - int flags, - int *pResOut -){ - SQLITE_KV_LOG(("xAccess(\"%s\")\n", zPath)); - if( strcmp(zPath, "local-journal")==0 ){ - *pResOut = sqlite3KvvfsMethods.xRead("local", "jrnl", 0, 0)>0; - }else - if( strcmp(zPath, "session-journal")==0 ){ - *pResOut = sqlite3KvvfsMethods.xRead("session", "jrnl", 0, 0)>0; - }else - if( strcmp(zPath, "local")==0 ){ - *pResOut = sqlite3KvvfsMethods.xRead("local", "sz", 0, 0)>0; - }else - if( strcmp(zPath, "session")==0 ){ - *pResOut = sqlite3KvvfsMethods.xRead("session", "sz", 0, 0)>0; - }else - { - *pResOut = 0; - } - SQLITE_KV_LOG(("xAccess returns %d\n",*pResOut)); - return SQLITE_OK; -} - -/* -** Populate buffer zOut with the full canonical pathname corresponding -** to the pathname in zPath. zOut is guaranteed to point to a buffer -** of at least (INST_MAX_PATHNAME+1) bytes. -*/ -static int kvvfsFullPathname( - sqlite3_vfs *pVfs, - const char *zPath, - int nOut, - char *zOut -){ - size_t nPath; -#ifdef SQLITE_OS_KV_ALWAYS_LOCAL - zPath = "local"; -#endif - nPath = strlen(zPath); - SQLITE_KV_LOG(("xFullPathname(\"%s\")\n", zPath)); - if( nOut -static int kvvfsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ - static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; - struct timeval sNow; - (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */ - *pTimeOut = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; - return SQLITE_OK; -} -#endif /* SQLITE_OS_KV || SQLITE_OS_UNIX */ - -#if SQLITE_OS_KV -/* -** This routine is called initialize the KV-vfs as the default VFS. -*/ -SQLITE_API int sqlite3_os_init(void){ - return sqlite3_vfs_register(&sqlite3OsKvvfsObject, 1); -} -SQLITE_API int sqlite3_os_end(void){ - return SQLITE_OK; -} -#endif /* SQLITE_OS_KV */ - -#if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) -SQLITE_PRIVATE int sqlite3KvvfsInit(void){ - return sqlite3_vfs_register(&sqlite3OsKvvfsObject, 0); -} -#endif - -/************** End of os_kv.c ***********************************************/ /************** Begin file os_unix.c *****************************************/ /* ** 2004 May 22 ** ** The author disclaims copyright to this source code. In place of @@ -36991,17 +35542,17 @@ #endif /* ** standard include files. */ -#include /* amalgamator: keep */ -#include /* amalgamator: keep */ +#include +#include #include #include -#include /* amalgamator: keep */ +#include /* #include */ -#include /* amalgamator: keep */ +#include #include #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 # include #endif @@ -37590,13 +36141,10 @@ if( fd<0 ){ if( errno==EINTR ) continue; break; } if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break; - if( (f & (O_EXCL|O_CREAT))==(O_EXCL|O_CREAT) ){ - (void)osUnlink(z); - } osClose(fd); sqlite3_log(SQLITE_WARNING, "attempt to open \"%s\" as file descriptor %d", z, fd); fd = -1; if( osOpen("/dev/null", O_RDONLY, m)<0 ) break; @@ -38555,11 +37103,11 @@ ** still short of its goal. The following chart shows the allowed ** transitions and the inserted intermediate states: ** ** UNLOCKED -> SHARED ** SHARED -> RESERVED -** SHARED -> EXCLUSIVE +** SHARED -> (PENDING) -> EXCLUSIVE ** RESERVED -> (PENDING) -> EXCLUSIVE ** PENDING -> EXCLUSIVE ** ** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. @@ -38588,24 +37136,23 @@ ** ** A process may only obtain a RESERVED lock after it has a SHARED lock. ** A RESERVED lock is implemented by grabbing a write-lock on the ** 'reserved byte'. ** - ** An EXCLUSIVE lock may only be requested after either a SHARED or - ** RESERVED lock is held. An EXCLUSIVE lock is implemented by obtaining - ** a write-lock on the entire 'shared byte range'. Since all other locks - ** require a read-lock on one of the bytes within this range, this ensures - ** that no other locks are held on the database. + ** A process may only obtain a PENDING lock after it has obtained a + ** SHARED lock. A PENDING lock is implemented by 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. A process + ** does not have to obtain a RESERVED lock on the way to a PENDING lock. + ** This property is used by the algorithm for rolling back a journal file + ** after a crash. ** - ** If a process that holds a RESERVED lock requests an EXCLUSIVE, then - ** a PENDING lock is obtained first. A PENDING lock is implemented by - ** 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 intead. The client may - ** then re-attempt the EXCLUSIVE lock later on, after existing SHARED - ** locks have cleared. + ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is + ** implemented by obtaining a write-lock on the entire 'shared byte + ** range'. Since all other locks require a read-lock on one of the bytes + ** within this range, this ensures that no other locks are held on the + ** database. */ int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; unixInodeInfo *pInode; struct flock lock; @@ -38672,11 +37219,11 @@ ** be released. */ lock.l_len = 1L; lock.l_whence = SEEK_SET; if( eFileLock==SHARED_LOCK - || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock==RESERVED_LOCK) + || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLockeFileLock = PENDING_LOCK; - pInode->eFileLock = PENDING_LOCK; } } /* If control gets to this point, then actually go ahead and make @@ -38772,14 +37316,18 @@ pFile->transCntrChng = 0; pFile->dbUpdate = 0; pFile->inNormalWrite = 1; } #endif + if( rc==SQLITE_OK ){ pFile->eFileLock = eFileLock; pInode->eFileLock = eFileLock; + }else if( eFileLock==EXCLUSIVE_LOCK ){ + pFile->eFileLock = PENDING_LOCK; + pInode->eFileLock = PENDING_LOCK; } end_lock: sqlite3_mutex_leave(pInode->pLockMutex); OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), @@ -42762,39 +41310,30 @@ ** pVfs->mxPathname bytes. */ static int unixGetTempname(int nBuf, char *zBuf){ const char *zDir; int iLimit = 0; - int rc = SQLITE_OK; /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. */ zBuf[0] = 0; SimulateIOError( return SQLITE_IOERR ); - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); zDir = unixTempFileDir(); - if( zDir==0 ){ - rc = SQLITE_IOERR_GETTEMPPATH; - }else{ - do{ - u64 r; - sqlite3_randomness(sizeof(r), &r); - assert( nBuf>2 ); - zBuf[nBuf-2] = 0; - sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c", - zDir, r, 0); - if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ){ - rc = SQLITE_ERROR; - break; - } - }while( osAccess(zBuf,0)==0 ); - } - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); - return rc; + if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH; + do{ + u64 r; + sqlite3_randomness(sizeof(r), &r); + assert( nBuf>2 ); + zBuf[nBuf-2] = 0; + sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c", + zDir, r, 0); + if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ) return SQLITE_ERROR; + }while( osAccess(zBuf,0)==0 ); + return SQLITE_OK; } #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) /* ** Routine to transform a unixFile into a proxy-locking unixFile. @@ -43366,14 +41905,16 @@ assert( nName>0 ); assert( zName!=0 ); if( zName[0]=='.' ){ if( nName==1 ) return; if( zName[1]=='.' && nName==2 ){ - if( pPath->nUsed>1 ){ - assert( pPath->zOut[0]=='/' ); - while( pPath->zOut[--pPath->nUsed]!='/' ){} + if( pPath->nUsed<=1 ){ + pPath->rc = SQLITE_ERROR; + return; } + assert( pPath->zOut[0]=='/' ); + while( pPath->zOut[--pPath->nUsed]!='/' ){} return; } } if( pPath->nUsed + nName + 2 >= pPath->nOut ){ pPath->rc = SQLITE_ERROR; @@ -43581,11 +42122,11 @@ ** requested from the underlying operating system, a number which ** might be greater than or equal to the argument, but not less ** than the argument. */ static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ -#if OS_VXWORKS || _POSIX_C_SOURCE >= 199309L +#if OS_VXWORKS struct timespec sp; sp.tv_sec = microseconds / 1000000; sp.tv_nsec = (microseconds % 1000000) * 1000; nanosleep(&sp, NULL); @@ -44963,20 +43504,12 @@ ** correctly. See ticket [bb3a86e890c8e96ab] */ assert( ArraySize(aSyscall)==29 ); /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ -#ifdef SQLITE_DEFAULT_UNIX_VFS - sqlite3_vfs_register(&aVfs[i], - 0==strcmp(aVfs[i].zName,SQLITE_DEFAULT_UNIX_VFS)); -#else sqlite3_vfs_register(&aVfs[i], i==0); -#endif } -#ifdef SQLITE_OS_KV_OPTIONAL - sqlite3KvvfsInit(); -#endif unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); #ifndef SQLITE_OMIT_WAL /* Validate lock assumptions */ assert( SQLITE_SHM_NLOCK==8 ); /* Number of available locks */ @@ -46935,16 +45468,14 @@ SQLITE_API int sqlite3_win32_set_directory8( unsigned long type, /* Identifier for directory being set or reset */ const char *zValue /* New value for directory being set or reset */ ){ char **ppDirectory = 0; - int rc; #ifndef SQLITE_OMIT_AUTOINIT - rc = sqlite3_initialize(); + int rc = sqlite3_initialize(); if( rc ) return rc; #endif - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){ ppDirectory = &sqlite3_data_directory; }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){ ppDirectory = &sqlite3_temp_directory; } @@ -46955,23 +45486,18 @@ if( ppDirectory ){ char *zCopy = 0; if( zValue && zValue[0] ){ zCopy = sqlite3_mprintf("%s", zValue); if ( zCopy==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto set_directory8_done; + return SQLITE_NOMEM_BKPT; } } sqlite3_free(*ppDirectory); *ppDirectory = zCopy; - rc = SQLITE_OK; - }else{ - rc = SQLITE_ERROR; + return SQLITE_OK; } -set_directory8_done: - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); - return rc; + return SQLITE_ERROR; } /* ** This function is the same as sqlite3_win32_set_directory (below); however, ** it accepts a UTF-16 string. @@ -49741,23 +48267,10 @@ } } return 0; } -/* -** If sqlite3_temp_directory is defined, take the mutex and return true. -** -** If sqlite3_temp_directory is NULL (undefined), omit the mutex and -** return false. -*/ -static int winTempDirDefined(void){ - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); - if( sqlite3_temp_directory!=0 ) return 1; - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); - return 0; -} - /* ** Create a temporary file name and store the resulting pointer into pzBuf. ** The pointer returned in pzBuf must be freed via sqlite3_free(). */ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ @@ -49790,27 +48303,24 @@ ** has been explicitly set by the application; otherwise, use the one ** configured by the operating system. */ nDir = nMax - (nPre + 15); assert( nDir>0 ); - if( winTempDirDefined() ){ + if( sqlite3_temp_directory ){ int nDirLen = sqlite3Strlen30(sqlite3_temp_directory); if( nDirLen>0 ){ if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){ nDirLen++; } if( nDirLen>nDir ){ - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0); } sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory); } - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); } - #if defined(__CYGWIN__) else{ static const char *azDirs[] = { 0, /* getenv("SQLITE_TMPDIR") */ 0, /* getenv("TMPDIR") */ @@ -50595,11 +49105,11 @@ /* ** Turn a relative pathname into a full pathname. Write the full ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname ** bytes in size. */ -static int winFullPathnameNoMutex( +static int winFullPathname( sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zRelative, /* Possibly relative input path */ int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ @@ -50774,24 +49284,10 @@ }else{ return SQLITE_IOERR_NOMEM_BKPT; } #endif } -static int winFullPathname( - sqlite3_vfs *pVfs, /* Pointer to vfs object */ - const char *zRelative, /* Possibly relative input path */ - int nFull, /* Size of output buffer in bytes */ - char *zFull /* Output buffer */ -){ - int rc; - MUTEX_LOGIC( sqlite3_mutex *pMutex; ) - MUTEX_LOGIC( pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR); ) - sqlite3_mutex_enter(pMutex); - rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull); - sqlite3_mutex_leave(pMutex); - return rc; -} #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Interfaces for opening a shared library, finding entry points ** within the shared library, and closing the shared library. @@ -51324,11 +49820,10 @@ static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); static int memdbTruncate(sqlite3_file*, sqlite3_int64 size); static int memdbSync(sqlite3_file*, int flags); static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize); static int memdbLock(sqlite3_file*, int); -static int memdbUnlock(sqlite3_file*, int); /* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */ static int memdbFileControl(sqlite3_file*, int op, void *pArg); /* static int memdbSectorSize(sqlite3_file*); // not used */ static int memdbDeviceCharacteristics(sqlite3_file*); static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); @@ -51383,11 +49878,11 @@ memdbWrite, /* xWrite */ memdbTruncate, /* xTruncate */ memdbSync, /* xSync */ memdbFileSize, /* xFileSize */ memdbLock, /* xLock */ - memdbUnlock, /* xUnlock */ + memdbLock, /* xUnlock - same as xLock in this case */ 0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */ memdbFileControl, /* xFileControl */ 0, /* memdbSectorSize,*/ /* xSectorSize */ memdbDeviceCharacteristics, /* xDeviceCharacteristics */ 0, /* xShmMap */ @@ -51584,87 +50079,45 @@ */ static int memdbLock(sqlite3_file *pFile, int eLock){ MemFile *pThis = (MemFile*)pFile; MemStore *p = pThis->pStore; int rc = SQLITE_OK; - if( eLock<=pThis->eLock ) return SQLITE_OK; + if( eLock==pThis->eLock ) return SQLITE_OK; memdbEnter(p); - - assert( p->nWrLock==0 || p->nWrLock==1 ); - assert( pThis->eLock<=SQLITE_LOCK_SHARED || p->nWrLock==1 ); - assert( pThis->eLock==SQLITE_LOCK_NONE || p->nRdLock>=1 ); - - if( eLock>SQLITE_LOCK_SHARED && (p->mFlags & SQLITE_DESERIALIZE_READONLY) ){ - rc = SQLITE_READONLY; - }else{ - switch( eLock ){ - case SQLITE_LOCK_SHARED: { - assert( pThis->eLock==SQLITE_LOCK_NONE ); - if( p->nWrLock>0 ){ - rc = SQLITE_BUSY; - }else{ - p->nRdLock++; - } - break; - }; - - case SQLITE_LOCK_RESERVED: - case SQLITE_LOCK_PENDING: { - assert( pThis->eLock>=SQLITE_LOCK_SHARED ); - if( ALWAYS(pThis->eLock==SQLITE_LOCK_SHARED) ){ - if( p->nWrLock>0 ){ - rc = SQLITE_BUSY; - }else{ - p->nWrLock = 1; - } - } - break; - } - - default: { - assert( eLock==SQLITE_LOCK_EXCLUSIVE ); - assert( pThis->eLock>=SQLITE_LOCK_SHARED ); - if( p->nRdLock>1 ){ - rc = SQLITE_BUSY; - }else if( pThis->eLock==SQLITE_LOCK_SHARED ){ - p->nWrLock = 1; - } - break; - } - } + if( eLock>SQLITE_LOCK_SHARED ){ + if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){ + rc = SQLITE_READONLY; + }else if( pThis->eLock<=SQLITE_LOCK_SHARED ){ + if( p->nWrLock ){ + rc = SQLITE_BUSY; + }else{ + p->nWrLock = 1; + } + } + }else if( eLock==SQLITE_LOCK_SHARED ){ + if( pThis->eLock > SQLITE_LOCK_SHARED ){ + assert( p->nWrLock==1 ); + p->nWrLock = 0; + }else if( p->nWrLock ){ + rc = SQLITE_BUSY; + }else{ + p->nRdLock++; + } + }else{ + assert( eLock==SQLITE_LOCK_NONE ); + if( pThis->eLock>SQLITE_LOCK_SHARED ){ + assert( p->nWrLock==1 ); + p->nWrLock = 0; + } + assert( p->nRdLock>0 ); + p->nRdLock--; } if( rc==SQLITE_OK ) pThis->eLock = eLock; memdbLeave(p); return rc; } -/* -** Unlock an memdb-file. -*/ -static int memdbUnlock(sqlite3_file *pFile, int eLock){ - MemFile *pThis = (MemFile*)pFile; - MemStore *p = pThis->pStore; - if( eLock>=pThis->eLock ) return SQLITE_OK; - memdbEnter(p); - - assert( eLock==SQLITE_LOCK_SHARED || eLock==SQLITE_LOCK_NONE ); - if( eLock==SQLITE_LOCK_SHARED ){ - if( ALWAYS(pThis->eLock>SQLITE_LOCK_SHARED) ){ - p->nWrLock--; - } - }else{ - if( pThis->eLock>SQLITE_LOCK_SHARED ){ - p->nWrLock--; - } - p->nRdLock--; - } - - pThis->eLock = eLock; - memdbLeave(p); - return SQLITE_OK; -} - #if 0 /* ** This interface is only used for crash recovery, which does not ** occur on an in-memory database. */ @@ -51768,11 +50221,11 @@ int szName; UNUSED_PARAMETER(pVfs); memset(pFile, 0, sizeof(*pFile)); szName = sqlite3Strlen30(zName); - if( szName>1 && (zName[0]=='/' || zName[0]=='\\') ){ + if( szName>1 && zName[0]=='/' ){ int i; #ifndef SQLITE_MUTEX_OMIT sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); #endif sqlite3_mutex_enter(pVfsMutex); @@ -52115,17 +50568,10 @@ } sqlite3_mutex_leave(db->mutex); return rc; } -/* -** Return true if the VFS is the memvfs. -*/ -SQLITE_PRIVATE int sqlite3IsMemdb(const sqlite3_vfs *pVfs){ - return pVfs==&memdb_vfs; -} - /* ** This routine is called when the extension is loaded. ** Register the new VFS. */ SQLITE_PRIVATE int sqlite3MemdbInit(void){ @@ -52626,56 +51072,37 @@ */ #if defined(SQLITE_DEBUG) && 0 int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */ int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */ # define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;} - static void pcachePageTrace(int i, sqlite3_pcache_page *pLower){ + void pcacheDump(PCache *pCache){ + int N; + int i, j; + sqlite3_pcache_page *pLower; PgHdr *pPg; unsigned char *a; - int j; - pPg = (PgHdr*)pLower->pExtra; - printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags); - a = (unsigned char *)pLower->pBuf; - for(j=0; j<12; j++) printf("%02x", a[j]); - printf(" ptr %p\n", pPg); - } - static void pcacheDump(PCache *pCache){ - int N; - int i; - sqlite3_pcache_page *pLower; if( sqlite3PcacheTrace<2 ) return; if( pCache->pCache==0 ) return; N = sqlite3PcachePagecount(pCache); if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump; for(i=1; i<=N; i++){ pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); if( pLower==0 ) continue; - pcachePageTrace(i, pLower); - if( ((PgHdr*)pLower)->pPage==0 ){ + pPg = (PgHdr*)pLower->pExtra; + printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags); + a = (unsigned char *)pLower->pBuf; + for(j=0; j<12; j++) printf("%02x", a[j]); + printf("\n"); + if( pPg->pPage==0 ){ sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0); } } } -#else + #else # define pcacheTrace(X) -# define pcachePageTrace(PGNO, X) # define pcacheDump(X) -#endif - -/* -** Return 1 if pPg is on the dirty list for pCache. Return 0 if not. -** This routine runs inside of assert() statements only. -*/ -#ifdef SQLITE_DEBUG -static int pageOnDirtyList(PCache *pCache, PgHdr *pPg){ - PgHdr *p; - for(p=pCache->pDirty; p; p=p->pDirtyNext){ - if( p==pPg ) return 1; - } - return 0; -} #endif /* ** Check invariants on a PgHdr entry. Return true if everything is OK. ** Return false if any invariant is violated. @@ -52692,17 +51119,12 @@ assert( pPg->pgno>0 || pPg->pPager==0 ); /* Page number is 1 or more */ pCache = pPg->pCache; 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( !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 ); - assert( pPg->pDirtyPrev==0 || pPg->pDirtyPrev->pDirtyNext==pPg ); - assert( pPg->pDirtyPrev!=0 || pCache->pDirty==pPg ); - assert( pageOnDirtyList(pCache, pPg) ); + assert( pCache->pDirty!=pPg ); /* CLEAN pages not on dirty list */ + assert( pCache->pDirtyTail!=pPg ); } /* WRITEABLE pages must also be DIRTY */ if( pPg->flags & PGHDR_WRITEABLE ){ assert( pPg->flags & PGHDR_DIRTY ); /* WRITEABLE implies DIRTY */ } @@ -52972,13 +51394,12 @@ eCreate = createFlag & pCache->eCreate; assert( eCreate==0 || eCreate==1 || eCreate==2 ); assert( createFlag==0 || pCache->eCreate==eCreate ); assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) ); pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); - pcacheTrace(("%p.FETCH %d%s (result: %p) ",pCache,pgno, + pcacheTrace(("%p.FETCH %d%s (result: %p)\n",pCache,pgno, createFlag?" create":"",pRes)); - pcachePageTrace(pgno, pRes); return pRes; } /* ** If the sqlite3PcacheFetch() routine is unable to allocate a new @@ -53102,11 +51523,10 @@ if( (--p->nRef)==0 ){ if( p->flags&PGHDR_CLEAN ){ pcacheUnpin(p); }else{ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); - assert( sqlite3PcachePageSanity(p) ); } } } /* @@ -53146,11 +51566,10 @@ if( p->flags & PGHDR_CLEAN ){ p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN); pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno)); assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY ); pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); - assert( sqlite3PcachePageSanity(p) ); } assert( sqlite3PcachePageSanity(p) ); } } @@ -53209,28 +51628,18 @@ /* ** Change the page number of page p to newPgno. */ SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ PCache *pCache = p->pCache; - sqlite3_pcache_page *pOther; assert( p->nRef>0 ); assert( newPgno>0 ); assert( sqlite3PcachePageSanity(p) ); pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno)); - pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0); - if( pOther ){ - PgHdr *pXPage = (PgHdr*)pOther->pExtra; - assert( pXPage->nRef==0 ); - pXPage->nRef++; - pCache->nRefSum++; - sqlite3PcacheDrop(pXPage); - } sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); p->pgno = newPgno; if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); - assert( sqlite3PcachePageSanity(p) ); } } /* ** Drop every cache entry whose page number is greater than "pgno". The @@ -53524,17 +51933,16 @@ ** runtime using sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &size). The ** sizes of the extensions sum to 272 bytes on x64 for 3.8.10, but this ** size can vary according to architecture, compile-time options, and ** SQLite library version number. ** -** Historical note: It used to be that if the SQLITE_PCACHE_SEPARATE_HEADER -** was defined, then the page content would be held in a separate memory -** allocation from the PgHdr1. This was intended to avoid clownshoe memory -** allocations. However, the btree layer needs a small (16-byte) overrun -** area after the page content buffer. The header serves as that overrun -** area. Therefore SQLITE_PCACHE_SEPARATE_HEADER was discontinued to avoid -** any possibility of a memory error. +** If SQLITE_PCACHE_SEPARATE_HEADER is defined, then the extension is obtained +** using a separate memory allocation from the database page content. This +** seeks to overcome the "clownshoe" problem (also called "internal +** fragmentation" in academic literature) of allocating a few bytes more +** than a power of two with the memory allocator rounding up to the next +** power of two, and leaving the rounded-up space unused. ** ** This module tracks pointers to PgHdr1 objects. Only pcache.c communicates ** with this module. Information is passed back and forth as PgHdr1 pointers. ** ** The pcache.c and pager.c modules deal pointers to PgHdr objects. @@ -53575,44 +51983,34 @@ typedef struct PgFreeslot PgFreeslot; typedef struct PGroup PGroup; /* ** Each cache entry is represented by an instance of the following -** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated -** directly before this structure and is used to cache the page content. -** -** When reading a corrupt database file, it is possible that SQLite might -** read a few bytes (no more than 16 bytes) past the end of the page buffer. -** It will only read past the end of the page buffer, never write. This -** object is positioned immediately after the page buffer to serve as an -** overrun area, so that overreads are harmless. -** -** Variables isBulkLocal and isAnchor were once type "u8". That works, +** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of +** PgHdr1.pCache->szPage bytes is allocated directly before this structure +** in memory. +** +** Note: Variables isBulkLocal and isAnchor were once type "u8". That works, ** but causes a 2-byte gap in the structure for most architectures (since ** pointers must be either 4 or 8-byte aligned). As this structure is located ** 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 unitialized gap is accessed. Using u16 -** ensures there is no such gap, and therefore no bytes of uninitialized -** memory in the structure. -** -** The pLruNext and pLruPrev pointers form a double-linked circular list -** of all pages that are unpinned. The PGroup.lru element (which should be -** the only element on the list with PgHdr1.isAnchor set to 1) forms the -** beginning and the end of the list. +** ensures there is no such gap, and therefore no bytes of unitialized memory +** in the structure. */ struct PgHdr1 { - sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ - unsigned int iKey; /* Key value (page number) */ - u16 isBulkLocal; /* This page from bulk local storage */ - u16 isAnchor; /* This is the PGroup.lru element */ - PgHdr1 *pNext; /* Next in hash table chain */ - PCache1 *pCache; /* Cache that currently owns this page */ - PgHdr1 *pLruNext; /* Next in circular LRU list of unpinned pages */ - PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ - /* NB: pLruPrev is only valid if pLruNext!=0 */ + sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ + unsigned int iKey; /* Key value (page number) */ + u16 isBulkLocal; /* This page from bulk local storage */ + u16 isAnchor; /* This is the PGroup.lru element */ + PgHdr1 *pNext; /* Next in hash table chain */ + PCache1 *pCache; /* Cache that currently owns this page */ + PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */ + PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ + /* NB: pLruPrev is only valid if pLruNext!=0 */ }; /* ** A page is pinned if it is not on the LRU list. To be "pinned" means ** that the page is in active use and must not be deallocated. @@ -53934,17 +52332,29 @@ assert( pcache1.separateCache==0 ); assert( pCache->pGroup==&pcache1.grp ); pcache1LeaveMutex(pCache->pGroup); #endif if( benignMalloc ){ sqlite3BeginBenignMalloc(); } +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + pPg = pcache1Alloc(pCache->szPage); + p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra); + if( !pPg || !p ){ + pcache1Free(pPg); + sqlite3_free(p); + pPg = 0; + } +#else pPg = pcache1Alloc(pCache->szAlloc); +#endif if( benignMalloc ){ sqlite3EndBenignMalloc(); } #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT pcache1EnterMutex(pCache->pGroup); #endif if( pPg==0 ) return 0; +#ifndef SQLITE_PCACHE_SEPARATE_HEADER p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; +#endif p->page.pBuf = pPg; p->page.pExtra = &p[1]; p->isBulkLocal = 0; p->isAnchor = 0; p->pLruPrev = 0; /* Initializing this saves a valgrind error */ @@ -53964,10 +52374,13 @@ if( p->isBulkLocal ){ p->pNext = pCache->pFree; pCache->pFree = p; }else{ pcache1Free(p->page.pBuf); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + sqlite3_free(p); +#endif } (*pCache->pnPurgeable)--; } /* @@ -54604,30 +53017,27 @@ unsigned int iNew ){ PCache1 *pCache = (PCache1 *)p; PgHdr1 *pPage = (PgHdr1 *)pPg; PgHdr1 **pp; - unsigned int hOld, hNew; + unsigned int h; assert( pPage->iKey==iOld ); assert( pPage->pCache==pCache ); - assert( iOld!=iNew ); /* The page number really is changing */ pcache1EnterMutex(pCache->pGroup); - assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */ - hOld = iOld%pCache->nHash; - pp = &pCache->apHash[hOld]; + h = iOld%pCache->nHash; + pp = &pCache->apHash[h]; while( (*pp)!=pPage ){ pp = &(*pp)->pNext; } *pp = pPage->pNext; - assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not in cache */ - hNew = iNew%pCache->nHash; + h = iNew%pCache->nHash; pPage->iKey = iNew; - pPage->pNext = pCache->apHash[hNew]; - pCache->apHash[hNew] = pPage; + pPage->pNext = pCache->apHash[h]; + pCache->apHash[h] = pPage; if( iNew>pCache->iMaxKey ){ pCache->iMaxKey = iNew; } pcache1LeaveMutex(pCache->pGroup); @@ -54730,10 +53140,13 @@ while( (nReq<0 || nFreeisAnchor==0 ){ nFree += pcache1MemSize(p->page.pBuf); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + nFree += sqlite3MemSize(p); +#endif assert( PAGE_IS_UNPINNED(p) ); pcache1PinPage(p); pcache1RemoveFromHash(p, 1); } pcache1LeaveMutex(&pcache1.grp); @@ -58367,11 +56780,11 @@ if( rc==SQLITE_OK && zSuper[0] && res ){ /* If there was a super-journal and this routine will return success, ** see if it is possible to delete the super-journal. */ assert( zSuper==&pPager->pTmpSpace[4] ); - memset(pPager->pTmpSpace, 0, 4); + memset(&zSuper[-4], 0, 4); rc = pager_delsuper(pPager, zSuper); testcase( rc!=SQLITE_OK ); } if( isHot && nPlayback ){ sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s", @@ -60125,10 +58538,11 @@ int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ const char *zUri = 0; /* URI args to copy */ int nUriByte = 1; /* Number of bytes of URI args at *zUri */ + int nUri = 0; /* Number of URI parameters */ /* Figure out how much space is required for each journal file-handle ** (there are two of them, the main journal and the sub-journal). */ journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); @@ -60172,10 +58586,11 @@ nPathname = sqlite3Strlen30(zPathname); z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1]; while( *z ){ z += strlen(z)+1; z += strlen(z)+1; + nUri++; } nUriByte = (int)(&z[1] - zUri); assert( nUriByte>=1 ); if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ /* This branch is taken when the journal path required by @@ -61216,11 +59631,10 @@ int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; int nSpill; if( pPager->tempFile ){ flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL); - flags |= SQLITE_OPEN_EXCLUSIVE; nSpill = sqlite3Config.nStmtSpill; }else{ flags |= SQLITE_OPEN_MAIN_JOURNAL; nSpill = jrnlBufferSize(pPager); } @@ -61252,11 +59666,10 @@ } if( rc!=SQLITE_OK ){ sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; - pPager->journalOff = 0; }else{ assert( pPager->eState==PAGER_WRITER_LOCKED ); pPager->eState = PAGER_WRITER_CACHEMOD; } @@ -61699,11 +60112,11 @@ UNUSED_PARAMETER(isDirectMode); #else # define DIRECT_MODE isDirectMode #endif - if( !pPager->changeCountDone && pPager->dbSize>0 ){ + if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){ PgHdr *pPgHdr; /* Reference to page 1 */ assert( !pPager->tempFile && isOpen(pPager->fd) ); /* Open page 1 of the file for writing. */ @@ -62439,15 +60852,11 @@ ** The return value to this routine is always safe to use with ** sqlite3_uri_parameter() and sqlite3_filename_database() and friends. */ SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){ static const char zFake[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - if( nullIfMemDb && (pPager->memDb || sqlite3IsMemdb(pPager->pVfs)) ){ - return &zFake[4]; - }else{ - return pPager->zFilename; - } + return (nullIfMemDb && pPager->memDb) ? &zFake[4] : pPager->zFilename; } /* ** Return the VFS structure for the pager. */ @@ -68026,19 +66435,19 @@ ** within an expression that is an argument to another macro ** (sqliteMallocRaw), it is not possible to use conditional compilation. ** So, this macro is defined instead. */ #ifndef SQLITE_OMIT_AUTOVACUUM -#define ISAUTOVACUUM(pBt) (pBt->autoVacuum) +#define ISAUTOVACUUM (pBt->autoVacuum) #else -#define ISAUTOVACUUM(pBt) 0 +#define ISAUTOVACUUM 0 #endif /* -** This structure is passed around through all the PRAGMA integrity_check -** checking routines in order to keep track of some global state information. +** This structure is passed around through all the sanity checking routines +** in order to keep track of some global state information. ** ** The aRef[] array is allocated so that there is 1 bit for each page in ** the database. As the integrity-check proceeds, for each page used in ** the database the corresponding bit is set. This allows integrity-check to ** detect pages that are used twice and orphaned pages (both of which @@ -68050,12 +66459,11 @@ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ u8 *aPgRef; /* 1 bit per page in the db (see above) */ 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 */ - u32 nStep; /* Number of steps into the integrity_check process */ + int bOomFault; /* A memory allocation error has occurred */ const char *zPfx; /* Error message prefix */ Pgno v1; /* Value for first %u substitution in zPfx */ int v2; /* Value for second %d substitution in zPfx */ StrAccum errMsg; /* Accumulate the error message text here */ u32 *heap; /* Min-heap used for analyzing cell coverage */ @@ -68321,11 +66729,10 @@ ** db using sqlite3SchemaToIndex(). */ SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3 *db, int iDb, Schema *pSchema){ Btree *p; assert( db!=0 ); - if( db->pVfs==0 && db->nDb==0 ) return 1; if( pSchema ) iDb = sqlite3SchemaToIndex(db, pSchema); assert( iDb>=0 && iDbnDb ); if( !sqlite3_mutex_held(db->mutex) ) return 0; if( iDb==1 ) return 1; p = db->aDb[iDb].pBt; @@ -69894,11 +68301,12 @@ assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt!=0 ); assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); assert( pPage->nOverflow==0 ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - data = pPage->aData; + temp = 0; + src = data = pPage->aData; hdr = pPage->hdrOffset; cellOffset = pPage->cellOffset; nCell = pPage->nCell; assert( nCell==get2byte(&data[hdr+3]) || CORRUPT_DB ); iCellFirst = cellOffset + 2*nCell; @@ -69928,11 +68336,11 @@ if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage); sz2 = get2byte(&data[iFree2+2]); if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage); memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); sz += sz2; - }else if( iFree+sz>usableSize ){ + }else if( NEVER(iFree+sz>usableSize) ){ return SQLITE_CORRUPT_PAGE(pPage); } cbrk = top+sz; assert( cbrk+(iFree-top) <= usableSize ); @@ -69948,42 +68356,43 @@ } cbrk = usableSize; iCellLast = usableSize - 4; iCellStart = get2byte(&data[hdr+5]); - if( nCell>0 ){ - temp = sqlite3PagerTempSpace(pPage->pBt->pPager); - memcpy(&temp[iCellStart], &data[iCellStart], usableSize - iCellStart); - src = temp; - for(i=0; iiCellLast ){ - return SQLITE_CORRUPT_PAGE(pPage); - } - assert( pc>=iCellStart && pc<=iCellLast ); - size = pPage->xCellSize(pPage, &src[pc]); - cbrk -= size; - if( cbrkusableSize ){ - return SQLITE_CORRUPT_PAGE(pPage); - } - assert( cbrk+size<=usableSize && cbrk>=iCellStart ); - testcase( cbrk+size==usableSize ); - testcase( pc+size==usableSize ); - put2byte(pAddr, cbrk); - memcpy(&data[cbrk], &src[pc], size); - } + for(i=0; iiCellLast ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( pc>=iCellStart && pc<=iCellLast ); + size = pPage->xCellSize(pPage, &src[pc]); + cbrk -= size; + if( cbrkusableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( cbrk+size<=usableSize && cbrk>=iCellStart ); + testcase( cbrk+size==usableSize ); + testcase( pc+size==usableSize ); + put2byte(pAddr, cbrk); + if( temp==0 ){ + if( cbrk==pc ) continue; + temp = sqlite3PagerTempSpace(pPage->pBt->pPager); + memcpy(&temp[iCellStart], &data[iCellStart], usableSize - iCellStart); + src = temp; + } + memcpy(&data[cbrk], &src[pc], size); } data[hdr+7] = 0; -defragment_out: + defragment_out: assert( pPage->nFree>=0 ); if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){ return SQLITE_CORRUPT_PAGE(pPage); } assert( cbrk>=iCellFirst ); @@ -70036,10 +68445,11 @@ /* Remove the slot from the free-list. Update the number of ** fragmented bytes within the page. */ memcpy(&aData[iAddr], &aData[pc], 2); aData[hdr+7] += (u8)x; + testcase( pc+x>maxPC ); return &aData[pc]; }else if( x+pc > maxPC ){ /* This slot extends off the end of the usable part of the page */ *pRc = SQLITE_CORRUPT_PAGE(pPg); return 0; @@ -70051,13 +68461,13 @@ return &aData[pc + x]; } iAddr = pc; pTmp = &aData[pc]; pc = get2byte(pTmp); - if( pc<=iAddr ){ + if( pc<=iAddr+size ){ if( pc ){ - /* The next slot in the chain comes before the current slot */ + /* The next slot in the chain is not past the end of the current slot */ *pRc = SQLITE_CORRUPT_PAGE(pPg); } return 0; } } @@ -70205,11 +68615,11 @@ iPtr = hdr + 1; if( data[iPtr+1]==0 && data[iPtr]==0 ){ iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */ }else{ while( (iFreeBlk = get2byte(&data[iPtr]))pBt */ assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 ); + flagByte &= ~PTF_LEAF; + pPage->childPtrSize = 4-4*pPage->leaf; pBt = pPage->pBt; - pPage->max1bytePayload = pBt->max1bytePayload; - if( flagByte>=(PTF_ZERODATA | PTF_LEAF) ){ - pPage->childPtrSize = 0; - pPage->leaf = 1; - if( flagByte==(PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF) ){ + if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ + /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an + ** interior table b-tree page. */ + assert( (PTF_LEAFDATA|PTF_INTKEY)==5 ); + /* EVIDENCE-OF: R-26900-09176 A value of 13 (0x0d) means the page is a + ** leaf table b-tree page. */ + assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 ); + pPage->intKey = 1; + if( pPage->leaf ){ pPage->intKeyLeaf = 1; pPage->xCellSize = cellSizePtrTableLeaf; pPage->xParseCell = btreeParseCellPtr; - pPage->intKey = 1; - pPage->maxLocal = pBt->maxLeaf; - pPage->minLocal = pBt->minLeaf; - }else if( flagByte==(PTF_ZERODATA | PTF_LEAF) ){ - pPage->intKey = 0; - pPage->intKeyLeaf = 0; - pPage->xCellSize = cellSizePtr; - pPage->xParseCell = btreeParseCellPtrIndex; - pPage->maxLocal = pBt->maxLocal; - pPage->minLocal = pBt->minLocal; - }else{ - pPage->intKey = 0; - pPage->intKeyLeaf = 0; - pPage->xCellSize = cellSizePtr; - pPage->xParseCell = btreeParseCellPtrIndex; - return SQLITE_CORRUPT_PAGE(pPage); - } - }else{ - pPage->childPtrSize = 4; - pPage->leaf = 0; - if( flagByte==(PTF_ZERODATA) ){ - pPage->intKey = 0; - pPage->intKeyLeaf = 0; - pPage->xCellSize = cellSizePtr; - pPage->xParseCell = btreeParseCellPtrIndex; - pPage->maxLocal = pBt->maxLocal; - pPage->minLocal = pBt->minLocal; - }else if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ + }else{ pPage->intKeyLeaf = 0; pPage->xCellSize = cellSizePtrNoPayload; pPage->xParseCell = btreeParseCellPtrNoPayload; - pPage->intKey = 1; - pPage->maxLocal = pBt->maxLeaf; - pPage->minLocal = pBt->minLeaf; - }else{ - pPage->intKey = 0; - pPage->intKeyLeaf = 0; - pPage->xCellSize = cellSizePtr; - pPage->xParseCell = btreeParseCellPtrIndex; - return SQLITE_CORRUPT_PAGE(pPage); - } - } + } + pPage->maxLocal = pBt->maxLeaf; + pPage->minLocal = pBt->minLeaf; + }else if( flagByte==PTF_ZERODATA ){ + /* EVIDENCE-OF: R-43316-37308 A value of 2 (0x02) means the page is an + ** interior index b-tree page. */ + assert( (PTF_ZERODATA)==2 ); + /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a + ** leaf index b-tree page. */ + assert( (PTF_ZERODATA|PTF_LEAF)==10 ); + pPage->intKey = 0; + pPage->intKeyLeaf = 0; + pPage->xCellSize = cellSizePtr; + pPage->xParseCell = btreeParseCellPtrIndex; + pPage->maxLocal = pBt->maxLocal; + pPage->minLocal = pBt->minLocal; + }else{ + /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is + ** an error. */ + pPage->intKey = 0; + pPage->intKeyLeaf = 0; + pPage->xCellSize = cellSizePtr; + pPage->xParseCell = btreeParseCellPtrIndex; + return SQLITE_CORRUPT_PAGE(pPage); + } + pPage->max1bytePayload = pBt->max1bytePayload; return SQLITE_OK; } /* ** Compute the amount of freespace on the page. In other words, fill @@ -70692,11 +69097,13 @@ if( pCur ){ pCur->iPage--; pCur->pPage = pCur->apPage[pCur->iPage]; } testcase( pgno==0 ); - assert( pgno!=0 || rc!=SQLITE_OK ); + assert( pgno!=0 || rc==SQLITE_CORRUPT + || rc==SQLITE_IOERR_NOMEM + || rc==SQLITE_NOMEM ); return rc; } /* ** Release a MemPage. This should be called once for each prior @@ -72128,13 +70535,10 @@ put4byte(pCell+info.nSize-4, iTo); break; } } }else{ - if( pCell+4 > pPage->aData+pPage->pBt->usableSize ){ - return SQLITE_CORRUPT_PAGE(pPage); - } if( get4byte(pCell)==iFrom ){ put4byte(pCell, iTo); break; } } @@ -73637,10 +72041,12 @@ ** the new child page does not match the flags field of the parent (i.e. ** if an intkey page appears to be the parent of a non-intkey page, or ** vice-versa). */ static int moveToChild(BtCursor *pCur, u32 newPgno){ + BtShared *pBt = pCur->pBt; + assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPageiPage>=0 ); if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ @@ -73650,12 +72056,11 @@ pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); pCur->aiIdx[pCur->iPage] = pCur->ix; pCur->apPage[pCur->iPage] = pCur->pPage; pCur->ix = 0; pCur->iPage++; - return getAndInitPage(pCur->pBt, newPgno, &pCur->pPage, pCur, - pCur->curPagerFlags); + return getAndInitPage(pBt, newPgno, &pCur->pPage, pCur, pCur->curPagerFlags); } #ifdef SQLITE_DEBUG /* ** Page pParent is an internal (non-leaf) tree page. This function @@ -73757,11 +72162,11 @@ assert( pCur->skipNext!=SQLITE_OK ); return pCur->skipNext; } sqlite3BtreeClearCursor(pCur); } - rc = getAndInitPage(pCur->pBt, pCur->pgnoRoot, &pCur->pPage, + rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->pPage, 0, pCur->curPagerFlags); if( rc!=SQLITE_OK ){ pCur->eState = CURSOR_INVALID; return rc; } @@ -73881,29 +72286,13 @@ /* Move the cursor to the last entry in the table. Return SQLITE_OK ** on success. Set *pRes to 0 if the cursor actually points to something ** or set *pRes to 1 if the table is empty. */ -static SQLITE_NOINLINE int btreeLast(BtCursor *pCur, int *pRes){ - int rc = moveToRoot(pCur); - if( rc==SQLITE_OK ){ - assert( pCur->eState==CURSOR_VALID ); - *pRes = 0; - rc = moveToRightmost(pCur); - if( rc==SQLITE_OK ){ - pCur->curFlags |= BTCF_AtLast; - }else{ - pCur->curFlags &= ~BTCF_AtLast; - } - }else if( rc==SQLITE_EMPTY ){ - assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); - *pRes = 1; - rc = SQLITE_OK; - } - return rc; -} SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ + int rc; + assert( cursorOwnsBtShared(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); /* If the cursor already points to the last entry, this is a no-op. */ if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ @@ -73920,11 +72309,27 @@ assert( pCur->pPage->leaf ); #endif *pRes = 0; return SQLITE_OK; } - return btreeLast(pCur, pRes); + + rc = moveToRoot(pCur); + if( rc==SQLITE_OK ){ + assert( pCur->eState==CURSOR_VALID ); + *pRes = 0; + rc = moveToRightmost(pCur); + if( rc==SQLITE_OK ){ + pCur->curFlags |= BTCF_AtLast; + }else{ + pCur->curFlags &= ~BTCF_AtLast; + } + }else if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = 1; + rc = SQLITE_OK; + } + return rc; } /* Move the cursor so that it points to an entry in a table (a.k.a INTKEY) ** table near the key intKey. Return a success code. ** @@ -74465,11 +72870,18 @@ } } pPage = pCur->pPage; idx = ++pCur->ix; - if( NEVER(!pPage->isInit) || sqlite3FaultSim(412) ){ + if( !pPage->isInit || sqlite3FaultSim(412) ){ + /* The only known way for this to happen is for there to be a + ** recursive SQL function that does a DELETE operation as part of a + ** SELECT which deletes content out from under an active cursor + ** in a corrupt database file where the table being DELETE-ed from + ** has pages in common with the table being queried. See TH3 + ** module cov1/btree78.test testcase 220 (2018-06-08) for an + ** example. */ return SQLITE_CORRUPT_BKPT; } if( idx>=pPage->nCell ){ if( !pPage->leaf ){ @@ -74641,12 +73053,12 @@ assert( sqlite3_mutex_held(pBt->mutex) ); assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) ); pPage1 = pBt->pPage1; mxPage = btreePagecount(pBt); - /* EVIDENCE-OF: R-21003-45125 The 4-byte big-endian integer at offset 36 - ** stores the total number of pages on the freelist. */ + /* EVIDENCE-OF: R-05119-02637 The 4-byte big-endian integer at offset 36 + ** stores stores the total number of pages on the freelist. */ n = get4byte(&pPage1->aData[36]); testcase( n==mxPage-1 ); if( n>=mxPage ){ return SQLITE_CORRUPT_BKPT; } @@ -74987,11 +73399,11 @@ } /* If the database supports auto-vacuum, write an entry in the pointer-map ** to indicate that the page is free. */ - if( ISAUTOVACUUM(pBt) ){ + if( ISAUTOVACUUM ){ ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc); if( rc ) goto freepage_out; } /* Now manipulate the actual database free-list structure. There are two @@ -75391,10 +73803,16 @@ data = pPage->aData; ptr = &pPage->aCellIdx[2*idx]; assert( pPage->pBt->usableSize > (u32)(ptr-data) ); pc = get2byte(ptr); hdr = pPage->hdrOffset; +#if 0 /* Not required. Omit for efficiency */ + if( pcnCell*2 ){ + *pRC = SQLITE_CORRUPT_BKPT; + return; + } +#endif testcase( pc==(u32)get2byte(&data[hdr+5]) ); testcase( pc+sz==pPage->pBt->usableSize ); if( pc+sz > pPage->pBt->usableSize ){ *pRC = SQLITE_CORRUPT_BKPT; return; @@ -75427,24 +73845,28 @@ ** pTemp is not null. Regardless of pTemp, allocate a new entry ** in pPage->apOvfl[] and make it point to the cell content (either ** in pTemp or the original pCell) and also record its index. ** Allocating a new entry in pPage->aCell[] implies that ** pPage->nOverflow is incremented. +** +** *pRC must be SQLITE_OK when this routine is called. */ -static int insertCell( +static void insertCell( MemPage *pPage, /* Page into which we are copying */ int i, /* New cell becomes the i-th cell of the page */ u8 *pCell, /* Content of the new cell */ int sz, /* Bytes of content in pCell */ u8 *pTemp, /* Temp storage space for pCell, if needed */ - Pgno iChild /* If non-zero, replace first 4 bytes with this value */ + Pgno iChild, /* If non-zero, replace first 4 bytes with this value */ + int *pRC /* Read and write return code from here */ ){ int idx = 0; /* Where to write new cell content in data[] */ int j; /* Loop counter */ u8 *data; /* The content of the whole page */ u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */ + assert( *pRC==SQLITE_OK ); assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); assert( MX_CELL(pPage->pBt)<=10921 ); assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); @@ -75475,17 +73897,18 @@ assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */ assert( j==0 || i==pPage->aiOvfl[j-1]+1 ); /* Overflows are sequential */ }else{ int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc!=SQLITE_OK ){ - return rc; + *pRC = rc; + return; } assert( sqlite3PagerIswriteable(pPage->pDbPage) ); data = pPage->aData; assert( &data[pPage->cellOffset]==pPage->aCellIdx ); rc = allocateSpace(pPage, sz, &idx); - if( rc ){ return rc; } + if( rc ){ *pRC = rc; return; } /* The allocateSpace() routine guarantees the following properties ** if it returns successfully */ assert( idx >= 0 ); assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); assert( idx+sz <= (int)pPage->pBt->usableSize ); @@ -75508,20 +73931,17 @@ /* increment the cell count */ if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++; assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB ); #ifndef SQLITE_OMIT_AUTOVACUUM if( pPage->pBt->autoVacuum ){ - int rc2 = SQLITE_OK; /* The cell may contain a pointer to an overflow page. If so, write ** the entry for the overflow page into the pointer map. */ - ptrmapPutOvflPtr(pPage, pPage, pCell, &rc2); - if( rc2 ) return rc2; + ptrmapPutOvflPtr(pPage, pPage, pCell, pRC); } #endif } - return SQLITE_OK; } /* ** The following parameters determine how many adjacent pages get involved ** in a balancing operation. NN is the number of neighbors on either side @@ -75618,20 +74038,18 @@ /* ** Make sure the cell sizes at idx, idx+1, ..., idx+N-1 have been ** computed. */ static void populateCellCache(CellArray *p, int idx, int N){ - MemPage *pRef = p->pRef; - u16 *szCell = p->szCell; assert( idx>=0 && idx+N<=p->nCell ); while( N>0 ){ assert( p->apCell[idx]!=0 ); - if( szCell[idx]==0 ){ - szCell[idx] = pRef->xCellSize(pRef, p->apCell[idx]); + if( p->szCell[idx]==0 ){ + p->szCell[idx] = p->pRef->xCellSize(p->pRef, p->apCell[idx]); }else{ assert( CORRUPT_DB || - szCell[idx]==pRef->xCellSize(pRef, p->apCell[idx]) ); + p->szCell[idx]==p->pRef->xCellSize(p->pRef, p->apCell[idx]) ); } idx++; N--; } } @@ -75829,12 +74247,12 @@ u8 * const pEnd = &aData[pPg->pBt->usableSize]; u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize]; int nRet = 0; int i; int iEnd = iFirst + nCell; - u8 *pFree = 0; /* \__ Parameters for pending call to */ - int szFree = 0; /* / freeSpace() */ + u8 *pFree = 0; + int szFree = 0; for(i=iFirst; iapCell[i]; if( SQLITE_WITHIN(pCell, pStart, pEnd) ){ int sz; @@ -75851,13 +74269,10 @@ szFree = sz; if( pFree+sz>pEnd ){ return 0; } }else{ - /* The current cell is adjacent to and before the pFree cell. - ** Combine the two regions into one to reduce the number of calls - ** to freeSpace(). */ pFree = pCell; szFree += sz; } nRet++; } @@ -76061,11 +74476,11 @@ ** 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. */ - if( ISAUTOVACUUM(pBt) ){ + if( ISAUTOVACUUM ){ ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc); if( szCell>pNew->minLocal ){ ptrmapPutOvflPtr(pNew, pNew, pCell, &rc); } } @@ -76089,12 +74504,12 @@ pStop = &pCell[9]; while( ((*(pOut++) = *(pCell++))&0x80) && pCellnCell, pSpace, (int)(pOut-pSpace), - 0, pPage->pgno); + insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace), + 0, pPage->pgno, &rc); } /* Set the right-child pointer of pParent to point to the new page. */ put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); @@ -76199,11 +74614,11 @@ } /* If this is an auto-vacuum database, update the pointer-map entries ** for any b-tree or overflow pages that pTo now contains the pointers to. */ - if( ISAUTOVACUUM(pBt) ){ + if( ISAUTOVACUUM ){ *pRC = setChildPtrmaps(pTo); } } } @@ -76277,10 +74692,12 @@ int szNew[NB+2]; /* Combined size of cells placed on i-th page */ u8 *aSpace1; /* Space for copies of dividers cells */ Pgno pgno; /* Temp var to store a page number in */ u8 abDone[NB+2]; /* True after i'th new page is populated */ Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */ + Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */ + u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */ CellArray b; /* Parsed information on cells being balanced */ memset(abDone, 0, sizeof(abDone)); memset(&b, 0, sizeof(b)); pBt = pParent->pBt; @@ -76623,21 +75040,19 @@ r = cntNew[i-1] - 1; d = r + 1 - leafData; (void)cachedCellSize(&b, d); do{ - int szR, szD; assert( d szLeft-(szR+(i==k-1?0:2)))){ + && (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+(i==k-1?0:2)))){ break; } - szRight += szD + 2; - szLeft -= szR + 2; + szRight += b.szCell[d] + 2; + szLeft -= b.szCell[r] + 2; cntNew[i-1] = r; r--; d--; }while( r>=0 ); szNew[i] = szRight; @@ -76687,11 +75102,11 @@ apNew[i] = pNew; nNew++; cntOld[i] = b.nCell; /* Set the pointer-map entry for the new sibling page. */ - if( ISAUTOVACUUM(pBt) ){ + if( ISAUTOVACUUM ){ ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc); if( rc!=SQLITE_OK ){ goto balance_cleanup; } } @@ -76702,43 +75117,46 @@ ** Reassign page numbers so that the new pages are in ascending order. ** This helps to keep entries in the disk file in order so that a scan ** of the table is closer to a linear scan through the file. That in turn ** helps the operating system to deliver pages from the disk more rapidly. ** - ** An O(N*N) sort algorithm is used, but since N is never more than NB+2 - ** (5), that is not a performance concern. + ** An O(n^2) insertion sort algorithm is used, but since n is never more + ** than (NB+2) (a small constant), that should not be a problem. ** ** When NB==3, this one optimization makes the database about 25% faster ** for large insertions and deletions. */ for(i=0; ipgno; - assert( apNew[i]->pDbPage->flags & PGHDR_WRITEABLE ); - assert( apNew[i]->pDbPage->flags & PGHDR_DIRTY ); - } - for(i=0; ipgno < apNew[iB]->pgno ) iB = j; - } - - /* If apNew[i] has a page number that is bigger than any of the - ** subsequence apNew[i] entries, then swap apNew[i] with the subsequent - ** entry that has the smallest page number (which we know to be - ** entry apNew[iB]). - */ - if( iB!=i ){ - Pgno pgnoA = apNew[i]->pgno; - Pgno pgnoB = apNew[iB]->pgno; - Pgno pgnoTemp = (PENDING_BYTE/pBt->pageSize)+1; - u16 fgA = apNew[i]->pDbPage->flags; - u16 fgB = apNew[iB]->pDbPage->flags; - sqlite3PagerRekey(apNew[i]->pDbPage, pgnoTemp, fgB); - sqlite3PagerRekey(apNew[iB]->pDbPage, pgnoA, fgA); - sqlite3PagerRekey(apNew[i]->pDbPage, pgnoB, fgB); - apNew[i]->pgno = pgnoB; - apNew[iB]->pgno = pgnoA; + aPgOrder[i] = aPgno[i] = apNew[i]->pgno; + aPgFlags[i] = apNew[i]->pDbPage->flags; + for(j=0; ji ){ + sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0); + } + sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]); + apNew[i]->pgno = pgno; } } TRACE(("BALANCE: new: %d(%d nc=%d) %d(%d nc=%d) %d(%d nc=%d) " "%d(%d nc=%d) %d(%d nc=%d)\n", @@ -76780,11 +75198,11 @@ ** If the sibling pages are not leaves, then the pointer map entry ** associated with the right-child of each sibling may also need to be ** updated. This happens below, after the sibling pages have been ** populated, not here. */ - if( ISAUTOVACUUM(pBt) ){ + if( ISAUTOVACUUM ){ MemPage *pOld; MemPage *pNew = pOld = apNew[0]; int cntOldNext = pNew->nCell + pNew->nOverflow; int iNew = 0; int iOld = 0; @@ -76877,11 +75295,11 @@ pSrcEnd = b.apEnd[k]; if( SQLITE_WITHIN(pSrcEnd, pCell, pCell+sz) ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } - rc = insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno); + insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc); if( rc!=SQLITE_OK ) goto balance_cleanup; assert( sqlite3PagerIswriteable(pParent->pDbPage) ); } /* Now update the actual sibling pages. The order in which they are updated @@ -76973,11 +75391,11 @@ - apNew[0]->nCell*2) || rc!=SQLITE_OK ); copyNodeContent(apNew[0], pParent, &rc); freePage(apNew[0], &rc); - }else if( ISAUTOVACUUM(pBt) && !leafCorrection ){ + }else if( ISAUTOVACUUM && !leafCorrection ){ /* Fix the pointer map entries associated with the right-child of each ** sibling page. All other pointer map entries have already been taken ** care of. */ for(i=0; iaData[8]); @@ -76994,11 +75412,11 @@ for(i=nNew; iisInit ){ + if( ISAUTOVACUUM && rc==SQLITE_OK && apNew[0]->isInit ){ /* The ptrmapCheckPages() contains assert() statements that verify that ** all pointer map pages are set correctly. This is helpful while ** debugging. This is usually disabled because a corrupt database may ** cause an assert() statement to fail. */ ptrmapCheckPages(apNew, nNew); @@ -77056,11 +75474,11 @@ */ rc = sqlite3PagerWrite(pRoot->pDbPage); if( rc==SQLITE_OK ){ rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0); copyNodeContent(pRoot, pChild, &rc); - if( ISAUTOVACUUM(pBt) ){ + if( ISAUTOVACUUM ){ ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc); } } if( rc ){ *ppChild = 0; @@ -77160,15 +75578,10 @@ assert( pCur->pPage->nOverflow ); } }else{ break; } - }else if( sqlite3PagerPageRefcount(pPage->pDbPage)>1 ){ - /* The page being written is not a root page, and there is currently - ** more than one reference to it. This only happens if the page is one - ** of its own ancestor pages. Corruption. */ - rc = SQLITE_CORRUPT_BKPT; }else{ MemPage * const pParent = pCur->apPage[iPage-1]; int const iIdx = pCur->aiIdx[iPage-1]; rc = sqlite3PagerWrite(pParent->pDbPage); @@ -77295,31 +75708,31 @@ return SQLITE_OK; } /* ** Overwrite the cell that cursor pCur is pointing to with fresh content -** contained in pX. In this variant, pCur is pointing to an overflow -** cell. +** contained in pX. */ -static SQLITE_NOINLINE int btreeOverwriteOverflowCell( - BtCursor *pCur, /* Cursor pointing to cell to ovewrite */ - const BtreePayload *pX /* Content to write into the cell */ -){ +static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ int iOffset; /* Next byte of pX->pData to write */ int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */ int rc; /* Return code */ MemPage *pPage = pCur->pPage; /* Page being written */ BtShared *pBt; /* Btree */ Pgno ovflPgno; /* Next overflow page to write */ u32 ovflPageSize; /* Size to write on overflow page */ - assert( pCur->info.nLocalinfo.pPayload + pCur->info.nLocal > pPage->aDataEnd + || pCur->info.pPayload < pPage->aData + pPage->cellOffset + ){ + return SQLITE_CORRUPT_BKPT; + } /* Overwrite the local portion first */ rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX, 0, pCur->info.nLocal); if( rc ) return rc; + if( pCur->info.nLocal==nTotal ) return SQLITE_OK; /* Now overwrite the overflow pages */ iOffset = pCur->info.nLocal; assert( nTotal>=0 ); assert( iOffset>=0 ); @@ -77345,33 +75758,10 @@ iOffset += ovflPageSize; }while( iOffsetnData + pX->nZero; /* Total bytes of to write */ - MemPage *pPage = pCur->pPage; /* Page being written */ - - if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd - || pCur->info.pPayload < pPage->aData + pPage->cellOffset - ){ - return SQLITE_CORRUPT_BKPT; - } - if( pCur->info.nLocal==nTotal ){ - /* The entire cell is local */ - return btreeOverwriteContent(pPage, pCur->info.pPayload, pX, - 0, pCur->info.nLocal); - }else{ - /* The cell contains overflow content */ - return btreeOverwriteOverflowCell(pCur, pX); - } -} - /* ** Insert a new record into the BTree. The content of the new record ** is described by the pX object. The pCur cursor is used only to ** define what table the record should be inserted into, and is left @@ -77411,10 +75801,11 @@ int loc = seekResult; /* -1: before desired location +1: after */ int szNew = 0; int idx; MemPage *pPage; Btree *p = pCur->pBtree; + BtShared *pBt = p->pBt; unsigned char *oldCell; unsigned char *newCell = 0; assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags ); assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 ); @@ -77429,11 +75820,11 @@ ** that the cursor is already where it needs to be and returns without ** doing any work. To avoid thwarting these optimizations, it is important ** not to clear the cursor here. */ if( pCur->curFlags & BTCF_Multiple ){ - rc = saveAllCursors(p->pBt, pCur->pgnoRoot, pCur); + rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); if( rc ) return rc; if( loc && pCur->iPage<0 ){ /* This can only happen if the schema is corrupt such that there is more ** than one table or index with the same root page as used by the cursor. ** Which can only happen if the SQLITE_NoSchemaError flag was set when @@ -77453,12 +75844,12 @@ if( rc && rc!=SQLITE_EMPTY ) return rc; } assert( cursorOwnsBtShared(pCur) ); assert( (pCur->curFlags & BTCF_WriteFlag)!=0 - && p->pBt->inTransaction==TRANS_WRITE - && (p->pBt->btsFlags & BTS_READ_ONLY)==0 ); + && pBt->inTransaction==TRANS_WRITE + && (pBt->btsFlags & BTS_READ_ONLY)==0 ); assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); /* Assert that the caller has been consistent. If this cursor was opened ** expecting an index b-tree, then the caller should be inserting blob ** keys with no associated data. If the cursor was opened expecting an @@ -77571,32 +75962,30 @@ TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno, loc==0 ? "overwrite" : "new entry")); assert( pPage->isInit || CORRUPT_DB ); - newCell = p->pBt->pTmpSpace; + newCell = pBt->pTmpSpace; assert( newCell!=0 ); - assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT ); if( flags & BTREE_PREFORMAT ){ rc = SQLITE_OK; - szNew = p->pBt->nPreformatSize; + szNew = pBt->nPreformatSize; if( szNew<4 ) szNew = 4; - if( ISAUTOVACUUM(p->pBt) && szNew>pPage->maxLocal ){ + if( ISAUTOVACUUM && szNew>pPage->maxLocal ){ CellInfo info; pPage->xParseCell(pPage, newCell, &info); if( info.nPayload!=info.nLocal ){ Pgno ovfl = get4byte(&newCell[szNew-4]); - ptrmapPut(p->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc); - if( NEVER(rc) ) goto end_insert; + ptrmapPut(pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc); } } }else{ rc = fillInCell(pPage, newCell, pX, &szNew); - if( rc ) goto end_insert; } + if( rc ) goto end_insert; assert( szNew==pPage->xCellSize(pPage, newCell) ); - assert( szNew <= MX_CELL_SIZE(p->pBt) ); + assert( szNew <= MX_CELL_SIZE(pBt) ); idx = pCur->ix; if( loc==0 ){ CellInfo info; assert( idx>=0 ); if( idx>=pPage->nCell ){ @@ -77612,11 +76001,11 @@ } BTREE_CLEAR_CELL(rc, pPage, oldCell, info); testcase( pCur->curFlags & BTCF_ValidOvfl ); invalidateOverflowCache(pCur); if( info.nSize==szNew && info.nLocal==info.nPayload - && (!ISAUTOVACUUM(p->pBt) || szNewminLocal) + && (!ISAUTOVACUUM || szNewminLocal) ){ /* Overwrite the old cell with the new if they are the same size. ** We could also try to do this if the old cell is smaller, then add ** the leftover space to the free list. But experiments show that ** doing that is no faster then skipping this optimization and just @@ -77642,11 +76031,11 @@ idx = ++pCur->ix; pCur->curFlags &= ~BTCF_ValidNKey; }else{ assert( pPage->leaf ); } - rc = insertCell(pPage, idx, newCell, szNew, 0, 0); + insertCell(pPage, idx, newCell, szNew, 0, 0, &rc); assert( pPage->nOverflow==0 || rc==SQLITE_OK ); assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); /* If no error has occurred and pPage has an overflow cell, call balance() ** to redistribute the cells within the tree. Since balance() may move @@ -77715,10 +76104,11 @@ ** calling sqlite3BtreeInsert() with the BTREE_PREFORMAT flag specified. ** ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. */ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ + int rc = SQLITE_OK; BtShared *pBt = pDest->pBt; u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ const u8 *aIn; /* Pointer to next input buffer */ u32 nIn; /* Size of input buffer aIn[] */ u32 nRem; /* Bytes of data still to copy */ @@ -77737,13 +76127,11 @@ } nRem = pSrc->info.nPayload; if( nIn==nRem && nInpPage->maxLocal ){ memcpy(aOut, aIn, nIn); pBt->nPreformatSize = nIn + (aOut - pBt->pTmpSpace); - return SQLITE_OK; }else{ - int rc = SQLITE_OK; Pager *pSrcPager = pSrc->pBt->pPager; u8 *pPgnoOut = 0; Pgno ovflIn = 0; DbPage *pPageIn = 0; MemPage *pPageOut = 0; @@ -77791,11 +76179,11 @@ if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){ Pgno pgnoNew; MemPage *pNew = 0; rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); put4byte(pPgnoOut, pgnoNew); - if( ISAUTOVACUUM(pBt) && pPageOut ){ + if( ISAUTOVACUUM && pPageOut ){ ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc); } releasePage(pPageOut); pPageOut = pNew; if( pPageOut ){ @@ -77807,12 +76195,13 @@ } }while( nRem>0 && rc==SQLITE_OK ); releasePage(pPageOut); sqlite3PagerUnref(pPageIn); - return rc; } + + return rc; } /* ** Delete the entry that the cursor is pointing to. ** @@ -77963,11 +76352,11 @@ assert( MX_CELL_SIZE(pBt) >= nCell ); pTmp = pBt->pTmpSpace; assert( pTmp!=0 ); rc = sqlite3PagerWrite(pLeaf->pDbPage); if( rc==SQLITE_OK ){ - rc = insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n); + insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc); } dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc); if( rc ) return rc; } @@ -78562,55 +76951,19 @@ SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){ return p->pBt->pPager; } #ifndef SQLITE_OMIT_INTEGRITY_CHECK -/* -** Record an OOM error during integrity_check -*/ -static void checkOom(IntegrityCk *pCheck){ - pCheck->rc = SQLITE_NOMEM; - pCheck->mxErr = 0; /* Causes integrity_check processing to stop */ - if( pCheck->nErr==0 ) pCheck->nErr++; -} - -/* -** Invoke the progress handler, if appropriate. Also check for an -** interrupt. -*/ -static void checkProgress(IntegrityCk *pCheck){ - sqlite3 *db = pCheck->db; - if( AtomicLoad(&db->u1.isInterrupted) ){ - pCheck->rc = SQLITE_INTERRUPT; - pCheck->nErr++; - pCheck->mxErr = 0; - } -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - if( db->xProgress ){ - assert( db->nProgressOps>0 ); - pCheck->nStep++; - if( (pCheck->nStep % db->nProgressOps)==0 - && db->xProgress(db->pProgressArg) - ){ - pCheck->rc = SQLITE_INTERRUPT; - pCheck->nErr++; - pCheck->mxErr = 0; - } - } -#endif -} - /* ** Append a message to the error message string. */ static void checkAppendMsg( IntegrityCk *pCheck, const char *zFormat, ... ){ va_list ap; - checkProgress(pCheck); if( !pCheck->mxErr ) return; pCheck->mxErr--; pCheck->nErr++; va_start(ap, zFormat); if( pCheck->errMsg.nChar ){ @@ -78620,11 +76973,11 @@ sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); } sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap); va_end(ap); if( pCheck->errMsg.accError==SQLITE_NOMEM ){ - checkOom(pCheck); + pCheck->bOomFault = 1; } } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ #ifndef SQLITE_OMIT_INTEGRITY_CHECK @@ -78662,10 +77015,11 @@ } if( getPageReferenced(pCheck, iPage) ){ checkAppendMsg(pCheck, "2nd reference to page %d", iPage); return 1; } + if( AtomicLoad(&pCheck->db->u1.isInterrupted) ) return 1; setPageReferenced(pCheck, iPage); return 0; } #ifndef SQLITE_OMIT_AUTOVACUUM @@ -78684,11 +77038,11 @@ u8 ePtrmapType; Pgno iPtrmapParent; rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) checkOom(pCheck); + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->bOomFault = 1; checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild); return; } if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ @@ -78791,13 +77145,11 @@ ** entry represents the span of a cell or freeblock on a btree page. ** The upper 16 bits are the index of the first byte of a range and the ** lower 16 bits are the index of the last byte of that range. */ static void btreeHeapInsert(u32 *aHeap, u32 x){ - u32 j, i; - assert( aHeap!=0 ); - i = ++aHeap[0]; + u32 j, i = ++aHeap[0]; aHeap[i] = x; while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){ x = aHeap[j]; aHeap[j] = aHeap[i]; aHeap[i] = x; @@ -78870,12 +77222,10 @@ int saved_v2 = pCheck->v2; u8 savedIsInit = 0; /* Check that the page exists */ - checkProgress(pCheck); - if( pCheck->mxErr==0 ) goto end_of_check; pBt = pCheck->pBt; usableSize = pBt->usableSize; if( iPage==0 ) return 0; if( checkRef(pCheck, iPage) ) return 0; pCheck->zPfx = "Page %u: "; @@ -79117,18 +77467,17 @@ ** and the checks to make sure every page is referenced are also skipped, ** since obviously it is not possible to know which pages are covered by ** the unverified btrees. Except, if aRoot[1] is 1, then the freelist ** checks are still performed. */ -SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( +SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( sqlite3 *db, /* Database connection that is running the check */ Btree *p, /* The btree to be checked */ Pgno *aRoot, /* An array of root pages numbers for individual trees */ int nRoot, /* Number of entries in aRoot[] */ int mxErr, /* Stop reporting errors after this many */ - int *pnErr, /* OUT: Write number of errors seen to this variable */ - char **pzOut /* OUT: Write the error message string here */ + int *pnErr /* Write number of errors seen to this variable */ ){ Pgno i; IntegrityCk sCheck; BtShared *pBt = p->pBt; u64 savedDbFlags = pBt->db->flags; @@ -79147,30 +77496,36 @@ sqlite3BtreeEnter(p); assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) ); assert( nRef>=0 ); - memset(&sCheck, 0, sizeof(sCheck)); sCheck.db = db; sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = btreePagecount(sCheck.pBt); sCheck.mxErr = mxErr; + sCheck.nErr = 0; + sCheck.bOomFault = 0; + sCheck.zPfx = 0; + sCheck.v1 = 0; + sCheck.v2 = 0; + sCheck.aPgRef = 0; + sCheck.heap = 0; sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; if( sCheck.nPage==0 ){ goto integrity_ck_cleanup; } sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); if( !sCheck.aPgRef ){ - checkOom(&sCheck); + sCheck.bOomFault = 1; goto integrity_ck_cleanup; } sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); if( sCheck.heap==0 ){ - checkOom(&sCheck); + sCheck.bOomFault = 1; goto integrity_ck_cleanup; } i = PENDING_BYTE_PAGE(pBt); if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i); @@ -79247,21 +77602,20 @@ /* Clean up and report errors. */ integrity_ck_cleanup: sqlite3PageFree(sCheck.heap); sqlite3_free(sCheck.aPgRef); - *pnErr = sCheck.nErr; - if( sCheck.nErr==0 ){ + if( sCheck.bOomFault ){ sqlite3_str_reset(&sCheck.errMsg); - *pzOut = 0; - }else{ - *pzOut = sqlite3StrAccumFinish(&sCheck.errMsg); + sCheck.nErr++; } + *pnErr = sCheck.nErr; + if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg); /* Make sure this analysis did not leave any unref() pages. */ assert( nRef==sqlite3PagerRefcount(pBt->pPager) ); sqlite3BtreeLeave(p); - return sCheck.rc; + return sqlite3StrAccumFinish(&sCheck.errMsg); } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* ** Return the full pathname of the underlying database file. Return @@ -79522,21 +77876,10 @@ /* ** Return the size of the header added to each page by this module. */ SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); } -/* -** If no transaction is active and the database is not a temp-db, clear -** the in-memory pager cache. -*/ -SQLITE_PRIVATE void sqlite3BtreeClearCache(Btree *p){ - BtShared *pBt = p->pBt; - if( pBt->inTransaction==TRANS_NONE ){ - sqlite3PagerClearCache(pBt->pPager); - } -} - #if !defined(SQLITE_OMIT_SHARED_CACHE) /* ** Return true if the Btree passed as the only argument is sharable. */ SQLITE_PRIVATE int sqlite3BtreeSharable(Btree *p){ @@ -80443,21 +78786,20 @@ /* Work-around for GCC bug ** https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96270 */ i64 x; assert( (p->flags&MEM_Int)*2==sizeof(x) ); memcpy(&x, (char*)&p->u, (p->flags&MEM_Int)*2); - p->n = sqlite3Int64ToText(x, zBuf); + sqlite3Int64ToText(x, zBuf); #else - p->n = sqlite3Int64ToText(p->u.i, zBuf); + sqlite3Int64ToText(p->u.i, zBuf); #endif }else{ sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0); sqlite3_str_appendf(&acc, "%!.15g", (p->flags & MEM_IntReal)!=0 ? (double)p->u.i : p->u.r); assert( acc.zText==zBuf && acc.mxAlloc<=0 ); zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */ - p->n = acc.nChar; } } #ifdef SQLITE_DEBUG /* @@ -80481,11 +78823,10 @@ ** true if everything is ok and false if there is a problem. ** ** This routine is for use inside of assert() statements only. */ SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){ - Mem tmp; char zBuf[100]; char *z; int i, j, incr; if( (p->flags & MEM_Str)==0 ) return 1; if( p->flags & MEM_Term ){ @@ -80498,12 +78839,11 @@ assert( p->z[p->n]==0 ); assert( p->enc==SQLITE_UTF8 || p->z[(p->n+1)&~1]==0 ); assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 ); } if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1; - memcpy(&tmp, p, sizeof(tmp)); - vdbeMemRenderNum(sizeof(zBuf), zBuf, &tmp); + vdbeMemRenderNum(sizeof(zBuf), zBuf, p); z = p->z; i = j = 0; incr = 1; if( p->enc!=SQLITE_UTF8 ){ incr = 2; @@ -80768,11 +79108,11 @@ return SQLITE_NOMEM_BKPT; } vdbeMemRenderNum(nByte, pMem->z, pMem); assert( pMem->z!=0 ); - assert( pMem->n==sqlite3Strlen30NN(pMem->z) ); + pMem->n = sqlite3Strlen30NN(pMem->z); pMem->enc = SQLITE_UTF8; pMem->flags |= MEM_Str|MEM_Term; if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); sqlite3VdbeChangeEncoding(pMem, enc); return SQLITE_OK; @@ -81008,39 +79348,36 @@ if( pMem->flags & MEM_Null ) return ifNull; return sqlite3VdbeRealValue(pMem)!=0.0; } /* -** The MEM structure is already a MEM_Real or MEM_IntReal. Try to -** make it a MEM_Int if we can. +** The MEM structure is already a MEM_Real. Try to also make it a +** MEM_Int if we can. */ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ + i64 ix; assert( pMem!=0 ); - assert( pMem->flags & (MEM_Real|MEM_IntReal) ); + assert( pMem->flags & MEM_Real ); assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - if( pMem->flags & MEM_IntReal ){ - MemSetTypeFlag(pMem, MEM_Int); - }else{ - i64 ix = doubleToInt64(pMem->u.r); - - /* Only mark the value as an integer if - ** - ** (1) the round-trip conversion real->int->real is a no-op, and - ** (2) The integer is neither the largest nor the smallest - ** possible integer (ticket #3922) - ** - ** The second and third terms in the following conditional enforces - ** the second condition under the assumption that addition overflow causes - ** values to wrap around. - */ - if( pMem->u.r==ix && ix>SMALLEST_INT64 && ixu.i = ix; - MemSetTypeFlag(pMem, MEM_Int); - } + ix = doubleToInt64(pMem->u.r); + + /* Only mark the value as an integer if + ** + ** (1) the round-trip conversion real->int->real is a no-op, and + ** (2) The integer is neither the largest nor the smallest + ** possible integer (ticket #3922) + ** + ** The second and third terms in the following conditional enforces + ** the second condition under the assumption that addition overflow causes + ** values to wrap around. + */ + if( pMem->u.r==ix && ix>SMALLEST_INT64 && ixu.i = ix; + MemSetTypeFlag(pMem, MEM_Int); } } /* ** Convert pMem to type integer. Invalidate any prior representations. @@ -81084,20 +79421,10 @@ return r1==0.0 || (memcmp(&r1, &r2, sizeof(r1))==0 && i >= -2251799813685248LL && i < 2251799813685248LL); } -/* Convert a floating point value to its closest integer. Do so in -** a way that avoids 'outside the range of representable values' warnings -** from UBSAN. -*/ -SQLITE_PRIVATE i64 sqlite3RealToI64(double r){ - if( r<=(double)SMALLEST_INT64 ) return SMALLEST_INT64; - if( r>=(double)LARGEST_INT64) return LARGEST_INT64; - return (i64)r; -} - /* ** Convert pMem so that it has type MEM_Real or MEM_Int. ** Invalidate any prior representations. ** ** Every effort is made to force the conversion, even if the input @@ -81115,11 +79442,11 @@ sqlite3_int64 ix; assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); if( ((rc==0 || rc==1) && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1) - || sqlite3RealSameAsInt(pMem->u.r, (ix = sqlite3RealToI64(pMem->u.r))) + || sqlite3RealSameAsInt(pMem->u.r, (ix = (i64)pMem->u.r)) ){ pMem->u.i = ix; MemSetTypeFlag(pMem, MEM_Int); }else{ MemSetTypeFlag(pMem, MEM_Real); @@ -81167,11 +79494,10 @@ assert( MEM_Str==(MEM_Blob>>3) ); pMem->flags |= (pMem->flags&MEM_Blob)>>3; sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, 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; return sqlite3VdbeChangeEncoding(pMem, encoding); } } return SQLITE_OK; } @@ -81837,10 +80163,11 @@ if( pVal==0 ){ rc = SQLITE_NOMEM_BKPT; goto value_from_function_out; } + assert( pCtx->pParse->rc==SQLITE_OK ); memset(&ctx, 0, sizeof(ctx)); ctx.pOut = pVal; ctx.pFunc = pFunc; ctx.enc = ENC(db); pFunc->xSFunc(&ctx, nVal, apVal); @@ -81848,18 +80175,15 @@ rc = ctx.isError; sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); }else{ sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); assert( rc==SQLITE_OK ); - assert( enc==pVal->enc || db->mallocFailed ); -#if 0 /* Not reachable except after a prior failure */ rc = sqlite3VdbeChangeEncoding(pVal, enc); if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){ rc = SQLITE_TOOBIG; pCtx->pParse->nErr++; } -#endif } pCtx->pParse->rc = rc; value_from_function_out: if( rc!=SQLITE_OK ){ @@ -82304,13 +80628,10 @@ Mem *p = (Mem*)pVal; assert( (p->flags & MEM_Null)==0 || (p->flags & (MEM_Str|MEM_Blob))==0 ); if( (p->flags & MEM_Str)!=0 && pVal->enc==enc ){ return p->n; } - if( (p->flags & MEM_Str)!=0 && enc!=SQLITE_UTF8 && pVal->enc!=SQLITE_UTF8 ){ - return p->n; - } if( (p->flags & MEM_Blob)!=0 ){ if( p->flags & MEM_Zero ){ return p->n + p->u.nZero; }else{ return p->n; @@ -82352,14 +80673,14 @@ p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) ); if( p==0 ) return 0; memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp)); p->db = db; if( db->pVdbe ){ - db->pVdbe->ppVPrev = &p->pVNext; + db->pVdbe->pPrev = p; } - p->pVNext = db->pVdbe; - p->ppVPrev = &db->pVdbe; + p->pNext = db->pVdbe; + p->pPrev = 0; db->pVdbe = p; assert( p->eVdbeState==VDBE_INIT_STATE ); p->pParse = pParse; pParse->pVdbe = p; assert( pParse->aLabel==0 ); @@ -82437,32 +80758,25 @@ return 0; } #endif /* -** Swap byte-code between two VDBE structures. -** -** This happens after pB was previously run and returned -** SQLITE_SCHEMA. The statement was then reprepared in pA. -** This routine transfers the new bytecode in pA over to pB -** so that pB can be run again. The old pB byte code is -** moved back to pA so that it will be cleaned up when pA is -** finalized. +** Swap all content between two VDBE structures. */ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ - Vdbe tmp, *pTmp, **ppTmp; + Vdbe tmp, *pTmp; char *zTmp; assert( pA->db==pB->db ); tmp = *pA; *pA = *pB; *pB = tmp; - pTmp = pA->pVNext; - pA->pVNext = pB->pVNext; - pB->pVNext = pTmp; - ppTmp = pA->ppVPrev; - pA->ppVPrev = pB->ppVPrev; - pB->ppVPrev = ppTmp; + pTmp = pA->pNext; + pA->pNext = pB->pNext; + pB->pNext = pTmp; + pTmp = pA->pPrev; + pA->pPrev = pB->pPrev; + pB->pPrev = pTmp; zTmp = pA->zSql; pA->zSql = pB->zSql; pB->zSql = zTmp; #ifdef SQLITE_ENABLE_NORMALIZE zTmp = pA->zNormSql; @@ -82534,12 +80848,10 @@ ** sqlite3MisuseError(lineno) ** sqlite3CantopenError(lineno) */ static void test_addop_breakpoint(int pc, Op *pOp){ static int n = 0; - (void)pc; - (void)pOp; n++; } #endif /* @@ -82586,19 +80898,19 @@ pOp->p4.p = 0; pOp->p4type = P4_NOTUSED; #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 VDBE_PROFILE + pOp->cycles = 0; + pOp->cnt = 0; #endif #ifdef SQLITE_VDBE_COVERAGE pOp->iSrcLine = 0; #endif return i; @@ -82712,11 +81024,10 @@ pCtx->argc = nArg; pCtx->iOp = sqlite3VdbeCurrentAddr(v); addr = sqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function, p1, p2, p3, (char*)pCtx, P4_FUNCCTX); sqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef); - sqlite3MayAbort(pParse); return addr; } /* ** Add an opcode that includes the p4 value with a P4_INT64 or @@ -82763,13 +81074,12 @@ ** Add a new OP_Explain opcode. ** ** If the bPush flag is true, then make this opcode the parent for ** subsequent Explains until sqlite3VdbeExplainPop() is called. */ -SQLITE_PRIVATE int sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ - int addr = 0; -#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS) +SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ +#ifndef SQLITE_DEBUG /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined. ** But omit them (for performance) during production builds */ if( pParse->explain==2 ) #endif { @@ -82780,19 +81090,17 @@ va_start(ap, zFmt); zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap); va_end(ap); v = pParse->pVdbe; iThis = v->nOp; - addr = sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, + sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, zMsg, P4_DYNAMIC); - sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetLastOp(v)->p4.z); + sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetOp(v,-1)->p4.z); if( bPush){ pParse->addrExplain = iThis; } - sqlite3VdbeScanStatus(v, iThis, 0, 0, 0, 0); } - return addr; } /* ** Pop the EXPLAIN QUERY PLAN stack one level. */ @@ -82896,13 +81204,10 @@ }else{ #ifdef SQLITE_DEBUG int i; for(i=p->nLabelAlloc; iaLabel[i] = -1; #endif - if( nNewSize>=100 && (nNewSize/100)>(p->nLabelAlloc/100) ){ - sqlite3ProgressCheck(p); - } p->nLabelAlloc = nNewSize; p->aLabel[j] = v->nOp; } } SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){ @@ -83054,11 +81359,10 @@ int opcode = pOp->opcode; if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename || opcode==OP_VDestroy || opcode==OP_VCreate || opcode==OP_ParseSchema - || opcode==OP_Function || opcode==OP_PureFunc || ((opcode==OP_Halt || opcode==OP_HaltIfNull) && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort)) ){ hasAbort = 1; break; @@ -83145,12 +81449,12 @@ Parse *pParse = p->pParse; int *aLabel = pParse->aLabel; p->readOnly = 1; p->bIsReader = 0; pOp = &p->aOp[p->nOp-1]; - assert( p->aOp[0].opcode==OP_Init ); - while( 1 /* Loop termates when it reaches the OP_Init opcode */ ){ + while(1){ + /* 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 ** any opcode that does not need processing by virtual of the fact that ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization. @@ -83175,14 +81479,10 @@ case OP_JournalMode: { p->readOnly = 0; p->bIsReader = 1; break; } - case OP_Init: { - assert( pOp->p2>=0 ); - goto resolve_p2_values_loop_exit; - } #ifndef SQLITE_OMIT_VIRTUALTABLE case OP_VUpdate: { if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; break; } @@ -83211,16 +81511,15 @@ /* The mkopcodeh.tcl script has so arranged things that the only ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to ** have non-negative values for P2. */ assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0); } - assert( pOp>p->aOp ); + if( pOp==p->aOp ) break; pOp--; } -resolve_p2_values_loop_exit: if( aLabel ){ - sqlite3DbNNFreeNN(p->db, pParse->aLabel); + sqlite3DbFreeNN(p->db, pParse->aLabel); pParse->aLabel = 0; } pParse->nLabel = 0; *pMaxFuncArgs = nMaxArgs; assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); @@ -83449,115 +81748,42 @@ sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus); ScanStatus *aNew; aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); if( aNew ){ ScanStatus *pNew = &aNew[p->nScan++]; - memset(pNew, 0, sizeof(ScanStatus)); pNew->addrExplain = addrExplain; pNew->addrLoop = addrLoop; pNew->addrVisit = addrVisit; pNew->nEst = nEst; pNew->zName = sqlite3DbStrDup(p->db, zName); p->aScan = aNew; } } - -/* -** Add the range of instructions from addrStart to addrEnd (inclusive) to -** the set of those corresponding to the sqlite3_stmt_scanstatus() counters -** associated with the OP_Explain instruction at addrExplain. The -** sum of the sqlite3Hwtime() values for each of these instructions -** will be returned for SQLITE_SCANSTAT_NCYCLE requests. -*/ -SQLITE_PRIVATE void sqlite3VdbeScanStatusRange( - Vdbe *p, - int addrExplain, - int addrStart, - int addrEnd -){ - ScanStatus *pScan = 0; - int ii; - for(ii=p->nScan-1; ii>=0; ii--){ - pScan = &p->aScan[ii]; - if( pScan->addrExplain==addrExplain ) break; - pScan = 0; - } - if( pScan ){ - if( addrEnd<0 ) addrEnd = sqlite3VdbeCurrentAddr(p)-1; - for(ii=0; iiaAddrRange); ii+=2){ - if( pScan->aAddrRange[ii]==0 ){ - pScan->aAddrRange[ii] = addrStart; - pScan->aAddrRange[ii+1] = addrEnd; - break; - } - } - } -} - -/* -** Set the addresses for the SQLITE_SCANSTAT_NLOOP and SQLITE_SCANSTAT_NROW -** counters for the query element associated with the OP_Explain at -** addrExplain. -*/ -SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters( - Vdbe *p, - int addrExplain, - int addrLoop, - int addrVisit -){ - ScanStatus *pScan = 0; - int ii; - for(ii=p->nScan-1; ii>=0; ii--){ - pScan = &p->aScan[ii]; - if( pScan->addrExplain==addrExplain ) break; - pScan = 0; - } - if( pScan ){ - pScan->addrLoop = addrLoop; - pScan->addrVisit = addrVisit; - } -} #endif /* ** Change the value of the opcode, or P1, P2, P3, or P5 operands ** for a specific instruction. */ SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe *p, int addr, u8 iNewOpcode){ - assert( addr>=0 ); sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode; } SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){ - assert( addr>=0 ); sqlite3VdbeGetOp(p,addr)->p1 = val; } SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ - assert( addr>=0 || p->db->mallocFailed ); sqlite3VdbeGetOp(p,addr)->p2 = val; } SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){ - assert( addr>=0 ); sqlite3VdbeGetOp(p,addr)->p3 = val; } SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){ assert( p->nOp>0 || p->db->mallocFailed ); if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5; } -/* -** If the previous opcode is an OP_Column that delivers results -** into register iDest, then add the OPFLAG_TYPEOFARG flag to that -** opcode. -*/ -SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe *p, int iDest){ - VdbeOp *pOp = sqlite3VdbeGetLastOp(p); - if( pOp->p3==iDest && pOp->opcode==OP_Column ){ - pOp->p5 |= OPFLAG_TYPEOFARG; - } -} - /* ** Change the P2 operand of instruction addr so that it points to ** the address of the next instruction to be coded. */ SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){ @@ -83582,11 +81808,11 @@ assert( p->aOp[addr].opcode==OP_Once || p->aOp[addr].opcode==OP_If || p->aOp[addr].opcode==OP_FkIfZero ); assert( p->aOp[addr].p4type==0 ); #ifdef SQLITE_VDBE_COVERAGE - sqlite3VdbeGetLastOp(p)->iSrcLine = 0; /* Erase VdbeCoverage() macros */ + sqlite3VdbeGetOp(p,-1)->iSrcLine = 0; /* Erase VdbeCoverage() macros */ #endif p->nOp--; }else{ sqlite3VdbeChangeP2(p, addr, p->nOp); } @@ -83596,27 +81822,25 @@ /* ** If the input FuncDef structure is ephemeral, then free it. If ** the FuncDef is not ephermal, then do nothing. */ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ - assert( db!=0 ); if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ - sqlite3DbNNFreeNN(db, pDef); + sqlite3DbFreeNN(db, pDef); } } /* ** Delete a P4 value if necessary. */ static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); - sqlite3DbNNFreeNN(db, p); + sqlite3DbFreeNN(db, p); } static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){ - assert( db!=0 ); freeEphemeralFunction(db, p->pFunc); - sqlite3DbNNFreeNN(db, p); + sqlite3DbFreeNN(db, p); } static void freeP4(sqlite3 *db, int p4type, void *p4){ assert( db ); switch( p4type ){ case P4_FUNCCTX: { @@ -83625,11 +81849,11 @@ } case P4_REAL: case P4_INT64: case P4_DYNAMIC: case P4_INTARRAY: { - if( p4 ) sqlite3DbNNFreeNN(db, p4); + sqlite3DbFree(db, p4); break; } case P4_KEYINFO: { if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4); break; @@ -83664,11 +81888,10 @@ ** opcodes contained within. If aOp is not NULL it is assumed to contain ** nOp entries. */ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ assert( nOp>=0 ); - assert( db!=0 ); if( aOp ){ Op *pOp = &aOp[nOp-1]; while(1){ /* Exit via break */ if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p); #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS @@ -83675,11 +81898,11 @@ sqlite3DbFree(db, pOp->zComment); #endif if( pOp==aOp ) break; pOp--; } - sqlite3DbNNFreeNN(db, aOp); + sqlite3DbFreeNN(db, aOp); } } /* ** Link the SubProgram object passed as the second argument into the linked @@ -83844,11 +82067,11 @@ assert( n!=P4_INT32 && n!=P4_VTAB ); assert( n<=0 ); if( p->db->mallocFailed ){ freeP4(p->db, n, pP4); }else{ - assert( pP4!=0 || n==P4_DYNAMIC ); + assert( pP4!=0 ); assert( p->nOp>0 ); pOp = &p->aOp[p->nOp-1]; assert( pOp->p4type==P4_NOTUSED ); pOp->p4type = n; pOp->p4.p = pP4; @@ -83906,17 +82129,17 @@ #ifdef SQLITE_VDBE_COVERAGE /* ** Set the value if the iSrcLine field for the previously coded instruction. */ SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){ - sqlite3VdbeGetLastOp(v)->iSrcLine = iLine; + sqlite3VdbeGetOp(v,-1)->iSrcLine = iLine; } #endif /* SQLITE_VDBE_COVERAGE */ /* -** Return the opcode for a given address. The address must be non-negative. -** See sqlite3VdbeGetLastOp() to get the most recently added opcode. +** Return the opcode for a given address. If the address is -1, then +** return the most recently inserted opcode. ** ** If a memory allocation error has occurred prior to the calling of this ** routine, then a pointer to a dummy VdbeOp will be returned. That opcode ** is readable but not writable, though it is cast to a writable value. ** The return of a dummy opcode allows the call to continue functioning @@ -83928,24 +82151,21 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ /* C89 specifies that the constant "dummy" will be initialized to all ** zeros, which is correct. MSVC generates a warning, nevertheless. */ static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ assert( p->eVdbeState==VDBE_INIT_STATE ); + if( addr<0 ){ + addr = p->nOp - 1; + } assert( (addr>=0 && addrnOp) || p->db->mallocFailed ); if( p->db->mallocFailed ){ return (VdbeOp*)&dummy; }else{ return &p->aOp[addr]; } } -/* Return the most recently added opcode -*/ -VdbeOp * sqlite3VdbeGetLastOp(Vdbe *p){ - return sqlite3VdbeGetOp(p, p->nOp - 1); -} - #if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) /* ** Return an integer value for one of the parameters to the opcode pOp ** determined by character c. */ @@ -84429,11 +82649,11 @@ if( p->flags&(MEM_Agg|MEM_Dyn) ){ testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel ); sqlite3VdbeMemRelease(p); p->flags = MEM_Undefined; }else if( p->szMalloc ){ - sqlite3DbNNFreeNN(db, p->zMalloc); + sqlite3DbFreeNN(db, p->zMalloc); p->szMalloc = 0; p->flags = MEM_Undefined; } #ifdef SQLITE_DEBUG else{ @@ -84643,10 +82863,11 @@ /* Even though this opcode does not use dynamic strings for ** the result, result columns may become dynamic if the user calls ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. */ releaseMemArray(pMem, 8); + p->pResultSet = 0; if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or ** sqlite3_column_text16() failed. */ sqlite3OomFault(db); @@ -84699,11 +82920,11 @@ sqlite3VdbeMemSetNull(pMem+7); #endif sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free); p->nResColumn = 8; } - p->pResultRow = pMem; + p->pResultSet = pMem; if( db->mallocFailed ){ p->rc = SQLITE_NOMEM; rc = SQLITE_ERROR; }else{ p->rc = SQLITE_OK; @@ -84810,11 +83031,11 @@ /* ** Rewind the VDBE back to the beginning in preparation for ** running it. */ SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ -#if defined(SQLITE_DEBUG) +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) int i; #endif assert( p!=0 ); assert( p->eVdbeState==VDBE_INIT_STATE || p->eVdbeState==VDBE_READY_STATE @@ -84839,12 +83060,12 @@ p->minWriteFileFormat = 255; p->iStatement = 0; p->nFkConstraint = 0; #ifdef VDBE_PROFILE for(i=0; inOp; i++){ - p->aOp[i].nExec = 0; - p->aOp[i].nCycle = 0; + p->aOp[i].cnt = 0; + p->aOp[i].cycles = 0; } #endif } /* @@ -84949,18 +83170,24 @@ x.nNeeded = 0; p->aMem = allocSpace(&x, 0, nMem*sizeof(Mem)); p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem)); p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*)); p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*)); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + p->anExec = allocSpace(&x, 0, p->nOp*sizeof(i64)); +#endif if( x.nNeeded ){ x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded); x.nFree = x.nNeeded; if( !db->mallocFailed ){ p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem)); p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64)); +#endif } } if( db->mallocFailed ){ p->nVar = 0; @@ -84971,10 +83198,13 @@ p->nVar = (ynVar)nVar; initMemArray(p->aVar, nVar, db, MEM_Null); p->nMem = nMem; initMemArray(p->aMem, nMem, db, MEM_Undefined); memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*)); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + memset(p->anExec, 0, p->nOp*sizeof(i64)); +#endif } sqlite3VdbeRewind(p); } /* @@ -85028,10 +83258,13 @@ ** control to the main program. */ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ Vdbe *v = pFrame->v; closeCursorsInFrame(v); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + v->anExec = pFrame->anExec; +#endif v->aOp = pFrame->aOp; v->nOp = pFrame->nOp; v->aMem = pFrame->aMem; v->nMem = pFrame->nMem; v->apCsr = pFrame->apCsr; @@ -85408,11 +83641,11 @@ if( sqlite3_stmt_busy((sqlite3_stmt*)p) ){ cnt++; if( p->readOnly==0 ) nWrite++; if( p->bIsReader ) nRead++; } - p = p->pVNext; + p = p->pNext; } assert( cnt==db->nVdbeActive ); assert( nWrite==db->nVdbeWrite ); assert( nRead==db->nVdbeRead ); } @@ -85831,11 +84064,11 @@ #endif if( p->zErrMsg ){ sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; } - p->pResultRow = 0; + p->pResultSet = 0; #ifdef SQLITE_DEBUG p->nWrite = 0; #endif /* Save profiling information from this VDBE run. @@ -85859,16 +84092,14 @@ } if( pc!='\n' ) fprintf(out, "\n"); } for(i=0; inOp; i++){ char zHdr[100]; - i64 cnt = p->aOp[i].nExec; - i64 cycles = p->aOp[i].nCycle; sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ", - cnt, - cycles, - cnt>0 ? cycles/cnt : 0 + p->aOp[i].cnt, + p->aOp[i].cycles, + p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0 ); fprintf(out, "%s", zHdr); sqlite3VdbePrintOp(out, i, &p->aOp[i]); } fclose(out); @@ -85939,28 +84170,27 @@ ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with ** the database connection and frees the object itself. */ static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ SubProgram *pSub, *pNext; - assert( db!=0 ); assert( p->db==0 || p->db==db ); if( p->aColName ){ releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); - sqlite3DbNNFreeNN(db, p->aColName); + sqlite3DbFreeNN(db, p->aColName); } for(pSub=p->pProgram; pSub; pSub=pNext){ pNext = pSub->pNext; vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); sqlite3DbFree(db, pSub); } if( p->eVdbeState!=VDBE_INIT_STATE ){ releaseMemArray(p->aVar, p->nVar); - if( p->pVList ) sqlite3DbNNFreeNN(db, p->pVList); - if( p->pFree ) sqlite3DbNNFreeNN(db, p->pFree); + if( p->pVList ) sqlite3DbFreeNN(db, p->pVList); + if( p->pFree ) sqlite3DbFreeNN(db, p->pFree); } vdbeFreeOpArray(db, p->aOp, p->nOp); - if( p->zSql ) sqlite3DbNNFreeNN(db, p->zSql); + sqlite3DbFree(db, p->zSql); #ifdef SQLITE_ENABLE_NORMALIZE sqlite3DbFree(db, p->zNormSql); { DblquoteStr *pThis, *pNext; for(pThis=p->pDblStr; pThis; pThis=pNext){ @@ -85986,21 +84216,24 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ sqlite3 *db; assert( p!=0 ); db = p->db; - assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); sqlite3VdbeClearObject(db, p); if( db->pnBytesFreed==0 ){ - assert( p->ppVPrev!=0 ); - *p->ppVPrev = p->pVNext; - if( p->pVNext ){ - p->pVNext->ppVPrev = p->ppVPrev; + if( p->pPrev ){ + p->pPrev->pNext = p->pNext; + }else{ + assert( db->pVdbe==p ); + db->pVdbe = p->pNext; + } + if( p->pNext ){ + p->pNext->pPrev = p->pPrev; } } - sqlite3DbNNFreeNN(db, p); + sqlite3DbFreeNN(db, p); } /* ** The cursor "p" has a pending seek operation that has not yet been ** carried out. Seek the cursor now. If an error occurs, return @@ -86951,21 +85184,21 @@ assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB ); assert( pPKey2->pKeyInfo->aSortFlags!=0 ); assert( pPKey2->pKeyInfo->nKeyField>0 ); assert( idx1<=szHdr1 || CORRUPT_DB ); - while( 1 /*exit-by-break*/ ){ + do{ u32 serial_type; /* RHS is an integer */ if( pRhs->flags & (MEM_Int|MEM_IntReal) ){ testcase( pRhs->flags & MEM_Int ); testcase( pRhs->flags & MEM_IntReal ); serial_type = aKey1[idx1]; testcase( serial_type==12 ); if( serial_type>=10 ){ - rc = serial_type==10 ? -1 : +1; + rc = +1; }else if( serial_type==0 ){ rc = -1; }else if( serial_type==7 ){ sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r); @@ -86986,11 +85219,11 @@ if( serial_type>=10 ){ /* 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 numberic values are. */ - rc = serial_type==10 ? -1 : +1; + rc = +1; }else if( serial_type==0 ){ rc = -1; }else{ sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); if( serial_type==7 ){ @@ -87067,11 +85300,11 @@ } /* RHS is null */ else{ serial_type = aKey1[idx1]; - rc = (serial_type!=0 && serial_type!=10); + rc = (serial_type!=0); } if( rc!=0 ){ int sortFlags = pPKey2->pKeyInfo->aSortFlags[i]; if( sortFlags ){ @@ -87089,17 +85322,12 @@ i++; if( i==pPKey2->nField ) break; pRhs++; d1 += sqlite3VdbeSerialTypeLen(serial_type); - if( d1>(unsigned)nKey1 ) break; idx1 += sqlite3VarintLen(serial_type); - if( idx1>=(unsigned)szHdr1 ){ - pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; - return 0; /* Corrupt index */ - } - } + }while( idx1<(unsigned)szHdr1 && d1<=(unsigned)nKey1 ); /* No memory allocation is ever used on mem1. Prove this using ** the following assert(). If the assert() fails, it indicates a ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */ assert( mem1.szMalloc==0 ); @@ -87496,11 +85724,11 @@ ** prepared statements. The flag is set to 1 for an immediate expiration ** and set to 2 for an advisory expiration. */ SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){ Vdbe *p; - for(p = db->pVdbe; p; p=p->pVNext){ + for(p = db->pVdbe; p; p=p->pNext){ p->expired = iCode+1; } } /* @@ -87617,18 +85845,17 @@ ** ** This function is used to free UnpackedRecord structures allocated by ** the vdbeUnpackRecord() function found in vdbeapi.c. */ static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){ - assert( db!=0 ); if( p ){ int i; for(i=0; iaMem[i]; if( pMem->zMalloc ) sqlite3VdbeMemReleaseMalloc(pMem); } - sqlite3DbNNFreeNN(db, p); + sqlite3DbFreeNN(db, p); } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK @@ -87695,11 +85922,11 @@ if( preupdate.aNew ){ int i; for(i=0; inField; i++){ sqlite3VdbeMemRelease(&preupdate.aNew[i]); } - sqlite3DbNNFreeNN(db, preupdate.aNew); + sqlite3DbFreeNN(db, preupdate.aNew); } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ /************** End of vdbeaux.c *********************************************/ @@ -87719,11 +85946,10 @@ ** This file contains code use to implement APIs that are part of the ** VDBE. */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ -/* #include "opcodes.h" */ #ifndef SQLITE_OMIT_DEPRECATED /* ** Return TRUE (non-zero) of the statement supplied as an argument needs ** to be recompiled. A statement needs to be recompiled whenever the @@ -87813,13 +86039,11 @@ Vdbe *v = (Vdbe*)pStmt; sqlite3 *db = v->db; if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; sqlite3_mutex_enter(db->mutex); checkProfileCallback(db, v); - assert( v->eVdbeState>=VDBE_READY_STATE ); - rc = sqlite3VdbeReset(v); - sqlite3VdbeDelete(v); + rc = sqlite3VdbeFinalize(v); rc = sqlite3ApiExit(db, rc); sqlite3LeaveMutexAndCloseZombie(db); } return rc; } @@ -88023,13 +86247,10 @@ assert( eType == aType[pVal->flags&MEM_AffMask] ); } #endif return aType[pVal->flags&MEM_AffMask]; } -SQLITE_API int sqlite3_value_encoding(sqlite3_value *pVal){ - return pVal->enc; -} /* Return true if a parameter to xUpdate represents an unchanged column */ SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){ return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero); } @@ -88210,14 +86431,11 @@ void (*xDel)(void *), unsigned char enc ){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); assert( xDel!=SQLITE_DYNAMIC ); - if( enc!=SQLITE_UTF8 ){ - if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; - n &= ~(u64)1; - } + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; if( n>0x7fffffff ){ (void)invokeValueDestructor(z, xDel, pCtx); }else{ setResultStrOrError(pCtx, z, (int)n, enc, xDel); } @@ -88228,29 +86446,29 @@ const void *z, int n, void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16NATIVE, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel); } SQLITE_API void sqlite3_result_text16be( sqlite3_context *pCtx, const void *z, int n, void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16BE, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel); } SQLITE_API void sqlite3_result_text16le( sqlite3_context *pCtx, const void *z, int n, void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16LE, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel); } #endif /* SQLITE_OMIT_UTF16 */ SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); @@ -88457,11 +86675,11 @@ }else{ #ifndef SQLITE_OMIT_TRACE /* If the statement completed successfully, invoke the profile callback */ checkProfileCallback(db, p); #endif - p->pResultRow = 0; + if( rc==SQLITE_DONE && db->autoCommit ){ assert( p->rc==SQLITE_OK ); p->rc = doWalCallbacks(db); if( p->rc!=SQLITE_OK ){ rc = SQLITE_ERROR; @@ -88586,21 +86804,10 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){ assert( p ); return sqlite3_value_nochange(p->pOut); } -/* -** 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 -** 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){ - sqlite3_free(pToDelete); -} - /* ** Implementation of sqlite3_vtab_in_first() (if bNext==0) and ** sqlite3_vtab_in_next() (if bNext!=0). */ static int valueFromValueList( @@ -88611,19 +86818,12 @@ int rc; ValueList *pRhs; *ppOut = 0; if( pVal==0 ) return SQLITE_MISUSE; - if( (pVal->flags & MEM_Dyn)==0 || pVal->xDel!=sqlite3VdbeValueListFree ){ - return SQLITE_ERROR; - }else{ - assert( (pVal->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) == - (MEM_Null|MEM_Term|MEM_Subtype) ); - assert( pVal->eSubtype=='p' ); - assert( pVal->u.zPType!=0 && strcmp(pVal->u.zPType,"ValueList")==0 ); - pRhs = (ValueList*)pVal->z; - } + pRhs = (ValueList*)sqlite3_value_pointer(pVal, "ValueList"); + if( pRhs==0 ) return SQLITE_MISUSE; if( bNext ){ rc = sqlite3BtreeNext(pRhs->pCsr, 0); }else{ int dummy = 0; rc = sqlite3BtreeFirst(pRhs->pCsr, &dummy); @@ -88839,11 +87039,11 @@ ** Return the number of values available from the current row of the ** currently executing statement pStmt. */ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){ Vdbe *pVm = (Vdbe *)pStmt; - if( pVm==0 || pVm->pResultRow==0 ) return 0; + if( pVm==0 || pVm->pResultSet==0 ) return 0; return pVm->nResColumn; } /* ** Return a pointer to static memory containing an SQL NULL value. @@ -88894,12 +87094,12 @@ pVm = (Vdbe *)pStmt; if( pVm==0 ) return (Mem*)columnNullValue(); assert( pVm->db ); sqlite3_mutex_enter(pVm->db->mutex); - if( pVm->pResultRow!=0 && inResColumn && i>=0 ){ - pOut = &pVm->pResultRow[i]; + if( pVm->pResultSet!=0 && inResColumn && i>=0 ){ + pOut = &pVm->pResultSet[i]; }else{ sqlite3Error(pVm->db, SQLITE_RANGE); pOut = (Mem*)columnNullValue(); } return pOut; @@ -89161,11 +87361,11 @@ ** the mutex is released if any kind of error occurs. ** ** The error code stored in database p->db is overwritten with the return ** value in any case. */ -static int vdbeUnbind(Vdbe *p, unsigned int i){ +static int vdbeUnbind(Vdbe *p, int i){ Mem *pVar; if( vdbeSafetyNotNull(p) ){ return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(p->db->mutex); @@ -89174,15 +87374,16 @@ sqlite3_mutex_leave(p->db->mutex); sqlite3_log(SQLITE_MISUSE, "bind on a busy prepared statement: [%s]", p->zSql); return SQLITE_MISUSE_BKPT; } - if( i>=(unsigned int)p->nVar ){ + if( i<1 || i>p->nVar ){ sqlite3Error(p->db, SQLITE_RANGE); sqlite3_mutex_leave(p->db->mutex); return SQLITE_RANGE; } + i--; pVar = &p->aVar[i]; sqlite3VdbeMemRelease(pVar); pVar->flags = MEM_Null; p->db->errCode = SQLITE_OK; @@ -89215,11 +87416,11 @@ ){ Vdbe *p = (Vdbe *)pStmt; Mem *pVar; int rc; - rc = vdbeUnbind(p, (u32)(i-1)); + rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ if( zData!=0 ){ pVar = &p->aVar[i-1]; rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); if( rc==SQLITE_OK && encoding!=0 ){ @@ -89264,11 +87465,11 @@ return bindText(pStmt, i, zData, nData, xDel, 0); } SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ int rc; Vdbe *p = (Vdbe *)pStmt; - rc = vdbeUnbind(p, (u32)(i-1)); + rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); sqlite3_mutex_leave(p->db->mutex); } return rc; @@ -89277,21 +87478,21 @@ return sqlite3_bind_int64(p, i, (i64)iValue); } SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ int rc; Vdbe *p = (Vdbe *)pStmt; - rc = vdbeUnbind(p, (u32)(i-1)); + rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); sqlite3_mutex_leave(p->db->mutex); } return rc; } SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ int rc; Vdbe *p = (Vdbe*)pStmt; - rc = vdbeUnbind(p, (u32)(i-1)); + rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ sqlite3_mutex_leave(p->db->mutex); } return rc; } @@ -89302,11 +87503,11 @@ const char *zPTtype, void (*xDestructor)(void*) ){ int rc; Vdbe *p = (Vdbe*)pStmt; - rc = vdbeUnbind(p, (u32)(i-1)); + rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); sqlite3_mutex_leave(p->db->mutex); }else if( xDestructor ){ xDestructor(pPtr); @@ -89329,25 +87530,22 @@ sqlite3_uint64 nData, void (*xDel)(void*), unsigned char enc ){ assert( xDel!=SQLITE_DYNAMIC ); - if( enc!=SQLITE_UTF8 ){ - if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; - nData &= ~(u16)1; - } + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; return bindText(pStmt, i, zData, nData, xDel, enc); } #ifndef SQLITE_OMIT_UTF16 SQLITE_API int sqlite3_bind_text16( sqlite3_stmt *pStmt, int i, const void *zData, - int n, + int nData, void (*xDel)(void*) ){ - return bindText(pStmt, i, zData, n & ~(u64)1, xDel, SQLITE_UTF16NATIVE); + return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE); } #endif /* SQLITE_OMIT_UTF16 */ SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ int rc; switch( sqlite3_value_type((sqlite3_value*)pValue) ){ @@ -89383,11 +87581,11 @@ return rc; } SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ int rc; Vdbe *p = (Vdbe *)pStmt; - rc = vdbeUnbind(p, (u32)(i-1)); + rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ #ifndef SQLITE_OMIT_INCRBLOB sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); #else rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); @@ -89543,11 +87741,11 @@ #endif sqlite3_mutex_enter(pDb->mutex); if( pStmt==0 ){ pNext = (sqlite3_stmt*)pDb->pVdbe; }else{ - pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pVNext; + pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext; } sqlite3_mutex_leave(pDb->mutex); return pNext; } @@ -89568,15 +87766,12 @@ if( op==SQLITE_STMTSTATUS_MEMUSED ){ sqlite3 *db = pVdbe->db; sqlite3_mutex_enter(db->mutex); v = 0; db->pnBytesFreed = (int*)&v; - assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); - db->lookaside.pEnd = db->lookaside.pStart; sqlite3VdbeDelete(pVdbe); db->pnBytesFreed = 0; - db->lookaside.pEnd = db->lookaside.pTrueEnd; sqlite3_mutex_leave(db->mutex); }else{ v = pVdbe->aCounter[op]; if( resetFlag ) pVdbe->aCounter[op] = 0; } @@ -89834,64 +88029,27 @@ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS /* ** Return status data for a single loop within query pStmt. */ -SQLITE_API int sqlite3_stmt_scanstatus_v2( +SQLITE_API int sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement being queried */ - int iScan, /* Index of loop to report on */ + int idx, /* Index of loop to report on */ int iScanStatusOp, /* Which metric to return */ - int flags, void *pOut /* OUT: Write the answer here */ ){ Vdbe *p = (Vdbe*)pStmt; ScanStatus *pScan; - int idx; - - if( iScan<0 ){ - int ii; - if( iScanStatusOp==SQLITE_SCANSTAT_NCYCLE ){ - i64 res = 0; - for(ii=0; iinOp; ii++){ - res += p->aOp[ii].nCycle; - } - *(i64*)pOut = res; - return 0; - } - return 1; - } - if( flags & SQLITE_SCANSTAT_COMPLEX ){ - idx = iScan; - pScan = &p->aScan[idx]; - }else{ - /* If the COMPLEX flag is clear, then this function must ignore any - ** ScanStatus structures with ScanStatus.addrLoop set to 0. */ - for(idx=0; idxnScan; idx++){ - pScan = &p->aScan[idx]; - if( pScan->zName ){ - iScan--; - if( iScan<0 ) break; - } - } - } - if( idx>=p->nScan ) return 1; - + if( idx<0 || idx>=p->nScan ) return 1; + pScan = &p->aScan[idx]; switch( iScanStatusOp ){ case SQLITE_SCANSTAT_NLOOP: { - if( pScan->addrLoop>0 ){ - *(sqlite3_int64*)pOut = p->aOp[pScan->addrLoop].nExec; - }else{ - *(sqlite3_int64*)pOut = -1; - } + *(sqlite3_int64*)pOut = p->anExec[pScan->addrLoop]; break; } case SQLITE_SCANSTAT_NVISIT: { - if( pScan->addrVisit>0 ){ - *(sqlite3_int64*)pOut = p->aOp[pScan->addrVisit].nExec; - }else{ - *(sqlite3_int64*)pOut = -1; - } + *(sqlite3_int64*)pOut = p->anExec[pScan->addrVisit]; break; } case SQLITE_SCANSTAT_EST: { double r = 1.0; LogEst x = pScan->nEst; @@ -89920,79 +88078,23 @@ }else{ *(int*)pOut = -1; } break; } - case SQLITE_SCANSTAT_PARENTID: { - if( pScan->addrExplain ){ - *(int*)pOut = p->aOp[ pScan->addrExplain ].p2; - }else{ - *(int*)pOut = -1; - } - break; - } - case SQLITE_SCANSTAT_NCYCLE: { - i64 res = 0; - if( pScan->aAddrRange[0]==0 ){ - res = -1; - }else{ - int ii; - for(ii=0; iiaAddrRange); ii+=2){ - int iIns = pScan->aAddrRange[ii]; - int iEnd = pScan->aAddrRange[ii+1]; - if( iIns==0 ) break; - if( iIns>0 ){ - while( iIns<=iEnd ){ - res += p->aOp[iIns].nCycle; - iIns++; - } - }else{ - int iOp; - for(iOp=0; iOpnOp; iOp++){ - Op *pOp = &p->aOp[iOp]; - if( pOp->p1!=iEnd ) continue; - if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_NCYCLE)==0 ){ - continue; - } - res += p->aOp[iOp].nCycle; - } - } - } - } - *(i64*)pOut = res; - break; - } default: { return 1; } } return 0; } -/* -** Return status data for a single loop within query pStmt. -*/ -SQLITE_API int sqlite3_stmt_scanstatus( - sqlite3_stmt *pStmt, /* Prepared statement being queried */ - int iScan, /* Index of loop to report on */ - int iScanStatusOp, /* Which metric to return */ - void *pOut /* OUT: Write the answer here */ -){ - return sqlite3_stmt_scanstatus_v2(pStmt, iScan, iScanStatusOp, 0, pOut); -} - /* ** Zero all counters associated with the sqlite3_stmt_scanstatus() data. */ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; - int ii; - for(ii=0; iinOp; ii++){ - Op *pOp = &p->aOp[ii]; - pOp->nExec = 0; - pOp->nCycle = 0; - } + memset(p->anExec, 0, p->nOp * sizeof(i64)); } #endif /* SQLITE_ENABLE_STMT_SCANSTATUS */ /************** End of vdbeapi.c *********************************************/ /************** Begin file vdbetrace.c ***************************************/ @@ -90324,13 +88426,10 @@ ** sqlite3MisuseError(lineno) ** sqlite3CantopenError(lineno) */ static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ static int n = 0; - (void)pc; - (void)pOp; - (void)v; n++; } #endif /* @@ -90508,12 +88607,11 @@ ** floating point value of rValue. Return true and set *piValue to the ** integer value if the string is in range to be an integer. Otherwise, ** return false. */ static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){ - i64 iValue; - iValue = sqlite3RealToI64(rValue); + i64 iValue = (double)rValue; if( sqlite3RealSameAsInt(rValue,iValue) ){ *piValue = iValue; return 1; } return 0==sqlite3Atoi64(pRec->z, piValue, pRec->n, pRec->enc); @@ -90565,14 +88663,10 @@ ** floating-point representation if an integer representation ** is not possible. Note that the integer representation is ** always preferred, even if the affinity is REAL, because ** an integer representation is more space efficient on disk. ** -** SQLITE_AFF_FLEXNUM: -** If the value is text, then try to convert it into a number of -** some kind (integer or real) but do not make any other changes. -** ** SQLITE_AFF_TEXT: ** Convert pRec to a text representation. ** ** SQLITE_AFF_BLOB: ** SQLITE_AFF_NONE: @@ -90583,15 +88677,15 @@ char affinity, /* The affinity to be applied */ u8 enc /* Use this text encoding */ ){ if( affinity>=SQLITE_AFF_NUMERIC ){ assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL - || affinity==SQLITE_AFF_NUMERIC || affinity==SQLITE_AFF_FLEXNUM ); + || affinity==SQLITE_AFF_NUMERIC ); if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/ - if( (pRec->flags & (MEM_Real|MEM_IntReal))==0 ){ + if( (pRec->flags & MEM_Real)==0 ){ if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); - }else if( affinity<=SQLITE_AFF_REAL ){ + }else{ sqlite3VdbeIntegerAffinity(pRec); } } }else if( affinity==SQLITE_AFF_TEXT ){ /* Only attempt the conversion to TEXT if there is an integer or real @@ -90675,22 +88769,21 @@ ** ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags. ** But it does set pMem->u.r and pMem->u.i appropriately. */ static u16 numericType(Mem *pMem){ - assert( (pMem->flags & MEM_Null)==0 - || pMem->db==0 || pMem->db->mallocFailed ); - if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null) ){ + if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){ testcase( pMem->flags & MEM_Int ); testcase( pMem->flags & MEM_Real ); testcase( pMem->flags & MEM_IntReal ); - return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null); + return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal); } - assert( pMem->flags & (MEM_Str|MEM_Blob) ); - testcase( pMem->flags & MEM_Str ); - testcase( pMem->flags & MEM_Blob ); - return computeNumericType(pMem); + if( pMem->flags & (MEM_Str|MEM_Blob) ){ + testcase( pMem->flags & MEM_Str ); + testcase( pMem->flags & MEM_Blob ); + return computeNumericType(pMem); + } return 0; } #ifdef SQLITE_DEBUG /* @@ -90815,10 +88908,21 @@ # define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M) #else # define REGISTER_TRACE(R,M) #endif + +#ifdef VDBE_PROFILE + +/* +** hwtime.h contains inline assembler code for implementing +** high-performance timing routines. +*/ +/* #include "hwtime.h" */ + +#endif + #ifndef NDEBUG /* ** This function is only called from within an assert() expression. It ** checks that the sqlite3.nTransaction variable is correctly set to ** the number of non-transaction savepoints currently in the @@ -90904,14 +89008,15 @@ SQLITE_PRIVATE int sqlite3VdbeExec( Vdbe *p /* The VDBE */ ){ Op *aOp = p->aOp; /* Copy of p->aOp */ Op *pOp = aOp; /* Current operation */ -#ifdef SQLITE_DEBUG +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) Op *pOrigOp; /* Value of pOp at the top of the loop */ +#endif +#ifdef SQLITE_DEBUG int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */ - u8 iCompareIsInit = 0; /* iCompare is initialized */ #endif int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ u8 encoding = ENC(db); /* The database encoding */ @@ -90923,19 +89028,17 @@ Mem *aMem = p->aMem; /* Copy of p->aMem */ Mem *pIn1 = 0; /* 1st input operand */ Mem *pIn2 = 0; /* 2nd input operand */ Mem *pIn3 = 0; /* 3rd input operand */ Mem *pOut = 0; /* Output operand */ -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) - u64 *pnCycle = 0; +#ifdef VDBE_PROFILE + u64 start; /* CPU clock count at start of opcode */ #endif /*** INSERT STACK UNION HERE ***/ assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */ - if( DbMaskNonZero(p->lockMask) ){ - sqlite3VdbeEnter(p); - } + sqlite3VdbeEnter(p); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; assert( 0 < db->nProgressOps ); nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps); @@ -90952,10 +89055,11 @@ testcase( p->rc!=SQLITE_OK ); p->rc = SQLITE_OK; assert( p->bIsReader || p->readOnly!=0 ); p->iCurrentTime = 0; assert( p->explain==0 ); + p->pResultSet = 0; db->busyHandler.nBusy = 0; if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt; sqlite3VdbeIOTraceSql(p); #ifdef SQLITE_DEBUG sqlite3BeginBenignMalloc(); @@ -90988,18 +89092,16 @@ /* Errors are detected by individual opcodes, with an immediate ** jumps to abort_due_to_error. */ assert( rc==SQLITE_OK ); assert( pOp>=aOp && pOp<&aOp[p->nOp]); +#ifdef VDBE_PROFILE + start = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); +#endif nVmStep++; -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) - pOp->nExec++; - pnCycle = &pOp->nCycle; -# ifdef VDBE_PROFILE - if( sqlite3NProfileCnt==0 ) -# endif - *pnCycle -= sqlite3Hwtime(); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + if( p->anExec ) p->anExec[(int)(pOp-aOp)]++; #endif /* Only allow tracing if SQLITE_DEBUG is defined. */ #ifdef SQLITE_DEBUG @@ -91057,11 +89159,11 @@ assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); memAboutToChange(p, &aMem[pOp->p3]); } } #endif -#ifdef SQLITE_DEBUG +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) pOrigOp = pOp; #endif switch( pOp->opcode ){ @@ -91341,16 +89443,10 @@ int pcx; #ifdef SQLITE_DEBUG if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } #endif - - /* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates - ** something is wrong with the code generator. Raise and assertion in order - ** to bring this to the attention of fuzzers and other testing tools. */ - assert( pOp->p1!=SQLITE_INTERNAL ); - if( p->pFrame && pOp->p1==SQLITE_OK ){ /* Halt the sub-program. Return control to the parent frame. */ pFrame = p->pFrame; p->pFrame = pFrame->pParent; p->nFrame--; @@ -91788,14 +89884,14 @@ assert( p->nResColumn==pOp->p2 ); assert( pOp->p1>0 || CORRUPT_DB ); assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); p->cacheCtr = (p->cacheCtr + 2)|1; - p->pResultRow = &aMem[pOp->p1]; + p->pResultSet = &aMem[pOp->p1]; #ifdef SQLITE_DEBUG { - Mem *pMem = p->pResultRow; + Mem *pMem = p->pResultSet; int i; for(i=0; ip2; i++){ assert( memIsValid(&pMem[i]) ); REGISTER_TRACE(pOp->p1+i, &pMem[i]); /* The registers in the result will not be used again when the @@ -91928,24 +90024,25 @@ case OP_Add: /* same as TK_PLUS, in1, in2, out3 */ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ + u16 flags; /* Combined MEM_* flags from both inputs */ u16 type1; /* Numeric type of left operand */ u16 type2; /* Numeric type of right operand */ i64 iA; /* Integer value of left operand */ i64 iB; /* Integer value of right operand */ double rA; /* Real value of left operand */ double rB; /* Real value of right operand */ pIn1 = &aMem[pOp->p1]; - type1 = pIn1->flags; + type1 = numericType(pIn1); pIn2 = &aMem[pOp->p2]; - type2 = pIn2->flags; + type2 = numericType(pIn2); pOut = &aMem[pOp->p3]; + flags = pIn1->flags | pIn2->flags; if( (type1 & type2 & MEM_Int)!=0 ){ -int_math: iA = pIn1->u.i; iB = pIn2->u.i; switch( pOp->opcode ){ case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break; case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break; @@ -91963,16 +90060,13 @@ break; } } pOut->u.i = iB; MemSetTypeFlag(pOut, MEM_Int); - }else if( ((type1 | type2) & MEM_Null)!=0 ){ + }else if( (flags & MEM_Null)!=0 ){ goto arithmetic_result_is_null; }else{ - type1 = numericType(pIn1); - type2 = numericType(pIn2); - if( (type1 & type2 & MEM_Int)!=0 ) goto int_math; fp_math: rA = sqlite3VdbeRealValue(pIn1); rB = sqlite3VdbeRealValue(pIn2); switch( pOp->opcode ){ case OP_Add: rB += rA; break; @@ -92321,32 +90415,30 @@ pIn1 = &aMem[pOp->p1]; pIn3 = &aMem[pOp->p3]; flags1 = pIn1->flags; flags3 = pIn3->flags; if( (flags1 & flags3 & MEM_Int)!=0 ){ + assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT || CORRUPT_DB ); /* Common case of comparison of two integers */ if( pIn3->u.i > pIn1->u.i ){ if( sqlite3aGTb[pOp->opcode] ){ VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); goto jump_to_p2; } iCompare = +1; - VVA_ONLY( iCompareIsInit = 1; ) }else if( pIn3->u.i < pIn1->u.i ){ if( sqlite3aLTb[pOp->opcode] ){ VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); goto jump_to_p2; } iCompare = -1; - VVA_ONLY( iCompareIsInit = 1; ) }else{ if( sqlite3aEQb[pOp->opcode] ){ VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); goto jump_to_p2; } iCompare = 0; - VVA_ONLY( iCompareIsInit = 1; ) } VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3); break; } if( (flags1 | flags3)&MEM_Null ){ @@ -92374,11 +90466,10 @@ VdbeBranchTaken(2,3); if( pOp->p5 & SQLITE_JUMPIFNULL ){ goto jump_to_p2; } iCompare = 1; /* Operands are not equal */ - VVA_ONLY( iCompareIsInit = 1; ) break; } }else{ /* Neither operand is NULL and we couldn't do the special high-speed ** integer comparison case. So do a general-case comparison. */ @@ -92385,26 +90476,26 @@ affinity = pOp->p5 & SQLITE_AFF_MASK; if( affinity>=SQLITE_AFF_NUMERIC ){ if( (flags1 | flags3)&MEM_Str ){ if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn1,0); - assert( flags3==pIn3->flags || CORRUPT_DB ); + testcase( flags3==pIn3->flags ); flags3 = pIn3->flags; } if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn3,0); } } - }else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){ + }else if( affinity==SQLITE_AFF_TEXT ){ if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn1->flags & MEM_Int ); testcase( pIn1->flags & MEM_Real ); testcase( pIn1->flags & MEM_IntReal ); sqlite3VdbeMemStringify(pIn1, encoding, 1); testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); - if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str; + if( pIn1==pIn3 ) flags3 = flags1 | MEM_Str; } if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn3->flags & MEM_Int ); testcase( pIn3->flags & MEM_Real ); testcase( pIn3->flags & MEM_IntReal ); @@ -92431,11 +90522,10 @@ res2 = sqlite3aEQb[pOp->opcode]; }else{ res2 = sqlite3aGTb[pOp->opcode]; } iCompare = res; - VVA_ONLY( iCompareIsInit = 1; ) /* Undo any changes made by applyAffinity() to the input registers. */ assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) ); pIn3->flags = flags3; assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); @@ -92470,11 +90560,10 @@ if( aOp[iAddr].opcode==OP_ReleaseReg ) continue; assert( aOp[iAddr].opcode==OP_Lt || aOp[iAddr].opcode==OP_Gt ); break; } #endif /* SQLITE_DEBUG */ - assert( iCompareIsInit ); VdbeBranchTaken(iCompare==0, 2); if( iCompare==0 ) goto jump_to_p2; break; } @@ -92565,11 +90654,10 @@ REGISTER_TRACE(p2+idx, &aMem[p2+idx]); assert( inKeyField ); pColl = pKeyInfo->aColl[i]; bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC); iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); - VVA_ONLY( iCompareIsInit = 1; ) if( iCompare ){ if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) && ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null)) ){ iCompare = -iCompare; @@ -92590,11 +90678,10 @@ ** ** This opcode must immediately follow an OP_Compare opcode. */ case OP_Jump: { /* jump */ assert( pOp>aOp && pOp[-1].opcode==OP_Compare ); - assert( iCompareIsInit ); if( iCompare<0 ){ VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1]; }else if( iCompare==0 ){ VdbeBranchTaken(1,4); pOp = &aOp[pOp->p2 - 1]; }else{ @@ -92790,94 +90877,23 @@ goto jump_to_p2; } break; } -/* Opcode: IsType P1 P2 P3 P4 P5 -** Synopsis: if typeof(P1.P3) in P5 goto P2 -** -** Jump to P2 if the type of a column in a btree is one of the types specified -** by the P5 bitmask. -** -** P1 is normally a cursor on a btree for which the row decode cache is -** valid through at least column P3. In other words, there should have been -** a prior OP_Column for column P3 or greater. If the cursor is not valid, -** then this opcode might give spurious results. -** The the btree row has fewer than P3 columns, then use P4 as the -** datatype. -** -** If P1 is -1, then P3 is a register number and the datatype is taken -** from the value in that register. -** -** P5 is a bitmask of data types. SQLITE_INTEGER is the least significant -** (0x01) bit. SQLITE_FLOAT is the 0x02 bit. SQLITE_TEXT is 0x04. -** SQLITE_BLOB is 0x08. SQLITE_NULL is 0x10. -** -** Take the jump to address P2 if and only if the datatype of the -** value determined by P1 and P3 corresponds to one of the bits in the -** P5 bitmask. -** -*/ -case OP_IsType: { /* jump */ - VdbeCursor *pC; - u16 typeMask; - u32 serialType; - - assert( pOp->p1>=(-1) && pOp->p1nCursor ); - assert( pOp->p1>=0 || (pOp->p3>=0 && pOp->p3<=(p->nMem+1 - p->nCursor)) ); - if( pOp->p1>=0 ){ - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pOp->p3>=0 ); - if( pOp->p3nHdrParsed ){ - serialType = pC->aType[pOp->p3]; - if( serialType>=12 ){ - if( serialType&1 ){ - typeMask = 0x04; /* SQLITE_TEXT */ - }else{ - typeMask = 0x08; /* SQLITE_BLOB */ - } - }else{ - static const unsigned char aMask[] = { - 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2, - 0x01, 0x01, 0x10, 0x10 - }; - testcase( serialType==0 ); - testcase( serialType==1 ); - testcase( serialType==2 ); - testcase( serialType==3 ); - testcase( serialType==4 ); - testcase( serialType==5 ); - testcase( serialType==6 ); - testcase( serialType==7 ); - testcase( serialType==8 ); - testcase( serialType==9 ); - testcase( serialType==10 ); - testcase( serialType==11 ); - typeMask = aMask[serialType]; - } - }else{ - typeMask = 1 << (pOp->p4.i - 1); - testcase( typeMask==0x01 ); - testcase( typeMask==0x02 ); - testcase( typeMask==0x04 ); - testcase( typeMask==0x08 ); - testcase( typeMask==0x10 ); - } - }else{ - assert( memIsValid(&aMem[pOp->p3]) ); - typeMask = 1 << (sqlite3_value_type((sqlite3_value*)&aMem[pOp->p3])-1); - testcase( typeMask==0x01 ); - testcase( typeMask==0x02 ); - testcase( typeMask==0x04 ); - testcase( typeMask==0x08 ); - testcase( typeMask==0x10 ); - } - VdbeBranchTaken( (typeMask & pOp->p5)!=0, 2); - if( typeMask & pOp->p5 ){ - goto jump_to_p2; - } +/* Opcode: IsNullOrType P1 P2 P3 * * +** Synopsis: if typeof(r[P1]) IN (P3,5) goto P2 +** +** Jump to P2 if the value in register P1 is NULL or has a datatype P3. +** P3 is an integer which should be one of SQLITE_INTEGER, SQLITE_FLOAT, +** SQLITE_BLOB, SQLITE_NULL, or SQLITE_TEXT. +*/ +case OP_IsNullOrType: { /* jump, in1 */ + int doTheJump; + pIn1 = &aMem[pOp->p1]; + doTheJump = (pIn1->flags & MEM_Null)!=0 || sqlite3_value_type(pIn1)==pOp->p3; + VdbeBranchTaken( doTheJump, 2); + if( doTheJump ) goto jump_to_p2; break; } /* Opcode: ZeroOrNull P1 P2 P3 * * ** Synopsis: r[P2] = 0 OR NULL @@ -92916,18 +90932,15 @@ ** ** Check the cursor P1 to see if it is currently pointing at a NULL row. ** If it is, then set register P3 to NULL and jump immediately to P2. ** If P1 is not on a NULL row, then fall through without making any ** changes. -** -** If P1 is not an open cursor, then this opcode is a no-op. */ case OP_IfNullRow: { /* jump */ - VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - if( ALWAYS(pC) && pC->nullRow ){ + assert( p->apCsr[pOp->p1]!=0 ); + if( p->apCsr[pOp->p1]->nullRow ){ sqlite3VdbeMemSetNull(aMem + pOp->p3); goto jump_to_p2; } break; } @@ -92974,27 +90987,25 @@ ** Synopsis: r[P3]=PX cursor P1 column P2 ** ** Interpret the data that cursor P1 points to as a structure built using ** the MakeRecord instruction. (See the MakeRecord opcode for additional ** information about the format of the data.) Extract the P2-th column -** from this record. If there are less than (P2+1) +** from this record. If there are less that (P2+1) ** values in the record, extract a NULL. ** ** The value extracted is stored in register P3. ** ** If the record contains fewer than P2 fields, then extract a NULL. Or, ** if the P4 argument is a P4_MEM use the value of the P4 argument as ** the result. ** -** If the OPFLAG_LENGTHARG bit is set in P5 then the result is guaranteed -** to only be used by the length() function or the equivalent. The content -** of large blobs is not loaded, thus saving CPU cycles. If the -** OPFLAG_TYPEOFARG bit is set then the result will only be used by the -** typeof() function or the IS NULL or IS NOT NULL operators or the -** equivalent. In this case, all content loading can be omitted. +** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then +** the result is guaranteed to only be used as the argument of a length() +** or typeof() function, respectively. The loading of large blobs can be +** skipped for length() and all content loading can be skipped for typeof(). */ -case OP_Column: { /* ncycle */ +case OP_Column: { u32 p2; /* column number to retrieve */ VdbeCursor *pC; /* The VDBE cursor */ BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */ u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ int len; /* The length of the serialized data for the column */ @@ -93339,11 +91350,11 @@ if( (pIn1->flags & MEM_Str)==0 ) goto vdbe_type_error; break; } case COLTYPE_REAL: { testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_Real ); - assert( (pIn1->flags & MEM_IntReal)==0 ); + testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_IntReal ); if( pIn1->flags & MEM_Int ){ /* When applying REAL affinity, if the result is still an MEM_Int ** that will fit in 6 bytes, then change the type to MEM_IntReal ** so that we keep the high-resolution integer value but know that ** the type really wants to be REAL. */ @@ -94241,11 +92252,11 @@ assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); /* See note about index shifting on OP_ReadCookie */ rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3); if( pOp->p2==BTREE_SCHEMA_VERSION ){ /* When the schema cookie changes, record the new cookie internally */ - *(u32*)&pDb->pSchema->schema_cookie = *(u32*)&pOp->p3 - pOp->p5; + pDb->pSchema->schema_cookie = pOp->p3 - pOp->p5; db->mDbFlags |= DBFLAG_SchemaChange; sqlite3FkClearTriggerCache(db, pOp->p1); }else if( pOp->p2==BTREE_FILE_FORMAT ){ /* Record changes in the file format */ pDb->pSchema->file_format = pOp->p3; @@ -94342,11 +92353,11 @@ ** This instruction works like OpenRead except that it opens the cursor ** in read/write mode. ** ** See also: OP_OpenRead, OP_ReopenIdx */ -case OP_ReopenIdx: { /* ncycle */ +case OP_ReopenIdx: { int nField; KeyInfo *pKeyInfo; u32 p2; int iDb; int wrFlag; @@ -94363,11 +92374,11 @@ sqlite3BtreeClearCursor(pCur->uc.pCursor); goto open_cursor_set_hints; } /* If the cursor is not currently open or is open on a different ** index, then fall through into OP_OpenRead to force a reopen */ -case OP_OpenRead: /* ncycle */ +case OP_OpenRead: case OP_OpenWrite: assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); assert( p->bIsReader ); assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx @@ -94457,11 +92468,11 @@ ** cursor P2. The P2 cursor must have been opened by a prior OP_OpenEphemeral ** opcode. Only ephemeral cursors may be duplicated. ** ** Duplicate ephemeral cursors are used for self-joins of materialized views. */ -case OP_OpenDup: { /* ncycle */ +case OP_OpenDup: { VdbeCursor *pOrig; /* The original cursor to be duplicated */ VdbeCursor *pCx; /* The new cursor */ pOrig = p->apCsr[pOp->p2]; assert( pOrig ); @@ -94519,12 +92530,12 @@ ** This opcode works the same as OP_OpenEphemeral. It has a ** different name to distinguish its use. Tables created using ** by this opcode will be used for automatically created transient ** indices in joins. */ -case OP_OpenAutoindex: /* ncycle */ -case OP_OpenEphemeral: { /* ncycle */ +case OP_OpenAutoindex: +case OP_OpenEphemeral: { VdbeCursor *pCx; KeyInfo *pKeyInfo; static const int vfsFlags = SQLITE_OPEN_READWRITE | @@ -94678,11 +92689,11 @@ /* Opcode: Close P1 * * * * ** ** Close a cursor previously opened as P1. If P1 is not ** currently open, this instruction is a no-op. */ -case OP_Close: { /* ncycle */ +case OP_Close: { assert( pOp->p1>=0 && pOp->p1nCursor ); sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); p->apCsr[pOp->p1] = 0; break; } @@ -94795,14 +92806,14 @@ ** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this ** is an equality search. ** ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt */ -case OP_SeekLT: /* jump, in3, group, ncycle */ -case OP_SeekLE: /* jump, in3, group, ncycle */ -case OP_SeekGE: /* jump, in3, group, ncycle */ -case OP_SeekGT: { /* jump, in3, group, ncycle */ +case OP_SeekLT: /* jump, in3, group */ +case OP_SeekLE: /* jump, in3, group */ +case OP_SeekGE: /* jump, in3, group */ +case OP_SeekGT: { /* jump, in3, group */ int res; /* Comparison result */ int oc; /* Opcode */ VdbeCursor *pC; /* The cursor to seek */ UnpackedRecord r; /* The key to seek for */ int nField; /* Number of columns or fields in the key */ @@ -94927,17 +92938,11 @@ assert( oc!=OP_SeekGE || r.default_rc==+1 ); assert( oc!=OP_SeekLT || r.default_rc==+1 ); r.aMem = &aMem[pOp->p3]; #ifdef SQLITE_DEBUG - { - int i; - for(i=0; i0 ) REGISTER_TRACE(pOp->p3+i, &r.aMem[i]); - } - } + { int i; for(i=0; iuc.pCursor, &r, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; @@ -94996,105 +93001,72 @@ } break; } -/* Opcode: SeekScan P1 P2 * * P5 +/* Opcode: SeekScan P1 P2 * * * ** Synopsis: Scan-ahead up to P1 rows ** ** This opcode is a prefix opcode to OP_SeekGE. In other words, this ** opcode must be immediately followed by OP_SeekGE. This constraint is ** checked by assert() statements. ** ** This opcode uses the P1 through P4 operands of the subsequent ** OP_SeekGE. In the text that follows, the operands of the subsequent ** OP_SeekGE opcode are denoted as SeekOP.P1 through SeekOP.P4. Only -** the P1, P2 and P5 operands of this opcode are also used, and are called -** This.P1, This.P2 and This.P5. +** the P1 and P2 operands of this opcode are also used, and are called +** This.P1 and This.P2. ** ** This opcode helps to optimize IN operators on a multi-column index ** where the IN operator is on the later terms of the index by avoiding ** unnecessary seeks on the btree, substituting steps to the next row ** of the b-tree instead. A correct answer is obtained if this opcode ** is omitted or is a no-op. ** ** The SeekGE.P3 and SeekGE.P4 operands identify an unpacked key which ** is the desired entry that we want the cursor SeekGE.P1 to be pointing -** to. Call this SeekGE.P3/P4 row the "target". +** to. Call this SeekGE.P4/P5 row the "target". ** ** If the SeekGE.P1 cursor is not currently pointing to a valid row, ** then this opcode is a no-op and control passes through into the OP_SeekGE. ** ** If the SeekGE.P1 cursor is pointing to a valid row, then that row ** might be the target row, or it might be near and slightly before the -** target row, or it might be after the target row. If the cursor is -** currently before the target row, then this opcode attempts to position -** the cursor on or after the target row by invoking sqlite3BtreeStep() -** on the cursor between 1 and This.P1 times. -** -** The This.P5 parameter is a flag that indicates what to do if the -** cursor ends up pointing at a valid row that is past the target -** 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 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 -** loop terminate. -** -** Possible outcomes from this opcode:
      -** -**
    1. If the cursor is initally not pointed to any valid row, then -** fall through into the subsequent OP_SeekGE opcode. -** -**
    2. If the cursor is left pointing to a row that is before the target -** row, even after making as many as This.P1 calls to -** sqlite3BtreeNext(), then also fall through into OP_SeekGE. -** -**
    3. If the cursor is left pointing at the target row, either because it -** was at the target row to begin with or because one or more -** sqlite3BtreeNext() calls moved the cursor to the target row, -** then jump to This.P2.., -** -**
    4. If the cursor started out before the target row and a call to -** to sqlite3BtreeNext() moved the cursor off the end of the index -** (indicating that the target row definitely does not exist in the -** btree) then jump to SeekGE.P2, ending the loop. -** -**
    5. If the cursor ends up on a valid row that is past the target row -** (indicating that the target row does not exist in the btree) then -** jump to SeekOP.P2 if This.P5==0 or to This.P2 if This.P5>0. +** target row. This opcode attempts to position the cursor on the target +** row by, perhaps by invoking sqlite3BtreeStep() on the cursor +** between 0 and This.P1 times. +** +** There are three possible outcomes from this opcode:
        +** +**
      1. If after This.P1 steps, the cursor is still pointing to a place that +** is earlier in the btree than the target row, then fall through +** into the subsquence OP_SeekGE opcode. +** +**
      2. If the cursor is successfully moved to the target row by 0 or more +** sqlite3BtreeNext() calls, then jump to This.P2, which will land just +** past the OP_IdxGT or OP_IdxGE opcode that follows the OP_SeekGE. +** +**
      3. If the cursor ends up past the target row (indicating the the target +** row does not exist in the btree) then jump to SeekOP.P2. **
      */ -case OP_SeekScan: { /* ncycle */ +case OP_SeekScan: { VdbeCursor *pC; int res; int nStep; UnpackedRecord r; assert( pOp[1].opcode==OP_SeekGE ); - /* If pOp->p5 is clear, then pOp->p2 points to the first instruction past the - ** OP_IdxGT that follows the OP_SeekGE. Otherwise, it points to the first - ** opcode past the OP_SeekGE itself. */ + /* pOp->p2 points to the first instruction past the OP_IdxGT that + ** follows the OP_SeekGE. */ assert( pOp->p2>=(int)(pOp-aOp)+2 ); -#ifdef SQLITE_DEBUG - if( pOp->p5==0 ){ - /* There are no inequality constraints following the IN constraint. */ - assert( pOp[1].p1==aOp[pOp->p2-1].p1 ); - assert( pOp[1].p2==aOp[pOp->p2-1].p2 ); - assert( pOp[1].p3==aOp[pOp->p2-1].p3 ); - assert( aOp[pOp->p2-1].opcode==OP_IdxGT - || aOp[pOp->p2-1].opcode==OP_IdxGE ); - testcase( aOp[pOp->p2-1].opcode==OP_IdxGE ); - }else{ - /* There are inequality constraints. */ - assert( pOp->p2==(int)(pOp-aOp)+2 ); - assert( aOp[pOp->p2-1].opcode==OP_SeekGE ); - } -#endif + assert( aOp[pOp->p2-1].opcode==OP_IdxGT || aOp[pOp->p2-1].opcode==OP_IdxGE ); + testcase( aOp[pOp->p2-1].opcode==OP_IdxGE ); + assert( pOp[1].p1==aOp[pOp->p2-1].p1 ); + assert( pOp[1].p2==aOp[pOp->p2-1].p2 ); + assert( pOp[1].p3==aOp[pOp->p2-1].p3 ); assert( pOp->p1>0 ); pC = p->apCsr[pOp[1].p1]; assert( pC!=0 ); assert( pC->eCurType==CURTYPE_BTREE ); @@ -95124,24 +93096,22 @@ #endif res = 0; /* Not needed. Only used to silence a warning. */ while(1){ rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res); if( rc ) goto abort_due_to_error; - if( res>0 && pOp->p5==0 ){ + if( res>0 ){ seekscan_search_fail: - /* Jump to SeekGE.P2, ending the loop */ #ifdef SQLITE_DEBUG if( db->flags&SQLITE_VdbeTrace ){ printf("... %d steps and then skip\n", pOp->p1 - nStep); } #endif VdbeBranchTaken(1,3); pOp++; goto jump_to_p2; } - if( res>=0 ){ - /* Jump to This.P2, bypassing the OP_SeekGE opcode */ + if( res==0 ){ #ifdef SQLITE_DEBUG if( db->flags&SQLITE_VdbeTrace ){ printf("... %d steps and then success\n", pOp->p1 - nStep); } #endif @@ -95186,11 +93156,11 @@ ** OP_IfNoHope opcode might run to see if the IN loop can be abandoned ** early, thus saving work. This is part of the IN-early-out optimization. ** ** P1 must be a valid b-tree cursor. */ -case OP_SeekHit: { /* ncycle */ +case OP_SeekHit: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pOp->p3>=pOp->p2 ); @@ -95213,20 +93183,16 @@ } /* Opcode: IfNotOpen P1 P2 * * * ** Synopsis: if( !csr[P1] ) goto P2 ** -** If cursor P1 is not open or if P1 is set to a NULL row using the -** OP_NullRow opcode, then jump to instruction P2. Otherwise, fall through. +** If cursor P1 is not open, jump to instruction P2. Otherwise, fall through. */ case OP_IfNotOpen: { /* jump */ - VdbeCursor *pCur; - assert( pOp->p1>=0 && pOp->p1nCursor ); - pCur = p->apCsr[pOp->p1]; - VdbeBranchTaken(pCur==0 || pCur->nullRow, 2); - if( pCur==0 || pCur->nullRow ){ + VdbeBranchTaken(p->apCsr[pOp->p1]==0, 2); + if( !p->apCsr[pOp->p1] ){ goto jump_to_p2_and_check_for_interrupt; } break; } @@ -95318,11 +93284,11 @@ ** advanced in either direction. In other words, the Next and Prev ** opcodes do not work after this operation. ** ** See also: NotFound, Found, NotExists */ -case OP_IfNoHope: { /* jump, in3, ncycle */ +case OP_IfNoHope: { /* jump, in3 */ VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); #ifdef SQLITE_DEBUG @@ -95332,13 +93298,13 @@ #endif if( pC->seekHit>=pOp->p4.i ) break; /* Fall through into OP_NotFound */ /* no break */ deliberate_fall_through } -case OP_NoConflict: /* jump, in3, ncycle */ -case OP_NotFound: /* jump, in3, ncycle */ -case OP_Found: { /* jump, in3, ncycle */ +case OP_NoConflict: /* jump, in3 */ +case OP_NotFound: /* jump, in3 */ +case OP_Found: { /* jump, in3 */ int alreadyExists; int ii; VdbeCursor *pC; UnpackedRecord *pIdxKey; UnpackedRecord r; @@ -95464,11 +93430,11 @@ ** in either direction. In other words, the Next and Prev opcodes will ** not work following this opcode. ** ** See also: Found, NotFound, NoConflict, SeekRowid */ -case OP_SeekRowid: { /* jump, in3, ncycle */ +case OP_SeekRowid: { /* jump, in3 */ VdbeCursor *pC; BtCursor *pCrsr; int res; u64 iKey; @@ -95489,11 +93455,11 @@ iKey = x.u.i; goto notExistsWithKey; } /* Fall through into OP_NotExists */ /* no break */ deliberate_fall_through -case OP_NotExists: /* jump, in3, ncycle */ +case OP_NotExists: /* jump, in3 */ pIn3 = &aMem[pOp->p3]; assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid ); assert( pOp->p1>=0 && pOp->p1nCursor ); iKey = pIn3->u.i; notExistsWithKey: @@ -95769,15 +93735,12 @@ } } if( pOp->p5 & OPFLAG_ISNOOP ) break; #endif - assert( (pOp->p5 & OPFLAG_LASTROWID)==0 || (pOp->p5 & OPFLAG_NCHANGE)!=0 ); - if( pOp->p5 & OPFLAG_NCHANGE ){ - p->nChange++; - if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; - } + if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 ); x.pData = pData->z; x.nData = pData->n; seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0); if( pData->flags & MEM_Zero ){ @@ -95784,11 +93747,10 @@ x.nZero = pData->u.nZero; }else{ x.nZero = 0; } x.pKey = 0; - assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT ); rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), seekResult ); pC->deferredMoveto = 0; @@ -96116,11 +94078,11 @@ ** ** P1 can be either an ordinary table or a virtual table. There used to ** be a separate OP_VRowid opcode for use with virtual tables, but this ** one opcode now works for both table types. */ -case OP_Rowid: { /* out2, ncycle */ +case OP_Rowid: { /* out2 */ VdbeCursor *pC; i64 v; sqlite3_vtab *pVtab; const sqlite3_module *pModule; @@ -96215,12 +94177,12 @@ ** ** This opcode leaves the cursor configured to move in reverse order, ** from the end toward the beginning. In other words, the cursor is ** configured to use Prev, not Next. */ -case OP_SeekEnd: /* ncycle */ -case OP_Last: { /* jump, ncycle */ +case OP_SeekEnd: +case OP_Last: { /* jump */ VdbeCursor *pC; BtCursor *pCrsr; int res; assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -96317,26 +94279,21 @@ ** will refer to the first entry in the database table or index. ** If the table or index is empty, jump immediately to P2. ** If the table or index is not empty, fall through to the following ** instruction. ** -** If P2 is zero, that is an assertion that the P1 table is never -** empty and hence the jump will never be taken. -** ** This opcode leaves the cursor configured to move in forward order, ** from the beginning toward the end. In other words, the cursor is ** configured to use Next, not Prev. */ -case OP_Rewind: { /* jump, ncycle */ +case OP_Rewind: { /* jump */ VdbeCursor *pC; BtCursor *pCrsr; int res; assert( pOp->p1>=0 && pOp->p1nCursor ); assert( pOp->p5==0 ); - assert( pOp->p2>=0 && pOp->p2nOp ); - pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); res = 1; #ifdef SQLITE_DEBUG @@ -96352,14 +94309,13 @@ pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; } if( rc ) goto abort_due_to_error; pC->nullRow = (u8)res; - if( pOp->p2>0 ){ - VdbeBranchTaken(res!=0,2); - if( res ) goto jump_to_p2; - } + assert( pOp->p2>0 && pOp->p2nOp ); + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; break; } /* Opcode: Next P1 P2 P3 * P5 ** @@ -96421,15 +94377,13 @@ pC = p->apCsr[pOp->p1]; assert( isSorter(pC) ); rc = sqlite3VdbeSorterNext(db, pC); goto next_tail; -case OP_Prev: /* jump, ncycle */ +case OP_Prev: /* jump */ assert( pOp->p1>=0 && pOp->p1nCursor ); - assert( pOp->p5==0 - || pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP - || pOp->p5==SQLITE_STMTSTATUS_AUTOINDEX); + assert( pOp->p5aCounter) ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->deferredMoveto==0 ); assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE @@ -96436,15 +94390,13 @@ || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope || pC->seekOp==OP_NullRow); rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3); goto next_tail; -case OP_Next: /* jump, ncycle */ +case OP_Next: /* jump */ assert( pOp->p1>=0 && pOp->p1nCursor ); - assert( pOp->p5==0 - || pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP - || pOp->p5==SQLITE_STMTSTATUS_AUTOINDEX); + assert( pOp->p5aCounter) ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->deferredMoveto==0 ); assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE @@ -96628,12 +94580,12 @@ ** the end of the index key pointed to by cursor P1. This integer should be ** the rowid of the table entry to which this index entry points. ** ** See also: Rowid, MakeRecord. */ -case OP_DeferredSeek: /* ncycle */ -case OP_IdxRowid: { /* out2, ncycle */ +case OP_DeferredSeek: +case OP_IdxRowid: { /* out2 */ VdbeCursor *pC; /* The P1 index cursor */ VdbeCursor *pTabCur; /* The P2 table cursor (OP_DeferredSeek only) */ i64 rowid; /* Rowid that P1 current points to */ assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -96647,14 +94599,14 @@ /* The IdxRowid and Seek opcodes are combined because of the commonality ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */ rc = sqlite3VdbeCursorRestore(pC); - /* sqlite3VdbeCursorRestore() may fail if the cursor has been disturbed - ** since it was last positioned and an error (e.g. OOM or an IO error) - ** occurs while trying to reposition it. */ - if( rc!=SQLITE_OK ) goto abort_due_to_error; + /* sqlite3VbeCursorRestore() can only fail if the record has been deleted + ** out from under the cursor. That will never happens for an IdxRowid + ** or Seek opcode */ + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; if( !pC->nullRow ){ rowid = 0; /* Not needed. Only used to silence a warning. */ rc = sqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid); if( rc!=SQLITE_OK ){ @@ -96691,12 +94643,12 @@ ** ** If cursor P1 was previously moved via OP_DeferredSeek, complete that ** seek operation now, without further delay. If the cursor seek has ** already occurred, this instruction is a no-op. */ -case OP_FinishSeek: { /* ncycle */ - VdbeCursor *pC; /* The P1 index cursor */ +case OP_FinishSeek: { + VdbeCursor *pC; /* The P1 index cursor */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; if( pC->deferredMoveto ){ rc = sqlite3VdbeFinishMoveto(pC); @@ -96747,14 +94699,14 @@ ** ROWID on the P1 index. ** ** If the P1 index entry is less than or equal to the key value then jump ** to P2. Otherwise fall through to the next instruction. */ -case OP_IdxLE: /* jump, ncycle */ -case OP_IdxGT: /* jump, ncycle */ -case OP_IdxLT: /* jump, ncycle */ -case OP_IdxGE: { /* jump, ncycle */ +case OP_IdxLE: /* jump */ +case OP_IdxGT: /* jump */ +case OP_IdxLT: /* jump */ +case OP_IdxGE: { /* jump */ VdbeCursor *pC; int res; UnpackedRecord r; assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -97161,18 +95113,17 @@ assert( (pnErr->flags & MEM_Int)!=0 ); assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); pIn1 = &aMem[pOp->p1]; assert( pOp->p5nDb ); assert( DbMaskTest(p->btreeMask, pOp->p5) ); - rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, - (int)pnErr->u.i+1, &nErr, &z); + z = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, + (int)pnErr->u.i+1, &nErr); sqlite3VdbeMemSetNull(pIn1); if( nErr==0 ){ assert( z==0 ); - }else if( rc ){ - sqlite3_free(z); - goto abort_due_to_error; + }else if( z==0 ){ + goto no_mem; }else{ pnErr->u.i -= nErr-1; sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); } UPDATE_MAX_BLOBSIZE(pIn1); @@ -97372,10 +95323,13 @@ pFrame->apCsr = p->apCsr; pFrame->nCursor = p->nCursor; pFrame->aOp = p->aOp; pFrame->nOp = p->nOp; pFrame->token = pProgram->token; +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + pFrame->anExec = p->anExec; +#endif #ifdef SQLITE_DEBUG pFrame->iFrameMagic = SQLITE_FRAME_MAGIC; #endif pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; @@ -97408,10 +95362,13 @@ p->apCsr = (VdbeCursor **)&aMem[p->nMem]; pFrame->aOnce = (u8*)&p->apCsr[pProgram->nCsr]; memset(pFrame->aOnce, 0, (pProgram->nOp + 7)/8); p->aOp = aOp = pProgram->aOp; p->nOp = pProgram->nOp; +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + p->anExec = 0; +#endif #ifdef SQLITE_DEBUG /* Verify that second and subsequent executions of the same trigger do not ** try to reuse register values from the first use. */ { int i; @@ -97547,11 +95504,11 @@ /* Opcode: OffsetLimit P1 P2 P3 * * ** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) ** ** This opcode performs a commonly used computation associated with -** LIMIT and OFFSET processing. r[P1] holds the limit counter. r[P3] +** LIMIT and OFFSET process. r[P1] holds the limit counter. r[P3] ** holds the offset counter. The opcode computes the combined value ** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2] ** value computed is the total number of rows that will need to be ** visited in order to complete the query. ** @@ -98164,11 +96121,11 @@ ** ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. ** P1 is a cursor number. This opcode opens a cursor to the virtual ** table and stores that cursor in P1. */ -case OP_VOpen: { /* ncycle */ +case OP_VOpen: { VdbeCursor *pCur; sqlite3_vtab_cursor *pVCur; sqlite3_vtab *pVtab; const sqlite3_module *pModule; @@ -98211,11 +96168,11 @@ ** can be used as the first argument to sqlite3_vtab_in_first() and ** sqlite3_vtab_in_next() to extract all of the values stored in the P1 ** cursor. Register P3 is used to hold the values returned by ** sqlite3_vtab_in_first() and sqlite3_vtab_in_next(). */ -case OP_VInitIn: { /* out2, ncycle */ +case OP_VInitIn: { /* out2 */ VdbeCursor *pC; /* The cursor containing the RHS values */ ValueList *pRhs; /* New ValueList object to put in reg[P2] */ pC = p->apCsr[pOp->p1]; pRhs = sqlite3_malloc64( sizeof(*pRhs) ); @@ -98222,11 +96179,11 @@ if( pRhs==0 ) goto no_mem; pRhs->pCsr = pC->uc.pCursor; pRhs->pOut = &aMem[pOp->p3]; pOut = out2Prerelease(p, pOp); pOut->flags = MEM_Null; - sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3VdbeValueListFree); + sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3_free); break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -98248,11 +96205,11 @@ ** additional parameters which are passed to ** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. ** ** A jump is made to P2 if the result set after filtering would be empty. */ -case OP_VFilter: { /* jump, ncycle */ +case OP_VFilter: { /* jump */ int nArg; int iQuery; const sqlite3_module *pModule; Mem *pQuery; Mem *pArgc; @@ -98308,11 +96265,11 @@ ** function to return true inside the xColumn method of the virtual ** table implementation. The P5 column might also contain other ** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are ** unused by OP_VColumn. */ -case OP_VColumn: { /* ncycle */ +case OP_VColumn: { sqlite3_vtab *pVtab; const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; @@ -98360,11 +96317,11 @@ ** ** Advance virtual table P1 to the next row in its result set and ** jump to instruction P2. Or, if the virtual table has reached ** the end of its result set, then fall through to the next instruction. */ -case OP_VNext: { /* jump, ncycle */ +case OP_VNext: { /* jump */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; int res; VdbeCursor *pCur; @@ -98943,16 +96900,16 @@ ** readability. From this point on down, the normal indentation rules are ** restored. *****************************************************************************/ } -#if defined(VDBE_PROFILE) - *pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); - pnCycle = 0; -#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) - *pnCycle += sqlite3Hwtime(); - pnCycle = 0; +#ifdef VDBE_PROFILE + { + u64 endTime = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); + if( endTime>start ) pOrigOp->cycles += endTime - start; + pOrigOp->cnt++; + } #endif /* The following code adds nothing to the actual functionality ** of the program. It is only here for testing and debugging. ** On the other hand, it does burn CPU cycles every time through @@ -99024,22 +96981,10 @@ /* This is the only way out of this procedure. We have to ** release the mutexes on btrees that were acquired at the ** top. */ vdbe_return: -#if defined(VDBE_PROFILE) - if( pnCycle ){ - *pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); - pnCycle = 0; - } -#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) - if( pnCycle ){ - *pnCycle += sqlite3Hwtime(); - pnCycle = 0; - } -#endif - #ifndef SQLITE_OMIT_PROGRESS_CALLBACK while( nVmStep>=nProgressLimit && db->xProgress!=0 ){ nProgressLimit += db->nProgressOps; if( db->xProgress(db->pProgressArg) ){ nProgressLimit = LARGEST_UINT64; @@ -99047,13 +96992,11 @@ goto abort_due_to_error; } } #endif p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; - if( DbMaskNonZero(p->lockMask) ){ - sqlite3VdbeLeave(p); - } + sqlite3VdbeLeave(p); assert( rc!=SQLITE_OK || nExtraDelete==0 || sqlite3_strlike("DELETE%",p->zSql,0)!=0 ); return rc; @@ -102456,13 +100399,10 @@ "subprog TEXT," "stmt HIDDEN" ");" }; - (void)argc; - (void)argv; - (void)pzErr; rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]); if( rc==SQLITE_OK ){ pNew = sqlite3_malloc( sizeof(*pNew) ); *ppVtab = (sqlite3_vtab*)pNew; if( pNew==0 ) return SQLITE_NOMEM; @@ -102694,11 +100634,10 @@ int argc, sqlite3_value **argv ){ bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor; bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab; int rc = SQLITE_OK; - (void)idxStr; bytecodevtabCursorClear(pCur); pCur->iRowid = 0; pCur->iAddr = 0; pCur->showSubprograms = idxNum==0; @@ -103163,12 +101102,10 @@ int flags, /* Opening flags */ int nSpill /* Bytes buffered before opening the file */ ){ MemJournal *p = (MemJournal*)pJfd; - assert( zName || nSpill<0 || (flags & SQLITE_OPEN_EXCLUSIVE) ); - /* Zero the file-handle object. If nSpill was passed zero, initialize ** it using the sqlite3OsOpen() function of the underlying VFS. In this ** case none of the code in this module is executed as a result of calls ** made on the journal file-handle. */ memset(p, 0, sizeof(MemJournal)); @@ -103592,25 +101529,37 @@ pDup = sqlite3ExprDup(db, pOrig, 0); if( db->mallocFailed ){ sqlite3ExprDelete(db, pDup); pDup = 0; }else{ - Expr temp; incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } - memcpy(&temp, pDup, sizeof(Expr)); - memcpy(pDup, pExpr, sizeof(Expr)); - memcpy(pExpr, &temp, sizeof(Expr)); + + /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This + ** prevents ExprDelete() from deleting the Expr structure itself, + ** allowing it to be repopulated by the memcpy() on the following line. + ** The pExpr->u.zToken might point into memory that will be freed by the + ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to + ** make a copy of the token before doing the sqlite3DbFree(). + */ + ExprSetProperty(pExpr, EP_Static); + sqlite3ExprDelete(db, pExpr); + memcpy(pExpr, pDup, sizeof(*pExpr)); + if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){ + assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 ); + pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken); + pExpr->flags |= EP_MemToken; + } if( ExprHasProperty(pExpr, EP_WinFunc) ){ if( ALWAYS(pExpr->y.pWin!=0) ){ pExpr->y.pWin->pOwner = pExpr; } } - sqlite3ExprDeferredDelete(pParse, pDup); + sqlite3DbFree(db, pDup); } } /* ** Subqueries stores the original database, table and column names for their @@ -103709,36 +101658,10 @@ ExprSetProperty(pNew, EP_CanBeNull); *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew); } } -/* -** Return TRUE (non-zero) if zTab is a valid name for the schema table pTab. -*/ -static SQLITE_NOINLINE int isValidSchemaTableName( - const char *zTab, /* Name as it appears in the SQL */ - Table *pTab, /* The schema table we are trying to match */ - Schema *pSchema /* non-NULL if a database qualifier is present */ -){ - const char *zLegacy; - assert( pTab!=0 ); - assert( pTab->tnum==1 ); - if( sqlite3StrNICmp(zTab, "sqlite_", 7)!=0 ) return 0; - zLegacy = pTab->zName; - if( strcmp(zLegacy+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){ - if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ - return 1; - } - if( pSchema==0 ) return 0; - if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1; - if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; - }else{ - if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; - } - return 0; -} - /* ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up ** that name in the set of source tables in pSrcList and make the pExpr ** expression node refer back to that source column. The following changes ** are made to pExpr: @@ -103835,11 +101758,11 @@ for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ u8 hCol; pTab = pItem->pTab; assert( pTab!=0 && pTab->zName!=0 ); assert( pTab->nCol>0 || pParse->nErr ); - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); if( pItem->fg.isNestedFrom ){ /* In this case, pItem is a subquery that has been formed from a ** parenthesized subset of the FROM clause terms. Example: ** .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ... ** \_________________________/ @@ -103888,21 +101811,19 @@ } if( hit || zTab==0 ) continue; } assert( zDb==0 || zTab!=0 ); if( zTab ){ + const char *zTabName; if( zDb ){ if( pTab->pSchema!=pSchema ) continue; if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue; } - if( pItem->zAlias!=0 ){ - if( sqlite3StrICmp(zTab, pItem->zAlias)!=0 ){ - continue; - } - }else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){ - if( pTab->tnum!=1 ) continue; - if( !isValidSchemaTableName(zTab, pTab, pSchema) ) continue; + zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; + assert( zTabName!=0 ); + if( sqlite3StrICmp(zTabName, zTab)!=0 ){ + continue; } assert( ExprUseYTab(pExpr) ); if( IN_RENAME_OBJECT && pItem->zAlias ){ sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); } @@ -104041,11 +101962,10 @@ assert( ExprUseYTab(pExpr) ); pExpr->y.pTab = pTab; if( pParse->bReturning ){ eNewExprOp = TK_REGISTER; pExpr->op2 = TK_COLUMN; - pExpr->iColumn = iCol; pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + sqlite3TableColumnToStorage(pTab, iCol) + 1; }else{ pExpr->iColumn = (i16)iCol; eNewExprOp = TK_TRIGGER; @@ -105718,125 +103638,53 @@ ** SELECT a AS b FROM t1 WHERE b; ** SELECT * FROM t1 WHERE (select a from t1); */ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ int op; + while( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ + assert( pExpr->op==TK_COLLATE + || pExpr->op==TK_IF_NULL_ROW + || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) ); + pExpr = pExpr->pLeft; + assert( pExpr!=0 ); + } op = pExpr->op; - while( 1 /* exit-by-break */ ){ - if( op==TK_COLUMN || (op==TK_AGG_COLUMN && pExpr->y.pTab!=0) ){ - assert( ExprUseYTab(pExpr) ); - assert( pExpr->y.pTab!=0 ); + if( op==TK_REGISTER ) op = pExpr->op2; + if( op==TK_COLUMN || op==TK_AGG_COLUMN ){ + assert( ExprUseYTab(pExpr) ); + if( pExpr->y.pTab ){ return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); } - if( op==TK_SELECT ){ - assert( ExprUseXSelect(pExpr) ); - assert( pExpr->x.pSelect!=0 ); - assert( pExpr->x.pSelect->pEList!=0 ); - assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 ); - return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); - } + } + if( op==TK_SELECT ){ + assert( ExprUseXSelect(pExpr) ); + assert( pExpr->x.pSelect!=0 ); + assert( pExpr->x.pSelect->pEList!=0 ); + assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 ); + return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); + } #ifndef SQLITE_OMIT_CAST - if( op==TK_CAST ){ - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - return sqlite3AffinityType(pExpr->u.zToken, 0); - } + if( op==TK_CAST ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + return sqlite3AffinityType(pExpr->u.zToken, 0); + } #endif - if( op==TK_SELECT_COLUMN ){ - assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) ); - assert( pExpr->iColumn < pExpr->iTable ); - assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); - return sqlite3ExprAffinity( - pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr - ); - } - if( op==TK_VECTOR ){ - assert( ExprUseXList(pExpr) ); - return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); - } - if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ - assert( pExpr->op==TK_COLLATE - || pExpr->op==TK_IF_NULL_ROW - || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) ); - pExpr = pExpr->pLeft; - op = pExpr->op; - continue; - } - if( op!=TK_REGISTER || (op = pExpr->op2)==TK_REGISTER ) break; + if( op==TK_SELECT_COLUMN ){ + assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) ); + assert( pExpr->iColumn < pExpr->iTable ); + assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); + return sqlite3ExprAffinity( + pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr + ); + } + if( op==TK_VECTOR ){ + assert( ExprUseXList(pExpr) ); + return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); } return pExpr->affExpr; } -/* -** Make a guess at all the possible datatypes of the result that could -** be returned by an expression. Return a bitmask indicating the answer: -** -** 0x01 Numeric -** 0x02 Text -** 0x04 Blob -** -** If the expression must return NULL, then 0x00 is returned. -*/ -SQLITE_PRIVATE int sqlite3ExprDataType(const Expr *pExpr){ - while( pExpr ){ - switch( pExpr->op ){ - case TK_COLLATE: - case TK_IF_NULL_ROW: - case TK_UPLUS: { - pExpr = pExpr->pLeft; - break; - } - case TK_NULL: { - pExpr = 0; - break; - } - case TK_STRING: { - return 0x02; - } - case TK_BLOB: { - return 0x04; - } - case TK_CONCAT: { - return 0x06; - } - case TK_VARIABLE: - case TK_AGG_FUNCTION: - case TK_FUNCTION: { - return 0x07; - } - case TK_COLUMN: - case TK_AGG_COLUMN: - case TK_SELECT: - case TK_CAST: - case TK_SELECT_COLUMN: - case TK_VECTOR: { - int aff = sqlite3ExprAffinity(pExpr); - if( aff>=SQLITE_AFF_NUMERIC ) return 0x05; - if( aff==SQLITE_AFF_TEXT ) return 0x06; - return 0x07; - } - case TK_CASE: { - int res = 0; - int ii; - ExprList *pList = pExpr->x.pList; - assert( ExprUseXList(pExpr) && pList!=0 ); - assert( pList->nExpr > 0); - for(ii=1; iinExpr; ii+=2){ - res |= sqlite3ExprDataType(pList->a[ii].pExpr); - } - if( pList->nExpr % 2 ){ - res |= sqlite3ExprDataType(pList->a[pList->nExpr-1].pExpr); - } - return res; - } - default: { - return 0x01; - } - } /* End of switch(op) */ - } /* End of while(pExpr) */ - return 0x00; -} - /* ** Set the collating sequence for expression pExpr to be the collating ** sequence named by pToken. Return a pointer to a new Expr node that ** implements the COLLATE operator. ** @@ -105920,21 +103768,22 @@ CollSeq *pColl = 0; const Expr *p = pExpr; while( p ){ int op = p->op; if( op==TK_REGISTER ) op = p->op2; - if( (op==TK_AGG_COLUMN && p->y.pTab!=0) - || op==TK_COLUMN || op==TK_TRIGGER - ){ - int j; + if( op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER ){ assert( ExprUseYTab(p) ); - assert( p->y.pTab!=0 ); - if( (j = p->iColumn)>=0 ){ - const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]); - pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + if( p->y.pTab!=0 ){ + /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally + ** a TK_COLUMN but was previously evaluated and cached in a register */ + int j = p->iColumn; + if( j>=0 ){ + const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]); + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + } + break; } - break; } if( op==TK_CAST || op==TK_UPLUS ){ p = p->pLeft; continue; } @@ -106515,13 +104364,11 @@ ** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags, ** if appropriate. */ static void exprSetHeight(Expr *p){ int nHeight = p->pLeft ? p->pLeft->nHeight : 0; - if( NEVER(p->pRight) && p->pRight->nHeight>nHeight ){ - nHeight = p->pRight->nHeight; - } + if( p->pRight && p->pRight->nHeight>nHeight ) nHeight = p->pRight->nHeight; if( ExprUseXSelect(p) ){ heightOfSelect(p->x.pSelect, &nHeight); }else if( p->x.pList ){ heightOfExprList(p->x.pList, &nHeight); p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); @@ -106660,30 +104507,19 @@ if( pRoot==0 ){ assert( db->mallocFailed ); sqlite3ExprDelete(db, pLeft); sqlite3ExprDelete(db, pRight); }else{ - assert( ExprUseXList(pRoot) ); - assert( pRoot->x.pSelect==0 ); if( pRight ){ pRoot->pRight = pRight; pRoot->flags |= EP_Propagate & pRight->flags; -#if SQLITE_MAX_EXPR_DEPTH>0 - pRoot->nHeight = pRight->nHeight+1; - }else{ - pRoot->nHeight = 1; -#endif } if( pLeft ){ pRoot->pLeft = pLeft; pRoot->flags |= EP_Propagate & pLeft->flags; -#if SQLITE_MAX_EXPR_DEPTH>0 - if( pLeft->nHeight>=pRoot->nHeight ){ - pRoot->nHeight = pLeft->nHeight+1; - } -#endif } + exprSetHeight(pRoot); } } /* ** Allocate an Expr node which joins as many as two subtrees. @@ -106965,11 +104801,10 @@ /* ** Recursively delete an expression tree. */ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ assert( p!=0 ); - assert( db!=0 ); assert( !ExprUseUValue(p) || p->u.iValue>=0 ); assert( !ExprUseYWin(p) || !ExprUseYSub(p) ); assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed ); assert( p->op!=TK_FUNCTION || !ExprUseYSub(p) ); #ifdef SQLITE_DEBUG @@ -106996,13 +104831,17 @@ if( ExprHasProperty(p, EP_WinFunc) ){ sqlite3WindowDelete(db, p->y.pWin); } #endif } + } + if( ExprHasProperty(p, EP_MemToken) ){ + assert( !ExprHasProperty(p, EP_IntValue) ); + sqlite3DbFree(db, p->u.zToken); } if( !ExprHasProperty(p, EP_Static) ){ - sqlite3DbNNFreeNN(db, p); + sqlite3DbFreeNN(db, p); } } SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ if( p ) sqlite3ExprDeleteNN(db, p); } @@ -107029,13 +104868,12 @@ ** ** The deferred delete is (currently) implemented by adding the ** pExpr to the pParse->pConstExpr list with a register number of 0. */ SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprDelete, - pExpr); + pParse->pConstExpr = + sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr); } /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the ** expression. */ @@ -107105,10 +104943,11 @@ ){ nSize = EXPR_FULLSIZE; }else{ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); assert( !ExprHasProperty(p, EP_OuterON) ); + assert( !ExprHasProperty(p, EP_MemToken) ); assert( !ExprHasVVAProperty(p, EP_NoReduce) ); if( p->pLeft || p->x.pList ){ nSize = EXPR_REDUCEDSIZE | EP_Reduced; }else{ assert( p->pRight==0 ); @@ -107208,11 +105047,11 @@ memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize); } } /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */ - pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static); + pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken); pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly); pNew->flags |= staticFlag; ExprClearVVAProperties(pNew); if( dupFlags ){ ExprSetVVAProperty(pNew, EP_Immutable); @@ -107784,17 +105623,16 @@ */ static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ int i = pList->nExpr; struct ExprList_item *pItem = pList->a; assert( pList->nExpr>0 ); - assert( db!=0 ); do{ sqlite3ExprDelete(db, pItem->pExpr); - if( pItem->zEName ) sqlite3DbNNFreeNN(db, pItem->zEName); + sqlite3DbFree(db, pItem->zEName); pItem++; }while( --i>0 ); - sqlite3DbNNFreeNN(db, pList); + sqlite3DbFreeNN(db, pList); } SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ if( pList ) exprListDeleteNN(db, pList); } @@ -108968,11 +106806,10 @@ } if( pKeyInfo ){ sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); } if( addrOnce ){ - sqlite3VdbeAddOp1(v, OP_NullRow, iTab); sqlite3VdbeJumpHere(v, addrOnce); /* Subroutine return */ assert( ExprUseYSub(pExpr) ); assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn || pParse->nErr ); @@ -109004,13 +106841,10 @@ int rReg = 0; /* Register storing resulting */ Select *pSel; /* SELECT statement to encode */ SelectDest dest; /* How to deal with SELECT result */ int nReg; /* Registers to allocate */ Expr *pLimit; /* New limit expression */ -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - int addrExplain; /* Address of OP_Explain instruction */ -#endif Vdbe *v = pParse->pVdbe; assert( v!=0 ); if( pParse->nErr ) return 0; testcase( pExpr->op==TK_EXISTS ); @@ -109059,13 +106893,12 @@ ** into a register and return that register number. ** ** In both cases, the query is augmented with "LIMIT 1". Any ** preexisting limit is discarded in place of the new LIMIT 1. */ - ExplainQueryPlan2(addrExplain, (pParse, 1, "%sSCALAR SUBQUERY %d", + ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY %d", addrOnce?"":"CORRELATED ", pSel->selId)); - sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, -1); nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1; sqlite3SelectDestInit(&dest, 0, pParse->nMem+1); pParse->nMem += nReg; if( pExpr->op==TK_SELECT ){ dest.eDest = SRT_Mem; @@ -109086,11 +106919,11 @@ if( pLimit ){ pLimit->affExpr = SQLITE_AFF_NUMERIC; pLimit = sqlite3PExpr(pParse, TK_NE, sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit); } - sqlite3ExprDeferredDelete(pParse, pSel->pLimit->pLeft); + sqlite3ExprDelete(db, pSel->pLimit->pLeft); pSel->pLimit->pLeft = pLimit; }else{ /* If there is no pre-existing limit add a limit of 1 */ pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1"); pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); @@ -109104,11 +106937,10 @@ pExpr->iTable = rReg = dest.iSDParm; ExprSetVVAProperty(pExpr, EP_NoReduce); if( addrOnce ){ sqlite3VdbeJumpHere(v, addrOnce); } - sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); /* Subroutine return */ assert( ExprUseYSub(pExpr) ); assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn || pParse->nErr ); @@ -109540,11 +107372,14 @@ int iCol, /* Index of the column to extract */ int regOut /* Extract the value into this register */ ){ Column *pCol; assert( v!=0 ); - assert( pTab!=0 ); + if( pTab==0 ){ + sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut); + return; + } if( iCol<0 || iCol==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); VdbeComment((v, "%s.rowid", pTab->zName)); }else{ int op; @@ -109598,11 +107433,11 @@ u8 p5 /* P5 value for OP_Column + FLAGS */ ){ assert( pParse->pVdbe!=0 ); sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg); if( p5 ){ - VdbeOp *pOp = sqlite3VdbeGetLastOp(pParse->pVdbe); + VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1); if( pOp->opcode==OP_Column ) pOp->p5 = p5; } return iReg; } @@ -109667,11 +107502,11 @@ /* ** If the last opcode is a OP_Copy, then set the do-not-merge flag (p5) ** so that a subsequent copy will not be merged into this one. */ static void setDoNotMergeFlagOnCopy(Vdbe *v){ - if( sqlite3VdbeGetLastOp(v)->opcode==OP_Copy ){ + if( sqlite3VdbeGetOp(v, -1)->opcode==OP_Copy ){ sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */ } } /* @@ -109790,57 +107625,10 @@ #endif /* !defined(SQLITE_UNTESTABLE) */ } return target; } -/* -** Check to see if pExpr is one of the indexed expressions on pParse->pIdxEpr. -** If it is, then resolve the expression by reading from the index and -** return the register into which the value has been read. If pExpr is -** not an indexed expression, then return negative. -*/ -static SQLITE_NOINLINE int sqlite3IndexedExprLookup( - Parse *pParse, /* The parsing context */ - Expr *pExpr, /* The expression to potentially bypass */ - int target /* Where to store the result of the expression */ -){ - IndexedExpr *p; - Vdbe *v; - for(p=pParse->pIdxEpr; p; p=p->pIENext){ - int iDataCur = p->iDataCur; - if( iDataCur<0 ) continue; - if( pParse->iSelfTab ){ - if( p->iDataCur!=pParse->iSelfTab-1 ) continue; - iDataCur = -1; - } - if( sqlite3ExprCompare(0, pExpr, p->pExpr, iDataCur)!=0 ) continue; - v = pParse->pVdbe; - assert( v!=0 ); - if( p->bMaybeNullRow ){ - /* If the index is on a NULL row due to an outer join, then we - ** cannot extract the value from the index. The value must be - ** computed using the original expression. */ - int addr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp3(v, OP_IfNullRow, p->iIdxCur, addr+3, target); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target); - VdbeComment((v, "%s expr-column %d", p->zIdxName, p->iIdxCol)); - sqlite3VdbeGoto(v, 0); - p = pParse->pIdxEpr; - pParse->pIdxEpr = 0; - sqlite3ExprCode(pParse, pExpr, target); - pParse->pIdxEpr = p; - sqlite3VdbeJumpHere(v, addr+2); - }else{ - sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target); - VdbeComment((v, "%s expr-column %d", p->zIdxName, p->iIdxCol)); - } - return target; - } - return -1; /* Not found */ -} - /* ** Generate code into the current Vdbe to evaluate the given ** expression. Attempt to store the results in register "target". ** Return the register where results are stored. @@ -109865,15 +107653,10 @@ assert( v!=0 ); expr_code_doover: if( pExpr==0 ){ op = TK_NULL; - }else if( pParse->pIdxEpr!=0 - && !ExprHasProperty(pExpr, EP_Leaf) - && (r1 = sqlite3IndexedExprLookup(pParse, pExpr, target))>=0 - ){ - return r1; }else{ assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); op = pExpr->op; } switch( op ){ @@ -109882,32 +107665,26 @@ struct AggInfo_col *pCol; assert( pAggInfo!=0 ); assert( pExpr->iAgg>=0 && pExpr->iAggnColumn ); pCol = &pAggInfo->aCol[pExpr->iAgg]; if( !pAggInfo->directMode ){ - return AggInfoColumnReg(pAggInfo, pExpr->iAgg); + assert( pCol->iMem>0 ); + return pCol->iMem; }else if( pAggInfo->useSortingIdx ){ Table *pTab = pCol->pTab; sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, pCol->iSorterColumn, target); - if( pTab==0 ){ - /* No comment added */ - }else if( pCol->iColumn<0 ){ + if( pCol->iColumn<0 ){ VdbeComment((v,"%s.rowid",pTab->zName)); }else{ VdbeComment((v,"%s.%s", pTab->zName, pTab->aCol[pCol->iColumn].zCnName)); if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){ sqlite3VdbeAddOp1(v, OP_RealAffinity, target); } } return target; - }else if( pExpr->y.pTab==0 ){ - /* This case happens when the argument to an aggregate function - ** is rewritten by aggregateConvertIndexedExprRefToColumn() */ - sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, pExpr->iColumn, target); - return target; } /* Otherwise, fall thru into the TK_COLUMN case */ /* no break */ deliberate_fall_through } case TK_COLUMN: { @@ -109921,14 +107698,17 @@ ** constant. */ int aff; iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); assert( ExprUseYTab(pExpr) ); - assert( pExpr->y.pTab!=0 ); - aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + if( pExpr->y.pTab ){ + aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + }else{ + aff = pExpr->affExpr; + } if( aff>SQLITE_AFF_BLOB ){ - static const char zAff[] = "B\000C\000D\000E\000F"; + static const char zAff[] = "B\000C\000D\000E"; assert( SQLITE_AFF_BLOB=='A' ); assert( SQLITE_AFF_TEXT=='B' ); sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0, &zAff[(aff-'B')*2], P4_STATIC); } @@ -109984,14 +107764,16 @@ ** in the index refer to the table to which the index belongs */ iTab = pParse->iSelfTab - 1; } } assert( ExprUseYTab(pExpr) ); - assert( pExpr->y.pTab!=0 ); iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, pExpr->iColumn, iTab, target, pExpr->op2); + if( pExpr->y.pTab==0 && pExpr->affExpr==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); + } return iReg; } case TK_INTEGER: { codeInteger(pParse, pExpr, 0, target); return target; @@ -110201,11 +107983,11 @@ || NEVER(pExpr->iAgg>=pInfo->nFunc) ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr); }else{ - return AggInfoFuncReg(pInfo, pExpr->iAgg); + return pInfo->aFunc[pExpr->iAgg].iMem; } break; } case TK_FUNCTION: { ExprList *pFarg; /* List of function arguments */ @@ -110486,25 +108268,10 @@ ** on a LEFT JOIN NULL row. */ case TK_IF_NULL_ROW: { int addrINR; u8 okConstFactor = pParse->okConstFactor; - AggInfo *pAggInfo = pExpr->pAggInfo; - if( pAggInfo ){ - assert( pExpr->iAgg>=0 && pExpr->iAggnColumn ); - if( !pAggInfo->directMode ){ - inReg = AggInfoColumnReg(pAggInfo, pExpr->iAgg); - break; - } - if( pExpr->pAggInfo->useSortingIdx ){ - sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, - pAggInfo->aCol[pExpr->iAgg].iSorterColumn, - target); - inReg = target; - break; - } - } addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable); /* Temporarily disable factoring of constant expressions, since ** even though expressions may appear to be constant, they are not ** really constant because they originate from the right-hand side ** of a LEFT JOIN. */ @@ -110842,11 +108609,11 @@ }else{ int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); if( inReg!=target+i ){ VdbeOp *pOp; if( copyOp==OP_Copy - && (pOp=sqlite3VdbeGetLastOp(v))->opcode==OP_Copy + && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy && pOp->p1+pOp->p3+1==inReg && pOp->p2+pOp->p3+1==target+i && pOp->p5==0 /* The do-not-merge flag must be clear */ ){ pOp->p3++; @@ -111041,11 +108808,10 @@ case TK_ISNULL: case TK_NOTNULL: { assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - sqlite3VdbeTypeofColumn(v, r1); sqlite3VdbeAddOp2(v, op, r1, dest); VdbeCoverageIf(v, op==TK_ISNULL); VdbeCoverageIf(v, op==TK_NOTNULL); testcase( regFree1==0 ); break; @@ -111216,11 +108982,10 @@ break; } case TK_ISNULL: case TK_NOTNULL: { r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - sqlite3VdbeTypeofColumn(v, r1); sqlite3VdbeAddOp2(v, op, r1, dest); testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL); testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL); testcase( regFree1==0 ); break; @@ -111370,17 +109135,11 @@ return 1; } if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){ return 1; } - if( pA->op==TK_AGG_COLUMN && pB->op==TK_COLUMN - && pB->iTable<0 && pA->iTable==iTab - ){ - /* fall through */ - }else{ - return 2; - } + return 2; } assert( !ExprHasProperty(pA, EP_IntValue) ); assert( !ExprHasProperty(pB, EP_IntValue) ); if( pA->u.zToken ){ if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){ @@ -111678,14 +109437,14 @@ /* The y.pTab=0 assignment in wherecode.c always happens after the ** impliesNotNullRow() test */ assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) ); assert( pRight->op!=TK_COLUMN || ExprUseYTab(pRight) ); if( (pLeft->op==TK_COLUMN - && ALWAYS(pLeft->y.pTab!=0) + && pLeft->y.pTab!=0 && IsVirtual(pLeft->y.pTab)) || (pRight->op==TK_COLUMN - && ALWAYS(pRight->y.pTab!=0) + && pRight->y.pTab!=0 && IsVirtual(pRight->y.pTab)) ){ return WRC_Prune; } /* no break */ deliberate_fall_through @@ -111886,11 +109645,10 @@ ** fact is exploited for efficiency. */ SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){ Walker w; struct RefSrcList x; - assert( pParse->db!=0 ); memset(&w, 0, sizeof(w)); memset(&x, 0, sizeof(x)); w.xExprCallback = exprRefToSrcList; w.xSelectCallback = selectRefEnter; w.xSelectCallback2 = selectRefLeave; @@ -111903,11 +109661,11 @@ #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); } #endif - if( x.aiExclude ) sqlite3DbNNFreeNN(pParse->db, x.aiExclude); + sqlite3DbFree(pParse->db, x.aiExclude); if( w.eCode & 0x01 ){ return 1; }else if( w.eCode ){ return 0; }else{ @@ -111921,32 +109679,34 @@ ** For Expr nodes that contain pAggInfo pointers, make sure the AggInfo ** object that is referenced does not refer directly to the Expr. If ** it does, make a copy. This is done because the pExpr argument is ** subject to change. ** -** The copy is scheduled for deletion using the sqlite3ExprDeferredDelete() -** which builds on the sqlite3ParserAddCleanup() mechanism. +** The copy is stored on pParse->pConstExpr with a register number of 0. +** This will cause the expression to be deleted automatically when the +** Parse object is destroyed, but the zero register number means that it +** will not generate any code in the preamble. */ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ if( ALWAYS(!ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced)) && pExpr->pAggInfo!=0 ){ AggInfo *pAggInfo = pExpr->pAggInfo; int iAgg = pExpr->iAgg; Parse *pParse = pWalker->pParse; sqlite3 *db = pParse->db; - if( pExpr->op!=TK_AGG_FUNCTION ){ + assert( pExpr->op==TK_AGG_COLUMN || pExpr->op==TK_AGG_FUNCTION ); + if( pExpr->op==TK_AGG_COLUMN ){ assert( iAgg>=0 && iAggnColumn ); if( pAggInfo->aCol[iAgg].pCExpr==pExpr ){ pExpr = sqlite3ExprDup(db, pExpr, 0); if( pExpr ){ pAggInfo->aCol[iAgg].pCExpr = pExpr; sqlite3ExprDeferredDelete(pParse, pExpr); } } }else{ - assert( pExpr->op==TK_AGG_FUNCTION ); assert( iAgg>=0 && iAggnFunc ); if( pAggInfo->aFunc[iAgg].pFExpr==pExpr ){ pExpr = sqlite3ExprDup(db, pExpr, 0); if( pExpr ){ pAggInfo->aFunc[iAgg].pFExpr = pExpr; @@ -111999,77 +109759,10 @@ &i ); return i; } -/* -** Search the AggInfo object for an aCol[] entry that has iTable and iColumn. -** 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 idex of pAggInfo->nColumn-1. -*/ -static void findOrCreateAggInfoColumn( - Parse *pParse, /* Parsing context */ - AggInfo *pAggInfo, /* The AggInfo object to search and/or modify */ - Expr *pExpr /* Expr describing the column to find or insert */ -){ - struct AggInfo_col *pCol; - int k; - - assert( pAggInfo->iFirstReg==0 ); - pCol = pAggInfo->aCol; - for(k=0; knColumn; k++, pCol++){ - if( pCol->iTable==pExpr->iTable - && pCol->iColumn==pExpr->iColumn - && pExpr->op!=TK_IF_NULL_ROW - ){ - goto fix_up_expr; - } - } - k = addAggInfoColumn(pParse->db, pAggInfo); - if( k<0 ){ - /* OOM on resize */ - assert( pParse->db->mallocFailed ); - return; - } - pCol = &pAggInfo->aCol[k]; - assert( ExprUseYTab(pExpr) ); - pCol->pTab = pExpr->y.pTab; - pCol->iTable = pExpr->iTable; - pCol->iColumn = pExpr->iColumn; - pCol->iSorterColumn = -1; - pCol->pCExpr = pExpr; - if( pAggInfo->pGroupBy && pExpr->op!=TK_IF_NULL_ROW ){ - int j, n; - ExprList *pGB = pAggInfo->pGroupBy; - struct ExprList_item *pTerm = pGB->a; - n = pGB->nExpr; - for(j=0; jpExpr; - if( pE->op==TK_COLUMN - && pE->iTable==pExpr->iTable - && pE->iColumn==pExpr->iColumn - ){ - pCol->iSorterColumn = j; - break; - } - } - } - if( pCol->iSorterColumn<0 ){ - pCol->iSorterColumn = pAggInfo->nSortingColumn++; - } -fix_up_expr: - ExprSetVVAProperty(pExpr, EP_NoReduce); - assert( pExpr->pAggInfo==0 || pExpr->pAggInfo==pAggInfo ); - pExpr->pAggInfo = pAggInfo; - if( pExpr->op==TK_COLUMN ){ - pExpr->op = TK_AGG_COLUMN; - } - pExpr->iAgg = (i16)k; -} - /* ** This is the xExprCallback for a tree walker. It is used to ** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates ** for additional information. */ @@ -112079,55 +109772,75 @@ Parse *pParse = pNC->pParse; SrcList *pSrcList = pNC->pSrcList; AggInfo *pAggInfo = pNC->uNC.pAggInfo; assert( pNC->ncFlags & NC_UAggInfo ); - assert( pAggInfo->iFirstReg==0 ); switch( pExpr->op ){ - default: { - IndexedExpr *pIEpr; - Expr tmp; - assert( pParse->iSelfTab==0 ); - if( (pNC->ncFlags & NC_InAggFunc)==0 ) break; - if( pParse->pIdxEpr==0 ) break; - for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){ - int iDataCur = pIEpr->iDataCur; - if( iDataCur<0 ) continue; - if( sqlite3ExprCompare(0, pExpr, pIEpr->pExpr, iDataCur)==0 ) break; - } - if( pIEpr==0 ) break; - if( NEVER(!ExprUseYTab(pExpr)) ) break; - if( pExpr->pAggInfo!=0 ) break; /* Already resolved by outer context */ - - /* If we reach this point, it means that expression pExpr can be - ** translated into a reference to an index column as described by - ** pIEpr. - */ - memset(&tmp, 0, sizeof(tmp)); - tmp.op = TK_AGG_COLUMN; - tmp.iTable = pIEpr->iIdxCur; - tmp.iColumn = pIEpr->iIdxCol; - findOrCreateAggInfoColumn(pParse, pAggInfo, &tmp); - pAggInfo->aCol[tmp.iAgg].pCExpr = pExpr; - pExpr->pAggInfo = pAggInfo; - pExpr->iAgg = tmp.iAgg; - return WRC_Prune; - } - case TK_IF_NULL_ROW: case TK_AGG_COLUMN: case TK_COLUMN: { testcase( pExpr->op==TK_AGG_COLUMN ); testcase( pExpr->op==TK_COLUMN ); - testcase( pExpr->op==TK_IF_NULL_ROW ); /* Check to see if the column is in one of the tables in the FROM ** clause of the aggregate query */ if( ALWAYS(pSrcList!=0) ){ SrcItem *pItem = pSrcList->a; for(i=0; inSrc; i++, pItem++){ + struct AggInfo_col *pCol; assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); if( pExpr->iTable==pItem->iCursor ){ - findOrCreateAggInfoColumn(pParse, pAggInfo, pExpr); + /* If we reach this point, it means that pExpr refers to a table + ** that is in the FROM clause of the aggregate query. + ** + ** Make an entry for the column in pAggInfo->aCol[] if there + ** is not an entry there already. + */ + int k; + pCol = pAggInfo->aCol; + for(k=0; knColumn; k++, pCol++){ + if( pCol->iTable==pExpr->iTable && + pCol->iColumn==pExpr->iColumn ){ + break; + } + } + if( (k>=pAggInfo->nColumn) + && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 + ){ + pCol = &pAggInfo->aCol[k]; + assert( ExprUseYTab(pExpr) ); + pCol->pTab = pExpr->y.pTab; + pCol->iTable = pExpr->iTable; + pCol->iColumn = pExpr->iColumn; + pCol->iMem = ++pParse->nMem; + pCol->iSorterColumn = -1; + pCol->pCExpr = pExpr; + if( pAggInfo->pGroupBy ){ + int j, n; + ExprList *pGB = pAggInfo->pGroupBy; + struct ExprList_item *pTerm = pGB->a; + n = pGB->nExpr; + for(j=0; jpExpr; + if( pE->op==TK_COLUMN && pE->iTable==pExpr->iTable && + pE->iColumn==pExpr->iColumn ){ + pCol->iSorterColumn = j; + break; + } + } + } + if( pCol->iSorterColumn<0 ){ + pCol->iSorterColumn = pAggInfo->nSortingColumn++; + } + } + /* There is now an entry for pExpr in pAggInfo->aCol[] (either + ** because it was there before or because we just created it). + ** Convert the pExpr to be a TK_AGG_COLUMN referring to that + ** pAggInfo->aCol[] entry. + */ + ExprSetVVAProperty(pExpr, EP_NoReduce); + pExpr->pAggInfo = pAggInfo; + pExpr->op = TK_AGG_COLUMN; + pExpr->iAgg = (i16)k; break; } /* endif pExpr->iTable==pItem->iCursor */ } /* end loop over pSrcList */ } return WRC_Prune; @@ -112153,10 +109866,11 @@ i = addAggInfoFunc(pParse->db, pAggInfo); if( i>=0 ){ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); pItem = &pAggInfo->aFunc[i]; pItem->pFExpr = pExpr; + pItem->iMem = ++pParse->nMem; assert( ExprUseUToken(pExpr) ); pItem->pFunc = sqlite3FindFunction(pParse->db, pExpr->u.zToken, pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0); if( pExpr->flags & EP_Distinct ){ @@ -113049,18 +110763,17 @@ static void renameTokenCheckAll(Parse *pParse, const void *pPtr){ assert( pParse==pParse->db->pParse ); assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); if( pParse->nErr==0 ){ const RenameToken *p; - u32 i = 1; + u8 i = 0; for(p=pParse->pRename; p; p=p->pNext){ if( p->p ){ assert( p->p!=pPtr ); - i += *(u8*)(p->p) | 1; + i += *(u8*)(p->p); } } - assert( i>0 ); } } #else # define renameTokenCheckAll(x,y) #endif @@ -115542,11 +113255,10 @@ assert( k>=0 && knColumn ); i = pIdx->aiColumn[k]; if( NEVER(i==XN_ROWID) ){ VdbeComment((v,"%s.rowid",pIdx->zName)); }else if( i==XN_EXPR ){ - assert( pIdx->bHasExpr ); VdbeComment((v,"%s.expr(%d)",pIdx->zName, k)); }else{ VdbeComment((v,"%s.%s", pIdx->zName, pIdx->pTable->aCol[i].zCnName)); } } @@ -116186,22 +113898,20 @@ /* ** If the Index.aSample variable is not NULL, delete the aSample[] array ** and its contents. */ SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ - assert( db!=0 ); - assert( pIdx!=0 ); #ifdef SQLITE_ENABLE_STAT4 if( pIdx->aSample ){ int j; for(j=0; jnSample; j++){ IndexSample *p = &pIdx->aSample[j]; sqlite3DbFree(db, p->p); } sqlite3DbFree(db, pIdx->aSample); } - if( db->pnBytesFreed==0 ){ + if( db && db->pnBytesFreed==0 ){ pIdx->nSample = 0; pIdx->aSample = 0; } #else UNUSED_PARAMETER(db); @@ -116616,11 +114326,11 @@ const char *zFile; char *zPath = 0; char *zErr = 0; unsigned int flags; Db *aNew; /* New array of Db pointers */ - Db *pNew = 0; /* Db object for the newly attached database */ + Db *pNew; /* Db object for the newly attached database */ char *zErrDyn = 0; sqlite3_vfs *pVfs; UNUSED_PARAMETER(NotUsed); zFile = (const char *)sqlite3_value_text(argv[0]); @@ -116636,30 +114346,17 @@ if( REOPEN_AS_MEMDB(db) ){ /* This is not a real ATTACH. Instead, this routine is being called ** from sqlite3_deserialize() to close database db->init.iDb and ** reopen it as a MemDB */ - Btree *pNewBt = 0; pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; - rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB); - if( rc==SQLITE_OK ){ - Schema *pNewSchema = sqlite3SchemaGet(db, pNewBt); - if( pNewSchema ){ - /* Both the Btree and the new Schema were allocated successfully. - ** Close the old db and update the aDb[] slot with the new memdb - ** values. */ - pNew = &db->aDb[db->init.iDb]; - if( ALWAYS(pNew->pBt) ) sqlite3BtreeClose(pNew->pBt); - pNew->pBt = pNewBt; - pNew->pSchema = pNewSchema; - }else{ - sqlite3BtreeClose(pNewBt); - rc = SQLITE_NOMEM; - } - } - if( rc ) goto attach_error; + pNew = &db->aDb[db->init.iDb]; + if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); + pNew->pBt = 0; + pNew->pSchema = 0; + rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB); }else{ /* This is a real ATTACH ** ** Check for the following errors: ** @@ -116768,11 +114465,11 @@ rc = SQLITE_AUTH_USER; } } #endif if( rc ){ - if( ALWAYS(!REOPEN_AS_MEMDB(db)) ){ + if( !REOPEN_AS_MEMDB(db) ){ int iDb = db->nDb - 1; assert( iDb>=2 ); if( db->aDb[iDb].pBt ){ sqlite3BtreeClose(db->aDb[iDb].pBt); db->aDb[iDb].pBt = 0; @@ -116885,12 +114582,10 @@ NameContext sName; Vdbe *v; sqlite3* db = pParse->db; int regArgs; - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto attach_end; - if( pParse->nErr ) goto attach_end; memset(&sName, 0, sizeof(NameContext)); sName.pParse = pParse; if( @@ -117562,11 +115257,10 @@ ** no VDBE code was generated. */ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ sqlite3 *db; Vdbe *v; - int iDb, i; assert( pParse->pToplevel==0 ); db = pParse->db; assert( db->pParse==pParse ); if( pParse->nested ) return; @@ -117592,10 +115286,11 @@ || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ if( pParse->bReturning ){ Returning *pReturning = pParse->u1.pReturning; int addrRewind; + int i; int reg; if( pReturning->nRetCol ){ sqlite3VdbeAddOp0(v, OP_FkCheck); addrRewind = @@ -117628,73 +115323,80 @@ ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are ** set for each database that is used. Generate code to start a ** transaction on each used database and to verify the schema cookie ** on each used database. */ - assert( pParse->nErr>0 || sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); - sqlite3VdbeJumpHere(v, 0); - assert( db->nDb>0 ); - iDb = 0; - do{ - Schema *pSchema; - if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; - sqlite3VdbeUsesBtree(v, iDb); - pSchema = db->aDb[iDb].pSchema; - sqlite3VdbeAddOp4Int(v, - OP_Transaction, /* Opcode */ - iDb, /* P1 */ - DbMaskTest(pParse->writeMask,iDb), /* P2 */ - pSchema->schema_cookie, /* P3 */ - pSchema->iGeneration /* P4 */ - ); - if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); - VdbeComment((v, - "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite)); - }while( ++iDbnDb ); + if( db->mallocFailed==0 + && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr) + ){ + int iDb, i; + assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); + sqlite3VdbeJumpHere(v, 0); + assert( db->nDb>0 ); + iDb = 0; + do{ + Schema *pSchema; + if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; + sqlite3VdbeUsesBtree(v, iDb); + pSchema = db->aDb[iDb].pSchema; + sqlite3VdbeAddOp4Int(v, + OP_Transaction, /* Opcode */ + iDb, /* P1 */ + DbMaskTest(pParse->writeMask,iDb), /* P2 */ + pSchema->schema_cookie, /* P3 */ + pSchema->iGeneration /* P4 */ + ); + if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); + VdbeComment((v, + "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite)); + }while( ++iDbnDb ); #ifndef SQLITE_OMIT_VIRTUALTABLE - for(i=0; inVtabLock; i++){ - char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); - sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); - } - pParse->nVtabLock = 0; + for(i=0; inVtabLock; i++){ + char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); + sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); + } + pParse->nVtabLock = 0; #endif - /* 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. - */ - codeTableLocks(pParse); - - /* Initialize any AUTOINCREMENT data structures required. - */ - sqlite3AutoincrementBegin(pParse); - - /* 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++){ - int iReg = pEL->a[i].u.iConstExprReg; - sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg); - } - } - - if( pParse->bReturning ){ - Returning *pRet = pParse->u1.pReturning; - if( pRet->nRetCol ){ - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); - } - } - - /* Finally, jump back to the beginning of the executable code. */ - sqlite3VdbeGoto(v, 1); + /* 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. + */ + codeTableLocks(pParse); + + /* Initialize any AUTOINCREMENT data structures required. + */ + sqlite3AutoincrementBegin(pParse); + + /* 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++){ + int iReg = pEL->a[i].u.iConstExprReg; + if( iReg>0 ){ + sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg); + } + } + } + + if( pParse->bReturning ){ + Returning *pRet = pParse->u1.pReturning; + if( pRet->nRetCol ){ + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); + } + } + + /* Finally, jump back to the beginning of the executable code. */ + sqlite3VdbeGoto(v, 1); + } } /* Get the VDBE program ready for execution */ assert( v!=0 || pParse->nErr ); @@ -117729,11 +115431,10 @@ sqlite3 *db = pParse->db; u32 savedDbFlags = db->mDbFlags; char saveBuf[PARSE_TAIL_SZ]; if( pParse->nErr ) return; - if( pParse->eParseMode ) return; assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ va_start(ap, zFormat); zSql = sqlite3VMPrintf(db, zFormat, ap); va_end(ap); if( zSql==0 ){ @@ -117747,10 +115448,12 @@ pParse->nested++; memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ); memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); db->mDbFlags |= DBFLAG_PreferBuiltin; sqlite3RunParser(pParse, zSql); + sqlite3DbFree(db, pParse->zErrMsg); + pParse->zErrMsg = 0; db->mDbFlags = savedDbFlags; sqlite3DbFree(db, zSql); memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ); pParse->nested--; } @@ -117876,11 +115579,11 @@ if( p==0 ){ #ifndef SQLITE_OMIT_VIRTUALTABLE /* If zName is the not the name of a table in the schema created using ** CREATE, then check to see if it is the name of an virtual table that ** can be an eponymous virtual table. */ - if( (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)==0 && db->init.busy==0 ){ + if( pParse->disableVtab==0 && db->init.busy==0 ){ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ pMod = sqlite3PragmaVtabRegister(db, zName); } if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ @@ -117889,11 +115592,11 @@ } } #endif if( flags & LOCATE_NOERR ) return 0; pParse->checkSchema = 1; - }else if( IsVirtual(p) && (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)!=0 ){ + }else if( IsVirtual(p) && pParse->disableVtab ){ p = 0; } if( p==0 ){ const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; @@ -118198,21 +115901,20 @@ */ SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ int i; Column *pCol; assert( pTable!=0 ); - assert( db!=0 ); if( (pCol = pTable->aCol)!=0 ){ for(i=0; inCol; i++, pCol++){ assert( pCol->zCnName==0 || pCol->hName==sqlite3StrIHash(pCol->zCnName) ); sqlite3DbFree(db, pCol->zCnName); } - sqlite3DbNNFreeNN(db, pTable->aCol); + sqlite3DbFree(db, pTable->aCol); if( IsOrdinaryTable(pTable) ){ sqlite3ExprListDelete(db, pTable->u.tab.pDfltList); } - if( db->pnBytesFreed==0 ){ + if( db==0 || db->pnBytesFreed==0 ){ pTable->aCol = 0; pTable->nCol = 0; if( IsOrdinaryTable(pTable) ){ pTable->u.tab.pDfltList = 0; } @@ -118245,22 +115947,21 @@ ** ** If malloc has already failed, it may be that it failed while allocating ** a Table object that was going to be marked ephemeral. So do not check ** that no lookaside memory is used in this case either. */ int nLookaside = 0; - assert( db!=0 ); - if( !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){ + if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){ nLookaside = sqlite3LookasideUsed(db, 0); } #endif /* Delete all indices associated with this table. */ for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ pNext = pIndex->pNext; assert( pIndex->pSchema==pTable->pSchema || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) ); - if( db->pnBytesFreed==0 && !IsVirtual(pTable) ){ + if( (db==0 || db->pnBytesFreed==0) && !IsVirtual(pTable) ){ char *zName = pIndex->zName; TESTONLY ( Index *pOld = ) sqlite3HashInsert( &pIndex->pSchema->idxHash, zName, 0 ); assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); @@ -118293,13 +115994,12 @@ /* Verify that no lookaside memory was used by schema tables */ assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) ); } SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ /* Do not delete the table until the reference count reaches zero. */ - assert( db!=0 ); if( !pTable ) return; - if( db->pnBytesFreed==0 && (--pTable->nTabRef)>0 ) return; + if( ((!db || db->pnBytesFreed==0) && (--pTable->nTabRef)>0) ) return; deleteTable(db, pTable); } /* @@ -119427,17 +117127,10 @@ assert( TF_HasStored==COLFLAG_STORED ); pTab->tabFlags |= eType; if( pCol->colFlags & COLFLAG_PRIMKEY ){ makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */ } - if( ALWAYS(pExpr) && pExpr->op==TK_ID ){ - /* The value of a generated column needs to be a real expression, not - ** just a reference to another column, in order for covering index - ** optimizations to work correctly. So if the value is not an expression, - ** turn it into one by adding a unary "+" operator. */ - pExpr = sqlite3PExpr(pParse, TK_UPLUS, pExpr, 0); - } sqlite3ColumnSetExpr(pParse, pTab, pCol, pExpr); pExpr = 0; goto generated_done; generated_error: @@ -119570,12 +117263,11 @@ static const char * const azType[] = { /* SQLITE_AFF_BLOB */ "", /* SQLITE_AFF_TEXT */ " TEXT", /* SQLITE_AFF_NUMERIC */ " NUM", /* SQLITE_AFF_INTEGER */ " INT", - /* SQLITE_AFF_REAL */ " REAL", - /* SQLITE_AFF_FLEXNUM */ " NUM", + /* SQLITE_AFF_REAL */ " REAL" }; int len; const char *zType; sqlite3_snprintf(n-k, &zStmt[k], zSep); @@ -119587,16 +117279,14 @@ testcase( pCol->affinity==SQLITE_AFF_BLOB ); testcase( pCol->affinity==SQLITE_AFF_TEXT ); testcase( pCol->affinity==SQLITE_AFF_NUMERIC ); testcase( pCol->affinity==SQLITE_AFF_INTEGER ); testcase( pCol->affinity==SQLITE_AFF_REAL ); - testcase( pCol->affinity==SQLITE_AFF_FLEXNUM ); zType = azType[pCol->affinity - SQLITE_AFF_BLOB]; len = sqlite3Strlen30(zType); assert( pCol->affinity==SQLITE_AFF_BLOB - || pCol->affinity==SQLITE_AFF_FLEXNUM || pCol->affinity==sqlite3AffinityType(zType, 0) ); memcpy(&zStmt[k], zType, len); k += len; assert( k<=n ); } @@ -119709,12 +117399,11 @@ } /* Recompute the colNotIdxed field of the Index. ** ** colNotIdxed is a bitmask that has a 0 bit representing each indexed -** columns that are within the first 63 columns of the table and a 1 for -** all other bits (all columns that are not in the index). The +** columns that are within the first 63 columns of the table. The ** high-order bit of colNotIdxed is always 1. All unindexed columns ** of the table have a 1. ** ** 2019-10-24: For the purpose of this computation, virtual columns are ** not considered to be covered by the index, even if they are in the @@ -119738,11 +117427,11 @@ testcase( x==BMS-2 ); if( xcolNotIdxed = ~m; - assert( (pIdx->colNotIdxed>>63)==1 ); /* See note-20221022-a */ + assert( (pIdx->colNotIdxed>>63)==1 ); } /* ** This routine runs at the end of parsing a CREATE TABLE statement that ** has a WITHOUT ROWID clause. The job of this routine is to convert both @@ -120007,11 +117696,10 @@ ** they should not be changed. Expressions attached to a table or ** index definition are tagged this way to help ensure that we do ** not pass them into code generator routines by mistake. */ static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){ - (void)pWalker; ExprSetVVAProperty(pExpr, EP_Immutable); return WRC_Continue; } static void markExprListImmutable(ExprList *pList){ if( pList ){ @@ -120480,11 +118168,11 @@ /* ** The Table structure pTable is really a VIEW. Fill in the names of ** the columns of the view in the pTable structure. Return the number ** of errors. If an error is seen leave an error message in pParse->zErrMsg. */ -static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){ +SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ Table *pSelTab; /* A fake table from which we get the result set */ Select *pSel; /* Copy of the SELECT that implements the view */ int nErr = 0; /* Number of errors encountered */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -120505,14 +118193,13 @@ } #endif #ifndef SQLITE_OMIT_VIEW /* A positive nCol means the columns names for this view are - ** already known. This routine is not called unless either the - ** table is virtual or nCol is zero. + ** already known. */ - assert( pTable->nCol<=0 ); + if( pTable->nCol>0 ) return 0; /* A negative nCol is a special marker meaning that we are currently ** trying to compute the column names. If we enter this routine with ** a negative nCol, it means two or more views form a loop, like this: ** @@ -120574,11 +118261,12 @@ &pTable->nCol, &pTable->aCol); if( pParse->nErr==0 && pTable->nCol==pSel->pEList->nExpr ){ assert( db->mallocFailed==0 ); - sqlite3SubqueryColumnTypes(pParse, pTable, pSel, SQLITE_AFF_NONE); + sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel, + SQLITE_AFF_NONE); } }else{ /* CREATE VIEW name AS... without an argument list. Construct ** the column names from the SELECT statement that defines the view. */ @@ -120603,15 +118291,10 @@ sqlite3DeleteColumnNames(db, pTable); } #endif /* SQLITE_OMIT_VIEW */ return nErr; } -SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ - assert( pTable!=0 ); - if( !IsVirtual(pTable) && pTable->nCol>0 ) return 0; - return viewGetColumnNames(pParse, pTable); -} #endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ #ifndef SQLITE_OMIT_VIEW /* ** Clear the column names from every VIEW in database idx. @@ -121473,11 +119156,11 @@ if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName,"index",pTab->zName) ){ goto exit_create_index; } if( !IN_RENAME_OBJECT ){ if( !db->init.busy ){ - if( sqlite3FindTable(db, zName, pDb->zDbSName)!=0 ){ + if( sqlite3FindTable(db, zName, 0)!=0 ){ sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); goto exit_create_index; } } if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ @@ -121626,11 +119309,10 @@ pList = 0; } j = XN_EXPR; pIndex->aiColumn[i] = XN_EXPR; pIndex->uniqNotNull = 0; - pIndex->bHasExpr = 1; }else{ j = pCExpr->iColumn; assert( j<=0x7fff ); if( j<0 ){ j = pTab->iPKey; @@ -121638,11 +119320,10 @@ if( pTab->aCol[j].notNull==0 ){ pIndex->uniqNotNull = 0; } if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){ pIndex->bHasVCol = 1; - pIndex->bHasExpr = 1; } } pIndex->aiColumn[i] = (i16)j; } zColl = 0; @@ -122128,17 +119809,16 @@ /* ** Delete an IdList. */ SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ int i; - assert( db!=0 ); if( pList==0 ) return; assert( pList->eU4!=EU4_EXPR ); /* EU4_EXPR mode is not currently used */ for(i=0; inId; i++){ sqlite3DbFree(db, pList->a[i].zName); } - sqlite3DbNNFreeNN(db, pList); + sqlite3DbFreeNN(db, pList); } /* ** Return the index in pList of the identifier named zId. Return -1 ** if not found. @@ -122337,16 +120017,15 @@ ** Delete an entire SrcList including all its substructure. */ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ int i; SrcItem *pItem; - assert( db!=0 ); if( pList==0 ) return; for(pItem=pList->a, i=0; inSrc; i++, pItem++){ - if( pItem->zDatabase ) sqlite3DbNNFreeNN(db, pItem->zDatabase); - if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName); - if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias); + if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase); + sqlite3DbFree(db, pItem->zName); + if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias); if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); sqlite3DeleteTable(db, pItem->pTab); if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect); if( pItem->fg.isUsing ){ @@ -122353,11 +120032,11 @@ sqlite3IdListDelete(db, pItem->u3.pUsing); }else if( pItem->u3.pOn ){ sqlite3ExprDelete(db, pItem->u3.pOn); } } - sqlite3DbNNFreeNN(db, pList); + sqlite3DbFreeNN(db, pList); } /* ** This routine is called by the parser to add a new term to the ** end of a growing FROM clause. The "p" parameter is the part of @@ -123605,25 +121284,23 @@ SQLITE_PRIVATE void sqlite3SchemaClear(void *p){ Hash temp1; Hash temp2; HashElem *pElem; Schema *pSchema = (Schema *)p; - sqlite3 xdb; - memset(&xdb, 0, sizeof(xdb)); temp1 = pSchema->tblHash; temp2 = pSchema->trigHash; sqlite3HashInit(&pSchema->trigHash); sqlite3HashClear(&pSchema->idxHash); for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ - sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem)); + sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem)); } sqlite3HashClear(&temp2); sqlite3HashInit(&pSchema->tblHash); for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ Table *pTab = sqliteHashData(pElem); - sqlite3DeleteTable(&xdb, pTab); + sqlite3DeleteTable(0, pTab); } sqlite3HashClear(&temp1); sqlite3HashClear(&pSchema->fkeyHash); pSchema->pSeqTab = 0; if( pSchema->schemaFlags & DB_SchemaLoaded ){ @@ -123718,46 +121395,22 @@ ** A table is read-only if any of the following are true: ** ** 1) It is a virtual table and no implementation of the xUpdate method ** has been provided ** -** 2) A trigger is currently being coded and the table is a virtual table -** that is SQLITE_VTAB_DIRECTONLY or if PRAGMA trusted_schema=OFF and -** the table is not SQLITE_VTAB_INNOCUOUS. -** -** 3) It is a system table (i.e. sqlite_schema), this call is not +** 2) It is a system table (i.e. sqlite_schema), this call is not ** part of a nested parse and writable_schema pragma has not ** been specified ** -** 4) The table is a shadow table, the database connection is in +** 3) The table is a shadow table, the database connection is in ** defensive mode, and the current sqlite3_prepare() ** is for a top-level SQL statement. */ -static int vtabIsReadOnly(Parse *pParse, Table *pTab){ - if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){ - return 1; - } - - /* Within triggers: - ** * Do not allow DELETE, INSERT, or UPDATE of SQLITE_VTAB_DIRECTONLY - ** virtual tables - ** * Only allow DELETE, INSERT, or UPDATE of non-SQLITE_VTAB_INNOCUOUS - ** virtual tables if PRAGMA trusted_schema=ON. - */ - if( pParse->pToplevel!=0 - && pTab->u.vtab.p->eVtabRisk > - ((pParse->db->flags & SQLITE_TrustedSchema)!=0) - ){ - sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", - pTab->zName); - } - return 0; -} static int tabIsReadOnly(Parse *pParse, Table *pTab){ sqlite3 *db; if( IsVirtual(pTab) ){ - return vtabIsReadOnly(pParse, pTab); + return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0; } if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0; db = pParse->db; if( (pTab->tabFlags & TF_Readonly)!=0 ){ return sqlite3WritableSchema(db)==0 && pParse->nested==0; @@ -123765,15 +121418,13 @@ assert( pTab->tabFlags & TF_Shadow ); return sqlite3ReadOnlyShadowTables(db); } /* -** Check to make sure the given table is writable. -** -** If pTab is not writable -> generate an error message and return 1. -** If pTab is writable but other errors have occurred -> return 1. -** If pTab is writable and no prior errors -> return 0; +** Check to make sure the given table is writable. If it is not +** writable, generate an error message and return 1. If it is +** writable return 0; */ SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ if( tabIsReadOnly(pParse, pTab) ){ sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); return 1; @@ -124130,14 +121781,13 @@ sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt ? memCnt : -1, pTab->zName, P4_STATIC); } for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ assert( pIdx->pSchema==pTab->pSchema ); + sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ - sqlite3VdbeAddOp3(v, OP_Clear, pIdx->tnum, iDb, memCnt ? memCnt : -1); - }else{ - sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); + sqlite3VdbeChangeP3(v, -1, memCnt ? memCnt : -1); } } }else #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ { @@ -124333,11 +121983,11 @@ sqlite3ExprDelete(db, pWhere); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) sqlite3ExprListDelete(db, pOrderBy); sqlite3ExprDelete(db, pLimit); #endif - if( aToOpen ) sqlite3DbNNFreeNN(db, aToOpen); + sqlite3DbFree(db, aToOpen); return; } /* Make sure "isView" and other macros defined above are undefined. Otherwise ** they may interfere with compilation of other functions in this file ** (or in another file, if this file becomes part of the amalgamation). */ @@ -125416,11 +123066,11 @@ ** ** For a case-insensitive search, set variable cx to be the same as ** c but in the other case and search the input string for either ** c or cx. */ - if( c<0x80 ){ + if( c<=0x80 ){ char zStop[3]; int bMatch; if( noCase ){ zStop[0] = sqlite3Toupper(c); zStop[1] = sqlite3Tolower(c); @@ -125499,31 +123149,19 @@ /* ** The sqlite3_strglob() interface. Return 0 on a match (like strcmp()) and ** non-zero if there is no match. */ SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){ - if( zString==0 ){ - return zGlobPattern!=0; - }else if( zGlobPattern==0 ){ - return 1; - }else { - return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '['); - } + return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '['); } /* ** The sqlite3_strlike() interface. Return 0 on a match and non-zero for ** a miss - like strcmp(). */ SQLITE_API int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){ - if( zStr==0 ){ - return zPattern!=0; - }else if( zPattern==0 ){ - return 1; - }else{ - return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc); - } + return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc); } /* ** Count the number of times that the LIKE operator (or GLOB which is ** just a variation of LIKE) gets called. This is used for testing @@ -125758,11 +123396,11 @@ sqlite3_str_appendf(pStr, "%lld", sqlite3_value_int64(pValue)); break; } case SQLITE_BLOB: { char const *zBlob = sqlite3_value_blob(pValue); - i64 nBlob = sqlite3_value_bytes(pValue); + int nBlob = sqlite3_value_bytes(pValue); assert( zBlob==sqlite3_value_blob(pValue) ); /* No encoding change */ sqlite3StrAccumEnlarge(pStr, nBlob*2 + 4); if( pStr->accError==0 ){ char *zText = pStr->zText; int i; @@ -125898,100 +123536,10 @@ } *z = 0; sqlite3_result_text(context, zHex, n*2, sqlite3_free); } } - -/* -** Buffer zStr contains nStr bytes of utf-8 encoded text. Return 1 if zStr -** contains character ch, or 0 if it does not. -*/ -static int strContainsChar(const u8 *zStr, int nStr, u32 ch){ - const u8 *zEnd = &zStr[nStr]; - const u8 *z = zStr; - while( zpNextFrom */ assert( IsOrdinaryTable(pTab) ); - assert( db!=0 ); for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pNext){ assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); /* Remove the FK from the fkeyHash hash table. */ - if( db->pnBytesFreed==0 ){ + if( !db || db->pnBytesFreed==0 ){ if( pFKey->pPrevTo ){ pFKey->pPrevTo->pNextTo = pFKey->pNextTo; }else{ void *p = (void *)pFKey->pNextTo; const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo); @@ -128742,11 +126285,10 @@ aff = pTab->aCol[x].affinity; }else if( x==XN_ROWID ){ aff = SQLITE_AFF_INTEGER; }else{ assert( x==XN_EXPR ); - assert( pIdx->bHasExpr ); assert( pIdx->aColExpr!=0 ); aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); } if( affSQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC; @@ -128756,32 +126298,10 @@ } return pIdx->zColAff; } -/* -** Compute an affinity string for a table. Space is obtained -** from sqlite3DbMalloc(). The caller is responsible for freeing -** the space when done. -*/ -SQLITE_PRIVATE char *sqlite3TableAffinityStr(sqlite3 *db, const Table *pTab){ - char *zColAff; - zColAff = (char *)sqlite3DbMallocRaw(db, pTab->nCol+1); - if( zColAff ){ - int i, j; - for(i=j=0; inCol; i++){ - if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ - zColAff[j++] = pTab->aCol[i].affinity; - } - } - do{ - zColAff[j--] = 0; - }while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB ); - } - return zColAff; -} - /* ** Make changes to the evolving bytecode to do affinity transformations ** of values that are about to be gathered into a row for table pTab. ** ** For ordinary (legacy, non-strict) tables: @@ -128819,20 +126339,20 @@ ** register set as the OP_MakeRecord. If iReg>0 then register iReg is ** the first of a series of registers that will form the new record. ** Apply the type checking to that array of registers. */ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ - int i; + int i, j; char *zColAff; if( pTab->tabFlags & TF_Strict ){ if( iReg==0 ){ /* Move the previous opcode (which should be OP_MakeRecord) forward ** by one slot and insert a new OP_TypeCheck where the current ** OP_MakeRecord is found */ VdbeOp *pPrev; sqlite3VdbeAppendP4(v, pTab, P4_TABLE); - pPrev = sqlite3VdbeGetLastOp(v); + pPrev = sqlite3VdbeGetOp(v, -1); assert( pPrev!=0 ); assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); pPrev->opcode = OP_TypeCheck; sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, pPrev->p3); }else{ @@ -128842,24 +126362,35 @@ } return; } zColAff = pTab->zColAff; if( zColAff==0 ){ - zColAff = sqlite3TableAffinityStr(0, pTab); + sqlite3 *db = sqlite3VdbeDb(v); + zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); if( !zColAff ){ - sqlite3OomFault(sqlite3VdbeDb(v)); + sqlite3OomFault(db); return; } + + for(i=j=0; inCol; i++){ + assert( pTab->aCol[i].affinity!=0 || sqlite3VdbeParser(v)->nErr>0 ); + if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ + zColAff[j++] = pTab->aCol[i].affinity; + } + } + do{ + zColAff[j--] = 0; + }while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB ); pTab->zColAff = zColAff; } assert( zColAff!=0 ); i = sqlite3Strlen30NN(zColAff); if( i ){ if( iReg ){ sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); }else{ - assert( sqlite3VdbeGetLastOp(v)->opcode==OP_MakeRecord + assert( sqlite3VdbeGetOp(v, -1)->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); sqlite3VdbeChangeP4(v, -1, zColAff, i); } } } @@ -128941,11 +126472,11 @@ /* Before computing generated columns, first go through and make sure ** that appropriate affinity has been applied to the regular columns */ sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore); if( (pTab->tabFlags & TF_HasStored)!=0 ){ - pOp = sqlite3VdbeGetLastOp(pParse->pVdbe); + pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1); if( pOp->opcode==OP_Affinity ){ /* Change the OP_Affinity argument to '@' (NONE) for all stored ** columns. '@' is the no-op affinity and those columns have not ** yet been computed. */ int ii, jj; @@ -129847,16 +127378,11 @@ }else if( pSelect ){ if( regFromSelect!=regData ){ sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+k, iRegStore); } }else{ - Expr *pX = pList->a[k].pExpr; - int y = sqlite3ExprCodeTarget(pParse, pX, iRegStore); - if( y!=iRegStore ){ - sqlite3VdbeAddOp2(v, - ExprHasProperty(pX, EP_Subquery) ? OP_Copy : OP_SCopy, y, iRegStore); - } + sqlite3ExprCode(pParse, pList->a[k].pExpr, iRegStore); } } /* Run the BEFORE and INSTEAD OF triggers, if there are any @@ -129989,13 +127515,11 @@ int isReplace = 0;/* Set to true if constraints may cause a replace */ int bUseSeek; /* True to use OPFLAG_SEEKRESULT */ sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert ); - if( db->flags & SQLITE_ForeignKeys ){ - sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); - } + sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); /* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE ** constraints or (b) there are no triggers and this table is not a ** parent table in a foreign key constraint. It is safe to set the ** flag in the second case as if any REPLACE constraint is hit, an @@ -130075,11 +127599,11 @@ sqlite3SrcListDelete(db, pTabList); sqlite3ExprListDelete(db, pList); sqlite3UpsertDelete(db, pUpsert); sqlite3SelectDelete(db, pSelect); sqlite3IdListDelete(db, pColumn); - if( aRegIdx ) sqlite3DbNNFreeNN(db, aRegIdx); + sqlite3DbFree(db, aRegIdx); } /* Make sure "isView" and other macros defined above are undefined. Otherwise ** they may interfere with compilation of other functions in this file ** (or in another file, if this file becomes part of the amalgamation). */ @@ -130439,11 +127963,10 @@ /* no break */ deliberate_fall_through case OE_Rollback: case OE_Fail: { char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, pCol->zCnName); - testcase( zMsg==0 && db->mallocFailed==0 ); sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError, iReg); sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); sqlite3VdbeChangeP5(v, P5_ConstraintNotNull); VdbeCoverage(v); @@ -132303,13 +129826,13 @@ const char *(*uri_key)(const char*,int); const char *(*filename_database)(const char*); const char *(*filename_journal)(const char*); const char *(*filename_wal)(const char*); /* Version 3.32.0 and later */ - const char *(*create_filename)(const char*,const char*,const char*, + char *(*create_filename)(const char*,const char*,const char*, int,const char**); - void (*free_filename)(const char*); + void (*free_filename)(char*); sqlite3_file *(*database_file_object)(const char*); /* Version 3.34.0 and later */ int (*txn_state)(sqlite3*,const char*); /* Version 3.36.1 and later */ sqlite3_int64 (*changes64)(sqlite3*); @@ -132329,14 +129852,10 @@ int (*deserialize)(sqlite3*,const char*,unsigned char*, sqlite3_int64,sqlite3_int64,unsigned); unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*, unsigned int); const char *(*db_name)(sqlite3*,int); - /* Version 3.40.0 and later */ - int (*value_encoding)(sqlite3_value*); - /* Version 3.41.0 and later */ - int (*is_interrupted)(sqlite3*); }; /* ** This is the function signature used for all extension entry points. It ** is also defined in the file "loadext.c". @@ -132657,14 +130176,10 @@ #ifndef SQLITE_OMIT_DESERIALIZE #define sqlite3_deserialize sqlite3_api->deserialize #define sqlite3_serialize sqlite3_api->serialize #endif #define sqlite3_db_name sqlite3_api->db_name -/* Version 3.40.0 and later */ -#define sqlite3_value_encoding sqlite3_api->value_encoding -/* Version 3.41.0 and later */ -#define sqlite3_is_interrupted sqlite3_api->is_interrupted #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ @@ -133173,15 +130688,11 @@ sqlite3_serialize, #else 0, 0, #endif - sqlite3_db_name, - /* Version 3.40.0 and later */ - sqlite3_value_encoding, - /* Version 3.41.0 and later */ - sqlite3_is_interrupted + sqlite3_db_name }; /* True if x is the directory separator character */ #if SQLITE_OS_WIN @@ -135194,21 +132705,19 @@ ** Setting to a null string reverts to the default temporary directory search. ** If temporary directory is changed, then invalidateTempStorage. ** */ case PragTyp_TEMP_STORE_DIRECTORY: { - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); if( !zRight ){ returnSingleText(v, sqlite3_temp_directory); }else{ #ifndef SQLITE_OMIT_WSD if( zRight[0] ){ int res; rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); if( rc!=SQLITE_OK || res==0 ){ sqlite3ErrorMsg(pParse, "not a writable directory"); - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); goto pragma_out; } } if( SQLITE_TEMP_STORE==0 || (SQLITE_TEMP_STORE==1 && db->temp_store<=1) @@ -135222,11 +132731,10 @@ }else{ sqlite3_temp_directory = 0; } #endif /* SQLITE_OMIT_WSD */ } - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); break; } #if SQLITE_OS_WIN /* @@ -135241,21 +132749,19 @@ ** process. Database file specified with an absolute path are not impacted ** by this setting, regardless of its value. ** */ case PragTyp_DATA_STORE_DIRECTORY: { - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); if( !zRight ){ returnSingleText(v, sqlite3_data_directory); }else{ #ifndef SQLITE_OMIT_WSD if( zRight[0] ){ int res; rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); if( rc!=SQLITE_OK || res==0 ){ sqlite3ErrorMsg(pParse, "not a writable directory"); - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); goto pragma_out; } } sqlite3_free(sqlite3_data_directory); if( zRight[0] ){ @@ -135263,11 +132769,10 @@ }else{ sqlite3_data_directory = 0; } #endif /* SQLITE_OMIT_WSD */ } - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); break; } #endif #if SQLITE_ENABLE_LOCKING_STYLE @@ -135977,28 +133482,19 @@ /* Make sure all the indices are constructed correctly. */ for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx, *pPk; - Index *pPrior = 0; /* Previous index */ + Index *pPrior = 0; int loopTop; int iDataCur, iIdxCur; int r1 = -1; - int bStrict; /* True for a STRICT table */ - int r2; /* Previous key for WITHOUT ROWID tables */ - int mxCol; /* Maximum non-virtual column number */ + int bStrict; if( !IsOrdinaryTable(pTab) ) continue; if( pObjTab && pObjTab!=pTab ) continue; - if( isQuick || HasRowid(pTab) ){ - pPk = 0; - r2 = 0; - }else{ - pPk = sqlite3PrimaryKeyIndex(pTab); - r2 = sqlite3GetTempRange(pParse, pPk->nKeyCol); - sqlite3VdbeAddOp3(v, OP_Null, 1, r2, r2+pPk->nKeyCol-1); - } + pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, 1, 0, &iDataCur, &iIdxCur); /* reg[7] counts the number of entries in the table. ** reg[8+i] counts the number of entries in the i-th index */ @@ -136008,170 +133504,56 @@ } assert( pParse->nMem>=8+j ); assert( sqlite3NoTempsInRange(pParse,1,7+j) ); sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); - - /* Fetch the right-most column from the table. This will cause - ** the entire record header to be parsed and sanity checked. It - ** will also prepopulate the cursor column cache that is used - ** by the OP_IsType code, so it is a required step. - */ - assert( !IsVirtual(pTab) ); - if( HasRowid(pTab) ){ - mxCol = -1; - for(j=0; jnCol; j++){ - if( (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)==0 ) mxCol++; - } - if( mxCol==pTab->iPKey ) mxCol--; - }else{ - /* COLFLAG_VIRTUAL columns are not included in the WITHOUT ROWID - ** PK index column-count, so there is no need to account for them - ** in this case. */ - mxCol = sqlite3PrimaryKeyIndex(pTab)->nColumn-1; - } - if( mxCol>=0 ){ - sqlite3VdbeAddOp3(v, OP_Column, iDataCur, mxCol, 3); - sqlite3VdbeTypeofColumn(v, 3); - } - if( !isQuick ){ - if( pPk ){ - /* Verify WITHOUT ROWID keys are in ascending order */ - int a1; - char *zErr; - a1 = sqlite3VdbeAddOp4Int(v, OP_IdxGT, iDataCur, 0,r2,pPk->nKeyCol); - VdbeCoverage(v); - sqlite3VdbeAddOp1(v, OP_IsNull, r2); VdbeCoverage(v); - zErr = sqlite3MPrintf(db, - "row not in PRIMARY KEY order for %s", - pTab->zName); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, a1); - sqlite3VdbeJumpHere(v, a1+1); - for(j=0; jnKeyCol; j++){ - sqlite3ExprCodeLoadIndexColumn(pParse, pPk, iDataCur, j, r2+j); - } - } - } - /* Verify datatypes for all columns: - ** - ** (1) NOT NULL columns may not contain a NULL - ** (2) Datatype must be exact for non-ANY columns in STRICT tables - ** (3) Datatype for TEXT columns in non-STRICT tables must be - ** NULL, TEXT, or BLOB. - ** (4) Datatype for numeric columns in non-STRICT tables must not - ** be a TEXT value that can be losslessly converted to numeric. - */ + /* Sanity check on record header decoding */ + sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3); + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + VdbeComment((v, "(right-most column)")); + } + /* Verify that all NOT NULL columns really are NOT NULL. At the + ** same time verify the type of the content of STRICT tables */ bStrict = (pTab->tabFlags & TF_Strict)!=0; for(j=0; jnCol; j++){ char *zErr; - Column *pCol = pTab->aCol + j; /* The column to be checked */ - int labelError; /* Jump here to report an error */ - int labelOk; /* Jump here if all looks ok */ - int p1, p3, p4; /* Operands to the OP_IsType opcode */ - int doTypeCheck; /* Check datatypes (besides NOT NULL) */ - + Column *pCol = pTab->aCol + j; + int doError, jmp2; if( j==pTab->iPKey ) continue; - if( bStrict ){ - doTypeCheck = pCol->eCType>COLTYPE_ANY; - }else{ - doTypeCheck = pCol->affinity>SQLITE_AFF_BLOB; - } - if( pCol->notNull==0 && !doTypeCheck ) continue; - - /* Compute the operands that will be needed for OP_IsType */ - p4 = SQLITE_NULL; - if( pCol->colFlags & COLFLAG_VIRTUAL ){ - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); - p1 = -1; - p3 = 3; - }else{ - if( pCol->iDflt ){ - sqlite3_value *pDfltValue = 0; - sqlite3ValueFromExpr(db, sqlite3ColumnExpr(pTab,pCol), ENC(db), - pCol->affinity, &pDfltValue); - if( pDfltValue ){ - p4 = sqlite3_value_type(pDfltValue); - sqlite3ValueFree(pDfltValue); - } - } - p1 = iDataCur; - if( !HasRowid(pTab) ){ - testcase( j!=sqlite3TableColumnToStorage(pTab, j) ); - p3 = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), j); - }else{ - p3 = sqlite3TableColumnToStorage(pTab,j); - testcase( p3!=j); - } - } - - labelError = sqlite3VdbeMakeLabel(pParse); - labelOk = sqlite3VdbeMakeLabel(pParse); + if( pCol->notNull==0 && !bStrict ) continue; + doError = bStrict ? sqlite3VdbeMakeLabel(pParse) : 0; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); + if( sqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){ + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + } if( pCol->notNull ){ - /* (1) NOT NULL columns may not contain a NULL */ - int jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); - sqlite3VdbeChangeP5(v, 0x0f); - VdbeCoverage(v); + jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, pCol->zCnName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - if( doTypeCheck ){ - sqlite3VdbeGoto(v, labelError); - sqlite3VdbeJumpHere(v, jmp2); + if( bStrict && pCol->eCType!=COLTYPE_ANY ){ + sqlite3VdbeGoto(v, doError); }else{ - /* VDBE byte code will fall thru */ - } - } - if( bStrict && doTypeCheck ){ - /* (2) Datatype must be exact for non-ANY columns in STRICT tables*/ - static unsigned char aStdTypeMask[] = { - 0x1f, /* ANY */ - 0x18, /* BLOB */ - 0x11, /* INT */ - 0x11, /* INTEGER */ - 0x13, /* REAL */ - 0x14 /* TEXT */ - }; - sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); - assert( pCol->eCType>=1 && pCol->eCType<=sizeof(aStdTypeMask) ); - sqlite3VdbeChangeP5(v, aStdTypeMask[pCol->eCType-1]); + integrityCheckResultRow(v); + } + sqlite3VdbeJumpHere(v, jmp2); + } + if( (pTab->tabFlags & TF_Strict)!=0 + && pCol->eCType!=COLTYPE_ANY + ){ + jmp2 = sqlite3VdbeAddOp3(v, OP_IsNullOrType, 3, 0, + sqlite3StdTypeMap[pCol->eCType-1]); VdbeCoverage(v); zErr = sqlite3MPrintf(db, "non-%s value in %s.%s", sqlite3StdType[pCol->eCType-1], pTab->zName, pTab->aCol[j].zCnName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - }else if( !bStrict && pCol->affinity==SQLITE_AFF_TEXT ){ - /* (3) Datatype for TEXT columns in non-STRICT tables must be - ** NULL, TEXT, or BLOB. */ - sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); - sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */ - VdbeCoverage(v); - zErr = sqlite3MPrintf(db, "NUMERIC value in %s.%s", - pTab->zName, pTab->aCol[j].zCnName); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - }else if( !bStrict && pCol->affinity>=SQLITE_AFF_NUMERIC ){ - /* (4) Datatype for numeric columns in non-STRICT tables must not - ** be a TEXT value that can be converted to numeric. */ - sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); - sqlite3VdbeChangeP5(v, 0x1b); /* NULL, INT, FLOAT, or BLOB */ - VdbeCoverage(v); - if( p1>=0 ){ - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); - } - sqlite3VdbeAddOp4(v, OP_Affinity, 3, 1, 0, "C", P4_STATIC); - sqlite3VdbeAddOp4Int(v, OP_IsType, -1, labelOk, 3, p4); - sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */ - VdbeCoverage(v); - zErr = sqlite3MPrintf(db, "TEXT value in %s.%s", - pTab->zName, pTab->aCol[j].zCnName); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - } - sqlite3VdbeResolveLabel(v, labelError); - integrityCheckResultRow(v); - sqlite3VdbeResolveLabel(v, labelOk); + sqlite3VdbeResolveLabel(v, doError); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, jmp2); + } } /* Verify CHECK constraints */ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0); if( db->mallocFailed==0 ){ @@ -136196,12 +133578,11 @@ sqlite3ExprListDelete(db, pCheck); } if( !isQuick ){ /* Omit the remaining tests for quick_check */ /* Validate index entries for the current row */ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - int jmp2, jmp3, jmp4, jmp5, label6; - int kk; + int jmp2, jmp3, jmp4, jmp5; int ckUniq = sqlite3VdbeMakeLabel(pParse); if( pPk==pIdx ) continue; r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, pPrior, r1); pPrior = pIdx; @@ -136215,36 +133596,17 @@ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); jmp4 = integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, jmp2); - - /* Any indexed columns with non-BINARY collations must still hold - ** the exact same text value as the table. */ - label6 = 0; - for(kk=0; kknKeyCol; kk++){ - if( pIdx->azColl[kk]==sqlite3StrBINARY ) continue; - if( label6==0 ) label6 = sqlite3VdbeMakeLabel(pParse); - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur+j, kk, 3); - sqlite3VdbeAddOp3(v, OP_Ne, 3, label6, r1+kk); VdbeCoverage(v); - } - if( label6 ){ - int jmp6 = sqlite3VdbeAddOp0(v, OP_Goto); - sqlite3VdbeResolveLabel(v, label6); - sqlite3VdbeLoadString(v, 3, "row "); - sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); - sqlite3VdbeLoadString(v, 4, " values differ from index "); - sqlite3VdbeGoto(v, jmp5-1); - sqlite3VdbeJumpHere(v, jmp6); - } - /* For UNIQUE indexes, verify that only one entry exists with the ** current key. The entry is unique if (1) any column is NULL ** or (2) the next entry has a different key */ if( IsUniqueIndex(pIdx) ){ int uniqOk = sqlite3VdbeMakeLabel(pParse); int jmp6; + int kk; for(kk=0; kknKeyCol; kk++){ int iCol = pIdx->aiColumn[kk]; assert( iCol!=XN_ROWID && iColnCol ); if( iCol>=0 && pTab->aCol[iCol].notNull ) continue; sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); @@ -136275,13 +133637,10 @@ sqlite3VdbeLoadString(v, 4, pIdx->zName); sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, addr); } - if( pPk ){ - sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol); - } } } } { static const int iLn = VDBE_OFFSET_LINENO(2); @@ -136428,15 +133787,10 @@ aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[1].p2 = iCookie; aOp[1].p3 = sqlite3Atoi(zRight); aOp[1].p5 = 1; - if( iCookie==BTREE_SCHEMA_VERSION && (db->flags & SQLITE_Defensive)!=0 ){ - /* Do not allow the use of PRAGMA schema_version=VALUE in defensive - ** mode. Change the OP_SetCookie opcode into a no-op. */ - aOp[1].opcode = OP_Noop; - } }else{ /* Read the specified cookie value */ static const VdbeOpList readCookie[] = { { OP_Transaction, 0, 0, 0}, /* 0 */ { OP_ReadCookie, 0, 1, 0}, /* 1 */ @@ -137413,16 +134767,11 @@ encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3; if( encoding==0 ) encoding = SQLITE_UTF8; #else encoding = SQLITE_UTF8; #endif - if( db->nVdbeActive>0 && encoding!=ENC(db) ){ - rc = SQLITE_LOCKED; - goto initone_error_out; - }else{ - sqlite3SetTextEncoding(db, encoding); - } + sqlite3SetTextEncoding(db, encoding); }else{ /* If opening an attached database, the encoding much match ENC(db) */ if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){ sqlite3SetString(pzErrMsg, db, "attached databases must use the same" " text encoding as main database"); @@ -137632,12 +134981,12 @@ ** value stored as part of the in-memory schema representation, ** set Parse.rc to SQLITE_SCHEMA. */ sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){ - if( DbHasProperty(db, iDb, DB_SchemaLoaded) ) pParse->rc = SQLITE_SCHEMA; sqlite3ResetOneSchema(db, iDb); + pParse->rc = SQLITE_SCHEMA; } /* Close the transaction, if one was opened. */ if( openedTransaction ){ sqlite3BtreeCommit(pBt); @@ -137686,19 +135035,19 @@ sqlite3 *db = pParse->db; assert( db!=0 ); assert( db->pParse==pParse ); assert( pParse->nested==0 ); #ifndef SQLITE_OMIT_SHARED_CACHE - if( pParse->aTableLock ) sqlite3DbNNFreeNN(db, pParse->aTableLock); + sqlite3DbFree(db, pParse->aTableLock); #endif while( pParse->pCleanup ){ ParseCleanup *pCleanup = pParse->pCleanup; pParse->pCleanup = pCleanup->pNext; pCleanup->xCleanup(db, pCleanup->pPtr); - sqlite3DbNNFreeNN(db, pCleanup); + sqlite3DbFreeNN(db, pCleanup); } - if( pParse->aLabel ) sqlite3DbNNFreeNN(db, pParse->aLabel); + sqlite3DbFree(db, pParse->aLabel); if( pParse->pConstExpr ){ sqlite3ExprListDelete(db, pParse->pConstExpr); } assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; @@ -137817,11 +135166,11 @@ */ if( prepFlags & SQLITE_PREPARE_PERSISTENT ){ sParse.disableLookaside++; DisableLookaside; } - sParse.prepFlags = prepFlags & 0xff; + sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0; /* Check to verify that it is possible to get a read lock on all ** database schemas. The inability to get a read lock indicates that ** some other database connection is holding a write-lock, which in ** turn means that the other connection has made uncommitted changes @@ -137858,13 +135207,11 @@ } } } } -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( db->pDisconnect ) sqlite3VtabUnlockList(db); -#endif + sqlite3VtabUnlockList(db); if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ char *zSqlCopy; int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; testcase( nBytes==mxLen ); @@ -138244,14 +135591,10 @@ int iCsr; /* Cursor number for table */ int nKey; /* Number of PK columns for table pTab (>=1) */ } aDefer[4]; #endif struct RowLoadInfo *pDeferredRowLoad; /* Deferred row loading info or NULL */ -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - int addrPush; /* First instruction to push data into sorter */ - int addrPushEnd; /* Last instruction that pushes data into sorter */ -#endif }; #define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ /* ** Delete all the content of a Select structure. Deallocate the structure @@ -138259,11 +135602,10 @@ ** ** If bFree==1, call sqlite3DbFree() on the p object. ** If bFree==0, Leave the first Select object unfreed */ static void clearSelect(sqlite3 *db, Select *p, int bFree){ - assert( db!=0 ); while( p ){ Select *pPrior = p->pPrior; sqlite3ExprListDelete(db, p->pEList); sqlite3SrcListDelete(db, p->pSrc); sqlite3ExprDelete(db, p->pWhere); @@ -138279,11 +135621,11 @@ while( p->pWin ){ assert( p->pWin->ppThis==&p->pWin ); sqlite3WindowUnlinkFromSelect(p->pWin); } #endif - if( bFree ) sqlite3DbNNFreeNN(db, p); + if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; bFree = 1; } } @@ -138508,11 +135850,11 @@ /* ** Mark a subquery result column as having been used. */ SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ assert( pItem!=0 ); - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); if( pItem->fg.isNestedFrom ){ ExprList *pResults; assert( pItem->pSelect!=0 ); pResults = pItem->pSelect->pEList; assert( pResults!=0 ); @@ -138904,14 +136246,10 @@ ** regOrigData is 0 to prevent this routine from trying to copy ** values that might not yet exist. */ assert( nData==1 || regData==regOrigData || regOrigData==0 ); -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - pSort->addrPush = sqlite3VdbeCurrentAddr(v); -#endif - if( nPrefixReg ){ assert( nPrefixReg==nExpr+bSeq ); regBase = regData - nPrefixReg; }else{ regBase = pParse->nMem + 1; @@ -139008,13 +136346,10 @@ regBase+nOBSat, nBase-nOBSat); if( iSkip ){ sqlite3VdbeChangeP2(v, iSkip, pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v)); } -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - pSort->addrPushEnd = sqlite3VdbeCurrentAddr(v)-1; -#endif } /* ** Add code to implement the OFFSET */ @@ -139692,14 +137027,13 @@ /* ** Deallocate a KeyInfo object */ SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){ if( p ){ - assert( p->db!=0 ); assert( p->nRef>0 ); p->nRef--; - if( p->nRef==0 ) sqlite3DbNNFreeNN(p->db, p); + if( p->nRef==0 ) sqlite3DbFreeNN(p->db, p); } } /* ** Make a new pointer to a KeyInfo object @@ -139834,20 +137168,10 @@ int iSortTab; /* Sorter cursor to read from */ int i; int bSeq; /* True if sorter record includes seq. no. */ int nRefKey = 0; struct ExprList_item *aOutEx = p->pEList->a; -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - int addrExplain; /* Address of OP_Explain instruction */ -#endif - - ExplainQueryPlan2(addrExplain, (pParse, 0, - "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat>0?"RIGHT PART OF ":"") - ); - sqlite3VdbeScanStatusRange(v, addrExplain,pSort->addrPush,pSort->addrPushEnd); - sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, pSort->addrPush); - assert( addrBreak<0 ); if( pSort->labelBkOut ){ sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); sqlite3VdbeGoto(v, addrBreak); @@ -139890,21 +137214,18 @@ sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nColumn+nRefKey); if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); VdbeCoverage(v); - assert( p->iLimit==0 && p->iOffset==0 ); + codeOffset(v, p->iOffset, addrContinue); sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab); bSeq = 0; }else{ addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); codeOffset(v, p->iOffset, addrContinue); iSortTab = iTab; bSeq = 1; - if( p->iOffset>0 ){ - sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); - } } for(i=0, iCol=nKey+bSeq-1; isortFlags & SORTFLAG_UseSorter ){ sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v); }else{ sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v); } - sqlite3VdbeScanStatusRange(v, addrExplain, sqlite3VdbeCurrentAddr(v)-1, -1); if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn); sqlite3VdbeResolveLabel(v, addrBreak); } /* ** Return a pointer to a string containing the 'declaration type' of the ** expression pExpr. The string may be treated as static by the caller. +** +** Also try to estimate the size of the returned value and return that +** result in *pEstWidth. ** ** The declaration type is the exact datatype definition extracted from the ** original CREATE TABLE statement if the expression is a column. The ** declaration type for a ROWID field is INTEGER. Exactly when an expression ** is considered a column can be complex in the presence of subqueries. The @@ -140290,11 +137612,11 @@ #endif if( pParse->colNamesSet ) return; /* Column names are determined by the left-most term of a compound select */ while( pSelect->pPrior ) pSelect = pSelect->pPrior; - TREETRACE(0x80,pParse,pSelect,("generating column names\n")); + SELECTTRACE(1,pParse,pSelect,("generating column names\n")); pTabList = pSelect->pSrc; pEList = pSelect->pEList; assert( v!=0 ); assert( pTabList!=0 ); pParse->colNamesSet = 1; @@ -140390,11 +137712,11 @@ } assert( nCol==(i16)nCol ); *pnCol = nCol; *paCol = aCol; - for(i=0, pCol=aCol; inErr; i++, pCol++){ + for(i=0, pCol=aCol; imallocFailed; i++, pCol++){ struct ExprList_item *pX = &pEList->a[i]; struct ExprList_item *pCollide; /* Get an appropriate name for the column */ if( (zName = pX->zEName)!=0 && pX->fg.eEName==ENAME_NAME ){ @@ -140440,14 +137762,11 @@ if( nName>0 ){ for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){} if( zName[j]==':' ) nName = j; } zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); - sqlite3ProgressCheck(pParse); - if( cnt>3 ){ - sqlite3_randomness(sizeof(cnt), &cnt); - } + if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt); } pCol->zCnName = zName; pCol->hName = sqlite3StrIHash(zName); if( pX->fg.bNoExpand ){ pCol->colFlags |= COLFLAG_NOEXPAND; @@ -140456,109 +137775,75 @@ if( zName && sqlite3HashInsert(&ht, zName, pX)==pX ){ sqlite3OomFault(db); } } sqlite3HashClear(&ht); - if( pParse->nErr ){ + if( db->mallocFailed ){ for(j=0; jrc; + return SQLITE_NOMEM_BKPT; } return SQLITE_OK; } /* -** pTab is a transient Table object that represents a subquery of some -** 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 infomation" means: +** Add type and collation information to a column list based on +** a SELECT statement. ** -** * The datatype name, as it might appear in a CREATE TABLE statement -** * Which collating sequence to use for the column -** * The affinity of the column +** The column list presumably came from selectColumnNamesFromExprList(). +** The column list has only names, not types or collations. This +** routine goes through and adds the types and collations. +** +** This routine requires that all identifiers in the SELECT +** statement be resolved. */ -SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( - Parse *pParse, /* Parsing contexts */ - Table *pTab, /* Add column type information to this table */ - Select *pSelect, /* SELECT used to determine types and collations */ - char aff /* Default affinity. */ +SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation( + Parse *pParse, /* Parsing contexts */ + Table *pTab, /* Add column type information to this table */ + Select *pSelect, /* SELECT used to determine types and collations */ + char aff /* Default affinity for columns */ ){ sqlite3 *db = pParse->db; + NameContext sNC; Column *pCol; CollSeq *pColl; - int i,j; + int i; Expr *p; struct ExprList_item *a; - NameContext sNC; assert( pSelect!=0 ); assert( (pSelect->selFlags & SF_Resolved)!=0 ); - assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 ); - assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB ); + assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed ); if( db->mallocFailed ) return; - while( pSelect->pPrior ) pSelect = pSelect->pPrior; - a = pSelect->pEList->a; memset(&sNC, 0, sizeof(sNC)); sNC.pSrcList = pSelect->pSrc; + a = pSelect->pEList->a; for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ const char *zType; - i64 n; + i64 n, m; pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT); p = a[i].pExpr; + zType = columnType(&sNC, p, 0, 0, 0); /* pCol->szEst = ... // Column size est for SELECT tables never used */ pCol->affinity = sqlite3ExprAffinity(p); - if( pCol->affinity<=SQLITE_AFF_NONE ){ - pCol->affinity = aff; - }else if( pCol->affinity>=SQLITE_AFF_NUMERIC && p->op==TK_CAST ){ - pCol->affinity = SQLITE_AFF_FLEXNUM; - } - if( pCol->affinity>=SQLITE_AFF_TEXT && pSelect->pNext ){ - int m = 0; - Select *pS2; - for(m=0, pS2=pSelect->pNext; pS2; pS2=pS2->pNext){ - m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr); - } - if( pCol->affinity==SQLITE_AFF_TEXT && (m&0x01)!=0 ){ - pCol->affinity = SQLITE_AFF_BLOB; - }else - if( pCol->affinity>=SQLITE_AFF_NUMERIC && (m&0x02)!=0 ){ - pCol->affinity = SQLITE_AFF_BLOB; - } - } - zType = columnType(&sNC, p, 0, 0, 0); - if( zType==0 || pCol->affinity!=sqlite3AffinityType(zType, 0) ){ - if( pCol->affinity==SQLITE_AFF_NUMERIC - || pCol->affinity==SQLITE_AFF_FLEXNUM - ){ - zType = "NUM"; - }else{ - zType = 0; - for(j=1; jaffinity ){ - zType = sqlite3StdType[j]; - break; - } - } - } - } - if( zType ){ - i64 m = sqlite3Strlen30(zType); - n = sqlite3Strlen30(pCol->zCnName); - pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2); - if( pCol->zCnName ){ - memcpy(&pCol->zCnName[n+1], zType, m+1); - pCol->colFlags |= COLFLAG_HASTYPE; - }else{ - testcase( pCol->colFlags & COLFLAG_HASTYPE ); + if( zType ){ + m = sqlite3Strlen30(zType); + n = sqlite3Strlen30(pCol->zCnName); + pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2); + if( pCol->zCnName ){ + memcpy(&pCol->zCnName[n+1], zType, m+1); + pCol->colFlags |= COLFLAG_HASTYPE; + }else{ + testcase( pCol->colFlags & COLFLAG_HASTYPE ); pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); } } + if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff; pColl = sqlite3ExprCollSeq(pParse, p); if( pColl ){ assert( pTab->pIndex==0 ); sqlite3ColumnSetColl(db, pCol, pColl->zName); } @@ -140588,11 +137873,11 @@ } pTab->nTabRef = 1; pTab->zName = 0; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); - sqlite3SubqueryColumnTypes(pParse, pTab, pSelect, aff); + sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect, aff); pTab->iPKey = -1; if( db->mallocFailed ){ sqlite3DeleteTable(db, pTab); return 0; } @@ -141113,11 +138398,11 @@ int nLimit = 0; /* Initialize to suppress harmless compiler warning */ assert( !pPrior->pLimit ); pPrior->iLimit = p->iLimit; pPrior->iOffset = p->iOffset; pPrior->pLimit = p->pLimit; - TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL left...\n")); + SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL left...\n")); rc = sqlite3Select(pParse, pPrior, &dest); pPrior->pLimit = 0; if( rc ){ goto multi_select_end; } @@ -141131,11 +138416,11 @@ sqlite3VdbeAddOp3(v, OP_OffsetLimit, p->iLimit, p->iOffset+1, p->iOffset); } } ExplainQueryPlan((pParse, 1, "UNION ALL")); - TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL right...\n")); + SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL right...\n")); rc = sqlite3Select(pParse, p, &dest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); @@ -141184,11 +138469,11 @@ /* Code the SELECT statements to our left */ assert( !pPrior->pOrderBy ); sqlite3SelectDestInit(&uniondest, priorOp, unionTab); - TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION left...\n")); + SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION left...\n")); rc = sqlite3Select(pParse, pPrior, &uniondest); if( rc ){ goto multi_select_end; } @@ -141204,11 +138489,11 @@ pLimit = p->pLimit; p->pLimit = 0; uniondest.eDest = op; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", sqlite3SelectOpName(p->op))); - TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION right...\n")); + SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION right...\n")); rc = sqlite3Select(pParse, p, &uniondest); testcase( rc!=SQLITE_OK ); assert( p->pOrderBy==0 ); pDelete = p->pPrior; p->pPrior = pPrior; @@ -141265,11 +138550,11 @@ assert( p->pEList ); /* Code the SELECTs to our left into temporary table "tab1". */ sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); - TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT left...\n")); + SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT left...\n")); rc = sqlite3Select(pParse, pPrior, &intersectdest); if( rc ){ goto multi_select_end; } @@ -141282,11 +138567,11 @@ pLimit = p->pLimit; p->pLimit = 0; intersectdest.iSDParm = tab2; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", sqlite3SelectOpName(p->op))); - TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT right...\n")); + SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT right...\n")); rc = sqlite3Select(pParse, p, &intersectdest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; if( p->nSelectRow>pPrior->nSelectRow ){ @@ -141929,15 +139214,14 @@ /* Jump to the this point in order to terminate the query. */ sqlite3VdbeResolveLabel(v, labelEnd); - /* Make arrangements to free the 2nd and subsequent arms of the compound - ** after the parse has finished */ + /* Reassembly the compound query so that it will be freed correctly + ** by the calling function */ if( pSplit->pPrior ){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3SelectDelete, pSplit->pPrior); + sqlite3SelectDelete(db, pSplit->pPrior); } pSplit->pPrior = pPrior; pPrior->pNext = pSplit; sqlite3ExprListDelete(db, pPrior->pOrderBy); pPrior->pOrderBy = 0; @@ -141963,11 +139247,11 @@ ** position in the parent that NULL-able due to an OUTER JOIN. Either the ** target slot in the parent is the right operand of a LEFT JOIN, or one of ** the left operands of a RIGHT JOIN. In either case, we need to potentially ** bypass the substituted expression with OP_IfNullRow. ** -** Suppose the original expression is an integer constant. Even though the table +** Suppose the original expression integer constant. Even though the table ** has the nullRow flag set, because the expression is an integer constant, ** it will not be NULLed out. So instead, we insert an OP_IfNullRow opcode ** that checks to see if the nullRow flag is set on the table. If the nullRow ** flag is set, then the value in the register is set to NULL and the original ** expression is bypassed. If the nullRow flag is not set, then the original @@ -141989,11 +139273,10 @@ Parse *pParse; /* The parsing context */ int iTable; /* Replace references to this table */ int iNewTable; /* New table number */ int isOuterJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ ExprList *pEList; /* Replacement expressions */ - ExprList *pCList; /* Collation sequences for replacement expr */ } SubstContext; /* Forward Declarations */ static void substExprList(SubstContext*, ExprList*); static void substSelect(SubstContext*, Select*, int); @@ -142031,14 +139314,13 @@ pExpr->op = TK_NULL; }else #endif { Expr *pNew; - int iColumn = pExpr->iColumn; - Expr *pCopy = pSubst->pEList->a[iColumn].pExpr; + Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr; Expr ifNullRow; - assert( pSubst->pEList!=0 && iColumnpEList->nExpr ); + assert( pSubst->pEList!=0 && pExpr->iColumnpEList->nExpr ); assert( pExpr->pRight==0 ); if( sqlite3ExprIsVector(pCopy) ){ sqlite3VectorErrorMsg(pSubst->pParse, pCopy); }else{ sqlite3 *db = pSubst->pParse->db; @@ -142045,11 +139327,10 @@ if( pSubst->isOuterJoin && pCopy->op!=TK_COLUMN ){ memset(&ifNullRow, 0, sizeof(ifNullRow)); ifNullRow.op = TK_IF_NULL_ROW; ifNullRow.pLeft = pCopy; ifNullRow.iTable = pSubst->iNewTable; - ifNullRow.iColumn = -99; ifNullRow.flags = EP_IfNullRow; pCopy = &ifNullRow; } testcase( ExprHasProperty(pCopy, EP_Subquery) ); pNew = sqlite3ExprDup(db, pCopy, 0); @@ -142072,20 +139353,15 @@ ExprSetProperty(pExpr, EP_IntValue); } /* Ensure that the expression now has an implicit collation sequence, ** just as it did when it was a column of a view or sub-query. */ - { - CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pExpr); - CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, - pSubst->pCList->a[iColumn].pExpr - ); - if( pNat!=pColl || (pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE) ){ - pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, - (pColl ? pColl->zName : "BINARY") - ); - } + if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){ + CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr); + pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, + (pColl ? pColl->zName : "BINARY") + ); } ExprClearProperty(pExpr, EP_Collate); } } }else{ @@ -142274,50 +139550,10 @@ w.xSelectCallback = sqlite3SelectWalkNoop; sqlite3WalkSelect(&w, p); } #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ -/* -** If pSel is not part of a compound SELECT, return a pointer to its -** expression list. Otherwise, return a pointer to the expression list -** of the leftmost SELECT in the compound. -*/ -static ExprList *findLeftmostExprlist(Select *pSel){ - while( pSel->pPrior ){ - pSel = pSel->pPrior; - } - return pSel->pEList; -} - -/* -** Return true if any of the result-set columns in the compound query -** have incompatible affinities on one or more arms of the compound. -*/ -static int compoundHasDifferentAffinities(Select *p){ - int ii; - ExprList *pList; - assert( p!=0 ); - assert( p->pEList!=0 ); - assert( p->pPrior!=0 ); - pList = p->pEList; - for(ii=0; iinExpr; ii++){ - char aff; - Select *pSub1; - assert( pList->a[ii].pExpr!=0 ); - aff = sqlite3ExprAffinity(pList->a[ii].pExpr); - for(pSub1=p->pPrior; pSub1; pSub1=pSub1->pPrior){ - assert( pSub1->pEList!=0 ); - assert( pSub1->pEList->nExpr>ii ); - assert( pSub1->pEList->a[ii].pExpr!=0 ); - if( sqlite3ExprAffinity(pSub1->pEList->a[ii].pExpr)!=aff ){ - return 1; - } - } - } - return 0; -} - #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* ** This routine attempts to flatten subqueries as a performance optimization. ** This routine returns 1 if it makes changes and 0 if no flattening occurs. ** @@ -142358,12 +139594,11 @@ ** ** (3) If the subquery is the right operand of a LEFT JOIN then ** (3a) the subquery may not be a join and ** (3b) the FROM clause of the subquery may not contain a virtual ** table and -** (**) Was: "The outer query may not have a GROUP BY." This case -** is now managed correctly +** (3c) the outer query may not be an aggregate. ** (3d) the outer query may not be DISTINCT. ** See also (26) for restrictions on RIGHT JOIN. ** ** (4) The subquery can not be DISTINCT. ** @@ -142413,16 +139648,10 @@ ** (17d) the outer query may not be ** (17d1) aggregate, or ** (17d2) DISTINCT ** (17e) the subquery may not contain window functions, and ** (17f) the subquery must not be the RHS of a LEFT JOIN. -** (17g) either the subquery is the first element of the outer -** query or there are no RIGHT or FULL JOINs in any arm -** of the subquery. (This is a duplicate of condition (27b).) -** (17h) The corresponding result set expressions in all arms of the -** compound must have the same affinity. (See restriction (9) -** on the push-down optimization.) ** ** The parent and sub-query may contain WHERE clauses. Subject to ** rules (11), (13) and (14), they may also contain ORDER BY, ** LIMIT and OFFSET clauses. The subquery cannot use any compound ** operator other than UNION ALL because all the other compound @@ -142470,16 +139699,18 @@ ** ** (26) The subquery may not be the right operand of a RIGHT JOIN. ** See also (3) for restrictions on LEFT JOIN. ** ** (27) The subquery may not contain a FULL or RIGHT JOIN unless it -** is the first element of the parent query. Two subcases: -** (27a) the subquery is not a compound query. -** (27b) the subquery is a compound query and the RIGHT JOIN occurs -** in any arm of the compound query. (See also (17g).) +** is the first element of the parent query. ** ** (28) The subquery is not a MATERIALIZED CTE. +** +** (29) Either the subquery is not the right-hand operand of a join with an +** ON or USING clause nor the right-hand operand of a NATURAL JOIN, or +** the right-most table within the FROM clause of the subquery +** is not part of an outer join. ** ** ** In this routine, the "p" parameter is a pointer to the outer query. ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query ** uses aggregates. @@ -142568,38 +139799,81 @@ ** ** (t1 LEFT OUTER JOIN t2) JOIN t3 ** ** which is not at all the same thing. ** + ** If the subquery is the right operand of a LEFT JOIN, then the outer + ** query cannot be an aggregate. (3c) This is an artifact of the way + ** aggregates are processed - there is no mechanism to determine if + ** the LEFT JOIN table should be all-NULL. + ** ** See also tickets #306, #350, and #3300. */ if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ if( pSubSrc->nSrc>1 /* (3a) */ - || IsVirtual(pSubSrc->a[0].pTab) /* (3b) */ + || isAgg /* (3b) */ + || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */ || (p->selFlags & SF_Distinct)!=0 /* (3d) */ || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ ){ return 0; } isOuterJoin = 1; } +#ifdef SQLITE_EXTRA_IFNULLROW + else if( iFrom>0 && !isAgg ){ + /* Setting isOuterJoin to -1 causes OP_IfNullRow opcodes to be generated for + ** every reference to any result column from subquery in a join, even + ** though they are not necessary. This will stress-test the OP_IfNullRow + ** opcode. */ + isOuterJoin = -1; + } +#endif assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */ if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ - return 0; /* Restriction (27a) */ + return 0; /* Restriction (27) */ } if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){ return 0; /* (28) */ } + + /* Restriction (29): + ** + ** We do not want two constraints on the same term of the flattened + ** query where one constraint has EP_InnerON and the other is EP_OuterON. + ** To prevent this, one or the other of the following conditions must be + ** false: + ** + ** (29a) The right-most entry in the FROM clause of the subquery + ** must not be part of an outer join. + ** + ** (29b) The subquery itself must not be the right operand of a + ** NATURAL join or a join that as an ON or USING clause. + ** + ** These conditions are sufficient to keep an EP_OuterON from being + ** flattened into an EP_InnerON. Restrictions (3a) and (27) prevent + ** an EP_InnerON from being flattened into an EP_OuterON. + */ + if( pSubSrc->nSrc>=2 + && (pSubSrc->a[pSubSrc->nSrc-1].fg.jointype & JT_OUTER)!=0 + ){ + if( (pSubitem->fg.jointype & JT_NATURAL)!=0 + || pSubitem->fg.isUsing + || NEVER(pSubitem->u3.pOn!=0) /* ON clause already shifted into WHERE */ + || pSubitem->fg.isOn + ){ + return 0; + } + } /* 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 ** that make up the compound SELECT are allowed to be aggregate or distinct ** queries. */ if( pSub->pPrior ){ - int ii; if( pSub->pOrderBy ){ return 0; /* Restriction (20) */ } if( isAgg || (p->selFlags & SF_Distinct)!=0 || isOuterJoin>0 ){ return 0; /* (17d1), (17d2), or (17f) */ @@ -142617,42 +139891,34 @@ || pSub1->pWin /* (17e) */ #endif ){ return 0; } - if( iFrom>0 && (pSub1->pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ - /* Without this restriction, the JT_LTORJ flag would end up being - ** omitted on left-hand tables of the right join that is being - ** flattened. */ - return 0; /* Restrictions (17g), (27b) */ - } testcase( pSub1->pSrc->nSrc>1 ); } /* Restriction (18). */ if( p->pOrderBy ){ + int ii; for(ii=0; iipOrderBy->nExpr; ii++){ if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0; } } /* Restriction (23) */ if( (p->selFlags & SF_Recursive) ) return 0; - /* Restriction (17h) */ - if( compoundHasDifferentAffinities(pSub) ) return 0; - if( pSrc->nSrc>1 ){ if( pParse->nSelect>500 ) return 0; if( OptimizationDisabled(db, SQLITE_FlttnUnionAll) ) return 0; aCsrMap = sqlite3DbMallocZero(db, ((i64)pParse->nTab+1)*sizeof(int)); if( aCsrMap ) aCsrMap[0] = pParse->nTab; } } /***** If we reach this point, flattening is permitted. *****/ - TREETRACE(0x4,pParse,p,("flatten %u.%p from term %d\n", + SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n", pSub->selId, pSub, iFrom)); /* Authorize the subquery */ pParse->zAuthContext = pSubitem->zName; TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); @@ -142727,11 +139993,11 @@ } pNew->pPrior = pPrior; if( pPrior ) pPrior->pNext = pNew; pNew->pNext = p; p->pPrior = pNew; - TREETRACE(0x4,pParse,p,("compound-subquery flattener" + SELECTTRACE(2,pParse,p,("compound-subquery flattener" " creates %u as peer\n",pNew->selId)); } assert( pSubitem->pSelect==0 ); } sqlite3DbFree(db, aCsrMap); @@ -142872,11 +140138,10 @@ x.pParse = pParse; x.iTable = iParent; x.iNewTable = iNewParent; x.isOuterJoin = isOuterJoin; x.pEList = pSub->pEList; - x.pCList = findLeftmostExprlist(pSub); substSelect(&x, pParent, 0); } /* The flattened query is a compound if either the inner or the ** outer query is a compound. */ @@ -142892,11 +140157,11 @@ if( pSub->pLimit ){ pParent->pLimit = pSub->pLimit; pSub->pLimit = 0; } - /* Recompute the SrcItem.colUsed masks for the flattened + /* Recompute the SrcList_item.colUsed masks for the flattened ** tables. */ for(i=0; ia[i+iFrom]); } } @@ -142907,12 +140172,12 @@ sqlite3AggInfoPersistWalkerInit(&w, pParse); sqlite3WalkSelect(&w,pSub1); sqlite3SelectDelete(db, pSub1); #if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x4 ){ - TREETRACE(0x4,pParse,p,("After flattening:\n")); + if( sqlite3TreeTrace & 0x100 ){ + SELECTTRACE(0x100,pParse,p,("After flattening:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif return 1; @@ -143281,19 +140546,10 @@ ** window over which any window-function is calculated. ** ** (7) The inner query is a Common Table Expression (CTE) that should ** be materialized. (This restriction is implemented in the calling ** routine.) -** -** (8) If the subquery is a compound that uses UNION, INTERSECT, -** or EXCEPT, then all of the result set columns for all arms of -** the compound must use the BINARY collating sequence. -** -** (9) If the subquery is a compound, then all arms of the compound must -** have the same affinity. (This is the same as restriction (17h) -** for query flattening.) -** ** ** Return 0 if no changes are made and non-zero if one or more WHERE clause ** terms are duplicated into the subquery. */ static int pushDownWhereTerms( @@ -143306,48 +140562,20 @@ int nChng = 0; if( pWhere==0 ) return 0; if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0; if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ) return 0; +#ifndef SQLITE_OMIT_WINDOWFUNC if( pSubq->pPrior ){ Select *pSel; - int notUnionAll = 0; for(pSel=pSubq; pSel; pSel=pSel->pPrior){ - u8 op = pSel->op; - assert( op==TK_ALL || op==TK_SELECT - || op==TK_UNION || op==TK_INTERSECT || op==TK_EXCEPT ); - if( op!=TK_ALL && op!=TK_SELECT ){ - notUnionAll = 1; - } -#ifndef SQLITE_OMIT_WINDOWFUNC if( pSel->pWin ) return 0; /* restriction (6b) */ -#endif - } - if( compoundHasDifferentAffinities(pSubq) ){ - return 0; /* restriction (9) */ - } - if( notUnionAll ){ - /* If any of the compound arms are connected using UNION, INTERSECT, - ** or EXCEPT, then we must ensure that none of the columns use a - ** non-BINARY collating sequence. */ - for(pSel=pSubq; pSel; pSel=pSel->pPrior){ - int ii; - const ExprList *pList = pSel->pEList; - assert( pList!=0 ); - for(ii=0; iinExpr; ii++){ - CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[ii].pExpr); - if( !sqlite3IsBinary(pColl) ){ - return 0; /* Restriction (8) */ - } - } - } } }else{ -#ifndef SQLITE_OMIT_WINDOWFUNC if( pSubq->pWin && pSubq->pWin->pPartition==0 ) return 0; + } #endif - } #ifdef SQLITE_DEBUG /* Only the first term of a compound can have a WITH clause. But make ** sure no other terms are marked SF_Recursive in case something changes ** in the future. @@ -143392,11 +140620,10 @@ x.pParse = pParse; x.iTable = pSrc->iCursor; x.iNewTable = pSrc->iCursor; x.isOuterJoin = 0; x.pEList = pSubq->pEList; - x.pCList = findLeftmostExprlist(pSubq); pNew = substExpr(&x, pNew); #ifndef SQLITE_OMIT_WINDOWFUNC if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){ /* Restriction 6c has prevented push-down in this case */ sqlite3ExprDelete(pParse->db, pNew); @@ -143496,11 +140723,10 @@ if( p->pWhere || p->pEList->nExpr!=1 || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect || pAggInfo->nFunc!=1 - || p->pHaving ){ return 0; } pTab = p->pSrc->a[0].pTab; assert( pTab!=0 ); @@ -143805,10 +141031,13 @@ return 2; } pFrom->fg.isCte = 1; pFrom->u2.pCteUse = pCteUse; pCteUse->nUse++; + if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){ + pCteUse->eM10d = M10d_Yes; + } /* Check if this is a recursive CTE. */ pRecTerm = pSel = pFrom->pSelect; bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); while( bMayRecursive && pRecTerm->op==pSel->op ){ @@ -143914,13 +141143,13 @@ } } #endif /* -** The SrcItem structure passed as the second argument represents a +** The SrcList_item structure passed as the second argument represents a ** sub-query in the FROM clause of a SELECT statement. This function -** allocates and populates the SrcItem.pTab object. If successful, +** allocates and populates the SrcList_item.pTab object. If successful, ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, ** SQLITE_NOMEM. */ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ Select *pSel = pFrom->pSelect; @@ -144195,11 +141424,11 @@ if( (zTabName = pFrom->zAlias)==0 ){ zTabName = pTab->zName; } if( db->mallocFailed ) break; - assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); + assert( pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); if( pFrom->fg.isNestedFrom ){ assert( pFrom->pSelect!=0 ); pNestedFrom = pFrom->pSelect->pEList; assert( pNestedFrom!=0 ); assert( pNestedFrom->nExpr==pTab->nCol ); @@ -144344,12 +141573,12 @@ if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){ p->selFlags |= SF_ComplexResult; } } #if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x8 ){ - TREETRACE(0x8,pParse,p,("After result-set wildcard expansion:\n")); + if( sqlite3TreeTrace & 0x100 ){ + SELECTTRACE(0x100,pParse,p,("After result-set wildcard expansion:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif return WRC_Continue; } @@ -144396,18 +141625,18 @@ #ifndef SQLITE_OMIT_SUBQUERY /* ** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo() ** interface. ** -** For each FROM-clause subquery, add Column.zType, Column.zColl, and -** Column.affinity information to the Table structure that represents -** the result set of that subquery. +** For each FROM-clause subquery, add Column.zType and Column.zColl +** information to the Table structure that represents the result set +** of that subquery. ** ** The Table structure that represents the result set was constructed -** by selectExpander() but the type and collation and affinity information -** was omitted at that point because identifiers had not yet been resolved. -** This routine is called after identifier resolution. +** by selectExpander() but the type and collation information was omitted +** at that point because identifiers had not yet been resolved. This +** routine is called after identifier resolution. */ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ Parse *pParse; int i; SrcList *pTabList; @@ -144423,11 +141652,13 @@ assert( pTab!=0 ); if( (pTab->tabFlags & TF_Ephemeral)!=0 ){ /* A sub-query in the FROM clause of a SELECT */ Select *pSel = pFrom->pSelect; if( pSel ){ - sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); + while( pSel->pPrior ) pSel = pSel->pPrior; + sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel, + SQLITE_AFF_NONE); } } } } #endif @@ -144478,177 +141709,10 @@ sqlite3ResolveSelectNames(pParse, p, pOuterNC); if( pParse->nErr ) return; sqlite3SelectAddTypeInfo(pParse, p); } -#if TREETRACE_ENABLED -/* -** Display all information about an AggInfo object -*/ -static void printAggInfo(AggInfo *pAggInfo){ - int ii; - for(ii=0; iinColumn; ii++){ - struct AggInfo_col *pCol = &pAggInfo->aCol[ii]; - sqlite3DebugPrintf( - "agg-column[%d] pTab=%s iTable=%d iColumn=%d iMem=%d" - " iSorterColumn=%d %s\n", - ii, pCol->pTab ? pCol->pTab->zName : "NULL", - pCol->iTable, pCol->iColumn, pAggInfo->iFirstReg+ii, - pCol->iSorterColumn, - ii>=pAggInfo->nAccumulator ? "" : " Accumulator"); - sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0); - } - for(ii=0; iinFunc; ii++){ - sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n", - ii, pAggInfo->iFirstReg+pAggInfo->nColumn+ii); - sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pFExpr, 0); - } -} -#endif /* TREETRACE_ENABLED */ - -/* -** Analyze the arguments to aggregate functions. Create new pAggInfo->aCol[] -** entries for columns that are arguments to aggregate functions but which -** are not otherwise used. -** -** The aCol[] entries in AggInfo prior to nAccumulator are columns that -** are referenced outside of aggregate functions. These might be columns -** that are part of the GROUP by clause, for example. Other database engines -** would throw an error if there is a column reference that is not in the -** GROUP BY clause and that is not part of an aggregate function argument. -** But SQLite allows this. -** -** The aCol[] entries beginning with the aCol[nAccumulator] and following -** are column references that are used exclusively as arguments to -** aggregate functions. This routine is responsible for computing -** (or recomputing) those aCol[] entries. -*/ -static void analyzeAggFuncArgs( - AggInfo *pAggInfo, - NameContext *pNC -){ - int i; - assert( pAggInfo!=0 ); - assert( pAggInfo->iFirstReg==0 ); - pNC->ncFlags |= NC_InAggFunc; - for(i=0; inFunc; i++){ - Expr *pExpr = pAggInfo->aFunc[i].pFExpr; - assert( ExprUseXList(pExpr) ); - sqlite3ExprAnalyzeAggList(pNC, pExpr->x.pList); -#ifndef SQLITE_OMIT_WINDOWFUNC - assert( !IsWindowFunc(pExpr) ); - if( ExprHasProperty(pExpr, EP_WinFunc) ){ - sqlite3ExprAnalyzeAggregates(pNC, pExpr->y.pWin->pFilter); - } -#endif - } - pNC->ncFlags &= ~NC_InAggFunc; -} - -/* -** An index on expressions is being used in the inner loop of an -** aggregate query with a GROUP BY clause. This routine attempts -** to adjust the AggInfo object to take advantage of index and to -** perhaps use the index as a covering index. -** -*/ -static void optimizeAggregateUseOfIndexedExpr( - Parse *pParse, /* Parsing context */ - Select *pSelect, /* The SELECT statement being processed */ - AggInfo *pAggInfo, /* The aggregate info */ - NameContext *pNC /* Name context used to resolve agg-func args */ -){ - assert( pAggInfo->iFirstReg==0 ); - pAggInfo->nColumn = pAggInfo->nAccumulator; - if( ALWAYS(pAggInfo->nSortingColumn>0) ){ - if( pAggInfo->nColumn==0 ){ - pAggInfo->nSortingColumn = 0; - }else{ - pAggInfo->nSortingColumn = - pAggInfo->aCol[pAggInfo->nColumn-1].iSorterColumn+1; - } - } - analyzeAggFuncArgs(pAggInfo, pNC); -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x20 ){ - IndexedExpr *pIEpr; - TREETRACE(0x20, pParse, pSelect, - ("AggInfo (possibly) adjusted for Indexed Exprs\n")); - sqlite3TreeViewSelect(0, pSelect, 0); - for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){ - printf("data-cursor=%d index={%d,%d}\n", - pIEpr->iDataCur, pIEpr->iIdxCur, pIEpr->iIdxCol); - sqlite3TreeViewExpr(0, pIEpr->pExpr, 0); - } - printAggInfo(pAggInfo); - } -#else - UNUSED_PARAMETER(pSelect); - UNUSED_PARAMETER(pParse); -#endif -} - -/* -** Walker callback for aggregateConvertIndexedExprRefToColumn(). -*/ -static int aggregateIdxEprRefToColCallback(Walker *pWalker, Expr *pExpr){ - AggInfo *pAggInfo; - struct AggInfo_col *pCol; - UNUSED_PARAMETER(pWalker); - if( pExpr->pAggInfo==0 ) return WRC_Continue; - if( pExpr->op==TK_AGG_COLUMN ) return WRC_Continue; - if( pExpr->op==TK_AGG_FUNCTION ) return WRC_Continue; - if( pExpr->op==TK_IF_NULL_ROW ) return WRC_Continue; - pAggInfo = pExpr->pAggInfo; - assert( pExpr->iAgg>=0 && pExpr->iAggnColumn ); - pCol = &pAggInfo->aCol[pExpr->iAgg]; - pExpr->op = TK_AGG_COLUMN; - pExpr->iTable = pCol->iTable; - pExpr->iColumn = pCol->iColumn; - return WRC_Prune; -} - -/* -** Convert every pAggInfo->aFunc[].pExpr such that any node within -** those expressions that has pAppInfo set is changed into a TK_AGG_COLUMN -** opcode. -*/ -static void aggregateConvertIndexedExprRefToColumn(AggInfo *pAggInfo){ - int i; - Walker w; - memset(&w, 0, sizeof(w)); - w.xExprCallback = aggregateIdxEprRefToColCallback; - for(i=0; inFunc; i++){ - sqlite3WalkExpr(&w, pAggInfo->aFunc[i].pFExpr); - } -} - - -/* -** Allocate a block of registers so that there is one register for each -** pAggInfo->aCol[] and pAggInfo->aFunc[] entry in pAggInfo. The first -** register in this block is stored in pAggInfo->iFirstReg. -** -** This routine may only be called once for each AggInfo object. Prior -** to calling this routine: -** -** * The aCol[] and aFunc[] arrays may be modified -** * The AggInfoColumnReg() and AggInfoFuncReg() macros may not be used -** -** After clling this routine: -** -** * The aCol[] and aFunc[] arrays are fixed -** * The AggInfoColumnReg() and AggInfoFuncReg() macros may be used -** -*/ -static void assignAggregateRegisters(Parse *pParse, AggInfo *pAggInfo){ - assert( pAggInfo!=0 ); - assert( pAggInfo->iFirstReg==0 ); - pAggInfo->iFirstReg = pParse->nMem + 1; - pParse->nMem += pAggInfo->nColumn + pAggInfo->nFunc; -} - /* ** Reset the aggregate accumulator. ** ** The aggregate accumulator is a set of memory cells that hold ** intermediate results while calculating an aggregate. This @@ -144658,17 +141722,28 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ Vdbe *v = pParse->pVdbe; int i; struct AggInfo_func *pFunc; int nReg = pAggInfo->nFunc + pAggInfo->nColumn; - assert( pAggInfo->iFirstReg>0 ); assert( pParse->db->pParse==pParse ); assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); if( nReg==0 ) return; if( pParse->nErr ) return; - sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->iFirstReg, - pAggInfo->iFirstReg+nReg-1); +#ifdef SQLITE_DEBUG + /* Verify that all AggInfo registers are within the range specified by + ** AggInfo.mnReg..AggInfo.mxReg */ + assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 ); + for(i=0; inColumn; i++){ + assert( pAggInfo->aCol[i].iMem>=pAggInfo->mnReg + && pAggInfo->aCol[i].iMem<=pAggInfo->mxReg ); + } + for(i=0; inFunc; i++){ + assert( pAggInfo->aFunc[i].iMem>=pAggInfo->mnReg + && pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg ); + } +#endif + sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg); for(pFunc=pAggInfo->aFunc, i=0; inFunc; i++, pFunc++){ if( pFunc->iDistinct>=0 ){ Expr *pE = pFunc->pFExpr; assert( ExprUseXList(pE) ); if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){ @@ -144696,20 +141771,19 @@ struct AggInfo_func *pF; for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); pList = pF->pFExpr->x.pList; - sqlite3VdbeAddOp2(v, OP_AggFinal, AggInfoFuncReg(pAggInfo,i), - pList ? pList->nExpr : 0); + sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, 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. +** Update the accumulator memory cells for an aggregate based on +** the current cursor position. ** ** If regAcc is non-zero and there are no min() or max() aggregates ** 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. @@ -144725,12 +141799,10 @@ int regHit = 0; int addrHitTest = 0; struct AggInfo_func *pF; struct AggInfo_col *pC; - assert( pAggInfo->iFirstReg>0 ); - if( pParse->nErr ) return; pAggInfo->directMode = 1; for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ int nArg; int addrNext = 0; int regAgg; @@ -144787,11 +141859,11 @@ 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)); + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nArg); sqlite3ReleaseTempRange(pParse, regAgg, nArg); if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); @@ -144802,11 +141874,11 @@ } if( regHit ){ addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); } for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ - sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i)); + sqlite3ExprCode(pParse, pC->pCExpr, pC->iMem); } pAggInfo->directMode = 0; if( addrHitTest ){ sqlite3VdbeJumpHereOrPopInst(v, addrHitTest); @@ -144898,35 +141970,30 @@ sWalker.xExprCallback = havingToWhereExprCb; sWalker.u.pSelect = p; sqlite3WalkExpr(&sWalker, p->pHaving); #if TREETRACE_ENABLED if( sWalker.eCode && (sqlite3TreeTrace & 0x100)!=0 ){ - TREETRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); + SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif } /* -** Check to see if the pThis entry of pTabList is a self-join of another view. -** Search FROM-clause entries in the range of iFirst..iEnd, including iFirst -** but stopping before iEnd. -** -** If pThis is a self-join, then return the SrcItem for the first other -** instance of that view found. If pThis is not a self-join then return 0. +** Check to see if the pThis entry of pTabList is a self-join of a prior view. +** If it is, then return the SrcList_item for the prior view. If it is not, +** then return 0. */ static SrcItem *isSelfJoinView( SrcList *pTabList, /* Search for self-joins in this FROM clause */ - SrcItem *pThis, /* Search for prior reference to this subquery */ - int iFirst, int iEnd /* Range of FROM-clause entries to search. */ + SrcItem *pThis /* Search for prior reference to this subquery */ ){ SrcItem *pItem; assert( pThis->pSelect!=0 ); if( pThis->pSelect->selFlags & SF_PushDown ) return 0; - while( iFirsta; pItema[iFirst++]; if( pItem->pSelect==0 ) continue; if( pItem->fg.viaCoroutine ) continue; if( pItem->zName==0 ) continue; assert( pItem->pTab!=0 ); assert( pThis->pTab!=0 ); @@ -145035,12 +142102,12 @@ } p->pEList->a[0].pExpr = pExpr; p->selFlags &= ~SF_Aggregate; #if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x200 ){ - TREETRACE(0x200,pParse,p,("After count-of-view optimization:\n")); + if( sqlite3TreeTrace & 0x400 ){ + SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif return 1; } @@ -145067,72 +142134,10 @@ } } return 0; } -/* -** Return TRUE (non-zero) if the i-th entry in the pTabList SrcList can -** be implemented as a co-routine. The i-th entry is guaranteed to be -** a subquery. -** -** The subquery is implemented as a co-routine if all of the following are -** true: -** -** (1) The subquery will likely be implemented in the outer loop of -** the query. This will be the case if any one of the following -** conditions hold: -** (a) The subquery is the only term in the FROM clause -** (b) The subquery is the left-most term and a CROSS JOIN or similar -** requires it to be the outer loop -** (c) All of the following are true: -** (i) The subquery is the left-most subquery in the FROM clause -** (ii) There is nothing that would prevent the subquery from -** being used as the outer loop if the sqlite3WhereBegin() -** routine nominates it to that position. -** (iii) The query is not a UPDATE ... FROM -** (2) The subquery is not a CTE that should be materialized because -** (a) the AS MATERIALIZED keyword is used, or -** (b) the CTE is used multiple times and does not have the -** NOT MATERIALIZED keyword -** (3) The subquery is not part of a left operand for a RIGHT JOIN -** (4) The SQLITE_Coroutine optimization disable flag is not set -** (5) The subquery is not self-joined -*/ -static int fromClauseTermCanBeCoroutine( - Parse *pParse, /* Parsing context */ - SrcList *pTabList, /* FROM clause */ - int i, /* Which term of the FROM clause holds the subquery */ - int selFlags /* Flags on the SELECT statement */ -){ - SrcItem *pItem = &pTabList->a[i]; - if( pItem->fg.isCte ){ - const CteUse *pCteUse = pItem->u2.pCteUse; - if( pCteUse->eM10d==M10d_Yes ) return 0; /* (2a) */ - if( pCteUse->nUse>=2 && pCteUse->eM10d!=M10d_No ) return 0; /* (2b) */ - } - if( pTabList->a[0].fg.jointype & JT_LTORJ ) return 0; /* (3) */ - if( OptimizationDisabled(pParse->db, SQLITE_Coroutines) ) return 0; /* (4) */ - if( isSelfJoinView(pTabList, pItem, i+1, pTabList->nSrc)!=0 ){ - return 0; /* (5) */ - } - if( i==0 ){ - if( pTabList->nSrc==1 ) return 1; /* (1a) */ - if( pTabList->a[1].fg.jointype & JT_CROSS ) return 1; /* (1b) */ - if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */ - return 1; - } - if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */ - while( 1 /*exit-by-break*/ ){ - if( pItem->fg.jointype & (JT_OUTER|JT_CROSS) ) return 0; /* (1c-ii) */ - if( i==0 ) break; - i--; - pItem--; - if( pItem->pSelect!=0 ) return 0; /* (1c-i) */ - } - return 1; -} - /* ** Generate code for the SELECT statement given in the p argument. ** ** The results are returned according to the SelectDest structure. ** See comments in sqliteInt.h for further information. @@ -145174,12 +142179,12 @@ return 1; } assert( db->mallocFailed==0 ); if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; #if TREETRACE_ENABLED - TREETRACE(0x1,pParse,p, ("begin processing:\n", pParse->addrExplain)); - if( sqlite3TreeTrace & 0x10000 ){ + SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); + if( sqlite3TreeTrace & 0x10100 ){ if( (sqlite3TreeTrace & 0x10001)==0x10000 ){ sqlite3TreeViewLine(0, "In sqlite3Select() at %s:%d", __FILE__, __LINE__); } sqlite3ShowSelect(p); @@ -145195,12 +142200,12 @@ pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo ); /* All of these destinations are also able to ignore the ORDER BY clause */ if( p->pOrderBy ){ #if TREETRACE_ENABLED - TREETRACE(0x800,pParse,p, ("dropping superfluous ORDER BY:\n")); - if( sqlite3TreeTrace & 0x800 ){ + SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n")); + if( sqlite3TreeTrace & 0x100 ){ sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); } #endif sqlite3ParserAddCleanup(pParse, (void(*)(sqlite3*,void*))sqlite3ExprListDelete, @@ -145216,12 +142221,12 @@ goto select_end; } assert( db->mallocFailed==0 ); assert( p->pEList!=0 ); #if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x10 ){ - TREETRACE(0x10,pParse,p, ("after name resolution:\n")); + if( sqlite3TreeTrace & 0x104 ){ + SELECTTRACE(0x104,pParse,p, ("after name resolution:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif /* If the SF_UFSrcCheck flag is set, then this function is being called @@ -145258,12 +142263,12 @@ if( sqlite3WindowRewrite(pParse, p) ){ assert( pParse->nErr ); goto select_end; } #if TREETRACE_ENABLED - if( p->pWin && (sqlite3TreeTrace & 0x40)!=0 ){ - TREETRACE(0x40,pParse,p, ("after window rewrite:\n")); + if( p->pWin && (sqlite3TreeTrace & 0x108)!=0 ){ + SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif #endif /* SQLITE_OMIT_WINDOWFUNC */ pTabList = p->pSrc; @@ -145290,11 +142295,11 @@ */ if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==JT_LEFT && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor) && OptimizationEnabled(db, SQLITE_SimplifyJoin) ){ - TREETRACE(0x1000,pParse,p, + SELECTTRACE(0x100,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); @@ -145346,15 +142351,13 @@ && pSub->pLimit==0 /* Condition (1) */ && (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */ && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ && OptimizationEnabled(db, SQLITE_OmitOrderBy) ){ - TREETRACE(0x800,pParse,p, + SELECTTRACE(0x100,pParse,p, ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprListDelete, - pSub->pOrderBy); + sqlite3ExprListDelete(db, pSub->pOrderBy); pSub->pOrderBy = 0; } /* If the outer query contains a "complex" result set (that is, ** if the result set of the outer query uses functions or subqueries) @@ -145401,12 +142404,12 @@ ** procedure. */ if( p->pPrior ){ rc = multiSelect(pParse, p, pDest); #if TREETRACE_ENABLED - TREETRACE(0x400,pParse,p,("end compound-select processing\n")); - if( (sqlite3TreeTrace & 0x400)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + SELECTTRACE(0x1,pParse,p,("end compound-select processing\n")); + if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif if( p->pNext==0 ) ExplainQueryPlanPop(pParse); return rc; @@ -145422,17 +142425,17 @@ && p->pWhere->op==TK_AND && OptimizationEnabled(db, SQLITE_PropagateConst) && propagateConstants(pParse, p) ){ #if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x2000 ){ - TREETRACE(0x2000,pParse,p,("After constant propagation:\n")); + if( sqlite3TreeTrace & 0x100 ){ + SELECTTRACE(0x100,pParse,p,("After constant propagation:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif }else{ - TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n")); + SELECTTRACE(0x100,pParse,p,("Constant propagation not helpful\n")); } #ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) && countOfViewOptimization(pParse, p) @@ -145501,27 +142504,40 @@ && (pItem->fg.isCte==0 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem) ){ #if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x4000 ){ - TREETRACE(0x4000,pParse,p, + if( sqlite3TreeTrace & 0x100 ){ + SELECTTRACE(0x100,pParse,p, ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); sqlite3TreeViewSelect(0, p, 0); } #endif assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); }else{ - TREETRACE(0x4000,pParse,p,("Push-down not possible\n")); + SELECTTRACE(0x100,pParse,p,("Push-down not possible\n")); } zSavedAuthContext = pParse->zAuthContext; pParse->zAuthContext = pItem->zName; /* Generate code to implement the subquery + ** + ** The subquery is implemented as a co-routine if all of the following are + ** true: + ** + ** (1) the subquery is guaranteed to be the outer loop (so that + ** it does not need to be computed more than once), and + ** (2) the subquery is not a CTE that should be materialized + ** (3) the subquery is not part of a left operand for a RIGHT JOIN */ - if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){ + if( i==0 + && (pTabList->nSrc==1 + || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0) /* (1) */ + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */ + && (pTabList->a[0].fg.jointype & JT_LTORJ)==0 /* (3) */ + ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. */ int addrTop = sqlite3VdbeCurrentAddr(v)+1; @@ -145548,11 +142564,11 @@ if( pItem->iCursor!=pCteUse->iCur ){ sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur); VdbeComment((v, "%!S", pItem)); } pSub->nSelectRow = pCteUse->nRowEst; - }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){ + }else if( (pPrior = isSelfJoinView(pTabList, pItem))!=0 ){ /* This view has already been materialized by a prior entry in ** this same FROM clause. Reuse it. */ if( pPrior->addrFillSub ){ sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub); } @@ -145562,13 +142578,10 @@ /* Materialize the view. If the view is not correlated, generate a ** subroutine to do the materialization so that subsequent uses of ** the same view can reuse the materialization. */ int topAddr; int onceAddr = 0; -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - int addrExplain; -#endif pItem->regReturn = ++pParse->nMem; topAddr = sqlite3VdbeAddOp0(v, OP_Goto); pItem->addrFillSub = topAddr+1; pItem->fg.isMaterialized = 1; @@ -145580,18 +142593,16 @@ VdbeComment((v, "materialize %!S", pItem)); }else{ VdbeNoopComment((v, "materialize %!S", pItem)); } sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); - - ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem)); + ExplainQueryPlan((pParse, 1, "MATERIALIZE %!S", pItem)); sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowLogEst = pSub->nSelectRow; if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1); VdbeComment((v, "end %!S", pItem)); - sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); sqlite3VdbeJumpHere(v, topAddr); sqlite3ClearTempRegCache(pParse); if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ CteUse *pCteUse = pItem->u2.pCteUse; pCteUse->addrM9e = pItem->addrFillSub; @@ -145613,12 +142624,12 @@ pGroupBy = p->pGroupBy; pHaving = p->pHaving; sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; #if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x8000 ){ - TREETRACE(0x8000,pParse,p,("After all FROM-clause analysis:\n")); + if( sqlite3TreeTrace & 0x400 ){ + SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and @@ -145650,12 +142661,12 @@ ** original setting of the SF_Distinct flag, not the current setting */ assert( sDistinct.isTnct ); sDistinct.isTnct = 2; #if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x20000 ){ - TREETRACE(0x20000,pParse,p,("Transform DISTINCT into GROUP BY:\n")); + if( sqlite3TreeTrace & 0x400 ){ + SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif } @@ -145703,11 +142714,11 @@ */ iEnd = sqlite3VdbeMakeLabel(pParse); if( (p->selFlags & SF_FixedLimit)==0 ){ p->nSelectRow = 320; /* 4 billion rows */ } - if( p->pLimit ) computeLimitRegisters(pParse, p, iEnd); + computeLimitRegisters(pParse, p, iEnd); if( p->iLimit==0 && sSort.addrSortIndex>=0 ){ sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen); sSort.sortFlags |= SORTFLAG_UseSorter; } @@ -145737,11 +142748,11 @@ #endif assert( WHERE_USE_LIMIT==SF_FixedLimit ); /* Begin the database scan. */ - TREETRACE(0x2,pParse,p,("WhereBegin\n")); + SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, p->pEList, p, wctrlFlags, p->nSelectRow); if( pWInfo==0 ) goto select_end; if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); @@ -145754,11 +142765,11 @@ sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo); if( sSort.nOBSat==sSort.pOrderBy->nExpr ){ sSort.pOrderBy = 0; } } - TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); /* If sorting index that was created by a prior OP_OpenEphemeral ** instruction ended up not being needed, then change the OP_OpenEphemeral ** into an OP_Noop. */ @@ -145793,11 +142804,11 @@ sqlite3WhereContinueLabel(pWInfo), sqlite3WhereBreakLabel(pWInfo)); /* End the database scan loop. */ - TREETRACE(0x2,pParse,p,("WhereEnd\n")); + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); } }else{ /* This case when there exist aggregate functions or a GROUP BY clause ** or both */ @@ -145874,18 +142885,16 @@ } if( db->mallocFailed ){ goto select_end; } pAggInfo->selId = p->selId; -#ifdef SQLITE_DEBUG - pAggInfo->pSelect = p; -#endif memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; sNC.pSrcList = pTabList; sNC.uNC.pAggInfo = pAggInfo; VVA_ONLY( sNC.ncFlags = NC_UAggInfo; ) + pAggInfo->mnReg = pParse->nMem+1; pAggInfo->nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; pAggInfo->pGroupBy = pGroupBy; sqlite3ExprAnalyzeAggList(&sNC, pEList); sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); if( pHaving ){ @@ -145902,21 +142911,44 @@ if( p->pGroupBy==0 && p->pHaving==0 && pAggInfo->nFunc==1 ){ minMaxFlag = minMaxQuery(db, pAggInfo->aFunc[0].pFExpr, &pMinMaxOrderBy); }else{ minMaxFlag = WHERE_ORDERBY_NORMAL; } - analyzeAggFuncArgs(pAggInfo, &sNC); + for(i=0; inFunc; i++){ + Expr *pExpr = pAggInfo->aFunc[i].pFExpr; + assert( ExprUseXList(pExpr) ); + sNC.ncFlags |= NC_InAggFunc; + sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList); +#ifndef SQLITE_OMIT_WINDOWFUNC + assert( !IsWindowFunc(pExpr) ); + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + sqlite3ExprAnalyzeAggregates(&sNC, pExpr->y.pWin->pFilter); + } +#endif + sNC.ncFlags &= ~NC_InAggFunc; + } + pAggInfo->mxReg = pParse->nMem; if( db->mallocFailed ) goto select_end; #if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x20 ){ - TREETRACE(0x20,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); + if( sqlite3TreeTrace & 0x400 ){ + int ii; + SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); sqlite3TreeViewSelect(0, p, 0); if( minMaxFlag ){ sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag); sqlite3TreeViewExprList(0, pMinMaxOrderBy, 0, "ORDERBY"); } - printAggInfo(pAggInfo); + for(ii=0; iinColumn; ii++){ + sqlite3DebugPrintf("agg-column[%d] iMem=%d\n", + ii, pAggInfo->aCol[ii].iMem); + sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0); + } + for(ii=0; iinFunc; ii++){ + sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n", + ii, pAggInfo->aFunc[ii].iMem); + sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pFExpr, 0); + } } #endif /* Processing for aggregates with GROUP BY is very different and @@ -145981,25 +143013,21 @@ ** This might involve two separate loops with an OP_Sort in between, or ** it might be a single loop that uses an index to extract information ** in the right order to begin with. */ sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); - TREETRACE(0x2,pParse,p,("WhereBegin\n")); + SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct, - p, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY) + 0, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY) | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0 ); if( pWInfo==0 ){ sqlite3ExprListDelete(db, pDistinct); goto select_end; } - if( pParse->pIdxEpr ){ - optimizeAggregateUseOfIndexedExpr(pParse, p, pAggInfo, &sNC); - } - assignAggregateRegisters(pParse, pAggInfo); eDist = sqlite3WhereIsDistinct(pWInfo); - TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ /* The optimizer is able to deliver rows in group by order so ** we do not have to sort. The OP_OpenEphemeral table will be ** cancelled later because we still need to use the pKeyInfo */ @@ -146030,49 +143058,32 @@ } } regBase = sqlite3GetTempRange(pParse, nCol); sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); j = nGroupBy; - pAggInfo->directMode = 1; for(i=0; inColumn; i++){ struct AggInfo_col *pCol = &pAggInfo->aCol[i]; if( pCol->iSorterColumn>=j ){ - sqlite3ExprCode(pParse, pCol->pCExpr, j + regBase); + int r1 = j + regBase; + sqlite3ExprCodeGetColumnOfTable(v, + pCol->pTab, pCol->iTable, pCol->iColumn, r1); j++; } } - pAggInfo->directMode = 0; regRecord = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempRange(pParse, regBase, nCol); - TREETRACE(0x2,pParse,p,("WhereEnd\n")); + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++; sortOut = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); sqlite3VdbeAddOp2(v, OP_SorterSort, pAggInfo->sortingIdx, addrEnd); VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); pAggInfo->useSortingIdx = 1; - } - - /* If there entries in pAgggInfo->aFunc[] that contain subexpressions - ** that are indexed (and that were previously identified and tagged - ** in optimizeAggregateUseOfIndexedExpr()) then those subexpressions - ** must now be converted into a TK_AGG_COLUMN node so that the value - ** is correctly pulled from the index rather than being recomputed. */ - if( pParse->pIdxEpr ){ - aggregateConvertIndexedExprRefToColumn(pAggInfo); -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x20 ){ - TREETRACE(0x20, pParse, p, - ("AggInfo function expressions converted to reference index\n")); - sqlite3TreeViewSelect(0, p, 0); - printAggInfo(pAggInfo); - } -#endif } /* If the index or temporary table used by the GROUP BY sort ** will naturally deliver rows in the order required by the ORDER BY ** clause, cancel the ephemeral table open coded earlier. @@ -146139,11 +143150,11 @@ */ if( groupBySort ){ sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop); VdbeCoverage(v); }else{ - TREETRACE(0x2,pParse,p,("WhereEnd\n")); + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); sqlite3VdbeChangeToNoop(v, addrSortingIdx); } sqlite3ExprListDelete(db, pDistinct); @@ -146249,12 +143260,11 @@ /* Open a read-only cursor, execute the OP_Count, close the cursor. */ sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, (int)iRoot, iDb, 1); if( pKeyInfo ){ sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); } - assignAggregateRegisters(pParse, pAggInfo); - sqlite3VdbeAddOp2(v, OP_Count, iCsr, AggInfoFuncReg(pAggInfo,0)); + sqlite3VdbeAddOp2(v, OP_Count, iCsr, pAggInfo->aFunc[0].iMem); sqlite3VdbeAddOp1(v, OP_Close, iCsr); explainSimpleCount(pParse, pTab, pBest); }else{ int regAcc = 0; /* "populate accumulators" flag */ ExprList *pDistinct = 0; @@ -146286,11 +143296,10 @@ }else if( pAggInfo->nFunc==1 && pAggInfo->aFunc[0].iDistinct>=0 ){ assert( ExprUseXList(pAggInfo->aFunc[0].pFExpr) ); pDistinct = pAggInfo->aFunc[0].pFExpr->x.pList; distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0; } - assignAggregateRegisters(pParse, pAggInfo); /* This case runs if the aggregate has no GROUP BY clause. The ** processing is much simpler since there is only a single row ** of output. */ @@ -146303,17 +143312,17 @@ ** be an appropriate ORDER BY expression for the optimization. */ assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 ); assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 ); - TREETRACE(0x2,pParse,p,("WhereBegin\n")); + SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, - pDistinct, p, minMaxFlag|distFlag, 0); + pDistinct, 0, minMaxFlag|distFlag, 0); if( pWInfo==0 ){ goto select_end; } - TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); eDist = sqlite3WhereIsDistinct(pWInfo); updateAccumulator(pParse, regAcc, pAggInfo, eDist); if( eDist!=WHERE_DISTINCT_NOOP ){ struct AggInfo_func *pF = pAggInfo->aFunc; if( pF ){ @@ -146323,11 +143332,11 @@ if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); if( minMaxFlag ){ sqlite3WhereMinMaxOptEarlyOut(v, pWInfo); } - TREETRACE(0x2,pParse,p,("WhereEnd\n")); + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); finalizeAggFunctions(pParse, pAggInfo); } sSort.pOrderBy = 0; @@ -146345,10 +143354,12 @@ /* If there is an ORDER BY clause, then we need to sort the results ** and send them to the callback one by one. */ if( sSort.pOrderBy ){ + explainTempTable(pParse, + sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY"); assert( p->pEList==pEList ); generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); } /* Jump here to skip this query @@ -146368,11 +143379,11 @@ sqlite3ExprListDelete(db, pMinMaxOrderBy); #ifdef SQLITE_DEBUG if( pAggInfo && !db->mallocFailed ){ for(i=0; inColumn; i++){ Expr *pExpr = pAggInfo->aCol[i].pCExpr; - if( pExpr==0 ) continue; + assert( pExpr!=0 ); assert( pExpr->pAggInfo==pAggInfo ); assert( pExpr->iAgg==i ); } for(i=0; inFunc; i++){ Expr *pExpr = pAggInfo->aFunc[i].pFExpr; @@ -146382,12 +143393,12 @@ } } #endif #if TREETRACE_ENABLED - TREETRACE(0x1,pParse,p,("end processing\n")); - if( (sqlite3TreeTrace & 0x40000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + SELECTTRACE(0x1,pParse,p,("end processing\n")); + if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif ExplainQueryPlanPop(pParse); return rc; @@ -146657,11 +143668,11 @@ while( p ){ Trigger *pTrig = (Trigger *)sqliteHashData(p); if( pTrig->pTabSchema==pTab->pSchema && pTrig->table && 0==sqlite3StrICmp(pTrig->table, pTab->zName) - && (pTrig->pTabSchema!=pTmpSchema || pTrig->bReturning) + && pTrig->pTabSchema!=pTmpSchema ){ pTrig->pNext = pList; pList = pTrig; }else if( pTrig->op==TK_RETURNING ){ #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -146947,27 +143958,10 @@ */ if( !db->init.busy ){ Vdbe *v; char *z; - /* If this is a new CREATE TABLE statement, and if shadow tables - ** are read-only, and the trigger makes a change to a shadow table, - ** then raise an error - do not allow the trigger to be created. */ - if( sqlite3ReadOnlyShadowTables(db) ){ - TriggerStep *pStep; - for(pStep=pTrig->step_list; pStep; pStep=pStep->pNext){ - if( pStep->zTarget!=0 - && sqlite3ShadowTableName(db, pStep->zTarget) - ){ - sqlite3ErrorMsg(pParse, - "trigger \"%s\" may not write to shadow table \"%s\"", - pTrig->zName, pStep->zTarget); - goto triggerfinish_cleanup; - } - } - } - /* Make an entry in the sqlite_schema table */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto triggerfinish_cleanup; sqlite3BeginWriteOperation(pParse, 0, iDb); z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); @@ -147787,11 +144781,11 @@ sSubParse.pTriggerTab = pTab; sSubParse.pToplevel = pTop; sSubParse.zAuthContext = pTrigger->zName; sSubParse.eTriggerOp = pTrigger->op; sSubParse.nQueryLoop = pParse->nQueryLoop; - sSubParse.prepFlags = pParse->prepFlags; + sSubParse.disableVtab = pParse->disableVtab; v = sqlite3GetVdbe(&sSubParse); if( v ){ VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", pTrigger->zName, onErrorText(orconf), @@ -148133,18 +145127,15 @@ ** (not a virtual table) then the value might have been stored as an ** integer. In that case, add an OP_RealAffinity opcode to make sure ** it has been converted into REAL. */ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ - Column *pCol; assert( pTab!=0 ); - assert( pTab->nCol>i ); - pCol = &pTab->aCol[i]; - if( pCol->iDflt ){ + if( !IsView(pTab) ){ sqlite3_value *pValue = 0; u8 enc = ENC(sqlite3VdbeDb(v)); - assert( !IsView(pTab) ); + Column *pCol = &pTab->aCol[i]; VdbeComment((v, "%s.%s", pTab->zName, pCol->zCnName)); assert( inCol ); sqlite3ValueFromExpr(sqlite3VdbeDb(v), sqlite3ColumnExpr(pTab,pCol), enc, pCol->affinity, &pValue); @@ -148151,11 +145142,11 @@ if( pValue ){ sqlite3VdbeAppendP4(v, pValue, P4_MEM); } } #ifndef SQLITE_OMIT_FLOATING_POINT - if( pCol->affinity==SQLITE_AFF_REAL && !IsVirtual(pTab) ){ + if( pTab->aCol[i].affinity==SQLITE_AFF_REAL && !IsVirtual(pTab) ){ sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); } #endif } @@ -148337,12 +145328,11 @@ sqlite3ExprDup(db, pChanges->a[i].pExpr, 0) ); } } pSelect = sqlite3SelectNew(pParse, pList, - pSrc, pWhere2, pGrp, 0, pOrderBy2, - SF_UFSrcCheck|SF_IncludeHidden|SF_UpdateFrom, pLimit2 + pSrc, pWhere2, pGrp, 0, pOrderBy2, SF_UFSrcCheck|SF_IncludeHidden, pLimit2 ); if( pSelect ) pSelect->selFlags |= SF_OrderByReqd; sqlite3SelectDestInit(&dest, eDest, iEph); dest.iSDParm2 = (pPk ? pPk->nKeyCol : -1); sqlite3Select(pParse, pSelect, &dest); @@ -149592,11 +146582,10 @@ Expr *pExpr; sCol[0].u.zToken = (char*)pIdx->azColl[ii]; if( pIdx->aiColumn[ii]==XN_EXPR ){ assert( pIdx->aColExpr!=0 ); assert( pIdx->aColExpr->nExpr>ii ); - assert( pIdx->bHasExpr ); pExpr = pIdx->aColExpr->a[ii].pExpr; if( pExpr->op!=TK_COLLATE ){ sCol[0].pLeft = pExpr; pExpr = &sCol[0]; } @@ -149906,11 +146895,10 @@ int isMemDb; /* True if vacuuming a :memory: database */ int nRes; /* Bytes of reserved space at the end of each page */ int nDb; /* Number of attached databases */ const char *zDbMain; /* Schema name of database to vacuum */ const char *zOut; /* Name of output file */ - u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); return SQLITE_ERROR; /* IMP: R-12218-18073 */ } @@ -149978,21 +146966,16 @@ rc = SQLITE_ERROR; sqlite3SetString(pzErrMsg, db, "output file already exists"); goto end_of_vacuum; } db->mDbFlags |= DBFLAG_VacuumInto; - - /* For a VACUUM INTO, the pager-flags are set to the same values as - ** they are for the database being vacuumed, except that PAGER_CACHESPILL - ** is always set. */ - pgflags = db->aDb[iDb].safety_level | (db->flags & PAGER_FLAGS_MASK); } nRes = sqlite3BtreeGetRequestedReserve(pMain); sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); - sqlite3BtreeSetPagerFlags(pTemp, pgflags|PAGER_CACHESPILL); + sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL); /* Begin a transaction and take an exclusive lock on the main database ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, ** to ensure that we do not try to change the page-size on a WAL database. */ @@ -150372,14 +147355,14 @@ || db->eOpenState==SQLITE_STATE_ZOMBIE ); pVTab->nRef--; if( pVTab->nRef==0 ){ sqlite3_vtab *p = pVTab->pVtab; + sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod); if( p ){ p->pModule->xDisconnect(p); } - sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod); sqlite3DbFree(db, pVTab); } } /* @@ -150501,12 +147484,11 @@ ** in the list are moved to the sqlite3.pDisconnect list of the associated ** database connection. */ SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){ assert( IsVirtual(p) ); - assert( db!=0 ); - if( db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); + if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); if( p->u.vtab.azArg ){ int i; for(i=0; iu.vtab.nArg; i++){ if( i!=1 ) sqlite3DbFree(db, p->u.vtab.azArg[i]); } @@ -151302,11 +148284,11 @@ /* Check to see the left operand is a column in a virtual table */ if( NEVER(pExpr==0) ) return pDef; if( pExpr->op!=TK_COLUMN ) return pDef; assert( ExprUseYTab(pExpr) ); pTab = pExpr->y.pTab; - if( NEVER(pTab==0) ) return pDef; + if( pTab==0 ) return pDef; if( !IsVirtual(pTab) ) return pDef; pVtab = sqlite3GetVTable(db, pTab)->pVtab; assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); pMod = (sqlite3_module *)pVtab->pModule; @@ -151909,11 +148891,11 @@ /* ** An instance of the following structure keeps track of a mapping ** between VDBE cursor numbers and bits of the bitmasks in WhereTerm. ** ** The VDBE cursor numbers are small integers contained in -** SrcItem.iCursor and Expr.iTable fields. For any given WHERE +** SrcList_item.iCursor and Expr.iTable fields. For any given WHERE ** clause, the cursor numbers might not begin with 0 and they might ** contain gaps in the numbering sequence. But we want to make maximum ** use of the bits in our bitmasks. This structure provides a mapping ** from the sparse cursor numbers into consecutive integers beginning ** with 0. @@ -151980,10 +148962,24 @@ #endif #ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR # define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000 #endif +/* +** Each instance of this object records a change to a single node +** in an expression tree to cause that node to point to a column +** of an index rather than an expression or a virtual column. All +** such transformations need to be undone at the end of WHERE clause +** processing. +*/ +typedef struct WhereExprMod WhereExprMod; +struct WhereExprMod { + WhereExprMod *pNext; /* Next translation on a list of them all */ + Expr *pExpr; /* The Expr node that was transformed */ + Expr orig; /* Original value of the Expr node */ +}; + /* ** The WHERE clause processing routine has two halves. The ** first part does the start of the WHERE loop and the second ** half does the tail of the WHERE loop. An instance of ** this structure is returned by the first half and passed @@ -151995,14 +148991,14 @@ struct WhereInfo { Parse *pParse; /* Parsing and code generating context */ SrcList *pTabList; /* List of tables in the join */ ExprList *pOrderBy; /* The ORDER BY clause or NULL */ ExprList *pResultSet; /* Result set of the query */ -#if WHERETRACE_ENABLED Expr *pWhere; /* The complete WHERE clause */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + Select *pLimit; /* Used to access LIMIT expr/registers for vtabs */ #endif - Select *pSelect; /* The entire SELECT statement containing WHERE */ int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ int iContinue; /* Jump here to continue with next record */ int iBreak; /* Jump here to break out of the loop */ int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ @@ -152017,10 +149013,11 @@ unsigned sorted :1; /* True if really sorted (not just grouped) */ LogEst nRowOut; /* Estimated number of output rows */ int iTop; /* The very beginning of the WHERE loop */ int iEndWhere; /* End of the WHERE clause itself */ WhereLoop *pLoops; /* List of all WhereLoop objects */ + WhereExprMod *pExprMods; /* Expression modifications */ WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ WhereClause sWC; /* Decomposition of the WHERE clause */ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ WhereLevel a[1]; /* Information about each nest loop in WHERE */ @@ -152164,12 +149161,10 @@ #define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */ #define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */ #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 */ -#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) */ /************** End of whereInt.h ********************************************/ /************** Continuing where we left off in wherecode.c ******************/ @@ -152422,12 +149417,10 @@ } sqlite3_str_append(&str, ")", 1); zMsg = sqlite3StrAccumFinish(&str); ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), pParse->addrExplain, 0, zMsg,P4_DYNAMIC); - - sqlite3VdbeScanStatus(v, sqlite3VdbeCurrentAddr(v)-1, 0, 0, 0, 0); return ret; } #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS @@ -152446,31 +149439,18 @@ WhereLevel *pLvl, /* Level to add scanstatus() entry for */ int addrExplain /* Address of OP_Explain (or 0) */ ){ const char *zObj = 0; WhereLoop *pLoop = pLvl->pWLoop; - int wsFlags = pLoop->wsFlags; - int viaCoroutine = 0; - - if( (wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ zObj = pLoop->u.btree.pIndex->zName; }else{ zObj = pSrclist->a[pLvl->iFrom].zName; - viaCoroutine = pSrclist->a[pLvl->iFrom].fg.viaCoroutine; } sqlite3VdbeScanStatus( v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj ); - - if( viaCoroutine==0 ){ - if( (wsFlags & (WHERE_MULTI_OR|WHERE_AUTO_INDEX))==0 ){ - sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur); - } - if( wsFlags & WHERE_INDEXED ){ - sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); - } - } } #endif /* @@ -152526,11 +149506,11 @@ pTerm->wtFlags |= TERM_LIKECOND; }else{ pTerm->wtFlags |= TERM_CODED; } #ifdef WHERETRACE_ENABLED - if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ + if( sqlite3WhereTrace & 0x20000 ){ sqlite3DebugPrintf("DISABLE-"); sqlite3WhereTermPrint(pTerm, (int)(pTerm - (pTerm->pWC->a))); } #endif if( pTerm->iParent<0 ) break; @@ -152789,12 +149769,11 @@ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); pExpr->iTable = iTab; } sqlite3ExprDelete(db, pX); }else{ - int n = sqlite3ExprVectorSize(pX->pLeft); - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); } pX = pExpr; } @@ -153060,11 +150039,11 @@ WhereTerm *pTerm /* The upper or lower bound just coded */ ){ if( pTerm->wtFlags & TERM_LIKEOPT ){ VdbeOp *pOp; assert( pLevel->iLikeRepCntr>0 ); - pOp = sqlite3VdbeGetLastOp(v); + pOp = sqlite3VdbeGetOp(v, -1); assert( pOp!=0 ); assert( pOp->opcode==OP_String8 || pTerm->pWC->pWInfo->pParse->db->mallocFailed ); pOp->p3 = (int)(pLevel->iLikeRepCntr>>1); /* Register holding counter */ pOp->p5 = (u8)(pLevel->iLikeRepCntr&1); /* ASC or DESC */ @@ -153383,10 +150362,147 @@ }else{ assert( nReg==1 || pParse->nErr ); sqlite3ExprCode(pParse, p, iReg); } } + +/* An instance of the IdxExprTrans object carries information about a +** mapping from an expression on table columns into a column in an index +** down through the Walker. +*/ +typedef struct IdxExprTrans { + Expr *pIdxExpr; /* The index expression */ + int iTabCur; /* The cursor of the corresponding table */ + int iIdxCur; /* The cursor for the index */ + int iIdxCol; /* The column for the index */ + int iTabCol; /* The column for the table */ + WhereInfo *pWInfo; /* Complete WHERE clause information */ + sqlite3 *db; /* Database connection (for malloc()) */ +} IdxExprTrans; + +/* +** Preserve pExpr on the WhereETrans list of the WhereInfo. +*/ +static void preserveExpr(IdxExprTrans *pTrans, Expr *pExpr){ + WhereExprMod *pNew; + pNew = sqlite3DbMallocRaw(pTrans->db, sizeof(*pNew)); + if( pNew==0 ) return; + pNew->pNext = pTrans->pWInfo->pExprMods; + pTrans->pWInfo->pExprMods = pNew; + pNew->pExpr = pExpr; + memcpy(&pNew->orig, pExpr, sizeof(*pExpr)); +} + +/* The walker node callback used to transform matching expressions into +** a reference to an index column for an index on an expression. +** +** If pExpr matches, then transform it into a reference to the index column +** that contains the value of pExpr. +*/ +static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ + IdxExprTrans *pX = p->u.pIdxTrans; + if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ + pExpr = sqlite3ExprSkipCollate(pExpr); + preserveExpr(pX, pExpr); + pExpr->affExpr = sqlite3ExprAffinity(pExpr); + pExpr->op = TK_COLUMN; + pExpr->iTable = pX->iIdxCur; + pExpr->iColumn = pX->iIdxCol; + testcase( ExprHasProperty(pExpr, EP_Unlikely) ); + ExprClearProperty(pExpr, EP_Skip|EP_Unlikely|EP_WinFunc|EP_Subrtn); + pExpr->y.pTab = 0; + return WRC_Prune; + }else{ + return WRC_Continue; + } +} + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* A walker node callback that translates a column reference to a table +** into a corresponding column reference of an index. +*/ +static int whereIndexExprTransColumn(Walker *p, Expr *pExpr){ + if( pExpr->op==TK_COLUMN ){ + IdxExprTrans *pX = p->u.pIdxTrans; + if( pExpr->iTable==pX->iTabCur && pExpr->iColumn==pX->iTabCol ){ + assert( ExprUseYTab(pExpr) && pExpr->y.pTab!=0 ); + preserveExpr(pX, pExpr); + pExpr->affExpr = sqlite3TableColumnAffinity(pExpr->y.pTab,pExpr->iColumn); + pExpr->iTable = pX->iIdxCur; + pExpr->iColumn = pX->iIdxCol; + pExpr->y.pTab = 0; + } + } + return WRC_Continue; +} +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + +/* +** For an indexes on expression X, locate every instance of expression X +** in pExpr and change that subexpression into a reference to the appropriate +** column of the index. +** +** 2019-10-24: Updated to also translate references to a VIRTUAL column in +** the table into references to the corresponding (stored) column of the +** index. +*/ +static void whereIndexExprTrans( + Index *pIdx, /* The Index */ + int iTabCur, /* Cursor of the table that is being indexed */ + int iIdxCur, /* Cursor of the index itself */ + WhereInfo *pWInfo /* Transform expressions in this WHERE clause */ +){ + int iIdxCol; /* Column number of the index */ + ExprList *aColExpr; /* Expressions that are indexed */ + Table *pTab; + Walker w; + IdxExprTrans x; + aColExpr = pIdx->aColExpr; + if( aColExpr==0 && !pIdx->bHasVCol ){ + /* The index does not reference any expressions or virtual columns + ** so no translations are needed. */ + return; + } + pTab = pIdx->pTable; + memset(&w, 0, sizeof(w)); + w.u.pIdxTrans = &x; + x.iTabCur = iTabCur; + x.iIdxCur = iIdxCur; + x.pWInfo = pWInfo; + x.db = pWInfo->pParse->db; + for(iIdxCol=0; iIdxColnColumn; iIdxCol++){ + i16 iRef = pIdx->aiColumn[iIdxCol]; + if( iRef==XN_EXPR ){ + assert( aColExpr!=0 && aColExpr->a[iIdxCol].pExpr!=0 ); + x.pIdxExpr = aColExpr->a[iIdxCol].pExpr; + if( sqlite3ExprIsConstant(x.pIdxExpr) ) continue; + w.xExprCallback = whereIndexExprTransNode; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + }else if( iRef>=0 + && (pTab->aCol[iRef].colFlags & COLFLAG_VIRTUAL)!=0 + && ((pTab->aCol[iRef].colFlags & COLFLAG_HASCOLL)==0 + || sqlite3StrICmp(sqlite3ColumnColl(&pTab->aCol[iRef]), + sqlite3StrBINARY)==0) + ){ + /* Check to see if there are direct references to generated columns + ** that are contained in the index. Pulling the generated column + ** out of the index is an optimization only - the main table is always + ** available if the index cannot be used. To avoid unnecessary + ** complication, omit this optimization if the collating sequence for + ** the column is non-standard */ + x.iTabCol = iRef; + w.xExprCallback = whereIndexExprTransColumn; +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + }else{ + continue; + } + x.iIdxCol = iIdxCol; + sqlite3WalkExpr(&w, pWInfo->pWhere); + sqlite3WalkExprList(&w, pWInfo->pOrderBy); + sqlite3WalkExprList(&w, pWInfo->pResultSet); + } +} /* ** The pTruth expression is always true because it is the WHERE clause ** a partial index that is driving a query loop. Look through all of the ** WHERE clause terms on the query, and if any of those terms must be @@ -153452,12 +150568,10 @@ assert( pTerm!=0 ); assert( pTerm->pExpr!=0 ); testcase( pTerm->wtFlags & TERM_VIRTUAL ); regRowid = sqlite3GetTempReg(pParse); regRowid = codeEqualityTerm(pParse, pTerm, pLevel, 0, 0, regRowid); - sqlite3VdbeAddOp2(pParse->pVdbe, OP_MustBeInt, regRowid, addrNxt); - VdbeCoverage(pParse->pVdbe); sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, addrNxt, regRowid, 1); VdbeCoverage(pParse->pVdbe); }else{ u16 nEq = pLoop->u.btree.nEq; @@ -153513,19 +150627,17 @@ pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; iCur = pTabItem->iCursor; pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); bRev = (pWInfo->revMask>>iLevel)&1; VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); -#if WHERETRACE_ENABLED /* 0x4001 */ - if( sqlite3WhereTrace & 0x1 ){ +#if WHERETRACE_ENABLED /* 0x20800 */ + if( sqlite3WhereTrace & 0x800 ){ sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom); - if( sqlite3WhereTrace & 0x1000 ){ - sqlite3WhereLoopPrint(pLoop, pWC); - } + sqlite3WhereLoopPrint(pLoop, pWC); } - if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ + if( sqlite3WhereTrace & 0x20000 ){ if( iLevel==0 ){ sqlite3DebugPrintf("WHERE clause being coded:\n"); sqlite3TreeViewExpr(0, pWInfo->pWhere, 0); } sqlite3DebugPrintf("All WHERE-clause terms before coding:\n"); @@ -153607,13 +150719,13 @@ codeExprOrVector(pParse, pRight, iTarget, 1); if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET && pLoop->u.vtab.bOmitOffset ){ assert( pTerm->eOperator==WO_AUX ); - assert( pWInfo->pSelect!=0 ); - assert( pWInfo->pSelect->iOffset>0 ); - sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pSelect->iOffset); + assert( pWInfo->pLimit!=0 ); + assert( pWInfo->pLimit->iOffset>0 ); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pLimit->iOffset); VdbeComment((v,"Zero OFFSET counter")); } } } sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); @@ -153717,12 +150829,10 @@ iReleaseReg = ++pParse->nMem; iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg); if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg); addrNxt = pLevel->addrNxt; if( pLevel->regFilter ){ - sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); - VdbeCoverage(v); sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt, iRowidReg, 1); VdbeCoverage(v); filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady); } @@ -154070,15 +151180,10 @@ ** of entries in the tree, so basing the number of steps to try ** on the estimated number of rows in the btree seems like a good ** guess. */ addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan, (pIdx->aiRowLogEst[0]+9)/10); - if( pRangeStart ){ - sqlite3VdbeChangeP5(v, 1); - sqlite3VdbeChangeP2(v, addrSeekScan, sqlite3VdbeCurrentAddr(v)+1); - addrSeekScan = 0; - } VdbeCoverage(v); } sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); VdbeCoverage(v); VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); @@ -154150,12 +151255,12 @@ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); endEq = 0; } nConstraint++; } - if( zStartAff ) sqlite3DbNNFreeNN(db, zStartAff); - if( zEndAff ) sqlite3DbNNFreeNN(db, zEndAff); + sqlite3DbFree(db, zStartAff); + sqlite3DbFree(db, zEndAff); /* Top of the loop body */ if( pLevel->p2==0 ) pLevel->p2 = sqlite3VdbeCurrentAddr(v); /* Check if the index cursor is past the end of the range. */ @@ -154213,10 +151318,31 @@ sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont, iRowidReg, pPk->nKeyCol); VdbeCoverage(v); } if( pLevel->iLeftJoin==0 ){ + /* If pIdx is an index on one or more expressions, then look through + ** all the expressions in pWInfo and try to transform matching expressions + ** into reference to index columns. Also attempt to translate references + ** to virtual columns in the table into references to (stored) columns + ** of the index. + ** + ** Do not do this for the RHS of a LEFT JOIN. This is because the + ** expression may be evaluated after OP_NullRow has been executed on + ** the cursor. In this case it is important to do the full evaluation, + ** as the result of the expression may not be NULL, even if all table + ** column values are. https://www.sqlite.org/src/info/7fa8049685b50b5a + ** + ** Also, do not do this when processing one index an a multi-index + ** OR clause, since the transformation will become invalid once we + ** move forward to the next index. + ** https://sqlite.org/src/info/4e8e4857d32d401f + */ + if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 ){ + whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); + } + /* If a partial index is driving the loop, try to eliminate WHERE clause ** terms from the query that must be true due to the WHERE clause of ** the partial index. ** ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work @@ -154325,11 +151451,11 @@ */ if( pWInfo->nLevel>1 ){ int nNotReady; /* The number of notReady tables */ SrcItem *origSrc; /* Original list of tables */ nNotReady = pWInfo->nLevel - iLevel - 1; - pOrTab = sqlite3DbMallocRawNN(db, + pOrTab = sqlite3StackAllocRaw(db, sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); if( pOrTab==0 ) return notReady; pOrTab->nAlloc = (u8)(nNotReady + 1); pOrTab->nSrc = pOrTab->nAlloc; memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem)); @@ -154445,11 +151571,11 @@ pAndExpr->pLeft = pOrExpr; pOrExpr = pAndExpr; } /* Loop through table entries that match term pOrTerm. */ ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1)); - WHERETRACE(0xffffffff, ("Subplan for OR-clause:\n")); + WHERETRACE(0xffff, ("Subplan for OR-clause:\n")); pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0, WHERE_OR_SUBCLAUSE, iCovCur); assert( pSubWInfo || pParse->nErr ); if( pSubWInfo ){ WhereLoop *pSubLoop; @@ -154578,11 +151704,11 @@ ** indent everything in between the this point and the final OP_Return. ** See tag-20220407a in vdbe.c and shell.c */ assert( pLevel->op==OP_Return ); pLevel->p2 = sqlite3VdbeCurrentAddr(v); - if( pWInfo->nLevel>1 ){ sqlite3DbFreeNN(db, pOrTab); } + if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); } if( !untestedTerms ) disableTerm(pLevel, pTerm); }else #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ { @@ -154682,16 +151808,16 @@ VdbeCoverageIf(v, (x&1)==1); VdbeCoverageIf(v, (x&1)==0); } #endif } -#ifdef WHERETRACE_ENABLED /* 0xffffffff */ +#ifdef WHERETRACE_ENABLED /* 0xffff */ if( sqlite3WhereTrace ){ VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d", pWC->nTerm-j, pTerm, iLoop)); } - if( sqlite3WhereTrace & 0x4000 ){ + if( sqlite3WhereTrace & 0x800 ){ sqlite3DebugPrintf("Coding auxiliary constraint:\n"); sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); } #endif sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); @@ -154716,12 +151842,12 @@ if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue; if( (pTerm->eOperator & WO_EQUIV)==0 ) continue; if( pTerm->leftCursor!=iCur ) continue; if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ) continue; pE = pTerm->pExpr; -#ifdef WHERETRACE_ENABLED /* 0x4001 */ - if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ +#ifdef WHERETRACE_ENABLED /* 0x800 */ + if( sqlite3WhereTrace & 0x800 ){ sqlite3DebugPrintf("Coding transitive constraint:\n"); sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); } #endif assert( !ExprHasProperty(pE, EP_OuterON) ); @@ -154832,17 +151958,17 @@ sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); pTerm->wtFlags |= TERM_CODED; } } -#if WHERETRACE_ENABLED /* 0x4001 */ - if( sqlite3WhereTrace & 0x4000 ){ +#if WHERETRACE_ENABLED /* 0x20800 */ + if( sqlite3WhereTrace & 0x20000 ){ sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n", iLevel); sqlite3WhereClausePrint(pWC); } - if( sqlite3WhereTrace & 0x1 ){ + if( sqlite3WhereTrace & 0x800 ){ sqlite3DebugPrintf("End Coding level %d: notReady=%llx\n", iLevel, (u64)pLevel->notReady); } #endif return pLevel->notReady; @@ -155206,11 +152332,11 @@ ** 2019-09-03 https://sqlite.org/src/info/0f0428096f17252a */ if( pLeft->op!=TK_COLUMN || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT || (ALWAYS( ExprUseYTab(pLeft) ) - && ALWAYS(pLeft->y.pTab) + && pLeft->y.pTab && IsVirtual(pLeft->y.pTab)) /* Might be numeric */ ){ int isNum; double rDummy; isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); @@ -155323,11 +152449,12 @@ ** ** vtab_column MATCH expression ** MATCH(expression,vtab_column) */ pCol = pList->a[1].pExpr; - assert( pCol->op!=TK_COLUMN || (ExprUseYTab(pCol) && pCol->y.pTab!=0) ); + assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) ); + testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); if( ExprIsVtab(pCol) ){ for(i=0; iu.zToken, aOp[i].zOp)==0 ){ *peOp2 = aOp[i].eOp2; @@ -155348,11 +152475,11 @@ ** names. But for this use case, xFindFunction is expected to deal ** with function names in an arbitrary case. */ pCol = pList->a[0].pExpr; assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) ); - assert( pCol->op!=TK_COLUMN || (ExprUseYTab(pCol) && pCol->y.pTab!=0) ); + testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); if( ExprIsVtab(pCol) ){ sqlite3_vtab *pVtab; sqlite3_module *pMod; void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); void *pNotUsed; @@ -155373,16 +152500,17 @@ } }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ int res = 0; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; - assert( pLeft->op!=TK_COLUMN || (ExprUseYTab(pLeft) && pLeft->y.pTab!=0) ); + assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) ); + testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 ); if( ExprIsVtab(pLeft) ){ res++; } - assert( pRight==0 || pRight->op!=TK_COLUMN - || (ExprUseYTab(pRight) && pRight->y.pTab!=0) ); + assert( pRight==0 || pRight->op!=TK_COLUMN || ExprUseYTab(pRight) ); + testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 ); if( pRight && ExprIsVtab(pRight) ){ res++; SWAP(Expr*, pLeft, pRight); } *ppLeft = pLeft; @@ -155927,11 +153055,10 @@ iCur = pFrom->a[i].iCursor; for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->aColExpr==0 ) continue; for(i=0; inKeyCol; i++){ if( pIdx->aiColumn[i]!=XN_EXPR ) continue; - assert( pIdx->bHasExpr ); if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){ aiCurCol[0] = iCur; aiCurCol[1] = XN_EXPR; return 1; } @@ -156541,13 +153668,13 @@ ** ** LIMIT and OFFSET terms are ignored by most of the planner code. They ** exist only so that they may be passed to the xBestIndex method of the ** single virtual table in the FROM clause of the SELECT. */ -SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ - assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */ - if( p->pGroupBy==0 +SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ + assert( p==0 || (p->pGroupBy==0 && (p->selFlags & SF_Aggregate)==0) ); + if( (p && p->pLimit) /* 1 */ && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */ ){ ExprList *pOrderBy = p->pOrderBy; int iCsr = p->pSrc->a[0].iCursor; @@ -156560,17 +153687,10 @@ ** other, subsequent terms. It can be ignored. See tag-20220128a */ assert( pWC->a[ii].wtFlags & TERM_VIRTUAL ); assert( pWC->a[ii].eOperator==WO_ROWVAL ); continue; } - if( pWC->a[ii].nChild ){ - /* If this term has child terms, then they are also part of the - ** pWC->a[] array. So this term can be ignored, as a LIMIT clause - ** will only be added if each of the child terms passes the - ** (leftCursor==iCsr) test below. */ - continue; - } if( pWC->a[ii].leftCursor!=iCsr ) return; } /* Check condition (5). Return early if it is not met. */ if( pOrderBy ){ @@ -156867,11 +153987,11 @@ ** terms means that no sorting is needed at all. A return that ** is positive but less than the number of ORDER BY terms means that ** block sorting is required. */ SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ - return pWInfo->nOBSat<0 ? 0 : pWInfo->nOBSat; + return pWInfo->nOBSat; } /* ** In the ORDER BY LIMIT optimization, if the inner-most loop is known ** to emit rows in increasing order, and if the last row emitted by the @@ -157505,11 +154625,11 @@ ** are no-ops. */ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ int i; - if( (sqlite3WhereTrace & 0x10)==0 ) return; + if( !sqlite3WhereTrace ) return; for(i=0; inConstraint; i++){ sqlite3DebugPrintf( " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", i, p->aConstraint[i].iColumn, @@ -157525,11 +154645,11 @@ p->aOrderBy[i].desc); } } static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ int i; - if( (sqlite3WhereTrace & 0x10)==0 ) return; + if( !sqlite3WhereTrace ) return; for(i=0; inConstraint; i++){ sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", i, p->aConstraintUsage[i].argvIndex, p->aConstraintUsage[i].omit); @@ -157542,47 +154662,10 @@ } #else #define whereTraceIndexInfoInputs(A) #define whereTraceIndexInfoOutputs(A) #endif - -/* -** We know that pSrc is an operand of an outer join. Return true if -** pTerm is a constraint that is compatible with that join. -** -** pTerm must be EP_OuterON if pSrc is the right operand of an -** outer join. pTerm can be either EP_OuterON or EP_InnerON if pSrc -** is the left operand of a RIGHT join. -** -** See https://sqlite.org/forum/forumpost/206d99a16dd9212f -** for an example of a WHERE clause constraints that may not be used on -** the right table of a RIGHT JOIN because the constraint implies a -** not-NULL condition on the left table of the RIGHT JOIN. -*/ -static int constraintCompatibleWithOuterJoin( - const WhereTerm *pTerm, /* WHERE clause term to check */ - const SrcItem *pSrc /* Table we are trying to access */ -){ - assert( (pSrc->fg.jointype&(JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ); /* By caller */ - testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT ); - testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ ); - testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) - testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) ); - if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) - || pTerm->pExpr->w.iJoin != pSrc->iCursor - ){ - return 0; - } - if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0 - && ExprHasProperty(pTerm->pExpr, EP_InnerON) - ){ - return 0; - } - return 1; -} - - #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* ** Return TRUE if the WHERE clause term pTerm is of a form where it ** could be used with an index to access pSrc, assuming an appropriate @@ -157595,14 +154678,20 @@ ){ char aff; if( pTerm->leftCursor!=pSrc->iCursor ) return 0; if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; assert( (pSrc->fg.jointype & JT_RIGHT)==0 ); - if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 - && !constraintCompatibleWithOuterJoin(pTerm,pSrc) - ){ - return 0; /* See https://sqlite.org/forum/forumpost/51e6959f61 */ + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){ + testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT ); + testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ ); + testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) + testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) ); + if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) + || pTerm->pExpr->w.iJoin != pSrc->iCursor + ){ + return 0; /* See tag-20191211-001 */ + } } if( (pTerm->prereqRight & notReady)!=0 ) return 0; assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); if( pTerm->u.x.leftColumn<0 ) return 0; aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity; @@ -157612,61 +154701,10 @@ } #endif #ifndef SQLITE_OMIT_AUTOMATIC_INDEX - -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS -/* -** Argument pIdx represents an automatic index that the current statement -** will create and populate. Add an OP_Explain with text of the form: -** -** CREATE AUTOMATIC INDEX ON () [WHERE ] -** -** This is only required if sqlite3_stmt_scanstatus() is enabled, to -** associate an SQLITE_SCANSTAT_NCYCLE and SQLITE_SCANSTAT_NLOOP -** values with. In order to avoid breaking legacy code and test cases, -** the OP_Explain is not added if this is an EXPLAIN QUERY PLAN command. -*/ -static void explainAutomaticIndex( - Parse *pParse, - Index *pIdx, /* Automatic index to explain */ - int bPartial, /* True if pIdx is a partial index */ - int *pAddrExplain /* OUT: Address of OP_Explain */ -){ - if( pParse->explain!=2 ){ - Table *pTab = pIdx->pTable; - const char *zSep = ""; - char *zText = 0; - int ii = 0; - sqlite3_str *pStr = sqlite3_str_new(pParse->db); - sqlite3_str_appendf(pStr,"CREATE AUTOMATIC INDEX ON %s(", pTab->zName); - assert( pIdx->nColumn>1 ); - assert( pIdx->aiColumn[pIdx->nColumn-1]==XN_ROWID ); - for(ii=0; ii<(pIdx->nColumn-1); ii++){ - const char *zName = 0; - int iCol = pIdx->aiColumn[ii]; - - zName = pTab->aCol[iCol].zCnName; - sqlite3_str_appendf(pStr, "%s%s", zSep, zName); - zSep = ", "; - } - zText = sqlite3_str_finish(pStr); - if( zText==0 ){ - sqlite3OomFault(pParse->db); - }else{ - *pAddrExplain = sqlite3VdbeExplain( - pParse, 0, "%s)%s", zText, (bPartial ? " WHERE " : "") - ); - sqlite3_free(zText); - } - } -} -#else -# define explainAutomaticIndex(a,b,c,d) -#endif - /* ** Generate code to construct the Index object for an automatic index ** and to set up the WhereLevel object pLevel so that the code generator ** makes use of the automatic index. */ @@ -157698,13 +154736,10 @@ Expr *pPartial = 0; /* Partial Index Expression */ int iContinue = 0; /* Jump here to skip excluded rows */ SrcItem *pTabItem; /* FROM clause term being indexed */ int addrCounter = 0; /* Address where integer counter is initialized */ int regBase; /* Array of registers where record is assembled */ -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - int addrExp = 0; /* Address of OP_Explain */ -#endif /* Generate code to skip over the creation and initialization of the ** transient index on 2nd and subsequent iterations of the loop. */ v = pParse->pVdbe; assert( v!=0 ); @@ -157824,11 +154859,10 @@ assert( n==nKeyCol ); pIdx->aiColumn[n] = XN_ROWID; pIdx->azColl[n] = sqlite3StrBINARY; /* Create the automatic index */ - explainAutomaticIndex(pParse, pIdx, pPartial!=0, &addrExp); assert( pLevel->iIdxCur>=0 ); pLevel->iIdxCur = pParse->nTab++; sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "for %s", pTable->zName)); @@ -157860,11 +154894,10 @@ ); if( pLevel->regFilter ){ sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, regBase, pLoop->u.btree.nEq); } - sqlite3VdbeScanStatusCounters(v, addrExp, addrExp, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); if( pTabItem->fg.viaCoroutine ){ sqlite3VdbeChangeP2(v, addrCounter, regBase+n); @@ -157881,11 +154914,10 @@ sqlite3VdbeJumpHere(v, addrTop); sqlite3ReleaseTempReg(pParse, regRecord); /* Jump here when skipping the initialization */ sqlite3VdbeJumpHere(v, addrInit); - sqlite3VdbeScanStatusRange(v, addrExp, addrExp, -1); end_auto_index_create: sqlite3ExprDelete(pParse->db, pPartial); } #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ @@ -158067,14 +155099,26 @@ if( pTerm->wtFlags & TERM_VNULL ) continue; assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); assert( pTerm->u.x.leftColumn>=XN_ROWID ); assert( pTerm->u.x.leftColumnnCol ); - if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 - && !constraintCompatibleWithOuterJoin(pTerm,pSrc) - ){ - continue; + + /* tag-20191211-002: WHERE-clause constraints are not useful to the + ** right-hand table of a LEFT JOIN nor to the either table of a + ** RIGHT JOIN. See tag-20191211-001 for the + ** equivalent restriction for ordinary tables. */ + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){ + testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT ); + testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT ); + testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ ); + testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) ); + testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) ); + if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) + || pTerm->pExpr->w.iJoin != pSrc->iCursor + ){ + continue; + } } nTerm++; pTerm->wtFlags |= TERM_OK; } @@ -158309,11 +155353,11 @@ #ifndef SQLITE_DEBUG UNUSED_PARAMETER( pParse ); #endif assert( pRec!=0 ); assert( pIdx->nSample>0 ); - assert( pRec->nField>0 ); + assert( pRec->nField>0 && pRec->nField<=pIdx->nSampleCol ); /* Do a binary search to find the first sample greater than or equal ** to pRec. If pRec contains a single field, the set of samples to search ** is simply the aSample[] array. If the samples in aSample[] contain more ** than one fields, all fields following the first are ignored. @@ -158355,11 +155399,11 @@ ** appears that it should be 1 field in size. However, that would make it ** smaller than sample 1, so the binary search would not work. As a result, ** it is extended to two fields. The duplicates that this creates do not ** cause any problems. */ - nField = MIN(pRec->nField, pIdx->nSample); + nField = pRec->nField; iCol = 0; iSample = pIdx->nSample * nField; do{ int iSamp; /* Index in aSample[] of test sample */ int n; /* Number of fields in test sample */ @@ -158443,11 +155487,11 @@ /* At this point, the (iCol+1) field prefix of aSample[i] is the first ** sample that is greater than pRec. Or, if i==pIdx->nSample then pRec ** is larger than all samples in the array. */ tRowcnt iUpper, iGap; if( i>=pIdx->nSample ){ - iUpper = pIdx->nRowEst0; + iUpper = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]); }else{ iUpper = aSample[i].anLt[iCol]; } if( iLower>=iUpper ){ @@ -158599,11 +155643,11 @@ ** using the method described in the header comment for this function. */ if( nDiff!=1 || pUpper==0 || pLower==0 ){ int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff)); pLoop->nOut -= nAdjust; *pbDone = 1; - WHERETRACE(0x20, ("range skip-scan regions: %u..%u adjust=%d est=%d\n", + WHERETRACE(0x10, ("range skip-scan regions: %u..%u adjust=%d est=%d\n", nLower, nUpper, nAdjust*-1, pLoop->nOut)); } }else{ assert( *pbDone==0 ); @@ -158777,11 +155821,11 @@ nNew = 10; assert( 10==sqlite3LogEst(2) ); } if( nNewnOut>nOut ){ - WHERETRACE(0x20,("Range scan lowers nOut from %d to %d\n", + WHERETRACE(0x10,("Range scan lowers nOut from %d to %d\n", pLoop->nOut, nOut)); } #endif pLoop->nOut = (LogEst)nOut; return rc; @@ -158875,11 +155919,11 @@ if( rc!=SQLITE_OK ) return rc; if( bOk==0 ) return SQLITE_NOTFOUND; pBuilder->nRecValid = nEq; whereKeyStats(pParse, p, pRec, 0, a); - WHERETRACE(0x20,("equality scan regions %s(%d): %d\n", + WHERETRACE(0x10,("equality scan regions %s(%d): %d\n", p->zName, nEq-1, (int)a[1])); *pnRow = a[1]; return rc; } @@ -158925,11 +155969,11 @@ } if( rc==SQLITE_OK ){ if( nRowEst > nRow0 ) nRowEst = nRow0; *pnRow = nRowEst; - WHERETRACE(0x20,("IN row estimate: est=%d\n", nRowEst)); + WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst)); } assert( pBuilder->nRecValid==nRecValid ); return rc; } #endif /* SQLITE_ENABLE_STAT4 */ @@ -159034,11 +156078,11 @@ sqlite3DebugPrintf(" f %06x %d-%d", p->wsFlags, p->nLTerm,p->nSkip); }else{ sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm); } sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); - if( p->nLTerm && (sqlite3WhereTrace & 0x4000)!=0 ){ + if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ int i; for(i=0; inLTerm; i++){ sqlite3WhereTermPrint(p->aLTerm[i], i); } } @@ -159072,22 +156116,16 @@ } } } /* -** Deallocate internal memory used by a WhereLoop object. Leave the -** object in an initialized state, as if it had been newly allocated. +** Deallocate internal memory used by a WhereLoop object */ static void whereLoopClear(sqlite3 *db, WhereLoop *p){ - if( p->aLTerm!=p->aLTermSpace ){ - sqlite3DbFreeNN(db, p->aLTerm); - p->aLTerm = p->aLTermSpace; - p->nLSlot = ArraySize(p->aLTermSpace); - } + if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm); whereLoopClearUnion(db, p); - p->nLTerm = 0; - p->wsFlags = 0; + whereLoopInit(p); } /* ** Increase the memory allocation for pLoop->aLTerm[] to be at least n. */ @@ -159107,13 +156145,11 @@ /* ** Transfer content from the second pLoop into the first. */ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ whereLoopClearUnion(db, pTo); - if( pFrom->nLTerm > pTo->nLSlot - && whereLoopResize(db, pTo, pFrom->nLTerm) - ){ + if( whereLoopResize(db, pTo, pFrom->nLTerm) ){ memset(pTo, 0, WHERE_LOOP_XFER_SZ); return SQLITE_NOMEM_BKPT; } memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ); memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0])); @@ -159127,33 +156163,43 @@ /* ** Delete a WhereLoop object */ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ - assert( db!=0 ); whereLoopClear(db, p); - sqlite3DbNNFreeNN(db, p); + sqlite3DbFreeNN(db, p); } /* ** Free a WhereInfo structure */ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ assert( pWInfo!=0 ); - assert( db!=0 ); sqlite3WhereClauseClear(&pWInfo->sWC); while( pWInfo->pLoops ){ WhereLoop *p = pWInfo->pLoops; pWInfo->pLoops = p->pNextLoop; whereLoopDelete(db, p); } + assert( pWInfo->pExprMods==0 ); while( pWInfo->pMemToFree ){ WhereMemBlock *pNext = pWInfo->pMemToFree->pNext; - sqlite3DbNNFreeNN(db, pWInfo->pMemToFree); + sqlite3DbFreeNN(db, pWInfo->pMemToFree); pWInfo->pMemToFree = pNext; } - sqlite3DbNNFreeNN(db, pWInfo); + sqlite3DbFreeNN(db, pWInfo); +} + +/* Undo all Expr node modifications +*/ +static void whereUndoExprMods(WhereInfo *pWInfo){ + while( pWInfo->pExprMods ){ + WhereExprMod *p = pWInfo->pExprMods; + pWInfo->pExprMods = p->pNext; + memcpy(p->pExpr, &p->orig, sizeof(p->orig)); + sqlite3DbFree(pWInfo->pParse->db, p); + } } /* ** Return TRUE if all of the following are true: ** @@ -159498,11 +156544,10 @@ if( pX==0 ) continue; if( pX==pTerm ) break; if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; } if( j<0 ){ - sqlite3ProgressCheck(pWC->pWInfo->pParse); if( pLoop->maskSelf==pTerm->prereqAll ){ /* If there are extra terms in the WHERE clause not used by an index ** that depend only on the table being scanned, and that will tend to ** cause many rows to be omitted, then mark that table as ** "self-culling". @@ -159666,14 +156711,11 @@ LogEst rSize; /* Number of rows in the table */ LogEst rLogSize; /* Logarithm of table size */ WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ pNew = pBuilder->pNew; - assert( db->mallocFailed==0 || pParse->nErr>0 ); - if( pParse->nErr ){ - return pParse->rc; - } + if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d, rRun=%d\n", pProbe->pTable->zName,pProbe->zName, pNew->u.btree.nEq, pNew->nSkip, pNew->rRun)); assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 ); @@ -159720,15 +156762,36 @@ /* Do not allow the upper bound of a LIKE optimization range constraint ** to mix with a lower range bound from some other source */ if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; - if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 - && !constraintCompatibleWithOuterJoin(pTerm,pSrc) - ){ - continue; + /* tag-20191211-001: Do not allow constraints from the WHERE clause to + ** be used by the right table of a LEFT JOIN nor by the left table of a + ** RIGHT JOIN. Only constraints in the ON clause are allowed. + ** See tag-20191211-002 for the vtab equivalent. + ** + ** 2022-06-06: See https://sqlite.org/forum/forumpost/206d99a16dd9212f + ** for an example of a WHERE clause constraints that may not be used on + ** the right table of a RIGHT JOIN because the constraint implies a + ** not-NULL condition on the left table of the RIGHT JOIN. + ** + ** 2022-06-10: The same condition applies to termCanDriveIndex() above. + ** https://sqlite.org/forum/forumpost/51e6959f61 + */ + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){ + testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT ); + testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT ); + testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ ); + testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) + testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) ); + if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) + || pTerm->pExpr->w.iJoin != pSrc->iCursor + ){ + continue; + } } + if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){ pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE; }else{ pBuilder->bldFlags1 |= SQLITE_BLDF1_INDEXED; } @@ -159735,15 +156798,11 @@ pNew->wsFlags = saved_wsFlags; pNew->u.btree.nEq = saved_nEq; pNew->u.btree.nBtm = saved_nBtm; pNew->u.btree.nTop = saved_nTop; pNew->nLTerm = saved_nLTerm; - if( pNew->nLTerm>=pNew->nLSlot - && whereLoopResize(db, pNew, pNew->nLTerm+1) - ){ - break; /* OOM while trying to enlarge the pNew->aLTerm array */ - } + if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ pNew->aLTerm[pNew->nLTerm++] = pTerm; pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf; assert( nInMul==0 || (pNew->wsFlags & WHERE_COLUMN_NULL)!=0 @@ -159832,43 +156891,42 @@ } } if( scan.iEquiv>1 ) pNew->wsFlags |= WHERE_TRANSCONS; }else if( eOp & WO_ISNULL ){ pNew->wsFlags |= WHERE_COLUMN_NULL; + }else if( eOp & (WO_GT|WO_GE) ){ + testcase( eOp & WO_GT ); + testcase( eOp & WO_GE ); + pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; + pNew->u.btree.nBtm = whereRangeVectorLen( + pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm + ); + pBtm = pTerm; + pTop = 0; + if( pTerm->wtFlags & TERM_LIKEOPT ){ + /* Range constraints that come from the LIKE optimization are + ** always used in pairs. */ + pTop = &pTerm[1]; + assert( (pTop-(pTerm->pWC->a))pWC->nTerm ); + assert( pTop->wtFlags & TERM_LIKEOPT ); + assert( pTop->eOperator==WO_LT ); + if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ + pNew->aLTerm[pNew->nLTerm++] = pTop; + pNew->wsFlags |= WHERE_TOP_LIMIT; + pNew->u.btree.nTop = 1; + } }else{ - int nVecLen = whereRangeVectorLen( + assert( eOp & (WO_LT|WO_LE) ); + testcase( eOp & WO_LT ); + testcase( eOp & WO_LE ); + pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; + pNew->u.btree.nTop = whereRangeVectorLen( pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm ); - if( eOp & (WO_GT|WO_GE) ){ - testcase( eOp & WO_GT ); - testcase( eOp & WO_GE ); - pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; - pNew->u.btree.nBtm = nVecLen; - pBtm = pTerm; - pTop = 0; - if( pTerm->wtFlags & TERM_LIKEOPT ){ - /* Range constraints that come from the LIKE optimization are - ** always used in pairs. */ - pTop = &pTerm[1]; - assert( (pTop-(pTerm->pWC->a))pWC->nTerm ); - assert( pTop->wtFlags & TERM_LIKEOPT ); - assert( pTop->eOperator==WO_LT ); - if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ - pNew->aLTerm[pNew->nLTerm++] = pTop; - pNew->wsFlags |= WHERE_TOP_LIMIT; - pNew->u.btree.nTop = 1; - } - }else{ - assert( eOp & (WO_LT|WO_LE) ); - testcase( eOp & WO_LT ); - testcase( eOp & WO_LE ); - pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; - pNew->u.btree.nTop = nVecLen; - pTop = pTerm; - pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? - pNew->aLTerm[pNew->nLTerm-2] : 0; - } + pTop = pTerm; + pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? + pNew->aLTerm[pNew->nLTerm-2] : 0; } /* At this point pNew->nOut is set to the number of rows expected to ** be visited by the index scan before considering term pTerm, or the ** values of nIn and nInMul. In other words, assuming that all @@ -159916,11 +156974,11 @@ ** to be true for half or more of the rows in the table. ** See tag-202002240-1 */ && pNew->nOut+10 > pProbe->aiRowLogEst[0] ){ #if WHERETRACE_ENABLED /* 0x01 */ - if( sqlite3WhereTrace & 0x20 ){ + if( sqlite3WhereTrace & 0x01 ){ sqlite3DebugPrintf( "STAT4 determines term has low selectivity:\n"); sqlite3WhereTermPrint(pTerm, 999); } #endif @@ -159953,21 +157011,13 @@ /* Set rCostIdx to the cost of visiting selected rows in index. Add ** it to pNew->rRun, which is currently set to the cost of the index ** seek only. Then, if this is a non-covering index, add the cost of ** visiting the rows in the main table. */ 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. 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; - }else{ - rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; - } + rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); - if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){ + if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); } ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); nOutUnadjusted = pNew->nOut; @@ -159985,13 +157035,10 @@ if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 && pNew->u.btree.nEqnColumn && (pNew->u.btree.nEqnKeyCol || pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY) ){ - if( pNew->u.btree.nEq>3 ){ - sqlite3ProgressCheck(pParse); - } whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); } pNew->nOut = saved_nOut; #ifdef SQLITE_ENABLE_STAT4 pBuilder->nRecValid = nRecValid; @@ -160119,153 +157166,10 @@ } } return 0; } -/* -** pIdx is an index containing expressions. Check it see if any of the -** expressions in the index match the pExpr expression. -*/ -static int exprIsCoveredByIndex( - const Expr *pExpr, - const Index *pIdx, - int iTabCur -){ - int i; - for(i=0; inColumn; i++){ - if( pIdx->aiColumn[i]==XN_EXPR - && sqlite3ExprCompare(0, pExpr, pIdx->aColExpr->a[i].pExpr, iTabCur)==0 - ){ - return 1; - } - } - return 0; -} - -/* -** Structure passed to the whereIsCoveringIndex Walker callback. -*/ -typedef struct CoveringIndexCheck CoveringIndexCheck; -struct CoveringIndexCheck { - Index *pIdx; /* The index */ - int iTabCur; /* Cursor number for the corresponding table */ - u8 bExpr; /* Uses an indexed expression */ - u8 bUnidx; /* Uses an unindexed column not within an indexed expr */ -}; - -/* -** Information passed in is pWalk->u.pCovIdxCk. Call it pCk. -** -** If the Expr node references the table with cursor pCk->iTabCur, then -** make sure that column is covered by the index pCk->pIdx. We know that -** all columns less than 63 (really BMS-1) are covered, so we don't need -** to check them. But we do need to check any column at 63 or greater. -** -** If the index does not cover the column, then set pWalk->eCode to -** non-zero and return WRC_Abort to stop the search. -** -** If this node does not disprove that the index can be a covering index, -** then just return WRC_Continue, to continue the search. -** -** If pCk->pIdx contains indexed expressions and one of those expressions -** matches pExpr, then prune the search. -*/ -static int whereIsCoveringIndexWalkCallback(Walker *pWalk, Expr *pExpr){ - int i; /* Loop counter */ - const Index *pIdx; /* The index of interest */ - const i16 *aiColumn; /* Columns contained in the index */ - u16 nColumn; /* Number of columns in the index */ - CoveringIndexCheck *pCk; /* Info about this search */ - - pCk = pWalk->u.pCovIdxCk; - pIdx = pCk->pIdx; - if( (pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN) ){ - /* if( pExpr->iColumn<(BMS-1) && pIdx->bHasExpr==0 ) return WRC_Continue;*/ - if( pExpr->iTable!=pCk->iTabCur ) return WRC_Continue; - pIdx = pWalk->u.pCovIdxCk->pIdx; - aiColumn = pIdx->aiColumn; - nColumn = pIdx->nColumn; - for(i=0; iiColumn ) return WRC_Continue; - } - pCk->bUnidx = 1; - return WRC_Abort; - }else if( pIdx->bHasExpr - && exprIsCoveredByIndex(pExpr, pIdx, pWalk->u.pCovIdxCk->iTabCur) ){ - pCk->bExpr = 1; - return WRC_Prune; - } - return WRC_Continue; -} - - -/* -** pIdx is an index that covers all of the low-number columns used by -** pWInfo->pSelect (columns from 0 through 62) or an index that has -** expressions terms. Hence, we cannot determine whether or not it is -** a covering index by using the colUsed bitmasks. We have to do a search -** to see if the index is covering. This routine does that search. -** -** The return value is one of these: -** -** 0 The index is definitely not a covering index -** -** WHERE_IDX_ONLY The index is definitely a covering index -** -** WHERE_EXPRIDX The index is likely a covering index, but it is -** difficult to determine precisely because of the -** expressions that are indexed. Score it as a -** covering index, but still keep the main table open -** just in case we need it. -** -** This routine is an optimization. It is always safe to return zero. -** But returning one of the other two values when zero should have been -** returned can lead to incorrect bytecode and assertion faults. -*/ -static SQLITE_NOINLINE u32 whereIsCoveringIndex( - WhereInfo *pWInfo, /* The WHERE clause context */ - Index *pIdx, /* Index that is being tested */ - int iTabCur /* Cursor for the table being indexed */ -){ - int i, rc; - struct CoveringIndexCheck ck; - Walker w; - if( pWInfo->pSelect==0 ){ - /* We don't have access to the full query, so we cannot check to see - ** if pIdx is covering. Assume it is not. */ - return 0; - } - if( pIdx->bHasExpr==0 ){ - for(i=0; inColumn; i++){ - if( pIdx->aiColumn[i]>=BMS-1 ) break; - } - if( i>=pIdx->nColumn ){ - /* pIdx does not index any columns greater than 62, but we know from - ** colMask that columns greater than 62 are used, so this is not a - ** covering index */ - return 0; - } - } - ck.pIdx = pIdx; - ck.iTabCur = iTabCur; - ck.bExpr = 0; - ck.bUnidx = 0; - memset(&w, 0, sizeof(w)); - w.xExprCallback = whereIsCoveringIndexWalkCallback; - w.xSelectCallback = sqlite3SelectWalkNoop; - w.u.pCovIdxCk = &ck; - sqlite3WalkSelect(&w, pWInfo->pSelect); - if( ck.bUnidx ){ - rc = 0; - }else if( ck.bExpr ){ - rc = WHERE_EXPRIDX; - }else{ - rc = WHERE_IDX_ONLY; - } - return rc; -} - /* ** 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 ** a b-tree table, not a virtual table. ** @@ -160344,11 +157248,11 @@ sPk.nColumn = 1; sPk.aiColumn = &aiColumnPk; sPk.aiRowLogEst = aiRowEstPk; sPk.onError = OE_Replace; sPk.pTable = pTab; - sPk.szIdxRow = 3; /* TUNING: Interior rows of IPK table are very small */ + sPk.szIdxRow = pTab->szTabRow; sPk.idxType = SQLITE_IDXTYPE_IPK; aiRowEstPk[0] = pTab->nRowLogEst; aiRowEstPk[1] = 0; pFirst = pSrc->pTab->pIndex; if( pSrc->fg.notIndexed==0 ){ @@ -160395,12 +157299,11 @@ ** indexes on subqueries and views. */ pNew->rSetup = rLogSize + rSize; if( !IsView(pTab) && (pTab->tabFlags & TF_Ephemeral)==0 ){ pNew->rSetup += 28; }else{ - pNew->rSetup -= 25; /* Greatly reduced setup cost for auto indexes - ** on ephemeral materializations of views */ + pNew->rSetup -= 10; } ApplyCostMultiplier(pNew->rSetup, pTab->costMult); if( pNew->rSetup<0 ) pNew->rSetup = 0; /* TUNING: Each index lookup yields 20 rows in the table. This ** is more than the usual guess of 10 rows, since we have no way @@ -160465,53 +157368,23 @@ #ifdef SQLITE_ENABLE_STAT4 pNew->rRun = rSize + 16 - 2*((pTab->tabFlags & TF_HasStat4)!=0); #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); pNew->nOut = rSize; if( rc ) break; }else{ Bitmask m; if( pProbe->isCovering ){ - m = 0; pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; + m = 0; }else{ m = pSrc->colUsed & pProbe->colNotIdxed; - pNew->wsFlags = WHERE_INDEXED; - if( m==TOPBIT || (pProbe->bHasExpr && !pProbe->bHasVCol && m!=0) ){ - u32 isCov = whereIsCoveringIndex(pWInfo, pProbe, pSrc->iCursor); - if( isCov==0 ){ - WHERETRACE(0x200, - ("-> %s is not a covering index" - " according to whereIsCoveringIndex()\n", pProbe->zName)); - assert( m!=0 ); - }else{ - m = 0; - pNew->wsFlags |= isCov; - if( isCov & WHERE_IDX_ONLY ){ - WHERETRACE(0x200, - ("-> %s is a covering expression index" - " according to whereIsCoveringIndex()\n", pProbe->zName)); - }else{ - assert( isCov==WHERE_EXPRIDX ); - WHERETRACE(0x200, - ("-> %s might be a covering expression index" - " according to whereIsCoveringIndex()\n", pProbe->zName)); - } - } - }else if( m==0 ){ - WHERETRACE(0x200, - ("-> %s a covering index according to bitmasks\n", - pProbe->zName, m==0 ? "is" : "is not")); - pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; - } + pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED; } /* Full scan via index */ if( b || !HasRowid(pTab) @@ -160680,11 +157553,11 @@ if( rc==SQLITE_CONSTRAINT ){ /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means ** that the particular combination of parameters provided is unusable. ** Make no entries in the loop table. */ - WHERETRACE(0xffffffff, (" ^^^^--- non-viable plan rejected!\n")); + WHERETRACE(0xffff, (" ^^^^--- non-viable plan rejected!\n")); return SQLITE_OK; } return rc; } @@ -160791,11 +157664,11 @@ rc = whereLoopInsert(pBuilder, pNew); if( pNew->u.vtab.needFree ){ sqlite3_free(pNew->u.vtab.idxStr); pNew->u.vtab.needFree = 0; } - WHERETRACE(0xffffffff, (" bIn=%d prereqIn=%04llx prereqOut=%04llx\n", + WHERETRACE(0xffff, (" bIn=%d prereqIn=%04llx prereqOut=%04llx\n", *pbIn, (sqlite3_uint64)mPrereq, (sqlite3_uint64)(pNew->prereq & ~mPrereq))); return rc; } @@ -160896,11 +157769,11 @@ #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ && !defined(SQLITE_OMIT_VIRTUALTABLE) /* ** Cause the prepared statement that is associated with a call to -** xBestIndex to potentially use all schemas. If the statement being +** xBestIndex to potentiall use all schemas. If the statement being ** prepared is read-only, then just start read transactions on all ** schemas. But if this is a write operation, start writes on all ** schemas. ** ** This is used by the (built-in) sqlite_dbpage virtual table. @@ -160911,11 +157784,11 @@ int nDb = pParse->db->nDb; int i; for(i=0; iwriteMask) ){ + if( pParse->writeMask ){ for(i=0; ipTab->zName)); - WHERETRACE(0x800, (" VirtualOne: all usable\n")); + WHERETRACE(0x40, (" VirtualOne: all usable\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry ); if( bRetry ){ assert( rc==SQLITE_OK ); @@ -161008,11 +157881,11 @@ Bitmask mBestNoIn = 0; /* If the plan produced by the earlier call uses an IN(...) term, call ** xBestIndex again, this time with IN(...) terms disabled. */ if( bIn ){ - WHERETRACE(0x800, (" VirtualOne: all usable w/o IN\n")); + WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0); assert( bIn==0 ); mBestNoIn = pNew->prereq & ~mPrereq; if( mBestNoIn==0 ){ @@ -161034,11 +157907,11 @@ if( mThis>mPrev && mThisprereq==mPrereq ){ seenZero = 1; @@ -161048,21 +157921,21 @@ /* If the calls to xBestIndex() in the above loop did not find a plan ** that requires no source tables at all (i.e. one guaranteed to be ** usable), make a call here with all source tables disabled */ if( rc==SQLITE_OK && seenZero==0 ){ - WHERETRACE(0x800, (" VirtualOne: all disabled\n")); + WHERETRACE(0x40, (" VirtualOne: all disabled\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0); if( bIn==0 ) seenZeroNoIN = 1; } /* If the calls to xBestIndex() have so far failed to find a plan ** that requires no source tables at all and does not use an IN(...) ** operator, make a final call to obtain one here. */ if( rc==SQLITE_OK && seenZeroNoIN==0 ){ - WHERETRACE(0x800, (" VirtualOne: all disabled and w/o IN\n")); + WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0); } } @@ -161114,11 +157987,11 @@ int i, j; sSubBuild = *pBuilder; sSubBuild.pOrSet = &sCur; - WHERETRACE(0x400, ("Begin processing OR-clause %p\n", pTerm)); + WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm)); for(pOrTerm=pOrWC->a; pOrTermeOperator & WO_AND)!=0 ){ sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc; }else if( pOrTerm->leftCursor==iCur ){ tempWC.pWInfo = pWC->pWInfo; @@ -161131,13 +158004,13 @@ }else{ continue; } sCur.n = 0; #ifdef WHERETRACE_ENABLED - WHERETRACE(0x400, ("OR-term %d of %p has %d subterms:\n", + WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n", (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm)); - if( sqlite3WhereTrace & 0x20000 ){ + if( sqlite3WhereTrace & 0x400 ){ sqlite3WhereClausePrint(sSubBuild.pWC); } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ @@ -161148,10 +158021,12 @@ rc = whereLoopAddBtree(&sSubBuild, mPrereq); } if( rc==SQLITE_OK ){ rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable); } + assert( rc==SQLITE_OK || rc==SQLITE_DONE || sCur.n==0 + || rc==SQLITE_NOMEM ); testcase( rc==SQLITE_NOMEM && sCur.n>0 ); testcase( rc==SQLITE_DONE ); if( sCur.n==0 ){ sSum.n = 0; break; @@ -161193,11 +158068,11 @@ pNew->rRun = sSum.a[i].rRun + 1; pNew->nOut = sSum.a[i].nOut; pNew->prereq = sSum.a[i].prereq; rc = whereLoopInsert(pBuilder, pNew); } - WHERETRACE(0x400, ("End processing OR-clause %p\n", pTerm)); + WHERETRACE(0x200, ("End processing OR-clause %p\n", pTerm)); } } return rc; } @@ -161213,23 +158088,16 @@ SrcItem *pItem; SrcItem *pEnd = &pTabList->a[pWInfo->nLevel]; sqlite3 *db = pWInfo->pParse->db; int rc = SQLITE_OK; int bFirstPastRJ = 0; - int hasRightJoin = 0; WhereLoop *pNew; /* Loop over the tables in the join, from left to right */ pNew = pBuilder->pNew; - - /* Verify that pNew has already been initialized */ - assert( pNew->nLTerm==0 ); - assert( pNew->wsFlags==0 ); - assert( pNew->nLSlot>=ArraySize(pNew->aLTermSpace) ); - assert( pNew->aLTerm!=0 ); - + whereLoopInit(pNew); pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT; for(iTab=0, pItem=pTabList->a; pItemiTab = iTab; pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR; @@ -161240,20 +158108,19 @@ /* Add prerequisites to prevent reordering of FROM clause terms ** across CROSS joins and outer joins. The bFirstPastRJ boolean ** prevents the right operand of a RIGHT JOIN from being swapped with ** other elements even further to the right. ** - ** The JT_LTORJ case and the hasRightJoin flag work together to - ** prevent FROM-clause terms from moving from the right side of - ** a LEFT JOIN over to the left side of that join if the LEFT JOIN - ** is itself on the left side of a RIGHT JOIN. + ** The JT_LTORJ term prevents any FROM-clause term reordering for terms + ** to the left of a RIGHT JOIN. This is conservative. Relaxing this + ** constraint somewhat to prevent terms from crossing from the right + ** side of a LEFT JOIN over to the left side when they are on the + ** left side of a RIGHT JOIN would be sufficient for all known failure + ** cases. FIX ME: Implement this optimization. */ - if( pItem->fg.jointype & JT_LTORJ ) hasRightJoin = 1; mPrereq |= mPrior; bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0; - }else if( !hasRightJoin ){ - mPrereq = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ SrcItem *p; for(p=&pItem[1]; p=XN_ROWID ){ if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) continue; if( pOBExpr->iTable!=iCur ) continue; if( pOBExpr->iColumn!=iColumn ) continue; }else{ - Expr *pIxExpr = pIndex->aColExpr->a[j].pExpr; - if( sqlite3ExprCompareSkip(pOBExpr, pIxExpr, iCur) ){ + Expr *pIdxExpr = pIndex->aColExpr->a[j].pExpr; + if( sqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){ continue; } } if( iColumn!=XN_ROWID ){ pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); @@ -161674,60 +158541,41 @@ ** Return the cost of sorting nRow rows, assuming that the keys have ** nOrderby columns and that the first nSorted columns are already in ** order. */ static LogEst whereSortingCost( - WhereInfo *pWInfo, /* Query planning context */ - LogEst nRow, /* Estimated number of rows to sort */ - int nOrderBy, /* Number of ORDER BY clause terms */ - int nSorted /* Number of initial ORDER BY terms naturally in order */ + WhereInfo *pWInfo, + LogEst nRow, + int nOrderBy, + int nSorted ){ - /* Estimated cost of a full external sort, where N is + /* TUNING: Estimated cost of a full external sort, where N is ** the number of rows to sort is: ** - ** cost = (K * N * log(N)). + ** cost = (3.0 * N * log(N)). ** ** Or, if the order-by clause has X terms but only the last Y ** terms are out of order, then block-sorting will reduce the ** sorting cost to: ** - ** cost = (K * N * log(N)) * (Y/X) - ** - ** The constant K is at least 2.0 but will be larger if there are a - ** large number of columns to be sorted, as the sorting time is - ** proportional to the amount of content to be sorted. The algorithm - ** does not currently distinguish between fat columns (BLOBs and TEXTs) - ** and skinny columns (INTs). It just uses the number of columns as - ** an approximation for the row width. - ** - ** And extra factor of 2.0 or 3.0 is added to the sorting cost if the sort - ** is built using OP_IdxInsert and OP_Sort rather than with OP_SorterInsert. - */ - LogEst rSortCost, nCol; - assert( pWInfo->pSelect!=0 ); - assert( pWInfo->pSelect->pEList!=0 ); - /* TUNING: sorting cost proportional to the number of output columns: */ - nCol = sqlite3LogEst((pWInfo->pSelect->pEList->nExpr+59)/30); - rSortCost = nRow + nCol; - if( nSorted>0 ){ - /* Scale the result by (Y/X) */ - rSortCost += sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; - } + ** cost = (3.0 * N * log(N)) * (Y/X) + ** + ** The (Y/X) term is implemented using stack variable rScale + ** below. + */ + LogEst rScale, rSortCost; + assert( nOrderBy>0 && 66==sqlite3LogEst(100) ); + rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; + rSortCost = nRow + rScale + 16; /* Multiple by log(M) where M is the number of output rows. ** Use the LIMIT for M if it is smaller. Or if this sort is for ** a DISTINCT operator, M will be the number of distinct output ** rows, so fudge it downwards a bit. */ - if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 ){ - rSortCost += 10; /* TUNING: Extra 2.0x if using LIMIT */ - if( nSorted!=0 ){ - rSortCost += 6; /* TUNING: Extra 1.5x if also using partial sort */ - } - if( pWInfo->iLimitiLimit; - } + if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimitiLimit; }else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){ /* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT ** reduces the number of output rows by a factor of 2 */ if( nRow>10 ){ nRow -= 10; assert( 10==sqlite3LogEst(2) ); } } @@ -161749,10 +158597,11 @@ */ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ int mxChoice; /* Maximum number of simultaneous paths tracked */ int nLoop; /* Number of terms in the join */ Parse *pParse; /* Parsing context */ + sqlite3 *db; /* The database connection */ int iLoop; /* Loop counter over the terms of the join */ int ii, jj; /* Loop counters */ int mxI = 0; /* Index of next entry to replace */ int nOrderBy; /* Number of ORDER BY clause terms */ LogEst mxCost = 0; /* Maximum cost of a set of paths */ @@ -161767,10 +158616,11 @@ LogEst *aSortCost = 0; /* Sorting and partial sorting costs */ char *pSpace; /* Temporary memory used by this routine */ int nSpace; /* Bytes of space allocated at pSpace */ pParse = pWInfo->pParse; + db = pParse->db; nLoop = pWInfo->nLevel; /* TUNING: For simple queries, only the best path is tracked. ** For 2-way joins, the 5 best paths are followed. ** For joins of 3 or more tables, track the 10 best paths */ mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); @@ -161789,11 +158639,11 @@ } /* Allocate and initialize space for aTo, aFrom and aSortCost[] */ nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2; nSpace += sizeof(LogEst) * nOrderBy; - pSpace = sqlite3StackAllocRawNN(pParse->db, nSpace); + pSpace = sqlite3DbMallocRawNN(db, nSpace); if( pSpace==0 ) return SQLITE_NOMEM_BKPT; aTo = (WherePath*)pSpace; aFrom = aTo+mxChoice; memset(aFrom, 0, sizeof(aFrom[0])); pX = (WhereLoop**)(aFrom+mxChoice); @@ -161839,13 +158689,13 @@ for(ii=0, pFrom=aFrom; iipLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ LogEst nOut; /* Rows visited by (pFrom+pWLoop) */ LogEst rCost; /* Cost of path (pFrom+pWLoop) */ LogEst rUnsorted; /* Unsorted cost of (pFrom+pWLoop) */ - i8 isOrdered; /* isOrdered for (pFrom+pWLoop) */ + i8 isOrdered = pFrom->isOrdered; /* isOrdered for (pFrom+pWLoop) */ Bitmask maskNew; /* Mask of src visited by (..) */ - Bitmask revMask; /* Mask of rev-order loops for (..) */ + Bitmask revMask = 0; /* Mask of rev-order loops for (..) */ if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){ /* Do not use an automatic index if the this loop is expected @@ -161860,13 +158710,11 @@ ** Compute its cost */ rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); nOut = pFrom->nRow + pWLoop->nOut; maskNew = pFrom->maskLoop | pWLoop->maskSelf; - isOrdered = pFrom->isOrdered; if( isOrdered<0 ){ - revMask = 0; isOrdered = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, iLoop, pWLoop, &revMask); }else{ revMask = pFrom->revLoop; @@ -161875,15 +158723,15 @@ if( aSortCost[isOrdered]==0 ){ aSortCost[isOrdered] = whereSortingCost( pWInfo, nRowEst, nOrderBy, isOrdered ); } - /* TUNING: Add a small extra penalty (3) to sorting as an + /* TUNING: Add a small extra penalty (5) to sorting as an ** 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; + rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5; WHERETRACE(0x002, ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", aSortCost[isOrdered], (nOrderBy-isOrdered), nOrderBy, rUnsorted, rCost)); @@ -161890,17 +158738,10 @@ }else{ rCost = rUnsorted; 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. ** ** First look for an existing path among best-so-far paths ** that covers the same set of loops and has the same isOrdered @@ -162047,11 +158888,11 @@ nFrom = nTo; } if( nFrom==0 ){ sqlite3ErrorMsg(pParse, "no query solution"); - sqlite3StackFreeNN(pParse->db, pSpace); + sqlite3DbFreeNN(db, pSpace); return SQLITE_ERROR; } /* Find the lowest cost path. pFrom will be left pointing to that path */ pFrom = aFrom; @@ -162129,11 +158970,11 @@ pWInfo->nRowOut = pFrom->nRow; /* Free temporary memory and return success */ - sqlite3StackFreeNN(pParse->db, pSpace); + sqlite3DbFreeNN(db, pSpace); return SQLITE_OK; } /* ** Most queries use only a single table (they are not joins) and have @@ -162227,11 +159068,11 @@ if( scan.iEquiv>1 ) pLoop->wsFlags |= WHERE_TRANSCONS; #ifdef SQLITE_DEBUG pLoop->cId = '0'; #endif #ifdef WHERETRACE_ENABLED - if( sqlite3WhereTrace & 0x02 ){ + if( sqlite3WhereTrace ){ sqlite3DebugPrintf("whereShortCut() used to compute solution\n"); } #endif return 1; } @@ -162357,11 +159198,11 @@ break; } } } if( pTerm drop loop %c not used\n", pLoop->cId)); + WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId)); notReady &= ~pLoop->maskSelf; for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ pTerm->wtFlags |= TERM_CODED; } @@ -162396,31 +159237,32 @@ */ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( const WhereInfo *pWInfo ){ int i; - LogEst nSearch = 0; + LogEst nSearch; assert( pWInfo->nLevel>=2 ); assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) ); - for(i=0; inLevel; i++){ + nSearch = pWInfo->a[0].pWLoop->nOut; + for(i=1; inLevel; i++){ WhereLoop *pLoop = pWInfo->a[i].pWLoop; const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); - SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; - Table *pTab = pItem->pTab; - if( (pTab->tabFlags & TF_HasStat1)==0 ) break; - pTab->tabFlags |= TF_StatsUsed; - if( i>=1 - && (pLoop->wsFlags & reqFlags)==reqFlags + if( (pLoop->wsFlags & reqFlags)==reqFlags /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ && ALWAYS((pLoop->wsFlags & (WHERE_IPK|WHERE_INDEXED))!=0) ){ - if( nSearch > pTab->nRowLogEst ){ + SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; + Table *pTab = pItem->pTab; + pTab->tabFlags |= TF_StatsUsed; + if( nSearch > pTab->nRowLogEst + && (pTab->tabFlags & TF_HasStat1)!=0 + ){ testcase( pItem->fg.jointype & JT_LEFT ); pLoop->wsFlags |= WHERE_BLOOMFILTER; pLoop->wsFlags &= ~WHERE_IDX_ONLY; - WHERETRACE(0xffffffff, ( + WHERETRACE(0xffff, ( "-> use Bloom-filter on loop %c because there are ~%.1e " "lookups into %s which has only ~%.1e rows\n", pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName, (double)sqlite3LogEstToInt(pTab->nRowLogEst))); } @@ -162427,87 +159269,10 @@ } nSearch += pLoop->nOut; } } -/* -** 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 -** number for the index and iDataCur is the cursor number for the corresponding -** table. -** -** This routine adds IndexedExpr entries to the Parse->pIdxEpr field for -** each of the expressions in the index so that the expression code generator -** will know to replace occurrences of the indexed expression with -** references to the corresponding column of the index. -*/ -static SQLITE_NOINLINE void whereAddIndexedExpr( - Parse *pParse, /* Add IndexedExpr entries to pParse->pIdxEpr */ - Index *pIdx, /* The index-on-expression that contains the expressions */ - int iIdxCur, /* Cursor number for pIdx */ - SrcItem *pTabItem /* The FROM clause entry for the table */ -){ - int i; - IndexedExpr *p; - Table *pTab; - assert( pIdx->bHasExpr ); - pTab = pIdx->pTable; - for(i=0; inColumn; i++){ - Expr *pExpr; - int j = pIdx->aiColumn[i]; - int bMaybeNullRow; - if( j==XN_EXPR ){ - pExpr = pIdx->aColExpr->a[i].pExpr; - testcase( pTabItem->fg.jointype & JT_LEFT ); - testcase( pTabItem->fg.jointype & JT_RIGHT ); - testcase( pTabItem->fg.jointype & JT_LTORJ ); - bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0; - }else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){ - pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]); - bMaybeNullRow = 0; - }else{ - continue; - } - if( sqlite3ExprIsConstant(pExpr) ) continue; - p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); - if( p==0 ) break; - p->pIENext = pParse->pIdxEpr; -#ifdef WHERETRACE_ENABLED - if( sqlite3WhereTrace & 0x200 ){ - sqlite3DebugPrintf("New pParse->pIdxEpr term {%d,%d}\n", iIdxCur, i); - if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(pExpr); - } -#endif - p->pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); - p->iDataCur = pTabItem->iCursor; - p->iIdxCur = iIdxCur; - p->iIdxCol = i; - p->bMaybeNullRow = bMaybeNullRow; -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - p->zIdxName = pIdx->zName; -#endif - pParse->pIdxEpr = p; - if( p->pIENext==0 ){ - sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pParse); - } - } -} - /* ** Generate the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an opaque structure that contains ** information needed to terminate the loop. Later, the calling routine ** should invoke sqlite3WhereEnd() with the return value of this function @@ -162598,11 +159363,11 @@ Parse *pParse, /* The parser context */ SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ Expr *pWhere, /* The WHERE clause */ ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */ - Select *pSelect, /* The entire SELECT statement */ + Select *pLimit, /* Use this LIMIT/OFFSET clause, if any */ u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */ int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number ** If WHERE_USE_LIMIT, then the limit amount */ ){ int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ @@ -162667,21 +159432,21 @@ goto whereBeginError; } pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; pWInfo->pOrderBy = pOrderBy; -#if WHERETRACE_ENABLED pWInfo->pWhere = pWhere; -#endif pWInfo->pResultSet = pResultSet; pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; pWInfo->nLevel = nTabList; pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse); pWInfo->wctrlFlags = wctrlFlags; pWInfo->iLimit = iAuxArg; pWInfo->savedNQueryLoop = pParse->nQueryLoop; - pWInfo->pSelect = pSelect; +#ifndef SQLITE_OMIT_VIRTUALTABLE + pWInfo->pLimit = pLimit; +#endif memset(&pWInfo->nOBSat, 0, offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat)); memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel)); assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */ pMaskSet = &pWInfo->sMaskSet; @@ -162746,14 +159511,12 @@ #endif } /* Analyze all of the subexpressions. */ sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); - if( pSelect && pSelect->pLimit ){ - sqlite3WhereAddLimit(&pWInfo->sWC, pSelect); - } - if( pParse->nErr ) goto whereBeginError; + sqlite3WhereAddLimit(&pWInfo->sWC, pLimit); + if( db->mallocFailed ) goto whereBeginError; /* Special case: WHERE terms that do not refer to any tables in the join ** (constant expressions). Evaluate each such term, and jump over all the ** generated code if the result is not true. ** @@ -162789,30 +159552,30 @@ } } /* Construct the WhereLoop objects */ #if defined(WHERETRACE_ENABLED) - if( sqlite3WhereTrace & 0xffffffff ){ + if( sqlite3WhereTrace & 0xffff ){ sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags); if( wctrlFlags & WHERE_USE_LIMIT ){ sqlite3DebugPrintf(", limit: %d", iAuxArg); } sqlite3DebugPrintf(")\n"); - if( sqlite3WhereTrace & 0x8000 ){ + if( sqlite3WhereTrace & 0x100 ){ Select sSelect; memset(&sSelect, 0, sizeof(sSelect)); sSelect.selFlags = SF_WhereBegin; sSelect.pSrc = pTabList; sSelect.pWhere = pWhere; sSelect.pOrderBy = pOrderBy; sSelect.pEList = pResultSet; sqlite3TreeViewSelect(0, &sSelect, 0); } - if( sqlite3WhereTrace & 0x4000 ){ /* Display all WHERE clause terms */ - sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n"); - sqlite3WhereClausePrint(sWLB.pWC); - } + } + if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ + sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n"); + sqlite3WhereClausePrint(sWLB.pWC); } #endif if( nTabList!=1 || whereShortCut(&sWLB)==0 ){ rc = whereLoopAddAll(&sWLB); @@ -162824,11 +159587,11 @@ ** changed based on STAT4 information while computing subsequent loops, ** then we need to rerun the whole loop building process so that all ** loops will be built using the revised truthProb values. */ if( sWLB.bldFlags2 & SQLITE_BLDF2_2NDPASS ){ WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); - WHERETRACE(0xffffffff, + WHERETRACE(0xffff, ("**** Redo all loop computations due to" " TERM_HIGHTRUTH changes ****\n")); while( pWInfo->pLoops ){ WhereLoop *p = pWInfo->pLoops; pWInfo->pLoops = p->pNextLoop; @@ -162910,15 +159673,15 @@ ){ whereCheckIfBloomFilterIsUseful(pWInfo); } #if defined(WHERETRACE_ENABLED) - if( sqlite3WhereTrace & 0x4000 ){ /* Display all terms of the WHERE clause */ + if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n"); sqlite3WhereClausePrint(sWLB.pWC); } - WHERETRACE(0xffffffff,("*** Optimizer Finished ***\n")); + WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); #endif pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; /* If the caller is an UPDATE or DELETE statement that is requesting ** to use a one-pass algorithm, determine if this is appropriate. @@ -163051,13 +159814,10 @@ }else if( iAuxArg && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ){ iIndexCur = iAuxArg; op = OP_ReopenIdx; }else{ iIndexCur = pParse->nTab++; - if( pIx->bHasExpr && OptimizationEnabled(db, SQLITE_IndexedExpr) ){ - whereAddIndexedExpr(pParse, pIx, iIndexCur, pTabItem); - } } pLevel->iIdxCur = iIndexCur; assert( pIx!=0 ); assert( pIx->pSchema==pTab->pSchema ); assert( iIndexCur>=0 ); @@ -163176,10 +159936,12 @@ return pWInfo; /* Jump here if malloc fails */ whereBeginError: if( pWInfo ){ + testcase( pWInfo->pExprMods!=0 ); + whereUndoExprMods(pWInfo); pParse->nQueryLoop = pWInfo->savedNQueryLoop; whereInfoFree(db, pWInfo); } return 0; } @@ -163394,10 +160156,11 @@ VdbeModuleComment((v, "End WHERE-loop%d: %s", i, pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); } assert( pWInfo->nLevel<=pTabList->nSrc ); + if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo); for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){ int k, last; VdbeOp *pOp, *pLastOp; Index *pIdx = 0; SrcItem *pTabItem = &pTabList->a[pLevel->iFrom]; @@ -163447,27 +160210,10 @@ if( pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable) ){ last = iEnd; }else{ last = pWInfo->iEndWhere; } - if( pIdx->bHasExpr ){ - IndexedExpr *p = pParse->pIdxEpr; - while( p ){ - if( p->iIdxCur==pLevel->iIdxCur ){ -#ifdef WHERETRACE_ENABLED - if( sqlite3WhereTrace & 0x200 ){ - sqlite3DebugPrintf("Disable pParse->pIdxEpr term {%d,%d}\n", - p->iIdxCur, p->iIdxCol); - if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(p->pExpr); - } -#endif - p->iDataCur = -1; - p->iIdxCur = -1; - } - p = p->pIENext; - } - } k = pLevel->addrBody + 1; #ifdef SQLITE_DEBUG if( db->flags & SQLITE_VdbeAddopTrace ){ printf("TRANSLATE opcodes in range %d..%d\n", k, last-1); } @@ -164457,10 +161203,11 @@ int i; int nInit = pList ? pList->nExpr : 0; for(i=0; inExpr; i++){ sqlite3 *db = pParse->db; Expr *pDup = sqlite3ExprDup(db, pAppend->a[i].pExpr, 0); + assert( pDup==0 || !ExprHasProperty(pDup, EP_MemToken) ); if( db->mallocFailed ){ sqlite3ExprDelete(db, pDup); break; } if( bIntToNull ){ @@ -164626,21 +161373,20 @@ } pSub = sqlite3SelectNew( pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0 ); - TREETRACE(0x40,pParse,pSub, + SELECTTRACE(1,pParse,pSub, ("New window-function subquery in FROM clause of (%u/%p)\n", p->selId, p)); p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside ** of sqlite3DbMallocRawNN() called from ** sqlite3SrcListAppend() */ if( p->pSrc ){ Table *pTab2; p->pSrc->a[0].pSelect = pSub; - p->pSrc->a[0].fg.isCorrelated = 1; sqlite3SrcListAssignCursors(pParse, p->pSrc); pSub->selFlags |= SF_Expanded|SF_OrderByReqd; pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); pSub->selFlags |= (selFlags & SF_Aggregate); if( pTab2==0 ){ @@ -165728,13 +162474,14 @@ } sqlite3VdbeAddOp2(v, OP_Goto, 0, addrDone); /* This block runs if reg1 is not NULL, but reg2 is. */ sqlite3VdbeJumpHere(v, addr); - sqlite3VdbeAddOp2(v, OP_IsNull, reg2, - (op==OP_Gt || op==OP_Ge) ? addrDone : lbl); - VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); + if( op==OP_Gt || op==OP_Ge ){ + sqlite3VdbeChangeP2(v, -1, addrDone); + } } /* Register reg1 currently contains csr1.peerVal (the peer-value from csr1). ** This block adds (or subtracts for DESC) the numeric value in regVal ** from it. Or, if reg1 is not numeric (it is a NULL, a text value or a blob), @@ -166502,11 +163249,12 @@ int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le); int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd); VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound */ VdbeCoverageNeverNullIf(v, op==OP_Le); /* values previously checked */ windowAggFinal(&s, 0); - sqlite3VdbeAddOp1(v, OP_Rewind, s.current.csr); + sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1); + VdbeCoverageNeverTaken(v); windowReturnOneRow(&s); sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr); sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd); sqlite3VdbeJumpHere(v, addrGe); } @@ -166514,14 +163262,17 @@ assert( pMWin->eEnd==TK_FOLLOWING ); sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart); } if( pMWin->eStart!=TK_UNBOUNDED ){ - sqlite3VdbeAddOp1(v, OP_Rewind, s.start.csr); + sqlite3VdbeAddOp2(v, OP_Rewind, s.start.csr, 1); + VdbeCoverageNeverTaken(v); } - sqlite3VdbeAddOp1(v, OP_Rewind, s.current.csr); - sqlite3VdbeAddOp1(v, OP_Rewind, s.end.csr); + sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1); + VdbeCoverageNeverTaken(v); + sqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1); + VdbeCoverageNeverTaken(v); if( regPeer && pOrderBy ){ sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1); sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1); sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1); sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1); @@ -173206,11 +169957,10 @@ while( 1 ){ n = sqlite3GetToken((u8*)zSql, &tokenType); mxSqlLen -= n; if( mxSqlLen<0 ){ pParse->rc = SQLITE_TOOBIG; - pParse->nErr++; break; } #ifndef SQLITE_OMIT_WINDOWFUNC if( tokenType>=TK_WINDOW ){ assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER @@ -173303,11 +170053,11 @@ sqlite3DeleteTable(db, pParse->pNewTable); } if( pParse->pNewTrigger && !IN_RENAME_OBJECT ){ sqlite3DeleteTrigger(db, pParse->pNewTrigger); } - if( pParse->pVList ) sqlite3DbNNFreeNN(db, pParse->pVList); + if( pParse->pVList ) sqlite3DbFreeNN(db, pParse->pVList); db->pParse = pParentParse; assert( nErr==0 || pParse->rc!=SQLITE_OK ); return nErr; } @@ -174659,23 +171409,22 @@ db->lookaside.pEnd = p; db->lookaside.bDisable = 0; db->lookaside.bMalloced = pBuf==0 ?1:0; db->lookaside.nSlot = nBig+nSm; }else{ - db->lookaside.pStart = 0; + db->lookaside.pStart = db; #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE db->lookaside.pSmallInit = 0; db->lookaside.pSmallFree = 0; - db->lookaside.pMiddle = 0; + db->lookaside.pMiddle = db; #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ - db->lookaside.pEnd = 0; + db->lookaside.pEnd = db; db->lookaside.bDisable = 1; db->lookaside.sz = 0; db->lookaside.bMalloced = 0; db->lookaside.nSlot = 0; } - db->lookaside.pTrueEnd = db->lookaside.pEnd; assert( sqlite3LookasideUsed(db,0)==0 ); #endif /* SQLITE_OMIT_LOOKASIDE */ return SQLITE_OK; } @@ -174750,11 +171499,10 @@ ** Configuration settings for an individual database connection */ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ va_list ap; int rc; - sqlite3_mutex_enter(db->mutex); va_start(ap, op); switch( op ){ case SQLITE_DBCONFIG_MAINDBNAME: { /* IMP: R-06824-28531 */ /* IMP: R-36257-52125 */ @@ -174816,11 +171564,10 @@ } break; } } va_end(ap); - sqlite3_mutex_leave(db->mutex); return rc; } /* ** This is the default collating function named "BINARY" which is always @@ -175401,11 +172148,10 @@ case SQLITE_ROW: zName = "SQLITE_ROW"; break; case SQLITE_NOTICE: zName = "SQLITE_NOTICE"; break; case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break; case SQLITE_NOTICE_RECOVER_ROLLBACK: zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break; - case SQLITE_NOTICE_RBU: zName = "SQLITE_NOTICE_RBU"; break; case SQLITE_WARNING: zName = "SQLITE_WARNING"; break; case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break; case SQLITE_DONE: zName = "SQLITE_DONE"; break; } } @@ -175631,35 +172377,18 @@ /* ** Cause any pending operation to stop at its earliest opportunity. */ SQLITE_API void sqlite3_interrupt(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) - && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) - ){ + if( !sqlite3SafetyCheckOk(db) && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) ){ (void)SQLITE_MISUSE_BKPT; return; } #endif AtomicStore(&db->u1.isInterrupted, 1); } -/* -** Return true or false depending on whether or not an interrupt is -** pending on connection db. -*/ -SQLITE_API int sqlite3_is_interrupted(sqlite3 *db){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) - && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) - ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - return AtomicLoad(&db->u1.isInterrupted)!=0; -} /* ** This function is exactly the same as sqlite3_create_function(), except ** that it is designed to be called by internal code. The difference is ** that if a malloc() fails in sqlite3_create_function(), an error code @@ -175700,11 +172429,11 @@ enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But ** the meaning is inverted. So flip the bit. */ assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS ); - extraFlags ^= SQLITE_FUNC_UNSAFE; /* tag-20230109-1 */ + extraFlags ^= SQLITE_FUNC_UNSAFE; #ifndef SQLITE_OMIT_UTF16 /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the @@ -175718,15 +172447,15 @@ enc = SQLITE_UTF16NATIVE; break; case SQLITE_ANY: { int rc; rc = sqlite3CreateFunc(db, zFunctionName, nArg, - (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE, /* tag-20230109-1 */ + (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE, pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); if( rc==SQLITE_OK ){ rc = sqlite3CreateFunc(db, zFunctionName, nArg, - (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE, /* tag-20230109-1*/ + (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE, pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); } if( rc!=SQLITE_OK ){ return rc; } @@ -175971,11 +172700,11 @@ #endif sqlite3_mutex_enter(db->mutex); rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0; sqlite3_mutex_leave(db->mutex); if( rc ) return SQLITE_OK; - zCopy = sqlite3_mprintf("%s", zName); + zCopy = sqlite3_mprintf(zName); if( zCopy==0 ) return SQLITE_NOMEM; return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8, zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free); } @@ -177205,23 +173934,10 @@ createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0); if( db->mallocFailed ){ goto opendb_out; } -#if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) - /* Process magic filenames ":localStorage:" and ":sessionStorage:" */ - if( zFilename && zFilename[0]==':' ){ - if( strcmp(zFilename, ":localStorage:")==0 ){ - zFilename = "file:local?vfs=kvvfs"; - flags |= SQLITE_OPEN_URI; - }else if( strcmp(zFilename, ":sessionStorage:")==0 ){ - zFilename = "file:session?vfs=kvvfs"; - flags |= SQLITE_OPEN_URI; - } - } -#endif /* SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) */ - /* Parse the filename/URI argument ** ** Only allow sensible combinations of bits in the flags argument. ** Throw an error if any non-sense combination is used. If we ** do not block illegal combinations here, it could trigger @@ -177248,16 +173964,10 @@ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); sqlite3_free(zErrMsg); goto opendb_out; } - assert( db->pVfs!=0 ); -#if SQLITE_OS_KV || defined(SQLITE_OS_KV_OPTIONAL) - if( sqlite3_stricmp(db->pVfs->zName, "kvvfs")==0 ){ - db->temp_store = 2; - } -#endif /* Open the backend database driver */ rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, flags | SQLITE_OPEN_MAIN_DB); if( rc!=SQLITE_OK ){ @@ -177803,13 +174513,10 @@ *(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree); if( iNew>=0 && iNew<=255 ){ sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0); } rc = SQLITE_OK; - }else if( op==SQLITE_FCNTL_RESET_CACHE ){ - sqlite3BtreeClearCache(pBtree); - rc = SQLITE_OK; }else{ int nSave = db->busyHandler.nBusy; rc = sqlite3OsFileControl(fd, op, pArg); db->busyHandler.nBusy = nSave; } @@ -177990,15 +174697,12 @@ sqlite3ShowUpsert(0); sqlite3ShowTriggerStep(0); sqlite3ShowTriggerStepList(0); sqlite3ShowTrigger(0); sqlite3ShowTriggerList(0); -#ifndef SQLITE_OMIT_WINDOWFUNC sqlite3ShowWindow(0); sqlite3ShowWinFunc(0); -#endif - sqlite3ShowSelect(0); } #endif break; } @@ -178366,11 +175070,11 @@ ** functions. ** ** Memory layout must be compatible with that generated by the pager ** and expected by sqlite3_uri_parameter() and databaseName(). */ -SQLITE_API const char *sqlite3_create_filename( +SQLITE_API char *sqlite3_create_filename( const char *zDatabase, const char *zJournal, const char *zWal, int nParam, const char **azParam @@ -178402,14 +175106,14 @@ /* ** Free memory obtained from sqlite3_create_filename(). It is a severe ** error to call this routine with any parameter other than a pointer ** previously obtained from sqlite3_create_filename() or a NULL pointer. */ -SQLITE_API void sqlite3_free_filename(const char *p){ +SQLITE_API void sqlite3_free_filename(char *p){ if( p==0 ) return; - p = databaseName(p); - sqlite3_free((char*)p - 4); + p = (char*)databaseName(p); + sqlite3_free(p - 4); } /* ** This is a utility routine, useful to VFS implementations, that checks @@ -178656,12 +175360,12 @@ ** Recover as many snapshots as possible from the wal file associated with ** schema zDb of database db. */ SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ int rc = SQLITE_ERROR; -#ifndef SQLITE_OMIT_WAL int iDb; +#ifndef SQLITE_OMIT_WAL #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ return SQLITE_MISUSE_BKPT; } @@ -180212,11 +176916,11 @@ Fts3SegReader **apSegment; /* Array of Fts3SegReader objects */ int nSegment; /* Size of apSegment array */ int nAdvance; /* How many seg-readers to advance */ Fts3SegFilter *pFilter; /* Pointer to filter object */ char *aBuffer; /* Buffer to merge doclists in */ - i64 nBuffer; /* Allocated size of aBuffer[] in bytes */ + int nBuffer; /* Allocated size of aBuffer[] in bytes */ int iColFilter; /* If >=0, filter for this column */ int bRestart; /* Used by fts3.c only. */ @@ -180304,12 +177008,10 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); #endif -SQLITE_PRIVATE int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*); - #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ #endif /* _FTSINT_H */ /************** End of fts3Int.h *********************************************/ /************** Continuing where we left off in fts3.c ***********************/ @@ -182910,11 +179612,11 @@ ** as a single-byte delta, whereas in the second it must be stored as a ** FTS3_VARINT_MAX byte varint. ** ** Similar padding is added in the fts3DoclistOrMerge() function. */ - pTS->aaOutput[0] = sqlite3_malloc64((i64)nDoclist + FTS3_VARINT_MAX + 1); + pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1); pTS->anOutput[0] = nDoclist; if( pTS->aaOutput[0] ){ memcpy(pTS->aaOutput[0], aDoclist, nDoclist); memset(&pTS->aaOutput[0][nDoclist], 0, FTS3_VARINT_MAX); }else{ @@ -184330,11 +181032,12 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ int iToken; /* Used to iterate through phrase tokens */ char *aPoslist = 0; /* Position list for deferred tokens */ int nPoslist = 0; /* Number of bytes in aPoslist */ int iPrev = -1; /* Token number of previous deferred token */ - char *aFree = (pPhrase->doclist.bFreeList ? pPhrase->doclist.pList : 0); + + assert( pPhrase->doclist.bFreeList==0 ); for(iToken=0; iTokennToken; iToken++){ Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; Fts3DeferredToken *pDeferred = pToken->pDeferred; @@ -184344,11 +181047,10 @@ int rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList); if( rc!=SQLITE_OK ) return rc; if( pList==0 ){ sqlite3_free(aPoslist); - sqlite3_free(aFree); pPhrase->doclist.pList = 0; pPhrase->doclist.nList = 0; return SQLITE_OK; }else if( aPoslist==0 ){ @@ -184365,11 +181067,10 @@ sqlite3_free(aPoslist); aPoslist = pList; nPoslist = (int)(aOut - aPoslist); if( nPoslist==0 ){ sqlite3_free(aPoslist); - sqlite3_free(aFree); pPhrase->doclist.pList = 0; pPhrase->doclist.nList = 0; return SQLITE_OK; } } @@ -184398,18 +181099,17 @@ p1 = pPhrase->doclist.pList; p2 = aPoslist; nDistance = iPrev - nMaxUndeferred; } - aOut = (char *)sqlite3Fts3MallocZero(nPoslist+FTS3_BUFFER_PADDING); + aOut = (char *)sqlite3_malloc(nPoslist+8); if( !aOut ){ sqlite3_free(aPoslist); return SQLITE_NOMEM; } pPhrase->doclist.pList = aOut; - assert( p1 && p2 ); if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){ pPhrase->doclist.bFreeList = 1; pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList); }else{ sqlite3_free(aOut); @@ -184418,11 +181118,10 @@ } sqlite3_free(aPoslist); } } - if( pPhrase->doclist.pList!=aFree ) sqlite3_free(aFree); return SQLITE_OK; } #endif /* SQLITE_DISABLE_FTS4_DEFERRED */ /* @@ -184767,11 +181466,11 @@ /* Check if the current entries really are a phrase match */ if( bEof==0 ){ int nList = 0; int nByte = a[p->nToken-1].nList; - char *aDoclist = sqlite3_malloc64((i64)nByte+FTS3_BUFFER_PADDING); + char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING); if( !aDoclist ) return SQLITE_NOMEM; memcpy(aDoclist, a[p->nToken-1].pList, nByte+1); memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING); for(i=0; i<(p->nToken-1); i++){ @@ -185309,12 +182008,13 @@ static void fts3EvalNextRow( Fts3Cursor *pCsr, /* FTS Cursor handle */ Fts3Expr *pExpr, /* Expr. to advance to next matching row */ int *pRc /* IN/OUT: Error code */ ){ - if( *pRc==SQLITE_OK && pExpr->bEof==0 ){ + if( *pRc==SQLITE_OK ){ int bDescDoclist = pCsr->bDesc; /* Used by DOCID_CMP() macro */ + assert( pExpr->bEof==0 ); pExpr->bStart = 1; switch( pExpr->eType ){ case FTSQUERY_NEAR: case FTSQUERY_AND: { @@ -185592,14 +182292,15 @@ ); break; default: { #ifndef SQLITE_DISABLE_FTS4_DEFERRED - if( pCsr->pDeferred && (pExpr->bDeferred || ( - pExpr->iDocid==pCsr->iPrevId && pExpr->pPhrase->doclist.pList - ))){ + if( pCsr->pDeferred + && (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred) + ){ Fts3Phrase *pPhrase = pExpr->pPhrase; + assert( pExpr->bDeferred || pPhrase->doclist.bFreeList==0 ); if( pExpr->bDeferred ){ fts3EvalInvalidatePoslist(pPhrase); } *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase); bHit = (pPhrase->doclist.pList!=0); @@ -185786,26 +182487,10 @@ fts3EvalUpdateCounts(pExpr->pLeft, nCol); fts3EvalUpdateCounts(pExpr->pRight, nCol); } } -/* -** This is an sqlite3Fts3ExprIterate() callback. If the Fts3Expr.aMI[] array -** has not yet been allocated, allocate and zero it. Otherwise, just zero -** it. -*/ -static int fts3AllocateMSI(Fts3Expr *pExpr, int iPhrase, void *pCtx){ - Fts3Table *pTab = (Fts3Table*)pCtx; - UNUSED_PARAMETER(iPhrase); - if( pExpr->aMI==0 ){ - pExpr->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32)); - if( pExpr->aMI==0 ) return SQLITE_NOMEM; - } - memset(pExpr->aMI, 0, pTab->nColumn * 3 * sizeof(u32)); - return SQLITE_OK; -} - /* ** Expression pExpr must be of type FTSQUERY_PHRASE. ** ** If it is not already allocated and populated, this function allocates and ** populates the Fts3Expr.aMI[] array for expression pExpr. If pExpr is part @@ -185823,29 +182508,34 @@ assert( pExpr->eType==FTSQUERY_PHRASE ); if( pExpr->aMI==0 ){ Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; Fts3Expr *pRoot; /* Root of NEAR expression */ + Fts3Expr *p; /* Iterator used for several purposes */ sqlite3_int64 iPrevId = pCsr->iPrevId; sqlite3_int64 iDocid; u8 bEof; /* Find the root of the NEAR expression */ pRoot = pExpr; - while( pRoot->pParent - && (pRoot->pParent->eType==FTSQUERY_NEAR || pRoot->bDeferred) - ){ + while( pRoot->pParent && pRoot->pParent->eType==FTSQUERY_NEAR ){ pRoot = pRoot->pParent; } iDocid = pRoot->iDocid; bEof = pRoot->bEof; assert( pRoot->bStart ); /* Allocate space for the aMSI[] array of each FTSQUERY_PHRASE node */ - rc = sqlite3Fts3ExprIterate(pRoot, fts3AllocateMSI, (void*)pTab); - if( rc!=SQLITE_OK ) return rc; + for(p=pRoot; p; p=p->pLeft){ + Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight); + assert( pE->aMI==0 ); + pE->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32)); + if( !pE->aMI ) return SQLITE_NOMEM; + memset(pE->aMI, 0, pTab->nColumn * 3 * sizeof(u32)); + } + fts3EvalRestart(pCsr, pRoot, &rc); while( pCsr->isEof==0 && rc==SQLITE_OK ){ do { @@ -185997,11 +182687,10 @@ int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */ int bOr = 0; u8 bTreeEof = 0; Fts3Expr *p; /* Used to iterate from pExpr to root */ Fts3Expr *pNear; /* Most senior NEAR ancestor (or pExpr) */ - Fts3Expr *pRun; /* Closest non-deferred ancestor of pNear */ int bMatch; /* Check if this phrase descends from an OR expression node. If not, ** return NULL. Otherwise, the entry that corresponds to docid ** pCsr->iPrevId may lie earlier in the doclist buffer. Or, if the @@ -186012,34 +182701,29 @@ if( p->eType==FTSQUERY_OR ) bOr = 1; if( p->eType==FTSQUERY_NEAR ) pNear = p; if( p->bEof ) bTreeEof = 1; } if( bOr==0 ) return SQLITE_OK; - pRun = pNear; - while( pRun->bDeferred ){ - assert( pRun->pParent ); - pRun = pRun->pParent; - } /* This is the descendent of an OR node. In this case we cannot use ** an incremental phrase. Load the entire doclist for the phrase ** into memory in this case. */ if( pPhrase->bIncr ){ - int bEofSave = pRun->bEof; - fts3EvalRestart(pCsr, pRun, &rc); - while( rc==SQLITE_OK && !pRun->bEof ){ - fts3EvalNextRow(pCsr, pRun, &rc); - if( bEofSave==0 && pRun->iDocid==iDocid ) break; + int bEofSave = pNear->bEof; + fts3EvalRestart(pCsr, pNear, &rc); + while( rc==SQLITE_OK && !pNear->bEof ){ + fts3EvalNextRow(pCsr, pNear, &rc); + if( bEofSave==0 && pNear->iDocid==iDocid ) break; } assert( rc!=SQLITE_OK || pPhrase->bIncr==0 ); - if( rc==SQLITE_OK && pRun->bEof!=bEofSave ){ + if( rc==SQLITE_OK && pNear->bEof!=bEofSave ){ rc = FTS_CORRUPT_VTAB; } } if( bTreeEof ){ - while( rc==SQLITE_OK && !pRun->bEof ){ - fts3EvalNextRow(pCsr, pRun, &rc); + while( rc==SQLITE_OK && !pNear->bEof ){ + fts3EvalNextRow(pCsr, pNear, &rc); } } if( rc!=SQLITE_OK ) return rc; bMatch = 1; @@ -189019,11 +185703,11 @@ if( c->iOffset>iStartOffset ){ int n = c->iOffset-iStartOffset; if( n>c->nAllocated ){ char *pNew; c->nAllocated = n+20; - pNew = sqlite3_realloc64(c->zToken, c->nAllocated); + pNew = sqlite3_realloc(c->zToken, c->nAllocated); if( !pNew ) return SQLITE_NOMEM; c->zToken = pNew; } porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes); *pzToken = c->zToken; @@ -189771,11 +186455,11 @@ if( c->iOffset>iStartOffset ){ int i, n = c->iOffset-iStartOffset; if( n>c->nTokenAllocated ){ char *pNew; c->nTokenAllocated = n+20; - pNew = sqlite3_realloc64(c->pToken, c->nTokenAllocated); + pNew = sqlite3_realloc(c->pToken, c->nTokenAllocated); if( !pNew ) return SQLITE_NOMEM; c->pToken = pNew; } for(i=0; inSpace = 100; p->aData = (char *)&p[1]; p->nData = 0; } else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){ - i64 nNew = p->nSpace * 2; - p = sqlite3_realloc64(p, sizeof(*p) + nNew); + int nNew = p->nSpace * 2; + p = sqlite3_realloc(p, sizeof(*p) + nNew); if( !p ){ sqlite3_free(*pp); *pp = 0; return SQLITE_NOMEM; } - p->nSpace = (int)nNew; + p->nSpace = nNew; p->aData = (char *)&p[1]; } /* Append the new serialized varint to the end of the list. */ p->nData += sqlite3Fts3PutVarint(&p->aData[p->nData], i); @@ -191506,11 +188190,11 @@ if( rc==SQLITE_OK ){ int nByte = sqlite3_blob_bytes(p->pSegments); *pnBlob = nByte; if( paBlob ){ - char *aByte = sqlite3_malloc64((i64)nByte + FTS3_NODE_PADDING); + char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING); if( !aByte ){ rc = SQLITE_NOMEM; }else{ if( pnLoad && nByte>(FTS3_NODE_CHUNK_THRESHOLD) ){ nByte = FTS3_NODE_CHUNKSIZE; @@ -191623,19 +188307,19 @@ int nCopy = pList->nData+1; int nTerm = fts3HashKeysize(pElem); if( (nTerm+1)>pReader->nTermAlloc ){ sqlite3_free(pReader->zTerm); - pReader->zTerm = (char*)sqlite3_malloc64(((i64)nTerm+1)*2); + pReader->zTerm = (char*)sqlite3_malloc((nTerm+1)*2); if( !pReader->zTerm ) return SQLITE_NOMEM; pReader->nTermAlloc = (nTerm+1)*2; } memcpy(pReader->zTerm, fts3HashKey(pElem), nTerm); pReader->zTerm[nTerm] = '\0'; pReader->nTerm = nTerm; - aCopy = (char*)sqlite3_malloc64(nCopy); + aCopy = (char*)sqlite3_malloc(nCopy); if( !aCopy ) return SQLITE_NOMEM; memcpy(aCopy, pList->aData, nCopy); pReader->nNode = pReader->nDoclist = nCopy; pReader->aNode = pReader->aDoclist = aCopy; pReader->ppNextElem++; @@ -191918,11 +188602,11 @@ if( iStartLeaf==0 ){ if( iEndLeaf!=0 ) return FTS_CORRUPT_VTAB; nExtra = nRoot + FTS3_NODE_PADDING; } - pReader = (Fts3SegReader *)sqlite3_malloc64(sizeof(Fts3SegReader) + nExtra); + pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra); if( !pReader ){ return SQLITE_NOMEM; } memset(pReader, 0, sizeof(Fts3SegReader)); pReader->iIdx = iAge; @@ -192010,11 +188694,11 @@ int nKey = fts3HashKeysize(pE); if( nTerm==0 || (nKey>=nTerm && 0==memcmp(zKey, zTerm, nTerm)) ){ if( nElem==nAlloc ){ Fts3HashElem **aElem2; nAlloc += 16; - aElem2 = (Fts3HashElem **)sqlite3_realloc64( + aElem2 = (Fts3HashElem **)sqlite3_realloc( aElem, nAlloc*sizeof(Fts3HashElem *) ); if( !aElem2 ){ rc = SQLITE_NOMEM; nElem = 0; @@ -192344,11 +189028,11 @@ ** p->nNodeSize bytes, but since this scenario only comes about when ** the database contain two terms that share a prefix of almost 2KB, ** this is not expected to be a serious problem. */ assert( pTree->aData==(char *)&pTree[1] ); - pTree->aData = (char *)sqlite3_malloc64(nReq); + pTree->aData = (char *)sqlite3_malloc(nReq); if( !pTree->aData ){ return SQLITE_NOMEM; } } @@ -192362,11 +189046,11 @@ pTree->nData = nData + nSuffix; pTree->nEntry++; if( isCopyTerm ){ if( pTree->nMalloczMalloc, (i64)nTerm*2); + char *zNew = sqlite3_realloc(pTree->zMalloc, nTerm*2); if( !zNew ){ return SQLITE_NOMEM; } pTree->nMalloc = nTerm*2; pTree->zMalloc = zNew; @@ -192388,11 +189072,11 @@ ** ** Otherwise, the term is not added to the new node, it is left empty for ** now. Instead, the term is inserted into the parent of pTree. If pTree ** has no parent, one is created here. */ - pNew = (SegmentNode *)sqlite3_malloc64(sizeof(SegmentNode) + p->nNodeSize); + pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize); if( !pNew ){ return SQLITE_NOMEM; } memset(pNew, 0, sizeof(SegmentNode)); pNew->nData = 1 + FTS3_VARINT_MAX; @@ -192526,26 +189210,26 @@ const char *aDoclist, /* Pointer to buffer containing doclist */ int nDoclist /* Size of doclist in bytes */ ){ int nPrefix; /* Size of term prefix in bytes */ int nSuffix; /* Size of term suffix in bytes */ - i64 nReq; /* Number of bytes required on leaf page */ + int nReq; /* Number of bytes required on leaf page */ int nData; SegmentWriter *pWriter = *ppWriter; if( !pWriter ){ int rc; sqlite3_stmt *pStmt; /* Allocate the SegmentWriter structure */ - pWriter = (SegmentWriter *)sqlite3_malloc64(sizeof(SegmentWriter)); + pWriter = (SegmentWriter *)sqlite3_malloc(sizeof(SegmentWriter)); if( !pWriter ) return SQLITE_NOMEM; memset(pWriter, 0, sizeof(SegmentWriter)); *ppWriter = pWriter; /* Allocate a buffer in which to accumulate data */ - pWriter->aData = (char *)sqlite3_malloc64(p->nNodeSize); + pWriter->aData = (char *)sqlite3_malloc(p->nNodeSize); if( !pWriter->aData ) return SQLITE_NOMEM; pWriter->nSize = p->nNodeSize; /* Find the next free blockid in the %_segments table */ rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pStmt, 0); @@ -192616,11 +189300,11 @@ /* If the buffer currently allocated is too small for this entry, realloc ** the buffer to make it large enough. */ if( nReq>pWriter->nSize ){ - char *aNew = sqlite3_realloc64(pWriter->aData, nReq); + char *aNew = sqlite3_realloc(pWriter->aData, nReq); if( !aNew ) return SQLITE_NOMEM; pWriter->aData = aNew; pWriter->nSize = nReq; } assert( nData+nReq<=pWriter->nSize ); @@ -192641,11 +189325,11 @@ ** zTerm is transient, so take a copy of the term data. Otherwise, just ** store a copy of the pointer. */ if( isCopyTerm ){ if( nTerm>pWriter->nMalloc ){ - char *zNew = sqlite3_realloc64(pWriter->zMalloc, (i64)nTerm*2); + char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2); if( !zNew ){ return SQLITE_NOMEM; } pWriter->nMalloc = nTerm*2; pWriter->zMalloc = zNew; @@ -192949,16 +189633,16 @@ ** trying to resize the buffer, return SQLITE_NOMEM. */ static int fts3MsrBufferData( Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ char *pList, - i64 nList + int nList ){ if( nList>pMsr->nBuffer ){ char *pNew; pMsr->nBuffer = nList*2; - pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, pMsr->nBuffer); + pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer); if( !pNew ) return SQLITE_NOMEM; pMsr->aBuffer = pNew; } assert( nList>0 ); @@ -193010,11 +189694,11 @@ } if( rc!=SQLITE_OK ) return rc; fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp); if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){ - rc = fts3MsrBufferData(pMsr, pList, (i64)nList+1); + rc = fts3MsrBufferData(pMsr, pList, nList+1); if( rc!=SQLITE_OK ) return rc; assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 ); pList = pMsr->aBuffer; } @@ -193147,15 +189831,15 @@ } return SQLITE_OK; } -static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, i64 nReq){ +static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, int nReq){ if( nReq>pCsr->nBuffer ){ char *aNew; pCsr->nBuffer = nReq*2; - aNew = sqlite3_realloc64(pCsr->aBuffer, pCsr->nBuffer); + aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer); if( !aNew ){ return SQLITE_NOMEM; } pCsr->aBuffer = aNew; } @@ -193242,12 +189926,11 @@ && !isFirst && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0) ){ pCsr->nDoclist = apSegment[0]->nDoclist; if( fts3SegReaderIsPending(apSegment[0]) ){ - rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, - (i64)pCsr->nDoclist); + rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist); pCsr->aDoclist = pCsr->aBuffer; }else{ pCsr->aDoclist = apSegment[0]->aDoclist; } if( rc==SQLITE_OK ) rc = SQLITE_ROW; @@ -193296,12 +189979,11 @@ iDelta = (i64)((u64)iDocid - (u64)iPrev); } nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); - rc = fts3GrowSegReaderBuffer(pCsr, - (i64)nByte+nDoclist+FTS3_NODE_PADDING); + rc = fts3GrowSegReaderBuffer(pCsr, nByte+nDoclist+FTS3_NODE_PADDING); if( rc ) return rc; if( isFirst ){ char *a = &pCsr->aBuffer[nDoclist]; int nWrite; @@ -193323,11 +190005,11 @@ } fts3SegReaderSort(apSegment, nMerge, j, xCmp); } if( nDoclist>0 ){ - rc = fts3GrowSegReaderBuffer(pCsr, (i64)nDoclist+FTS3_NODE_PADDING); + rc = fts3GrowSegReaderBuffer(pCsr, nDoclist+FTS3_NODE_PADDING); if( rc ) return rc; memset(&pCsr->aBuffer[nDoclist], 0, FTS3_NODE_PADDING); pCsr->aDoclist = pCsr->aBuffer; pCsr->nDoclist = nDoclist; rc = SQLITE_ROW; @@ -194036,11 +190718,11 @@ ** to reflect the new size of the pBlob->a[] buffer. */ static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){ if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){ int nAlloc = nMin; - char *a = (char *)sqlite3_realloc64(pBlob->a, nAlloc); + char *a = (char *)sqlite3_realloc(pBlob->a, nAlloc); if( a ){ pBlob->nAlloc = nAlloc; pBlob->a = a; }else{ *pRc = SQLITE_NOMEM; @@ -194833,11 +191515,11 @@ sqlite3_bind_int64(pSelect, 1, iAbsLevel); while( SQLITE_ROW==sqlite3_step(pSelect) ){ if( nIdx>=nAlloc ){ int *aNew; nAlloc += 16; - aNew = sqlite3_realloc64(aIdx, nAlloc*sizeof(int)); + aNew = sqlite3_realloc(aIdx, nAlloc*sizeof(int)); if( !aNew ){ rc = SQLITE_NOMEM; break; } aIdx = aNew; @@ -195207,11 +191889,11 @@ Blob hint = {0, 0, 0}; /* Hint read from %_stat table */ int bDirtyHint = 0; /* True if blob 'hint' has been modified */ /* Allocate space for the cursor, filter and writer objects */ const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter); - pWriter = (IncrmergeWriter *)sqlite3_malloc64(nAlloc); + pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc); if( !pWriter ) return SQLITE_NOMEM; pFilter = (Fts3SegFilter *)&pWriter[1]; pCsr = (Fts3MultiSegReader *)&pFilter[1]; rc = fts3IncrmergeHintLoad(p, &hint); @@ -195843,11 +192525,11 @@ if( p->pList==0 ){ return SQLITE_OK; } - pRet = (char *)sqlite3_malloc64(p->pList->nData); + pRet = (char *)sqlite3_malloc(p->pList->nData); if( !pRet ) return SQLITE_NOMEM; nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy); *pnData = p->pList->nData - nSkip; *ppData = pRet; @@ -195863,11 +192545,11 @@ Fts3Cursor *pCsr, /* Fts3 table cursor */ Fts3PhraseToken *pToken, /* Token to defer */ int iCol /* Column that token must appear in (or -1) */ ){ Fts3DeferredToken *pDeferred; - pDeferred = sqlite3_malloc64(sizeof(*pDeferred)); + pDeferred = sqlite3_malloc(sizeof(*pDeferred)); if( !pDeferred ){ return SQLITE_NOMEM; } memset(pDeferred, 0, sizeof(*pDeferred)); pDeferred->pToken = pToken; @@ -196142,11 +192824,11 @@ */ #define FTS3_MATCHINFO_DEFAULT "pcx" /* -** Used as an sqlite3Fts3ExprIterate() context when loading phrase doclists to +** Used as an fts3ExprIterate() context when loading phrase doclists to ** Fts3Expr.aDoclist[]/nDoclist. */ typedef struct LoadDoclistCtx LoadDoclistCtx; struct LoadDoclistCtx { Fts3Cursor *pCsr; /* FTS3 Cursor */ @@ -196186,11 +192868,11 @@ u64 covered; /* Mask of query phrases covered */ u64 hlmask; /* Mask of snippet terms to highlight */ }; /* -** This type is used as an sqlite3Fts3ExprIterate() context object while +** This type is used as an fts3ExprIterate() context object while ** accumulating the data returned by the matchinfo() function. */ typedef struct MatchInfo MatchInfo; struct MatchInfo { Fts3Cursor *pCursor; /* FTS3 Cursor */ @@ -196345,11 +193027,11 @@ *pp += fts3GetVarint32(*pp, &iVal); *piPos += (iVal-2); } /* -** Helper function for sqlite3Fts3ExprIterate() (see below). +** Helper function for fts3ExprIterate() (see below). */ static int fts3ExprIterate2( Fts3Expr *pExpr, /* Expression to iterate phrases of */ int *piPhrase, /* Pointer to phrase counter */ int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ @@ -196379,22 +193061,23 @@ ** If the callback function returns anything other than SQLITE_OK, ** the iteration is abandoned and the error code returned immediately. ** Otherwise, SQLITE_OK is returned after a callback has been made for ** all eligible phrase nodes. */ -SQLITE_PRIVATE int sqlite3Fts3ExprIterate( +static int fts3ExprIterate( Fts3Expr *pExpr, /* Expression to iterate phrases of */ int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ void *pCtx /* Second argument to pass to callback */ ){ int iPhrase = 0; /* Variable used as the phrase counter */ return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx); } + /* -** This is an sqlite3Fts3ExprIterate() callback used while loading the -** doclists for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also +** This is an fts3ExprIterate() callback used while loading the doclists +** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also ** fts3ExprLoadDoclists(). */ static int fts3ExprLoadDoclistsCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ int rc = SQLITE_OK; Fts3Phrase *pPhrase = pExpr->pPhrase; @@ -196422,13 +193105,13 @@ Fts3Cursor *pCsr, /* Fts3 cursor for current query */ int *pnPhrase, /* OUT: Number of phrases in query */ int *pnToken /* OUT: Number of tokens in query */ ){ int rc; /* Return Code */ - LoadDoclistCtx sCtx = {0,0,0}; /* Context for sqlite3Fts3ExprIterate() */ + LoadDoclistCtx sCtx = {0,0,0}; /* Context for fts3ExprIterate() */ sCtx.pCsr = pCsr; - rc = sqlite3Fts3ExprIterate(pCsr->pExpr,fts3ExprLoadDoclistsCb,(void*)&sCtx); + rc = fts3ExprIterate(pCsr->pExpr, fts3ExprLoadDoclistsCb, (void *)&sCtx); if( pnPhrase ) *pnPhrase = sCtx.nPhrase; if( pnToken ) *pnToken = sCtx.nToken; return rc; } @@ -196437,11 +193120,11 @@ pExpr->iPhrase = iPhrase; return SQLITE_OK; } static int fts3ExprPhraseCount(Fts3Expr *pExpr){ int nPhrase = 0; - (void)sqlite3Fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase); + (void)fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase); return nPhrase; } /* ** Advance the position list iterator specified by the first two @@ -196565,13 +193248,12 @@ *pmCover = mCover; *pmHighlight = mHighlight; } /* -** This function is an sqlite3Fts3ExprIterate() callback used by -** fts3BestSnippet(). Each invocation populates an element of the -** SnippetIter.aPhrase[] array. +** This function is an fts3ExprIterate() callback used by fts3BestSnippet(). +** Each invocation populates an element of the SnippetIter.aPhrase[] array. */ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){ SnippetIter *p = (SnippetIter *)ctx; SnippetPhrase *pPhrase = &p->aPhrase[iPhrase]; char *pCsr; @@ -196657,13 +193339,11 @@ sIter.pCsr = pCsr; sIter.iCol = iCol; sIter.nSnippet = nSnippet; sIter.nPhrase = nList; sIter.iCurrent = -1; - rc = sqlite3Fts3ExprIterate( - pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter - ); + rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter); if( rc==SQLITE_OK ){ /* Set the *pmSeen output variable. */ for(i=0; ipCursor, pExpr, &p->aMatchinfo[3*iPhrase*p->nCol] ); } /* -** sqlite3Fts3ExprIterate() callback used to collect the "local" part of the +** fts3ExprIterate() callback used to collect the "local" part of the ** FTS3_MATCHINFO_HITS array. The local stats are those elements of the ** array that are different for each row returned by the query. */ static int fts3ExprLocalHitsCb( Fts3Expr *pExpr, /* Phrase expression node */ @@ -197254,11 +193934,11 @@ /* Allocate and populate the array of LcsIterator objects. The array ** contains one element for each matchable phrase in the query. **/ aIter = sqlite3Fts3MallocZero(sizeof(LcsIterator) * pCsr->nPhrase); if( !aIter ) return SQLITE_NOMEM; - (void)sqlite3Fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); + (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); for(i=0; inPhrase; i++){ LcsIterator *pIter = &aIter[i]; nToken -= pIter->pExpr->pPhrase->nToken; pIter->iPosOffset = nToken; @@ -197431,15 +194111,15 @@ if( bGlobal ){ if( pCsr->pDeferred ){ rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc,0,0); if( rc!=SQLITE_OK ) break; } - rc = sqlite3Fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); + rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); sqlite3Fts3EvalTestDeferred(pCsr, &rc); if( rc!=SQLITE_OK ) break; } - (void)sqlite3Fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo); + (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo); break; } } pInfo->aMatchinfo += fts3MatchinfoSize(pInfo, zArg[i]); @@ -197658,11 +194338,11 @@ sqlite3_int64 iDocid; TermOffset *aTerm; }; /* -** This function is an sqlite3Fts3ExprIterate() callback used by sqlite3Fts3Offsets(). +** This function is an fts3ExprIterate() callback used by sqlite3Fts3Offsets(). */ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){ TermOffsetCtx *p = (TermOffsetCtx *)ctx; int nTerm; /* Number of tokens in phrase */ int iTerm; /* For looping through nTerm phrase terms */ @@ -197740,13 +194420,11 @@ /* Initialize the contents of sCtx.aTerm[] for column iCol. This ** operation may fail if the database contains corrupt records. */ sCtx.iCol = iCol; sCtx.iTerm = 0; - rc = sqlite3Fts3ExprIterate( - pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx - ); + rc = fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx); if( rc!=SQLITE_OK ) goto offsets_out; /* Retreive the text stored in column iCol. If an SQL NULL is stored ** in column iCol, jump immediately to the next iteration of the loop. ** If an OOM occurs while retrieving the data (this can happen if SQLite @@ -201118,17 +197796,10 @@ }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ aIdx[iCol] = i; idxMask |= iMask; } } - if( pIdxInfo->nOrderBy>0 - && pIdxInfo->aOrderBy[0].iColumn<0 - && pIdxInfo->aOrderBy[0].desc==0 - ){ - pIdxInfo->orderByConsumed = 1; - } - if( (unusableMask & ~idxMask)!=0 ){ /* If there are any unusable constraints on JSON or ROOT, then reject ** this entire plan */ return SQLITE_CONSTRAINT; } @@ -201320,14 +197991,14 @@ 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_UTF8|SQLITE_DETERMINISTIC), + SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS), WAGGREGATE(json_group_object, 2, 0, 0, jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, - SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC) + SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS) }; sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc)); #endif } @@ -201855,11 +198526,11 @@ */ static int readInt16(u8 *p){ return (p[0]<<8) + p[1]; } static void readCoord(u8 *p, RtreeCoord *pCoord){ - assert( (((sqlite3_uint64)p)&3)==0 ); /* p is always 4-byte aligned */ + assert( ((((char*)p) - (char*)0)&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 pCoord->u = __builtin_bswap32(*(u32*)p); #elif SQLITE_BYTEORDER==4321 @@ -201909,11 +198580,11 @@ p[0] = (i>> 8)&0xFF; p[1] = (i>> 0)&0xFF; } static int writeCoord(u8 *p, RtreeCoord *pCoord){ u32 i; - assert( (((sqlite3_uint64)p)&3)==0 ); /* p is always 4-byte aligned */ + assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */ assert( sizeof(RtreeCoord)==4 ); assert( sizeof(u32)==4 ); #if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 i = __builtin_bswap32(pCoord->u); memcpy(p, &i, 4); @@ -202637,11 +199308,11 @@ pCellData += 8 + 4*(p->iCoord&0xfe); 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( (((sqlite3_uint64)pCellData)&3)==0 ); /* 4-byte aligned */ + assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ switch( p->op ){ case RTREE_TRUE: return; /* Always satisfied */ case RTREE_FALSE: break; /* Never satisfied */ case RTREE_EQ: RTREE_DECODE_COORD(eInt, pCellData, val); @@ -202690,11 +199361,11 @@ 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 ); pCellData += 8 + p->iCoord*4; - assert( (((sqlite3_uint64)pCellData)&3)==0 ); /* 4-byte aligned */ + assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ RTREE_DECODE_COORD(eInt, pCellData, xN); switch( p->op ){ case RTREE_TRUE: return; /* Always satisfied */ case RTREE_FALSE: break; /* Never satisfied */ case RTREE_LE: if( xN <= p->u.rValue ) return; break; @@ -204589,11 +201260,11 @@ return SQLITE_LOCKED_VTAB; } rtreeReference(pRtree); assert(nData>=1); - memset(&cell, 0, sizeof(cell)); + cell.iRowid = 0; /* Used only to suppress a compiler warning */ /* Constraint handling. A write operation on an r-tree table may return ** SQLITE_CONSTRAINT for two reasons: ** ** 1. A duplicate rowid value, or @@ -206062,11 +202733,11 @@ ){ GeoPoly *p = 0; int nByte; testcase( pCtx==0 ); if( sqlite3_value_type(pVal)==SQLITE_BLOB - && (nByte = sqlite3_value_bytes(pVal))>=(int)(4+6*sizeof(GeoCoord)) + && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord)) ){ const unsigned char *a = sqlite3_value_blob(pVal); int nVertex; if( a==0 ){ if( pCtx ) sqlite3_result_error_nomem(pCtx); @@ -206120,11 +202791,10 @@ sqlite3_context *context, int argc, sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); - (void)argc; if( p ){ sqlite3_result_blob(context, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); sqlite3_free(p); } @@ -206140,11 +202810,10 @@ sqlite3_context *context, int argc, sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); - (void)argc; if( p ){ sqlite3 *db = sqlite3_context_db_handle(context); sqlite3_str *x = sqlite3_str_new(db); int i; sqlite3_str_append(x, "[", 1); @@ -206222,11 +202891,10 @@ double D = sqlite3_value_double(argv[4]); double E = sqlite3_value_double(argv[5]); double F = sqlite3_value_double(argv[6]); GeoCoord x1, y1, x0, y0; int ii; - (void)argc; if( p ){ for(ii=0; iinVertex; ii++){ x0 = GeoX(p,ii); y0 = GeoY(p,ii); x1 = (GeoCoord)(A*x0 + B*y0 + E); @@ -206273,11 +202941,10 @@ sqlite3_context *context, int argc, sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); - (void)argc; if( p ){ sqlite3_result_double(context, geopolyArea(p)); sqlite3_free(p); } } @@ -206299,11 +202966,10 @@ sqlite3_context *context, int argc, sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); - (void)argc; if( p ){ if( geopolyArea(p)<0.0 ){ int ii, jj; for(ii=1, jj=p->nVertex-1; ii1000 ) n = 1000; p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) ); if( p==0 ){ @@ -206464,11 +203129,10 @@ sqlite3_context *context, int argc, sqlite3_value **argv ){ GeoPoly *p = geopolyBBox(context, argv[0], 0, 0); - (void)argc; if( p ){ sqlite3_result_blob(context, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); sqlite3_free(p); } @@ -206492,11 +203156,10 @@ int argc, sqlite3_value **argv ){ RtreeCoord a[4]; int rc = SQLITE_OK; - (void)argc; (void)geopolyBBox(context, argv[0], a, &rc); if( rc==SQLITE_OK ){ GeoBBox *pBBox; pBBox = (GeoBBox*)sqlite3_aggregate_context(context, sizeof(*pBBox)); if( pBBox==0 ) return; @@ -206581,12 +203244,10 @@ double x0 = sqlite3_value_double(argv[1]); double y0 = sqlite3_value_double(argv[2]); int v = 0; int cnt = 0; int ii; - (void)argc; - if( p1==0 ) return; for(ii=0; iinVertex-1; ii++){ v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii), GeoX(p1,ii+1),GeoY(p1,ii+1)); if( v==2 ) break; @@ -206622,11 +203283,10 @@ int argc, sqlite3_value **argv ){ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); - (void)argc; if( p1 && p2 ){ int x = geopolyOverlap(p1, p2); if( x<0 ){ sqlite3_result_error_nomem(context); }else{ @@ -206953,11 +203613,10 @@ int argc, sqlite3_value **argv ){ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); - (void)argc; if( p1 && p2 ){ int x = geopolyOverlap(p1, p2); if( x<0 ){ sqlite3_result_error_nomem(context); }else{ @@ -206974,16 +203633,12 @@ static void geopolyDebugFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ - (void)context; - (void)argc; #ifdef GEOPOLY_ENABLE_DEBUG geo_debug = sqlite3_value_int(argv[0]); -#else - (void)argv; #endif } /* ** This function is the implementation of both the xConnect and xCreate @@ -207007,11 +203662,10 @@ sqlite3_int64 nDb; /* Length of string argv[1] */ sqlite3_int64 nName; /* Length of string argv[2] */ sqlite3_str *pSql; char *zSql; int ii; - (void)pAux; sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); /* Allocate the sqlite3_vtab structure */ nDb = strlen(argv[1]); @@ -207124,11 +203778,10 @@ Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; RtreeNode *pRoot = 0; int rc = SQLITE_OK; int iCell = 0; - (void)idxStr; rtreeReference(pRtree); /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ resetCursor(pCsr); @@ -207251,11 +203904,10 @@ static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int ii; int iRowidTerm = -1; int iFuncTerm = -1; int idxNum = 0; - (void)tab; for(ii=0; iinConstraint; ii++){ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; if( !p->usable ) continue; if( p->iColumn<0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ @@ -207472,11 +204124,11 @@ sqlite3_bind_value(pUp, 2, aData[2]); } sqlite3_free(p); nChange = 1; } - for(jj=1; jjnAux; jj++){ nChange++; sqlite3_bind_value(pUp, jj+2, aData[jj+2]); } if( nChange ){ sqlite3_step(pUp); @@ -207498,12 +204150,10 @@ int nArg, const char *zName, void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), void **ppArg ){ - (void)pVtab; - (void)nArg; if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){ *pxFunc = geopolyOverlapFunc; *ppArg = 0; return SQLITE_INDEX_CONSTRAINT_FUNCTION; } @@ -207569,11 +204219,11 @@ void (*xFinal)(sqlite3_context*); const char *zName; } aAgg[] = { { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" }, }; - unsigned int i; + int i; for(i=0; i naming scheme. +** tables or view named using the data_ naming scheme. ** ** Instead of the plain data_ naming scheme, RBU database tables ** may also be named data_, where is any sequence ** of zero or more numeric characters (0-9). This can be significant because ** tables within the RBU database are always processed in order sorted by @@ -208803,11 +205452,11 @@ ** are processed. This can be useful, for example, to ensure that "external ** content" FTS4 tables are updated before their underlying content tables. ** ** If the target database table is a virtual table or a table that has no ** PRIMARY KEY declaration, the data_% table must also contain a column -** named "rbu_rowid". This column is mapped to the table's implicit primary +** named "rbu_rowid". This column is mapped to the tables implicit primary ** key column - "rowid". Virtual tables for which the "rowid" column does ** not function like a primary key value cannot be updated using RBU. For ** example, if the target db contains either of the following: ** ** CREATE VIRTUAL TABLE x1 USING fts3(a, b); @@ -209235,38 +205884,10 @@ #define SQLITE_RBU_STATE_CHECKPOINT 3 #define SQLITE_RBU_STATE_DONE 4 #define SQLITE_RBU_STATE_ERROR 5 SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu); - -/* -** As part of applying an RBU update or performing an RBU vacuum operation, -** the system must at one point move the *-oal file to the equivalent *-wal -** path. Normally, it does this by invoking POSIX function rename(2) directly. -** Except on WINCE platforms, where it uses win32 API MoveFileW(). This -** function may be used to register a callback that the RBU module will invoke -** instead of one of these APIs. -** -** If a callback is registered with an RBU handle, it invokes it instead -** of rename(2) when it needs to move a file within the file-system. The -** first argument passed to the xRename() callback is a copy of the second -** argument (pArg) passed to this function. The second is the full path -** to the file to move and the third the full path to which it should be -** moved. The callback function should return SQLITE_OK to indicate -** success. If an error occurs, it should return an SQLite error code. -** In this case the RBU operation will be abandoned and the error returned -** to the RBU user. -** -** Passing a NULL pointer in place of the xRename argument to this function -** restores the default behaviour. -*/ -SQLITE_API void sqlite3rbu_rename_handler( - sqlite3rbu *pRbu, - void *pArg, - int (*xRename)(void *pArg, const char *zOld, const char *zNew) -); - /* ** Create an RBU VFS named zName that accesses the underlying file-system ** via existing VFS zParent. Or, if the zParent parameter is passed NULL, ** then the new RBU VFS uses the default system VFS to access the file-system. @@ -209631,12 +206252,10 @@ const char *zVfsName; /* Name of automatically created rbu vfs */ rbu_file *pTargetFd; /* File handle open on target db */ int nPagePerSector; /* Pages per sector for pTargetFd */ i64 iOalSz; i64 nPhaseOneStep; - void *pRenameArg; - int (*xRename)(void*, const char*, const char*); /* The following state variables are used as part of the incremental ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding ** function rbuSetupCheckpoint() for details. */ u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */ @@ -212021,11 +208640,11 @@ if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); if( p->zState==0 ){ const char *zFile = sqlite3_db_filename(p->dbRbu, "main"); - p->zState = rbuMPrintf(p, "file:///%s-vacuum?modeof=%s", zFile, zFile); + p->zState = rbuMPrintf(p, "file://%s-vacuum?modeof=%s", zFile, zFile); } } /* If using separate RBU and state databases, attach the state database to ** the RBU db handle now. */ @@ -212269,25 +208888,25 @@ ** * Calls to xShmLock(UNLOCK) to release the exclusive shm WRITER, ** READ0 and CHECKPOINT locks taken as part of the checkpoint are ** no-ops. These locks will not be released until the connection ** is closed. ** - ** * Attempting to xSync() the database file causes an SQLITE_NOTICE + ** * Attempting to xSync() the database file causes an SQLITE_INTERNAL ** error. ** ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the - ** checkpoint below fails with SQLITE_NOTICE, and leaves the aFrame[] + ** checkpoint below fails with SQLITE_INTERNAL, and leaves the aFrame[] ** array populated with a set of (frame -> page) mappings. Because the ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy ** data from the wal file into the database file according to the ** contents of aFrame[]. */ if( p->rc==SQLITE_OK ){ int rc2; p->eStage = RBU_STAGE_CAPTURE; rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0); - if( rc2!=SQLITE_NOTICE ) p->rc = rc2; + if( rc2!=SQLITE_INTERNAL ) p->rc = rc2; } if( p->rc==SQLITE_OK && p->nFrame>0 ){ p->eStage = RBU_STAGE_CKPT; p->nStep = (pState ? pState->nRow : 0); @@ -212329,11 +208948,11 @@ const u32 mReq = (1<mLock!=mReq ){ pRbu->rc = SQLITE_BUSY; - return SQLITE_NOTICE_RBU; + return SQLITE_INTERNAL; } pRbu->pgsz = iAmt; if( pRbu->nFrame==pRbu->nFrameAlloc ){ int nNew = (pRbu->nFrameAlloc ? pRbu->nFrameAlloc : 64) * 2; @@ -212481,11 +209100,36 @@ assert( p->rc==SQLITE_OK ); p->rc = rbuLockDatabase(dbMain); } if( p->rc==SQLITE_OK ){ - p->rc = p->xRename(p->pRenameArg, zOal, zWal); +#if defined(_WIN32_WCE) + { + LPWSTR zWideOal; + LPWSTR zWideWal; + + zWideOal = rbuWinUtf8ToUnicode(zOal); + if( zWideOal ){ + zWideWal = rbuWinUtf8ToUnicode(zWal); + if( zWideWal ){ + if( MoveFileW(zWideOal, zWideWal) ){ + p->rc = SQLITE_OK; + }else{ + p->rc = SQLITE_IOERR; + } + sqlite3_free(zWideWal); + }else{ + p->rc = SQLITE_IOERR_NOMEM; + } + sqlite3_free(zWideOal); + }else{ + p->rc = SQLITE_IOERR_NOMEM; + } + } +#else + p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK; +#endif } if( p->rc!=SQLITE_OK || rbuIsVacuum(p) || rbuExclusiveCheckpoint(dbMain)==0 @@ -213068,12 +209712,11 @@ ** leave an error code and error message in the rbu handle. */ static void rbuDeleteOalFile(sqlite3rbu *p){ char *zOal = rbuMPrintf(p, "%s-oal", p->zTarget); if( zOal ){ - sqlite3_vfs *pVfs = 0; - sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_VFS_POINTER, &pVfs); + sqlite3_vfs *pVfs = sqlite3_vfs_find(0); assert( pVfs && p->rc==SQLITE_OK && p->zErrmsg==0 ); pVfs->xDelete(pVfs, zOal, 0); sqlite3_free(zOal); } } @@ -213221,11 +209864,10 @@ if( p ){ RbuState *pState = 0; /* Create the custom VFS. */ memset(p, 0, sizeof(sqlite3rbu)); - sqlite3rbu_rename_handler(p, 0, 0); rbuCreateVfs(p); /* Open the target, RBU and state databases */ if( p->rc==SQLITE_OK ){ char *pCsr = (char*)&p[1]; @@ -213613,58 +210255,10 @@ p->rc = rc; return rc; } -/* -** Default xRename callback for RBU. -*/ -static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){ - int rc = SQLITE_OK; -#if defined(_WIN32_WCE) - { - LPWSTR zWideOld; - LPWSTR zWideNew; - - zWideOld = rbuWinUtf8ToUnicode(zOld); - if( zWideOld ){ - zWideNew = rbuWinUtf8ToUnicode(zNew); - if( zWideNew ){ - if( MoveFileW(zWideOld, zWideNew) ){ - rc = SQLITE_OK; - }else{ - rc = SQLITE_IOERR; - } - sqlite3_free(zWideNew); - }else{ - rc = SQLITE_IOERR_NOMEM; - } - sqlite3_free(zWideOld); - }else{ - rc = SQLITE_IOERR_NOMEM; - } - } -#else - rc = rename(zOld, zNew) ? SQLITE_IOERR : SQLITE_OK; -#endif - return rc; -} - -SQLITE_API void sqlite3rbu_rename_handler( - sqlite3rbu *pRbu, - void *pArg, - int (*xRename)(void *pArg, const char *zOld, const char *zNew) -){ - if( xRename ){ - pRbu->xRename = xRename; - pRbu->pRenameArg = pArg; - }else{ - pRbu->xRename = xDefaultRename; - pRbu->pRenameArg = 0; - } -} - /************************************************************************** ** Beginning of RBU VFS shim methods. The VFS shim modifies the behaviour ** of a standard VFS in the following ways: ** ** 1. Whenever the first page of a main database file is read or @@ -213717,11 +210311,11 @@ ** are recorded. Additionally, successful attempts to obtain exclusive ** xShmLock() WRITER, CHECKPOINTER and READ0 locks on the target ** database file are recorded. xShmLock() calls to unlock the same ** locks are no-ops (so that once obtained, these locks are never ** relinquished). Finally, calls to xSync() on the target database -** file fail with SQLITE_NOTICE errors. +** file fail with SQLITE_INTERNAL errors. */ static void rbuUnlockShm(rbu_file *p){ assert( p->openFlags & SQLITE_OPEN_MAIN_DB ); if( p->pRbu ){ @@ -213826,16 +210420,13 @@ sqlite3_free(p->apShm); p->apShm = 0; sqlite3_free(p->zDel); if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ - const sqlite3_io_methods *pMeth = p->pReal->pMethods; rbuMainlistRemove(p); rbuUnlockShm(p); - if( pMeth->iVersion>1 && pMeth->xShmUnmap ){ - pMeth->xShmUnmap(p->pReal, 0); - } + p->pReal->pMethods->xShmUnmap(p->pReal, 0); } else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){ rbuUpdateTempSize(p, 0); } assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p ); @@ -213999,11 +210590,11 @@ */ static int rbuVfsSync(sqlite3_file *pFile, int flags){ rbu_file *p = (rbu_file *)pFile; if( p->pRbu && p->pRbu->eStage==RBU_STAGE_CAPTURE ){ if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ - return SQLITE_NOTICE_RBU; + return SQLITE_INTERNAL; } return SQLITE_OK; } return p->pReal->pMethods->xSync(p->pReal, flags); } @@ -214290,29 +210881,10 @@ rbuVfsShmLock, /* xShmLock */ rbuVfsShmBarrier, /* xShmBarrier */ rbuVfsShmUnmap, /* xShmUnmap */ 0, 0 /* xFetch, xUnfetch */ }; - static sqlite3_io_methods rbuvfs_io_methods1 = { - 1, /* iVersion */ - rbuVfsClose, /* xClose */ - rbuVfsRead, /* xRead */ - rbuVfsWrite, /* xWrite */ - rbuVfsTruncate, /* xTruncate */ - rbuVfsSync, /* xSync */ - rbuVfsFileSize, /* xFileSize */ - rbuVfsLock, /* xLock */ - rbuVfsUnlock, /* xUnlock */ - rbuVfsCheckReservedLock, /* xCheckReservedLock */ - rbuVfsFileControl, /* xFileControl */ - rbuVfsSectorSize, /* xSectorSize */ - rbuVfsDeviceCharacteristics, /* xDeviceCharacteristics */ - 0, 0, 0, 0, 0, 0 - }; - - - rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs; sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs; rbu_file *pFd = (rbu_file *)pFile; int rc = SQLITE_OK; const char *zOpen = zName; @@ -214363,19 +210935,14 @@ if( rc==SQLITE_OK ){ rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, oflags, pOutFlags); } if( pFd->pReal->pMethods ){ - const sqlite3_io_methods *pMeth = pFd->pReal->pMethods; /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods ** pointer and, if the file is a main database file, link it into the ** mutex protected linked list of all such files. */ - if( pMeth->iVersion<2 || pMeth->xShmLock==0 ){ - pFile->pMethods = &rbuvfs_io_methods1; - }else{ - pFile->pMethods = &rbuvfs_io_methods; - } + pFile->pMethods = &rbuvfs_io_methods; if( flags & SQLITE_OPEN_MAIN_DB ){ rbuMainlistAdd(pFd); } }else{ sqlite3_free(pFd->zDel); @@ -214804,11 +211371,10 @@ char **pzErr ){ StatTable *pTab = 0; int rc = SQLITE_OK; int iDb; - (void)pAux; if( argc>=4 ){ Token nm; sqlite3TokenInit(&nm, (char*)argv[3]); iDb = sqlite3FindDb(db, &nm); @@ -214858,11 +211424,10 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int i; int iSchema = -1; int iName = -1; int iAgg = -1; - (void)tab; /* Look for a valid schema=? constraint. If found, change the idxNum to ** 1 and request the value of that constraint be sent to xFilter. And ** lower the cost estimate to encourage the constrained version to be ** used. @@ -215384,12 +211949,10 @@ sqlite3_str *pSql; /* Query of btrees to analyze */ char *zSql; /* String value of pSql */ int iArg = 0; /* Count of argv[] parameters used so far */ int rc = SQLITE_OK; /* Result of this operation */ const char *zName = 0; /* Only provide analysis of this table */ - (void)argc; - (void)idxStr; statResetCsr(pCsr); sqlite3_finalize(pCsr->pStmt); pCsr->pStmt = 0; if( idxNum & 0x01 ){ @@ -215469,28 +212032,28 @@ if( !pCsr->isAgg ){ sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC); } break; case 4: /* ncell */ - sqlite3_result_int64(ctx, pCsr->nCell); + sqlite3_result_int(ctx, pCsr->nCell); break; case 5: /* payload */ - sqlite3_result_int64(ctx, pCsr->nPayload); + sqlite3_result_int(ctx, pCsr->nPayload); break; case 6: /* unused */ - sqlite3_result_int64(ctx, pCsr->nUnused); + sqlite3_result_int(ctx, pCsr->nUnused); break; case 7: /* mx_payload */ - sqlite3_result_int64(ctx, pCsr->nMxPayload); + sqlite3_result_int(ctx, pCsr->nMxPayload); break; case 8: /* pgoffset */ if( !pCsr->isAgg ){ sqlite3_result_int64(ctx, pCsr->iOffset); } break; case 9: /* pgsize */ - sqlite3_result_int64(ctx, pCsr->szPage); + sqlite3_result_int(ctx, pCsr->szPage); break; case 10: { /* schema */ sqlite3 *db = sqlite3_context_db_handle(ctx); int iDb = pCsr->iDb; sqlite3_result_text(ctx, db->aDb[iDb].zDbSName, -1, SQLITE_STATIC); @@ -215620,14 +212183,10 @@ sqlite3_vtab **ppVtab, char **pzErr ){ DbpageTable *pTab = 0; int rc = SQLITE_OK; - (void)pAux; - (void)argc; - (void)argv; - (void)pzErr; sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); rc = sqlite3_declare_vtab(db, "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)"); if( rc==SQLITE_OK ){ @@ -215662,11 +212221,10 @@ ** 3 schema=?1, pgno=?2 */ static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int i; int iPlan = 0; - (void)tab; /* If there is a schema= constraint, it must be honored. Report a ** ridiculously large estimated cost if the schema= constraint is ** unavailable */ @@ -215778,12 +212336,10 @@ DbpageTable *pTab = (DbpageTable *)pCursor->pVtab; int rc; sqlite3 *db = pTab->db; Btree *pBt; - (void)idxStr; - /* Default setting is no rows of result */ pCsr->pgno = 1; pCsr->mxPgno = 0; if( idxNum & 2 ){ @@ -215794,11 +212350,11 @@ if( pCsr->iDb<0 ) return SQLITE_OK; }else{ pCsr->iDb = 0; } pBt = db->aDb[pCsr->iDb].pBt; - if( NEVER(pBt==0) ) return SQLITE_OK; + if( pBt==0 ) return SQLITE_OK; pCsr->pPager = sqlite3BtreePager(pBt); pCsr->szPage = sqlite3BtreeGetPageSize(pBt); pCsr->mxPgno = sqlite3BtreeLastPage(pBt); if( idxNum & 1 ){ assert( argc>(idxNum>>1) ); @@ -215829,31 +212385,25 @@ sqlite3_result_int(ctx, pCsr->pgno); break; } case 1: { /* data */ DbPage *pDbPage = 0; - if( pCsr->pgno==((PENDING_BYTE/pCsr->szPage)+1) ){ - /* The pending byte page. Assume it is zeroed out. Attempting to - ** request this page from the page is an SQLITE_CORRUPT error. */ - sqlite3_result_zeroblob(ctx, pCsr->szPage); - }else{ - rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0); - if( rc==SQLITE_OK ){ - sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage, - SQLITE_TRANSIENT); - } - sqlite3PagerUnref(pDbPage); - } + rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0); + if( rc==SQLITE_OK ){ + sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage, + SQLITE_TRANSIENT); + } + sqlite3PagerUnref(pDbPage); break; } default: { /* schema */ sqlite3 *db = sqlite3_context_db_handle(ctx); sqlite3_result_text(ctx, db->aDb[pCsr->iDb].zDbSName, -1, SQLITE_STATIC); break; } } - return rc; + return SQLITE_OK; } static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ DbpageCursor *pCsr = (DbpageCursor *)pCursor; *pRowid = pCsr->pgno; @@ -215875,34 +212425,31 @@ int iDb; Btree *pBt; Pager *pPager; int szPage; - (void)pRowid; if( pTab->db->flags & SQLITE_Defensive ){ zErr = "read-only"; goto update_fail; } if( argc==1 ){ zErr = "cannot delete"; goto update_fail; } pgno = sqlite3_value_int(argv[0]); - if( sqlite3_value_type(argv[0])==SQLITE_NULL - || (Pgno)sqlite3_value_int(argv[1])!=pgno - ){ + if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ zErr = "cannot insert"; goto update_fail; } zSchema = (const char*)sqlite3_value_text(argv[4]); - iDb = ALWAYS(zSchema) ? sqlite3FindDbName(pTab->db, zSchema) : -1; - if( NEVER(iDb<0) ){ + iDb = zSchema ? sqlite3FindDbName(pTab->db, zSchema) : -1; + if( iDb<0 ){ zErr = "no such schema"; goto update_fail; } pBt = pTab->db->aDb[iDb].pBt; - if( NEVER(pgno<1) || NEVER(pBt==0) || NEVER(pgno>sqlite3BtreeLastPage(pBt)) ){ + if( pgno<1 || pBt==0 || pgno>sqlite3BtreeLastPage(pBt) ){ zErr = "bad page number"; goto update_fail; } szPage = sqlite3BtreeGetPageSize(pBt); if( sqlite3_value_type(argv[3])!=SQLITE_BLOB @@ -215912,16 +212459,15 @@ goto update_fail; } pPager = sqlite3BtreePager(pBt); rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); if( rc==SQLITE_OK ){ - const void *pData = sqlite3_value_blob(argv[3]); - assert( pData!=0 || pTab->db->mallocFailed ); - if( pData - && (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK - ){ - memcpy(sqlite3PagerGetData(pDbPage), pData, szPage); + rc = sqlite3PagerWrite(pDbPage); + if( rc==SQLITE_OK ){ + memcpy(sqlite3PagerGetData(pDbPage), + sqlite3_value_blob(argv[3]), + szPage); } } sqlite3PagerUnref(pDbPage); return rc; @@ -215939,11 +212485,11 @@ DbpageTable *pTab = (DbpageTable *)pVtab; sqlite3 *db = pTab->db; int i; for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0); + if( pBt ) sqlite3BtreeBeginTrans(pBt, 1, 0); } return SQLITE_OK; } @@ -217484,12 +214030,10 @@ ){ sqlite3_session *pSession; int nDb = sqlite3Strlen30(zDb); assert( sqlite3_mutex_held(db->mutex) ); - (void)iKey1; - (void)iKey2; for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){ SessionTable *pTab; /* If this session is attached to a different database ("main", "temp" @@ -217562,11 +214106,10 @@ static int sessionDiffCount(void *pCtx){ SessionDiffCtx *p = (SessionDiffCtx*)pCtx; return p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt); } static int sessionDiffDepth(void *pCtx){ - (void)pCtx; return 0; } /* ** Install the diff hooks on the session object passed as the only @@ -217636,10 +214179,11 @@ return zRet; } static char *sessionSelectFindNew( + int nCol, const char *zDb1, /* Pick rows in this db only */ const char *zDb2, /* But not in this one */ const char *zTbl, /* Table name */ const char *zExpr ){ @@ -217659,11 +214203,11 @@ const char *zDb1, const char *zDb2, char *zExpr ){ int rc = SQLITE_OK; - char *zStmt = sessionSelectFindNew(zDb1, zDb2, pTab->zName,zExpr); + char *zStmt = sessionSelectFindNew(pTab->nCol, zDb1, zDb2, pTab->zName,zExpr); if( zStmt==0 ){ rc = SQLITE_NOMEM; }else{ sqlite3_stmt *pStmt; @@ -219314,26 +215858,10 @@ } }else if( p->bInvert ){ if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE; else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT; } - - /* If this is an UPDATE that is part of a changeset, then check that - ** there are no fields in the old.* record that are not (a) PK fields, - ** or (b) also present in the new.* record. - ** - ** Such records are technically corrupt, but the rebaser was at one - ** point generating them. Under most circumstances this is benign, but - ** can cause spurious SQLITE_RANGE errors when applying the changeset. */ - if( p->bPatchset==0 && p->op==SQLITE_UPDATE){ - for(i=0; inCol; i++){ - if( p->abPK[i]==0 && p->apValue[i+p->nCol]==0 ){ - sqlite3ValueFree(p->apValue[i]); - p->apValue[i] = 0; - } - } - } } return SQLITE_ROW; } @@ -220176,10 +216704,11 @@ ** If the iterator currently points to an INSERT record, bind values from the ** new.* record to the SELECT statement. Or, if it points to a DELETE or ** UPDATE, bind values from the old.* record. */ static int sessionSeekToRow( + sqlite3 *db, /* Database handle */ sqlite3_changeset_iter *pIter, /* Changeset iterator */ u8 *abPK, /* Primary key flags array */ sqlite3_stmt *pSelect /* SELECT statement from sessionSelectRow() */ ){ int rc; /* Return code */ @@ -220305,11 +216834,11 @@ assert( SQLITE_CHANGESET_CONFLICT+1==SQLITE_CHANGESET_CONSTRAINT ); assert( SQLITE_CHANGESET_DATA+1==SQLITE_CHANGESET_NOTFOUND ); /* Bind the new.* PRIMARY KEY values to the SELECT statement. */ if( pbReplace ){ - rc = sessionSeekToRow(pIter, p->abPK, p->pSelect); + rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect); }else{ rc = SQLITE_OK; } if( rc==SQLITE_ROW ){ @@ -220479,11 +217008,11 @@ assert( op==SQLITE_INSERT ); if( p->bStat1 ){ /* Check if there is a conflicting row. For sqlite_stat1, this needs ** to be done using a SELECT, as there is no PRIMARY KEY in the ** database schema to throw an exception if a duplicate is inserted. */ - rc = sessionSeekToRow(pIter, p->abPK, p->pSelect); + rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect); if( rc==SQLITE_ROW ){ rc = SQLITE_CONSTRAINT; sqlite3_reset(p->pSelect); } } @@ -221525,11 +218054,11 @@ int n2 = sessionSerialLen(a2); if( pIter->abPK[i] || a2[0]==0 ){ if( !pIter->abPK[i] && a1[0] ) bData = 1; memcpy(pOut, a1, n1); pOut += n1; - }else if( a2[0]!=0xFF && a1[0] ){ + }else if( a2[0]!=0xFF ){ bData = 1; memcpy(pOut, a2, n2); pOut += n2; }else{ *pOut++ = '\0'; @@ -222682,11 +219211,11 @@ static void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...); static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); #define fts5BufferZero(x) sqlite3Fts5BufferZero(x) -#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,(i64)c) +#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c) #define fts5BufferFree(a) sqlite3Fts5BufferFree(a) #define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d) #define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d) #define fts5BufferGrow(pRc,pBuf,nn) ( \ @@ -230526,12 +227055,10 @@ #if FTS5_MAX_PREFIX_INDEXES > 31 # error "FTS5_MAX_PREFIX_INDEXES is too large" #endif -#define FTS5_MAX_LEVEL 64 - /* ** Details: ** ** The %_data table managed by this module, ** @@ -234561,13 +231088,11 @@ /* Write the rowid. */ if( pWriter->bFirstRowidInDoclist || pWriter->bFirstRowidInPage ){ fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid); }else{ assert_nc( p->rc || iRowid>pWriter->iPrevRowid ); - fts5BufferAppendVarint(&p->rc, &pPage->buf, - (u64)iRowid - (u64)pWriter->iPrevRowid - ); + fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid - pWriter->iPrevRowid); } pWriter->iPrevRowid = iRowid; pWriter->bFirstRowidInDoclist = 0; pWriter->bFirstRowidInPage = 0; } @@ -235245,11 +231770,11 @@ Fts5StructureLevel *pLvl; nByte = nSeg * sizeof(Fts5StructureSegment); pNew->nLevel = pStruct->nLevel+1; pNew->nRef = 1; pNew->nWriteCounter = pStruct->nWriteCounter; - pLvl = &pNew->aLevel[MIN(pStruct->nLevel, FTS5_MAX_LEVEL-1)]; + pLvl = &pNew->aLevel[pStruct->nLevel]; pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pLvl->aSeg ){ int iLvl, iSeg; int iSegOut = 0; /* Iterate through all segments, from oldest to newest. Add them to @@ -235327,21 +231852,21 @@ return fts5IndexReturn(p); } static void fts5AppendRowid( Fts5Index *p, - u64 iDelta, + i64 iDelta, Fts5Iter *pUnused, Fts5Buffer *pBuf ){ UNUSED_PARAM(pUnused); fts5BufferAppendVarint(&p->rc, pBuf, iDelta); } static void fts5AppendPoslist( Fts5Index *p, - u64 iDelta, + i64 iDelta, Fts5Iter *pMulti, Fts5Buffer *pBuf ){ int nData = pMulti->base.nData; int nByte = nData + 9 + 9 + FTS5_DATA_ZERO_PADDING; @@ -235412,14 +231937,14 @@ fts5BufferSafeAppendVarint(pBuf, iRowid - *piLastRowid); *piLastRowid = iRowid; } #endif -#define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) { \ - assert( (pBuf)->n!=0 || (iLastRowid)==0 ); \ - fts5BufferSafeAppendVarint((pBuf), (u64)(iRowid) - (u64)(iLastRowid)); \ - (iLastRowid) = (iRowid); \ +#define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) { \ + assert( (pBuf)->n!=0 || (iLastRowid)==0 ); \ + fts5BufferSafeAppendVarint((pBuf), (iRowid) - (iLastRowid)); \ + (iLastRowid) = (iRowid); \ } /* ** Swap the contents of buffer *p1 with that of *p2. */ @@ -235547,11 +232072,11 @@ i64 iLastRowid = 0; /* Initialize a doclist-iterator for each input buffer. Arrange them in ** a linked-list starting at pHead in ascending order of rowid. Avoid ** linking any iterators already at EOF into the linked list at all. */ - assert( nBuf+1<=(int)(sizeof(aMerger)/sizeof(aMerger[0])) ); + assert( nBuf+1<=sizeof(aMerger)/sizeof(aMerger[0]) ); memset(aMerger, 0, sizeof(PrefixMerger)*(nBuf+1)); pHead = &aMerger[nBuf]; fts5DoclistIterInit(p1, &pHead->iter); for(i=0; ipConfig->eDetail==FTS5_DETAIL_NONE ){ xMerge = fts5MergeRowidLists; xAppend = fts5AppendRowid; }else{ nMerge = FTS5_MERGE_NLIST-1; @@ -235725,11 +232250,11 @@ fts5MultiIterNext2(p, p1, &dummy) ){ Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; p1->xSetOutputs(p1, pSeg); if( p1->base.nData ){ - xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist); + xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist); iLastRowid = p1->base.iRowid; } } fts5MultiIterFree(p1); } @@ -235773,11 +232298,11 @@ } } iLastRowid = 0; } - xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist); + xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist); iLastRowid = p1->base.iRowid; } assert( (nBuf%nMerge)==0 ); for(i=0; irc ) break; if( eDetail==FTS5_DETAIL_NONE ){ if( 0==fts5MultiIterIsEmpty(p, pIter) ){ cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, 0, 0, -1, z, n); } @@ -237557,11 +234081,11 @@ p->ts.eState = 1; p->ts.iSavepoint = -1; break; case FTS5_SYNC: - assert( p->ts.eState==1 || p->ts.eState==2 ); + assert( p->ts.eState==1 ); p->ts.eState = 2; break; case FTS5_COMMIT: assert( p->ts.eState==2 ); @@ -237572,25 +234096,25 @@ assert( p->ts.eState==1 || p->ts.eState==2 || p->ts.eState==0 ); p->ts.eState = 0; break; case FTS5_SAVEPOINT: - assert( p->ts.eState>=1 ); + assert( p->ts.eState==1 ); assert( iSavepoint>=0 ); assert( iSavepoint>=p->ts.iSavepoint ); p->ts.iSavepoint = iSavepoint; break; case FTS5_RELEASE: - assert( p->ts.eState>=1 ); + assert( p->ts.eState==1 ); assert( iSavepoint>=0 ); assert( iSavepoint<=p->ts.iSavepoint ); p->ts.iSavepoint = iSavepoint-1; break; case FTS5_ROLLBACKTO: - assert( p->ts.eState>=1 ); + assert( p->ts.eState==1 ); assert( iSavepoint>=-1 ); /* The following assert() can fail if another vtab strikes an error ** within an xSavepoint() call then SQLite calls xRollbackTo() - without ** having called xSavepoint() on this vtab. */ /* assert( iSavepoint<=p->ts.iSavepoint ); */ @@ -238922,11 +235446,11 @@ Fts5Config *pConfig = pTab->p.pConfig; int eType0; /* value_type() of apVal[0] */ int rc = SQLITE_OK; /* Return code */ /* A transaction must be open when this is called. */ - assert( pTab->ts.eState==1 || pTab->ts.eState==2 ); + assert( pTab->ts.eState==1 ); assert( pVtab->zErrMsg==0 ); assert( nArg==1 || nArg==(2+pConfig->nCol+2) ); assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER || sqlite3_value_type(apVal[0])==SQLITE_NULL @@ -240090,11 +236614,11 @@ int nArg, /* Number of args */ sqlite3_value **apUnused /* Function arguments */ ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2023-02-05 17:09:18 6a58179aaffa77a5542ab620ffce6f68135e399de957b1a97113fd2f1dc0c098", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2022-06-22 18:51:47 83ff1a28e3e7a99fa90d5079897d76529c4256eed859bf7cb98b860fbedfdc5b", -1, SQLITE_TRANSIENT); } /* ** Return true if zName is the extension on one of the shadow tables used ** by this module. @@ -240163,13 +236687,11 @@ db, "fts5", 1, SQLITE_UTF8, p, fts5Fts5Func, 0, 0 ); } if( rc==SQLITE_OK ){ rc = sqlite3_create_function( - db, "fts5_source_id", 0, - SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS, - p, fts5SourceIdFunc, 0, 0 + db, "fts5_source_id", 0, SQLITE_UTF8, p, fts5SourceIdFunc, 0, 0 ); } } /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file @@ -244763,20 +241285,10 @@ /* #include */ /* #include */ #ifndef SQLITE_OMIT_VIRTUALTABLE - -#define STMT_NUM_INTEGER_COLUMN 10 -typedef struct StmtRow StmtRow; -struct StmtRow { - sqlite3_int64 iRowid; /* Rowid value */ - char *zSql; /* column "sql" */ - int aCol[STMT_NUM_INTEGER_COLUMN+1]; /* all other column values */ - StmtRow *pNext; /* Next row to return */ -}; - /* stmt_vtab is a subclass of sqlite3_vtab which will ** serve as the underlying representation of a stmt virtual table */ typedef struct stmt_vtab stmt_vtab; struct stmt_vtab { @@ -244790,11 +241302,12 @@ */ typedef struct stmt_cursor stmt_cursor; struct stmt_cursor { sqlite3_vtab_cursor base; /* Base class - must be first */ sqlite3 *db; /* Database connection for this cursor */ - StmtRow *pRow; /* Current row */ + sqlite3_stmt *pStmt; /* Statement cursor is currently pointing at */ + sqlite3_int64 iRowid; /* The rowid */ }; /* ** The stmtConnect() method is invoked to create a new ** stmt_vtab that describes the stmt virtual table. @@ -244830,19 +241343,15 @@ #define STMT_COLUMN_REPREP 8 /* SQLITE_STMTSTATUS_REPREPARE */ #define STMT_COLUMN_RUN 9 /* SQLITE_STMTSTATUS_RUN */ #define STMT_COLUMN_MEM 10 /* SQLITE_STMTSTATUS_MEMUSED */ - (void)pAux; - (void)argc; - (void)argv; - (void)pzErr; rc = sqlite3_declare_vtab(db, "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep," "reprep,run,mem)"); if( rc==SQLITE_OK ){ - pNew = sqlite3_malloc64( sizeof(*pNew) ); + pNew = sqlite3_malloc( sizeof(*pNew) ); *ppVtab = (sqlite3_vtab*)pNew; if( pNew==0 ) return SQLITE_NOMEM; memset(pNew, 0, sizeof(*pNew)); pNew->db = db; } @@ -244860,33 +241369,22 @@ /* ** Constructor for a new stmt_cursor object. */ static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ stmt_cursor *pCur; - pCur = sqlite3_malloc64( sizeof(*pCur) ); + pCur = sqlite3_malloc( sizeof(*pCur) ); if( pCur==0 ) return SQLITE_NOMEM; memset(pCur, 0, sizeof(*pCur)); pCur->db = ((stmt_vtab*)p)->db; *ppCursor = &pCur->base; return SQLITE_OK; } -static void stmtCsrReset(stmt_cursor *pCur){ - StmtRow *pRow = 0; - StmtRow *pNext = 0; - for(pRow=pCur->pRow; pRow; pRow=pNext){ - pNext = pRow->pNext; - sqlite3_free(pRow); - } - pCur->pRow = 0; -} - /* ** Destructor for a stmt_cursor. */ static int stmtClose(sqlite3_vtab_cursor *cur){ - stmtCsrReset((stmt_cursor*)cur); sqlite3_free(cur); return SQLITE_OK; } @@ -244893,13 +241391,12 @@ /* ** Advance a stmt_cursor to its next row of output. */ static int stmtNext(sqlite3_vtab_cursor *cur){ stmt_cursor *pCur = (stmt_cursor*)cur; - StmtRow *pNext = pCur->pRow->pNext; - sqlite3_free(pCur->pRow); - pCur->pRow = pNext; + pCur->iRowid++; + pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt); return SQLITE_OK; } /* ** Return values of columns for the row at which the stmt_cursor @@ -244909,15 +241406,43 @@ sqlite3_vtab_cursor *cur, /* The cursor */ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ int i /* Which column to return */ ){ stmt_cursor *pCur = (stmt_cursor*)cur; - StmtRow *pRow = pCur->pRow; - if( i==STMT_COLUMN_SQL ){ - sqlite3_result_text(ctx, pRow->zSql, -1, SQLITE_TRANSIENT); - }else{ - sqlite3_result_int(ctx, pRow->aCol[i]); + switch( i ){ + case STMT_COLUMN_SQL: { + sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT); + break; + } + case STMT_COLUMN_NCOL: { + sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt)); + break; + } + case STMT_COLUMN_RO: { + sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt)); + break; + } + case STMT_COLUMN_BUSY: { + sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt)); + break; + } + default: { + assert( i==STMT_COLUMN_MEM ); + i = SQLITE_STMTSTATUS_MEMUSED + + STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP; + /* Fall thru */ + } + case STMT_COLUMN_NSCAN: + case STMT_COLUMN_NSORT: + case STMT_COLUMN_NAIDX: + case STMT_COLUMN_NSTEP: + case STMT_COLUMN_REPREP: + case STMT_COLUMN_RUN: { + sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt, + i-STMT_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0)); + break; + } } return SQLITE_OK; } /* @@ -244924,21 +241449,21 @@ ** Return the rowid for the current row. In this implementation, the ** rowid is the same as the output value. */ static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ stmt_cursor *pCur = (stmt_cursor*)cur; - *pRowid = pCur->pRow->iRowid; + *pRowid = pCur->iRowid; return SQLITE_OK; } /* ** Return TRUE if the cursor has been moved off of the last ** row of output. */ static int stmtEof(sqlite3_vtab_cursor *cur){ stmt_cursor *pCur = (stmt_cursor*)cur; - return pCur->pRow==0; + return pCur->pStmt==0; } /* ** This method is called to "rewind" the stmt_cursor object back ** to the first row of output. This method is always called at least @@ -244949,61 +241474,13 @@ sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ stmt_cursor *pCur = (stmt_cursor *)pVtabCursor; - sqlite3_stmt *p = 0; - sqlite3_int64 iRowid = 1; - StmtRow **ppRow = 0; - - (void)idxNum; - (void)idxStr; - (void)argc; - (void)argv; - stmtCsrReset(pCur); - ppRow = &pCur->pRow; - for(p=sqlite3_next_stmt(pCur->db, 0); p; p=sqlite3_next_stmt(pCur->db, p)){ - const char *zSql = sqlite3_sql(p); - sqlite3_int64 nSql = zSql ? strlen(zSql)+1 : 0; - StmtRow *pNew = (StmtRow*)sqlite3_malloc64(sizeof(StmtRow) + nSql); - - if( pNew==0 ) return SQLITE_NOMEM; - memset(pNew, 0, sizeof(StmtRow)); - if( zSql ){ - pNew->zSql = (char*)&pNew[1]; - memcpy(pNew->zSql, zSql, nSql); - } - pNew->aCol[STMT_COLUMN_NCOL] = sqlite3_column_count(p); - pNew->aCol[STMT_COLUMN_RO] = sqlite3_stmt_readonly(p); - pNew->aCol[STMT_COLUMN_BUSY] = sqlite3_stmt_busy(p); - pNew->aCol[STMT_COLUMN_NSCAN] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_FULLSCAN_STEP, 0 - ); - pNew->aCol[STMT_COLUMN_NSORT] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_SORT, 0 - ); - pNew->aCol[STMT_COLUMN_NAIDX] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_AUTOINDEX, 0 - ); - pNew->aCol[STMT_COLUMN_NSTEP] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_VM_STEP, 0 - ); - pNew->aCol[STMT_COLUMN_REPREP] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_REPREPARE, 0 - ); - pNew->aCol[STMT_COLUMN_RUN] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_RUN, 0 - ); - pNew->aCol[STMT_COLUMN_MEM] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_MEMUSED, 0 - ); - pNew->iRowid = iRowid++; - *ppRow = pNew; - ppRow = &pNew->pNext; - } - - return SQLITE_OK; + pCur->pStmt = 0; + pCur->iRowid = 0; + return stmtNext(pVtabCursor); } /* ** SQLite will invoke this method one or more times while planning a query ** that uses the stmt virtual table. This routine needs to create @@ -245012,11 +241489,10 @@ */ static int stmtBestIndex( sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo ){ - (void)tab; pIdxInfo->estimatedCost = (double)500; pIdxInfo->estimatedRows = 500; return SQLITE_OK; } Index: src/sqlite3.h ================================================================== --- src/sqlite3.h +++ src/sqlite3.h @@ -144,13 +144,13 @@ ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.41.0" -#define SQLITE_VERSION_NUMBER 3041000 -#define SQLITE_SOURCE_ID "2023-02-06 16:23:52 5dde07a91dcf99b9c9a418b4e2178f66eef4cffd4799538a419674314a7530f9" +#define SQLITE_VERSION "3.39.0" +#define SQLITE_VERSION_NUMBER 3039000 +#define SQLITE_SOURCE_ID "2022-06-22 18:51:47 83ff1a28e3e7a99fa90d5079897d76529c4256eed859bf7cb98b860fbedfdc5b" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** @@ -561,11 +561,10 @@ #define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8)) #define SQLITE_CONSTRAINT_PINNED (SQLITE_CONSTRAINT |(11<<8)) #define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT |(12<<8)) #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) -#define SQLITE_NOTICE_RBU (SQLITE_NOTICE | (3<<8)) #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) #define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */ @@ -669,21 +668,17 @@ /* ** CAPI3REF: File Locking Levels ** ** SQLite uses one of these integer values as the second ** argument to calls it makes to the xLock() and xUnlock() methods -** of an [sqlite3_io_methods] object. These values are ordered from -** lest restrictive to most restrictive. -** -** The argument to xLock() is always SHARED or higher. The argument to -** xUnlock is either SHARED or NONE. +** of an [sqlite3_io_methods] object. */ -#define SQLITE_LOCK_NONE 0 /* xUnlock() only */ -#define SQLITE_LOCK_SHARED 1 /* xLock() or xUnlock() */ -#define SQLITE_LOCK_RESERVED 2 /* xLock() only */ -#define SQLITE_LOCK_PENDING 3 /* xLock() only */ -#define SQLITE_LOCK_EXCLUSIVE 4 /* xLock() only */ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 /* ** CAPI3REF: Synchronization Type Flags ** ** When SQLite invokes the xSync() method of an @@ -757,18 +752,11 @@ **
    6. [SQLITE_LOCK_SHARED], **
    7. [SQLITE_LOCK_RESERVED], **
    8. [SQLITE_LOCK_PENDING], or **
    9. [SQLITE_LOCK_EXCLUSIVE]. ** -** xLock() upgrades the database file lock. In other words, xLock() moves the -** database file lock in the direction NONE toward EXCLUSIVE. The argument to -** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never -** SQLITE_LOCK_NONE. If the database file lock is already at or above the -** requested lock, then the call to xLock() is a no-op. -** xUnlock() downgrades the database file lock to either SHARED or NONE. -* If the lock is already at or below the requested lock state, then the call -** to xUnlock() is a no-op. +** xLock() increases the lock. xUnlock() decreases the lock. ** The xCheckReservedLock() method checks whether any database connection, ** either in this process or in some other process, is holding a RESERVED, ** PENDING, or EXCLUSIVE lock on the file. It returns true ** if such a lock exists and false otherwise. ** @@ -869,12 +857,13 @@ **
    10. [[SQLITE_FCNTL_LOCKSTATE]] ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This ** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) -** into an integer that the pArg argument points to. -** This capability is only available if SQLite is compiled with [SQLITE_DEBUG]. +** into an integer that the pArg argument points to. This capability +** is used during testing and is only available when the SQLITE_TEST +** compile-time option is used. ** **
    11. [[SQLITE_FCNTL_SIZE_HINT]] ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS ** layer a hint of how large the database file will grow to be during the ** current transaction. This hint is not guaranteed to be accurate but it @@ -1191,16 +1180,10 @@ ** by clients within the current process, only within other processes. ** ** **
    12. [[SQLITE_FCNTL_CKSM_FILE]] ** Used by the cksmvfs VFS module only. -** -**
    13. [[SQLITE_FCNTL_RESET_CACHE]] -** If there is currently no transaction open on the database, and the -** database is not a temp db, then this file-control purges the contents -** of the in-memory page cache. If there is an open transaction, or if -** the db is a temp-db, it is a no-op, not an error. ** */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 @@ -1239,11 +1222,10 @@ #define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 -#define SQLITE_FCNTL_RESET_CACHE 42 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO @@ -1269,30 +1251,10 @@ ** structure must be typedefed in order to work around compiler warnings ** on some platforms. */ typedef struct sqlite3_api_routines sqlite3_api_routines; -/* -** CAPI3REF: File Name -** -** Type [sqlite3_filename] is used by SQLite to pass filenames to the -** xOpen method of a [VFS]. It may be cast to (const char*) and treated -** as a normal, nul-terminated, UTF-8 buffer containing the filename, but -** may also be passed to special APIs such as: -** -**
        -**
      • sqlite3_filename_database() -**
      • sqlite3_filename_journal() -**
      • sqlite3_filename_wal() -**
      • sqlite3_uri_parameter() -**
      • sqlite3_uri_boolean() -**
      • sqlite3_uri_int64() -**
      • sqlite3_uri_key() -**
      -*/ -typedef const char *sqlite3_filename; - /* ** CAPI3REF: OS Interface Object ** ** An instance of the sqlite3_vfs object defines the interface between ** the SQLite core and the underlying operating system. The "vfs" @@ -1467,11 +1429,11 @@ int szOsFile; /* Size of subclassed sqlite3_file */ int mxPathname; /* Maximum file pathname length */ sqlite3_vfs *pNext; /* Next registered VFS */ const char *zName; /* Name of this virtual file system */ void *pAppData; /* Pointer to application-specific data */ - int (*xOpen)(sqlite3_vfs*, sqlite3_filename zName, sqlite3_file*, + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, int flags, int *pOutFlags); int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); @@ -2183,11 +2145,11 @@ ** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally ** rounded down to the next smaller multiple of 8. ^(The lookaside memory ** configuration for a database connection can only be changed when that ** connection is not currently using lookaside memory, or in other words ** when the "current value" returned by -** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero. +** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. ** Any attempt to change the lookaside memory configuration when lookaside ** memory is in use leaves the configuration unchanged and returns ** [SQLITE_BUSY].)^ ** ** [[SQLITE_DBCONFIG_ENABLE_FKEY]] @@ -2333,16 +2295,12 @@ **
    14. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); **
    15. [sqlite3_exec](db, "[VACUUM]", 0, 0, 0); **
    16. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); ** ** Because resetting a database is destructive and irreversible, the -** process requires the use of this obscure API and multiple steps to -** help ensure that it does not happen by accident. Because this -** feature must be capable of resetting corrupt databases, and -** shutting down virtual tables may require access to that corrupt -** storage, the library must abandon any installed virtual tables -** without calling their xDestroy() methods. +** process requires the use of this obscure API and multiple steps to help +** ensure that it does not happen by accident. ** ** [[SQLITE_DBCONFIG_DEFENSIVE]]
      SQLITE_DBCONFIG_DEFENSIVE
      **
      The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the ** "defensive" flag for a database connection. When the defensive ** flag is enabled, language features that allow ordinary SQL to @@ -2349,11 +2307,10 @@ ** deliberately corrupt the database file are disabled. The disabled ** features include but are not limited to the following: **
        **
      • The [PRAGMA writable_schema=ON] statement. **
      • The [PRAGMA journal_mode=OFF] statement. -**
      • The [PRAGMA schema_version=N] statement. **
      • Writes to the [sqlite_dbpage] virtual table. **
      • Direct writes to [shadow tables]. **
      **
      ** @@ -2677,16 +2634,12 @@ ** that are started after the running statement count reaches zero are ** not effected by the sqlite3_interrupt(). ** ^A call to sqlite3_interrupt(D) that occurs when there are no running ** SQL statements is a no-op and has no effect on SQL statements ** that are started after the sqlite3_interrupt() call returns. -** -** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether -** or not an interrupt is currently in effect for [database connection] D. */ SQLITE_API void sqlite3_interrupt(sqlite3*); -SQLITE_API int sqlite3_is_interrupted(sqlite3*); /* ** CAPI3REF: Determine If An SQL Statement Is Complete ** ** These routines are useful during command-line input to determine if the @@ -3300,12 +3253,12 @@ ** ** [[SQLITE_TRACE_PROFILE]]
      SQLITE_TRACE_PROFILE
      **
      ^An SQLITE_TRACE_PROFILE callback provides approximately the same ** information as is provided by the [sqlite3_profile()] callback. ** ^The P argument is a pointer to the [prepared statement] and the -** X argument points to a 64-bit integer which is approximately -** the number of nanoseconds that the prepared statement took to run. +** X argument points to a 64-bit integer which is the estimated of +** the number of nanosecond that the prepared statement took to run. ** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. ** ** [[SQLITE_TRACE_ROW]]
      SQLITE_TRACE_ROW
      **
      ^An SQLITE_TRACE_ROW callback is invoked whenever a prepared ** statement generates a single row of result. @@ -3364,11 +3317,11 @@ ** CAPI3REF: Query Progress Callbacks ** METHOD: sqlite3 ** ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback ** function X to be invoked periodically during long running calls to -** [sqlite3_step()] and [sqlite3_prepare()] and similar for +** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for ** database connection D. An example use for this ** interface is to keep a GUI updated during a large query. ** ** ^The parameter P is passed through as the only parameter to the ** callback function X. ^The parameter N is the approximate number of @@ -3389,17 +3342,10 @@ ** The progress handler callback must not do anything that will modify ** the database connection that invoked the progress handler. ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** -** The progress handler callback would originally only be invoked from the -** bytecode engine. It still might be invoked during [sqlite3_prepare()] -** and similar because those routines might force a reparse of the schema -** which involves running the bytecode engine. However, beginning with -** SQLite version 3.41.0, the progress handler callback might also be -** invoked directly from [sqlite3_prepare()] while analyzing and generating -** code for complex queries. */ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection @@ -3432,22 +3378,17 @@ ** sqlite3_open_v2() must include, at a minimum, one of the following ** three flag combinations:)^ ** **
      ** ^(
      [SQLITE_OPEN_READONLY]
      -**
      The database is opened in read-only mode. If the database does -** not already exist, an error is returned.
      )^ +**
      The database is opened in read-only mode. If the database does not +** already exist, an error is returned.
      )^ ** ** ^(
      [SQLITE_OPEN_READWRITE]
      -**
      The database is opened for reading and writing if possible, or -** reading only if the file is write protected by the operating -** system. In either case the database must already exist, otherwise -** an error is returned. For historical reasons, if opening in -** read-write mode fails due to OS-level permissions, an attempt is -** made to open it in read-only mode. [sqlite3_db_readonly()] can be -** used to determine whether the database is actually -** read-write.
      )^ +**
      The database is opened for reading and writing if possible, or reading +** only if the file is write protected by the operating system. In either +** case the database must already exist, otherwise an error is returned.
      )^ ** ** ^(
      [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
      **
      The database is opened for reading and writing, and is created if ** it does not already exist. This is the behavior that is always used for ** sqlite3_open() and sqlite3_open16().
      )^ @@ -3481,13 +3422,10 @@ ** ** ^(
      [SQLITE_OPEN_SHAREDCACHE]
      **
      The database is opened [shared cache] enabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ -** The [use of shared cache mode is discouraged] and hence shared cache -** capabilities may be omitted from many builds of SQLite. In such cases, -** this option is a no-op. ** ** ^(
      [SQLITE_OPEN_PRIVATECACHE]
      **
      The database is opened [shared cache] disabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ @@ -3499,11 +3437,11 @@ ** connection as soon as the connection is created. In addition to setting ** the extended result code mode, this flag also causes [sqlite3_open_v2()] ** to return an extended result code.
      ** ** [[OPEN_NOFOLLOW]] ^(
      [SQLITE_OPEN_NOFOLLOW]
      -**
      The database filename is not allowed to contain a symbolic link
      +**
      The database filename is not allowed to be a symbolic link
      **
      )^ ** ** If the 3rd parameter to sqlite3_open_v2() is not one of the ** required combinations shown above optionally combined with other ** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] @@ -3758,14 +3696,14 @@ ** it has access to all the same query parameters as were found on the ** main database file. ** ** See the [URI filename] documentation for additional information. */ -SQLITE_API const char *sqlite3_uri_parameter(sqlite3_filename z, const char *zParam); -SQLITE_API int sqlite3_uri_boolean(sqlite3_filename z, const char *zParam, int bDefault); -SQLITE_API sqlite3_int64 sqlite3_uri_int64(sqlite3_filename, const char*, sqlite3_int64); -SQLITE_API const char *sqlite3_uri_key(sqlite3_filename z, int N); +SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); +SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); +SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N); /* ** CAPI3REF: Translate filenames ** ** These routines are available to [VFS|custom VFS implementations] for @@ -3790,13 +3728,13 @@ ** In all of the above, if F is not the name of a database, journal or WAL ** filename passed into the VFS from the SQLite core and F is not the ** return value from [sqlite3_db_filename()], then the result is ** undefined and is likely a memory access violation. */ -SQLITE_API const char *sqlite3_filename_database(sqlite3_filename); -SQLITE_API const char *sqlite3_filename_journal(sqlite3_filename); -SQLITE_API const char *sqlite3_filename_wal(sqlite3_filename); +SQLITE_API const char *sqlite3_filename_database(const char*); +SQLITE_API const char *sqlite3_filename_journal(const char*); +SQLITE_API const char *sqlite3_filename_wal(const char*); /* ** CAPI3REF: Database File Corresponding To A Journal ** ** ^If X is the name of a rollback or WAL-mode journal file that is @@ -3858,18 +3796,18 @@ ** used again after sqlite3_free_filename(Y) has been called. This means ** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y, ** then the corresponding [sqlite3_module.xClose() method should also be ** invoked prior to calling sqlite3_free_filename(Y). */ -SQLITE_API sqlite3_filename sqlite3_create_filename( +SQLITE_API char *sqlite3_create_filename( const char *zDatabase, const char *zJournal, const char *zWal, int nParam, const char **azParam ); -SQLITE_API void sqlite3_free_filename(sqlite3_filename); +SQLITE_API void sqlite3_free_filename(char*); /* ** CAPI3REF: Error Codes And Messages ** METHOD: sqlite3 ** @@ -5424,25 +5362,14 @@ ** [[SQLITE_DIRECTONLY]]
      SQLITE_DIRECTONLY
      ** The SQLITE_DIRECTONLY flag means that the function may only be invoked ** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in ** schema structures such as [CHECK constraints], [DEFAULT clauses], ** [expression indexes], [partial indexes], or [generated columns]. -**

      -** The SQLITE_DIRECTONLY flag is recommended for any -** [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 surreptiously -** modified to invoke the application-defined function in ways that are -** harmful. -**

      -** Some people say it is good practice to set SQLITE_DIRECTONLY on all -** [application-defined SQL functions], regardless of whether or not they -** are security sensitive, as doing so prevents those functions from being used -** inside of the database schema, and thus ensures that the database -** can be inspected and modified using generic tools (such as the [CLI]) -** that do not have access to the application-defined functions. +** The SQLITE_DIRECTONLY flags is a security feature which is recommended +** for all [application-defined SQL functions], and especially for functions +** that have side-effects or that could potentially leak sensitive +** information. **

      ** ** [[SQLITE_INNOCUOUS]]
      SQLITE_INNOCUOUS
      ** The SQLITE_INNOCUOUS flag means that the function is unlikely ** to cause problems even if misused. An innocuous function should have @@ -5644,32 +5571,10 @@ SQLITE_API int sqlite3_value_type(sqlite3_value*); SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); SQLITE_API int sqlite3_value_nochange(sqlite3_value*); SQLITE_API int sqlite3_value_frombind(sqlite3_value*); -/* -** CAPI3REF: Report the internal text encoding state of an sqlite3_value object -** METHOD: sqlite3_value -** -** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8], -** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current text encoding -** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X) -** returns something other than SQLITE_TEXT, then the return value from -** sqlite3_value_encoding(X) is meaningless. ^Calls to -** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)], -** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or -** [sqlite3_value_bytes16(X)] might change the encoding of the value X and -** thus change the return from subsequent calls to sqlite3_value_encoding(X). -** -** This routine is intended for used by applications that test and validate -** the SQLite implementation. This routine is inquiring about the opaque -** internal state of an [sqlite3_value] object. Ordinary applications should -** not need to know what the internal state of an sqlite3_value object is and -** hence should not need to use this interface. -*/ -SQLITE_API int sqlite3_value_encoding(sqlite3_value*); - /* ** CAPI3REF: Finding The Subtype Of SQL Values ** METHOD: sqlite3_value ** ** The sqlite3_value_subtype(V) function returns the subtype for @@ -5718,11 +5623,11 @@ ** In those cases, sqlite3_aggregate_context() might be called for the ** first time from within xFinal().)^ ** ** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer ** when first called if N is less than or equal to zero or if a memory -** allocation error occurs. +** allocate error occurs. ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is ** determined by the N parameter on first successful call. Changing the ** value of N in any subsequent call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory @@ -5923,14 +5828,13 @@ ** application-defined function to be a text string in an encoding ** specified by the fifth (and last) parameter, which must be one ** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. ** ^SQLite takes the text result from the application from ** the 2nd parameter of the sqlite3_result_text* interfaces. -** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces -** other than sqlite3_result_text64() is negative, then SQLite computes -** the string length itself by searching the 2nd parameter for the first -** zero character. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is negative, then SQLite takes result text from the 2nd parameter +** through the first zero character. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would @@ -6376,11 +6280,11 @@ ** CAPI3REF: Return The Schema Name For A Database Connection ** METHOD: sqlite3 ** ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name ** for the N-th database on database connection D, or a NULL pointer of N is -** out of range. An N value of 0 means the main database file. An N of 1 is +** out of range. An N alue of 0 means the main database file. An N of 1 is ** the "temp" schema. Larger values of N correspond to various ATTACH-ed ** databases. ** ** Space to hold the string that is returned by sqlite3_db_name() is managed ** by SQLite itself. The string might be deallocated by any operation that @@ -6422,11 +6326,11 @@ **
    17. [sqlite3_filename_database()] **
    18. [sqlite3_filename_journal()] **
    19. [sqlite3_filename_wal()] ** */ -SQLITE_API sqlite3_filename sqlite3_db_filename(sqlite3 *db, const char *zDbName); +SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Determine if a database is read-only ** METHOD: sqlite3 ** @@ -6559,11 +6463,11 @@ ** ** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback ** function C that is invoked prior to each autovacuum of the database ** file. ^The callback is passed a copy of the generic data pointer (P), ** the schema-name of the attached database that is being autovacuumed, -** the size of the database file in pages, the number of free pages, +** the the size of the database file in pages, the number of free pages, ** and the number of bytes per page, respectively. The callback should ** return the number of free pages that should be removed by the ** autovacuum. ^If the callback returns zero, then no autovacuum happens. ** ^If the value returned is greater than or equal to the number of ** free pages, then a complete autovacuum happens. @@ -6680,15 +6584,10 @@ ** ^(This routine enables or disables the sharing of the database cache ** and schema data structures between [database connection | connections] ** to the same database. Sharing is enabled if the argument is true ** and disabled if the argument is false.)^ ** -** This interface is omitted if SQLite is compiled with -** [-DSQLITE_OMIT_SHARED_CACHE]. The [-DSQLITE_OMIT_SHARED_CACHE] -** compile-time option is recommended because the -** [use of shared cache mode is discouraged]. -** ** ^Cache sharing is enabled and disabled for an entire process. ** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). ** In prior versions of SQLite, ** sharing was enabled or disabled for each thread separately. ** @@ -6783,11 +6682,11 @@ ** ^Setting the heap limits to zero disables the heap limiter mechanism. ** ** ^The soft heap limit may not be greater than the hard heap limit. ** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N) ** is invoked with a value of N that is greater than the hard heap limit, -** the soft heap limit is set to the value of the hard heap limit. +** the the soft heap limit is set to the value of the hard heap limit. ** ^The soft heap limit is automatically enabled whenever the hard heap ** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and ** the soft heap limit is outside the range of 1..N, then the soft heap ** limit is set to N. ^Invoking sqlite3_soft_heap_limit64(0) when the ** hard heap limit is enabled makes the soft heap limit equal to the @@ -7044,10 +6943,19 @@ ** ^This interface disables all automatic extensions previously ** registered using [sqlite3_auto_extension()]. */ SQLITE_API void sqlite3_reset_auto_extension(void); +/* +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + /* ** Structures used by the virtual table interface */ typedef struct sqlite3_vtab sqlite3_vtab; typedef struct sqlite3_index_info sqlite3_index_info; @@ -7162,14 +7070,14 @@ ** checked separately in byte code. If the omit flag is change to true, then ** the constraint may or may not be checked in byte code. In other words, ** when the omit flag is true there is no guarantee that the constraint will ** not be checked again using byte code.)^ ** -** ^The idxNum and idxStr values are recorded and passed into the +** ^The idxNum and idxPtr values are recorded and passed into the ** [xFilter] method. -** ^[sqlite3_free()] is used to free idxStr if and only if -** needToFreeIdxStr is true. +** ^[sqlite3_free()] is used to free idxPtr if and only if +** needToFreeIdxPtr is true. ** ** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in ** the correct order to satisfy the ORDER BY clause so that no separate ** sorting step is required. ** @@ -7285,11 +7193,11 @@ ** ** The collating sequence to be used for comparison can be found using ** the [sqlite3_vtab_collation()] interface. For most real-world virtual ** tables, the collating sequence of constraints does not matter (for example ** because the constraints are numeric) and so the sqlite3_vtab_collation() -** interface is not commonly needed. +** interface is no commonly needed. */ #define SQLITE_INDEX_CONSTRAINT_EQ 2 #define SQLITE_INDEX_CONSTRAINT_GT 4 #define SQLITE_INDEX_CONSTRAINT_LE 8 #define SQLITE_INDEX_CONSTRAINT_LT 16 @@ -7443,10 +7351,20 @@ ** the new function is not good for anything by itself. Its only ** purpose is to be a placeholder function that can be overloaded ** by a [virtual table]. */ SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ /* ** CAPI3REF: A Handle To An Open BLOB ** KEYWORDS: {BLOB handle} {BLOB handles} ** @@ -9059,11 +8977,11 @@ ** sqlite3_backup_init() is called and before the corresponding call to ** sqlite3_backup_finish(). SQLite does not currently check to see ** if the application incorrectly accesses the destination [database connection] ** and so no error code is reported, but the operations may malfunction ** nevertheless. Use of the destination database connection while a -** backup is in progress might also cause a mutex deadlock. +** backup is in progress might also also cause a mutex deadlock. ** ** If running in [shared cache mode], the application must ** guarantee that the shared cache used by the destination database ** is not accessed while the backup is running. In practice this means ** that the application must guarantee that the disk file being @@ -9487,11 +9405,11 @@ ** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the ** meaning of each of these checkpoint modes. */ #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ -#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */ +#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ /* ** CAPI3REF: Virtual Table Interface Configuration ** @@ -9647,11 +9565,11 @@ ** statement that was passed into [sqlite3_declare_vtab()], then the ** name of that alternative collating sequence is returned. **
    20. Otherwise, "BINARY" is returned. ** */ -SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); +SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); /* ** CAPI3REF: Determine if a virtual table query is DISTINCT ** METHOD: sqlite3_index_info ** @@ -9804,17 +9722,18 @@ ** [xFilter|xFilter() method] of a [virtual table] implementation. ** The result of invoking these interfaces from any other context ** is undefined and probably harmful. ** ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or -** sqlite3_vtab_in_next(X,P) should be one of the parameters to the +** sqlite3_vtab_in_next(X,P) must be one of the parameters to the ** xFilter method which invokes these routines, and specifically ** a parameter that was previously selected for all-at-once IN constraint ** processing use the [sqlite3_vtab_in()] interface in the ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not ** an xFilter argument that was selected for all-at-once IN constraint -** processing, then these routines return [SQLITE_ERROR].)^ +** processing, then these routines return [SQLITE_MISUSE])^ or perhaps +** exhibit some other undefined or harmful behavior. ** ** ^(Use these routines to access all values on the right-hand side ** of the IN constraint using code like the following: ** **

      @@ -9915,14 +9834,10 @@
       **
       ** When the value returned to V is a string, space to hold that string is
       ** managed by the prepared statement S and will be automatically freed when
       ** S is finalized.
       **
      -** Not all values are available for all query elements. When a value is
      -** not available, the output variable is set to -1 if the value is numeric,
      -** or to NULL if it is a string (SQLITE_SCANSTAT_NAME).
      -**
       ** 
      ** [[SQLITE_SCANSTAT_NLOOP]]
      SQLITE_SCANSTAT_NLOOP
      **
      ^The [sqlite3_int64] variable pointed to by the V parameter will be ** set to the total number of times that the X-th loop has run.
      ** @@ -9946,44 +9861,30 @@ ** [[SQLITE_SCANSTAT_EXPLAIN]]
      SQLITE_SCANSTAT_EXPLAIN
      **
      ^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] ** description for the X-th loop. ** -** [[SQLITE_SCANSTAT_SELECTID]]
      SQLITE_SCANSTAT_SELECTID
      +** [[SQLITE_SCANSTAT_SELECTID]]
      SQLITE_SCANSTAT_SELECT
      **
      ^The "int" variable pointed to by the V parameter will be set to the -** id for the X-th query plan element. The id value is unique within the -** statement. The select-id is the same value as is output in the first -** column of an [EXPLAIN QUERY PLAN] query. +** "select-id" for the X-th loop. The select-id identifies which query or +** subquery the loop is part of. The main query has a select-id of zero. +** The select-id is the same value as is output in the first column +** of an [EXPLAIN QUERY PLAN] query. **
      -** -** [[SQLITE_SCANSTAT_PARENTID]]
      SQLITE_SCANSTAT_PARENTID
      -**
      The "int" variable pointed to by the V parameter will be set to the -** the id of the parent of the current query element, if applicable, or -** to zero if the query element has no parent. This is the same value as -** returned in the second column of an [EXPLAIN QUERY PLAN] query. -** -** [[SQLITE_SCANSTAT_NCYCLE]]
      SQLITE_SCANSTAT_NCYCLE
      -**
      The sqlite3_int64 output value is set to the number of cycles, -** according to the processor time-stamp counter, that elapsed while the -** query element was being processed. This value is not available for -** all query elements - if it is unavailable the output variable is -** set to -1. */ #define SQLITE_SCANSTAT_NLOOP 0 #define SQLITE_SCANSTAT_NVISIT 1 #define SQLITE_SCANSTAT_EST 2 #define SQLITE_SCANSTAT_NAME 3 #define SQLITE_SCANSTAT_EXPLAIN 4 #define SQLITE_SCANSTAT_SELECTID 5 -#define SQLITE_SCANSTAT_PARENTID 6 -#define SQLITE_SCANSTAT_NCYCLE 7 /* ** CAPI3REF: Prepared Statement Scan Status ** METHOD: sqlite3_stmt ** -** These interfaces return information about the predicted and measured +** This interface returns information about the predicted and measured ** performance for pStmt. Advanced applications can use this ** interface to compare the predicted and the measured performance and ** issue warnings and/or rerun [ANALYZE] if discrepancies are found. ** ** Since this interface is expected to be rarely used, it is only @@ -9990,51 +9891,32 @@ ** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS] ** compile-time option. ** ** The "iScanStatusOp" parameter determines which status information to return. ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior -** of this interface is undefined. ^The requested measurement is written into -** a variable pointed to by the "pOut" parameter. -** -** The "flags" parameter must be passed a mask of flags. At present only -** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX -** is specified, then status information is available for all elements -** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If -** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements -** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of -** the EXPLAIN QUERY PLAN output) are available. Invoking API -** sqlite3_stmt_scanstatus() is equivalent to calling -** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. -** -** Parameter "idx" identifies the specific query element to retrieve statistics -** for. Query elements are numbered starting from zero. A value of -1 may be -** to query for statistics regarding the entire query. ^If idx is out of range -** - less than -1 or greater than or equal to the total number of query -** elements used to implement the statement - a non-zero value is returned and -** the variable that pOut points to is unchanged. +** of this interface is undefined. +** ^The requested measurement is written into a variable pointed to by +** the "pOut" parameter. +** Parameter "idx" identifies the specific loop to retrieve statistics for. +** Loops are numbered starting from zero. ^If idx is out of range - less than +** zero or greater than or equal to the total number of loops used to implement +** the statement - a non-zero value is returned and the variable that pOut +** points to is unchanged. +** +** ^Statistics might not be available for all loops in all statements. ^In cases +** where there exist loops with no available statistics, this function behaves +** as if the loop did not exist - it returns non-zero and leave the variable +** that pOut points to unchanged. ** ** See also: [sqlite3_stmt_scanstatus_reset()] */ SQLITE_API int sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ void *pOut /* Result written here */ ); -SQLITE_API int sqlite3_stmt_scanstatus_v2( - sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ - int idx, /* Index of loop to report on */ - int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ - int flags, /* Mask of flags defined below */ - void *pOut /* Result written here */ -); - -/* -** CAPI3REF: Prepared Statement Scan Status -** KEYWORDS: {scan status flags} -*/ -#define SQLITE_SCANSTAT_COMPLEX 0x0001 /* ** CAPI3REF: Zero Scan-Status Counters ** METHOD: sqlite3_stmt ** @@ -10121,14 +10003,10 @@ ** seventh parameter is the final rowid value of the row being inserted ** or updated. The value of the seventh parameter passed to the callback ** function is not defined for operations on WITHOUT ROWID tables, or for ** DELETE operations on rowid tables. ** -** ^The sqlite3_update_hook(D,C,P) function returns the P argument from -** the previous call on the same [database connection] D, or NULL for -** the first call on D. -** ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces ** provide additional information about a preupdate event. These routines ** may only be called from within a preupdate callback. Invoking any of ** these routines from outside of a preupdate callback or with a