diff options
author | stas <stas@FreeBSD.org> | 2011-10-08 04:08:44 +0000 |
---|---|---|
committer | stas <stas@FreeBSD.org> | 2011-10-08 04:08:44 +0000 |
commit | 2db247d3fc10ef5304f61dbd66448efff8cc6684 (patch) | |
tree | 353454e541452788c2b3c59d1fb19ada4daf5646 /lib/sqlite/sqlite3.c | |
parent | 33f661cecdad3182ee66b47805fa4bb212e0da6c (diff) | |
download | FreeBSD-src-2db247d3fc10ef5304f61dbd66448efff8cc6684.zip FreeBSD-src-2db247d3fc10ef5304f61dbd66448efff8cc6684.tar.gz |
- Update vendor tree of heimdal to 1.5.1.
Diffstat (limited to 'lib/sqlite/sqlite3.c')
-rw-r--r-- | lib/sqlite/sqlite3.c | 47648 |
1 files changed, 33138 insertions, 14510 deletions
diff --git a/lib/sqlite/sqlite3.c b/lib/sqlite/sqlite3.c index efe31d8..d04fa38 100644 --- a/lib/sqlite/sqlite3.c +++ b/lib/sqlite/sqlite3.c @@ -1,15 +1,15 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.6.23.1. By combining all the individual C code files into this -** single large file, the entire code can be compiled as a one translation +** version 3.7.8. 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% are more are commonly seen when SQLite is compiled as a single +** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. ** ** This file is all you need to compile SQLite. To use SQLite in other ** programs, you need this file and the "sqlite3.h" header file that defines -** the programming interface to the SQLite library. (If you do not have +** the programming interface to the SQLite library. (If you do not have ** the "sqlite3.h" header file at hand, you will find a copy embedded within ** the text of this file. Search for "Begin file sqlite3.h" to find the start ** of the embedded sqlite3.h header file.) Additional code files may be needed @@ -91,7 +91,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** +** ** This file defines various limits of what SQLite can process. */ @@ -139,9 +139,9 @@ #endif /* -** The maximum depth of an expression tree. This is limited to -** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might -** want to place more severe limits on the complexity of an +** The maximum depth of an expression tree. This is limited to +** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might +** want to place more severe limits on the complexity of an ** expression. ** ** A value of 0 used to mean that the limit was not enforced. @@ -191,8 +191,16 @@ #endif /* +** The default number of frames to accumulate in the log file before +** checkpointing the database in WAL mode. +*/ +#ifndef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT +# define SQLITE_DEFAULT_WAL_AUTOCHECKPOINT 1000 +#endif + +/* ** The maximum number of attached databases. This must be between 0 -** and 30. The upper bound on 30 is because a 32-bit integer bitmap +** and 62. The upper bound on 62 is because a 64-bit integer bitmap ** is used internally to track attached databases. */ #ifndef SQLITE_MAX_ATTACHED @@ -207,20 +215,21 @@ # define SQLITE_MAX_VARIABLE_NUMBER 999 #endif -/* Maximum page size. The upper bound on this value is 32768. This a limit -** imposed by the necessity of storing the value in a 2-byte unsigned integer -** and the fact that the page size must be a power of 2. +/* Maximum page size. The upper bound on this value is 65536. This a limit +** imposed by the use of 16-bit offsets within each page. ** -** If this limit is changed, then the compiled library is technically -** incompatible with an SQLite library compiled with a different limit. If -** a process operating on a database with a page-size of 65536 bytes -** crashes, then an instance of SQLite compiled with the default page-size -** limit will not be able to rollback the aborted transaction. This could -** lead to database corruption. +** Earlier versions of SQLite allowed the user to change this value at +** compile time. This is no longer permitted, on the grounds that it creates +** a library that is technically incompatible with an SQLite library +** compiled with a different limit. If a process operating on a database +** with a page-size of 65536 bytes crashes, then an instance of SQLite +** compiled with the default page-size limit will not be able to rollback +** the aborted transaction. This could lead to database corruption. */ -#ifndef SQLITE_MAX_PAGE_SIZE -# define SQLITE_MAX_PAGE_SIZE 32768 +#ifdef SQLITE_MAX_PAGE_SIZE +# undef SQLITE_MAX_PAGE_SIZE #endif +#define SQLITE_MAX_PAGE_SIZE 65536 /* @@ -273,7 +282,7 @@ ** Maximum depth of recursion for triggers. ** ** A value of 1 means that a trigger program will not be able to itself -** fire any triggers. A value of 0 means that no trigger programs at all +** fire any triggers. A value of 0 means that no trigger programs at all ** may be executed. */ #ifndef SQLITE_MAX_TRIGGER_DEPTH @@ -308,7 +317,7 @@ #endif /* -** The number of samples of an index that SQLite takes in order to +** The number of samples of an index that SQLite takes in order to ** construct a histogram of the table content when running ANALYZE ** and with SQLITE_ENABLE_STAT2 */ @@ -320,10 +329,10 @@ ** to the next, so we have developed the following set of #if statements ** to generate appropriate macros for a wide range of compilers. ** -** The correct "ANSI" way to do this is to use the intptr_t type. +** The correct "ANSI" way to do this is to use the intptr_t type. ** Unfortunately, that typedef is not available on all compilers, or ** if it is available, it requires an #include of specific headers -** that very from one machine to the next. +** that vary from one machine to the next. ** ** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on ** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)). @@ -345,21 +354,27 @@ #endif /* -** The SQLITE_THREADSAFE macro must be defined as either 0 or 1. +** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. +** 0 means mutexes are permanently disable and the library is never +** threadsafe. 1 means the library is serialized which is the highest +** level of threadsafety. 2 means the libary is multithreaded - multiple +** threads can use SQLite as long as no two threads try to use the same +** database connection at the same time. +** ** Older versions of SQLite used an optional THREADSAFE macro. -** We support that for legacy +** We support that for legacy. */ #if !defined(SQLITE_THREADSAFE) #if defined(THREADSAFE) # define SQLITE_THREADSAFE THREADSAFE #else -# define SQLITE_THREADSAFE 1 +# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */ #endif #endif /* ** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1. -** It determines whether or not the features related to +** It determines whether or not the features related to ** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can ** be overridden at runtime using the sqlite3_config() API. */ @@ -372,19 +387,25 @@ ** specify which memory allocation subsystem to use. ** ** SQLITE_SYSTEM_MALLOC // Use normal system malloc() +** SQLITE_WIN32_MALLOC // Use Win32 native heap API ** SQLITE_MEMDEBUG // Debugging version of system malloc() ** +** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the +** assert() macro is enabled, each call into the Win32 native heap subsystem +** will cause HeapValidate to be called. If heap validation should fail, an +** assertion will be triggered. +** ** (Historical note: There used to be several other options, but we've ** pared it down to just these two.) ** ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as ** the default. */ -#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_MEMDEBUG)>1 +#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1 # error "At most one of the following compile-time configuration options\ - is allows: SQLITE_SYSTEM_MALLOC, SQLITE_MEMDEBUG" + is allows: SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG" #endif -#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_MEMDEBUG)==0 +#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)==0 # define SQLITE_SYSTEM_MALLOC 1 #endif @@ -410,8 +431,12 @@ ** See also ticket #2741. */ #if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) && SQLITE_THREADSAFE +#ifdef __sun +# define _XOPEN_SOURCE 600 +#else # define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */ #endif +#endif /* ** The TCL headers are only needed when compiling the TCL bindings. @@ -427,12 +452,12 @@ ** option is set. Thus NDEBUG becomes an opt-in rather than an opt-out ** feature. */ -#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) # define NDEBUG 1 #endif /* -** The testcase() macro is used to aid in coverage testing. When +** The testcase() macro is used to aid in coverage testing. When ** doing coverage testing, the condition inside the argument to ** testcase() must be evaluated both true and false in order to ** get full branch coverage. The testcase() macro is inserted @@ -478,7 +503,7 @@ SQLITE_PRIVATE void sqlite3Coverage(int); #endif /* -** The ALWAYS and NEVER macros surround boolean expressions which +** The ALWAYS and NEVER macros surround boolean expressions which ** are intended to always be true or false, respectively. Such ** expressions could be omitted from the code completely. But they ** are included in a few cases in order to enhance the resilience @@ -504,6 +529,13 @@ SQLITE_PRIVATE void sqlite3Coverage(int); #endif /* +** Return true (non-zero) if the input is a integer that is too large +** to fit in 32-bits. This macro is used inside of various testcase() +** macros to verify that we have tested SQLite for large-file support. +*/ +#define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0) + +/* ** The macro unlikely() is a hint that surrounds a boolean ** expression that is usually false. Macro likely() surrounds ** a boolean expression that is usually true. GCC is able to @@ -618,7 +650,7 @@ extern "C" { ** ** Since version 3.6.18, SQLite source code has been stored in the ** <a href="http://www.fossil-scm.org/">Fossil configuration management -** system</a>. ^The SQLITE_SOURCE_ID macro evalutes to +** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to ** a string which identifies a particular check-in of SQLite ** within its configuration management system. ^The SQLITE_SOURCE_ID ** string contains the date and time of the check-in (UTC) and an SHA1 @@ -628,9 +660,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.6.23.1" -#define SQLITE_VERSION_NUMBER 3006023 -#define SQLITE_SOURCE_ID "2010-03-26 22:28:06 b078b588d617e07886ad156e9f54ade6d823568e" +#define SQLITE_VERSION "3.7.8" +#define SQLITE_VERSION_NUMBER 3007008 +#define SQLITE_SOURCE_ID "2011-09-19 14:49:19 3e0da808d2f5b4d12046e05980ca04578f581177" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -656,8 +688,8 @@ extern "C" { ** function is provided for use in DLLs since DLL users usually do not have ** direct access to string constants within the DLL. ^The ** sqlite3_libversion_number() function returns an integer equal to -** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns -** a pointer to a string constant whose value is the same as the +** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns +** a pointer to a string constant whose value is the same as the ** [SQLITE_SOURCE_ID] C preprocessor macro. ** ** See also: [sqlite_version()] and [sqlite_source_id()]. @@ -667,32 +699,32 @@ SQLITE_API const char *sqlite3_libversion(void); SQLITE_API const char *sqlite3_sourceid(void); SQLITE_API int sqlite3_libversion_number(void); -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS /* ** CAPI3REF: Run-Time Library Compilation Options Diagnostics ** -** ^The sqlite3_compileoption_used() function returns 0 or 1 -** indicating whether the specified option was defined at -** compile time. ^The SQLITE_ prefix may be omitted from the -** option name passed to sqlite3_compileoption_used(). +** ^The sqlite3_compileoption_used() function returns 0 or 1 +** indicating whether the specified option was defined at +** compile time. ^The SQLITE_ prefix may be omitted from the +** option name passed to sqlite3_compileoption_used(). ** -** ^The sqlite3_compileoption_get() function allows interating +** ^The sqlite3_compileoption_get() function allows iterating ** over the list of options that were defined at compile time by ** returning the N-th compile time option string. ^If N is out of range, -** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ -** prefix is omitted from any strings returned by +** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ +** prefix is omitted from any strings returned by ** sqlite3_compileoption_get(). ** ** ^Support for the diagnostic functions sqlite3_compileoption_used() -** and sqlite3_compileoption_get() may be omitted by specifing the +** and sqlite3_compileoption_get() may be omitted by specifying the ** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. ** ** See also: SQL functions [sqlite_compileoption_used()] and ** [sqlite_compileoption_get()] and the [compile_options pragma]. */ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS SQLITE_API int sqlite3_compileoption_used(const char *zOptName); SQLITE_API const char *sqlite3_compileoption_get(int N); -#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ +#endif /* ** CAPI3REF: Test To See If The Library Is Threadsafe @@ -704,7 +736,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N); ** SQLite can be compiled with or without mutexes. When ** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes ** are enabled and SQLite is threadsafe. When the -** [SQLITE_THREADSAFE] macro is 0, +** [SQLITE_THREADSAFE] macro is 0, ** the mutexes are omitted. Without the mutexes, it is not safe ** to use SQLite concurrently from more than one thread. ** @@ -760,7 +792,7 @@ typedef struct sqlite3 sqlite3; ** ** ^The sqlite3_int64 and sqlite_int64 types can store integer values ** between -9223372036854775808 and +9223372036854775807 inclusive. ^The -** sqlite3_uint64 and sqlite_uint64 types can store integer values +** sqlite3_uint64 and sqlite_uint64 types can store integer values ** between 0 and +18446744073709551615 inclusive. */ #ifdef SQLITE_INT64_TYPE @@ -789,7 +821,7 @@ typedef sqlite_uint64 sqlite3_uint64; ** ** ^The sqlite3_close() routine is the destructor for the [sqlite3] object. ** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is -** successfullly destroyed and all associated resources are deallocated. +** successfully destroyed and all associated resources are deallocated. ** ** Applications must [sqlite3_finalize | finalize] all [prepared statements] ** and [sqlite3_blob_close | close] all [BLOB handles] associated with @@ -805,7 +837,7 @@ typedef sqlite_uint64 sqlite3_uint64; ** pointer or an [sqlite3] object pointer obtained ** from [sqlite3_open()], [sqlite3_open16()], or ** [sqlite3_open_v2()], and not previously closed. -** ^Calling sqlite3_close() with a NULL pointer argument is a +** ^Calling sqlite3_close() with a NULL pointer argument is a ** harmless no-op. */ SQLITE_API int sqlite3_close(sqlite3 *); @@ -823,7 +855,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** The sqlite3_exec() interface is a convenience wrapper around ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], ** that allows an application to run multiple statements of SQL -** without having to use a lot of C code. +** without having to use a lot of C code. ** ** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, ** semicolon-separate SQL statements passed into its 2nd argument, @@ -831,7 +863,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** argument. ^If the callback function of the 3rd argument to ** sqlite3_exec() is not NULL, then it is invoked for each result row ** coming out of the evaluated SQL statements. ^The 4th argument to -** to sqlite3_exec() is relayed through to the 1st argument of each +** sqlite3_exec() is relayed through to the 1st argument of each ** callback invocation. ^If the callback pointer to sqlite3_exec() ** is NULL, then no callback is ever invoked and result rows are ** ignored. @@ -863,7 +895,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** from [sqlite3_column_name()]. ** ** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer -** to an empty string, or a pointer that contains only whitespace and/or +** to an empty string, or a pointer that contains only whitespace and/or ** SQL comments, then no SQL statements are evaluated and the database ** is not changed. ** @@ -896,7 +928,8 @@ SQLITE_API int sqlite3_exec( ** ** New error codes may be added in future versions of SQLite. ** -** See also: [SQLITE_IOERR_READ | extended result codes] +** See also: [SQLITE_IOERR_READ | extended result codes], +** [sqlite3_vtab_on_conflict()] [SQLITE_ROLLBACK | result codes]. */ #define SQLITE_OK 0 /* Successful result */ /* beginning-of-error-codes */ @@ -911,10 +944,10 @@ SQLITE_API int sqlite3_exec( #define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ #define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ #define SQLITE_CORRUPT 11 /* The database disk image is malformed */ -#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */ +#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */ #define SQLITE_FULL 13 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ -#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */ +#define SQLITE_PROTOCOL 15 /* Database lock protocol error */ #define SQLITE_EMPTY 16 /* Database is empty */ #define SQLITE_SCHEMA 17 /* The database schema changed */ #define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ @@ -970,15 +1003,24 @@ SQLITE_API int sqlite3_exec( #define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8)) #define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8)) #define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8)) -#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8) ) +#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) +#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) +#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) +#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) +#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) +#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) +#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) +#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) +#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) +#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) +#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and -** in the 4th parameter to the xOpen method of the -** [sqlite3_vfs] object. +** in the 4th parameter to the [sqlite3_vfs.xOpen] method. */ #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ @@ -986,6 +1028,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ #define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ +#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ #define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ @@ -997,11 +1040,14 @@ SQLITE_API int sqlite3_exec( #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ + +/* Reserved: 0x00F00000 */ /* ** CAPI3REF: Device Characteristics ** -** The xDeviceCapabilities method of the [sqlite3_io_methods] +** The xDeviceCharacteristics method of the [sqlite3_io_methods] ** object returns an integer which is a vector of the these ** bit values expressing I/O characteristics of the mass storage ** device that holds the file that the [sqlite3_io_methods] @@ -1018,17 +1064,18 @@ SQLITE_API int sqlite3_exec( ** information is written to disk in the same order as calls ** to xWrite(). */ -#define SQLITE_IOCAP_ATOMIC 0x00000001 -#define SQLITE_IOCAP_ATOMIC512 0x00000002 -#define SQLITE_IOCAP_ATOMIC1K 0x00000004 -#define SQLITE_IOCAP_ATOMIC2K 0x00000008 -#define SQLITE_IOCAP_ATOMIC4K 0x00000010 -#define SQLITE_IOCAP_ATOMIC8K 0x00000020 -#define SQLITE_IOCAP_ATOMIC16K 0x00000040 -#define SQLITE_IOCAP_ATOMIC32K 0x00000080 -#define SQLITE_IOCAP_ATOMIC64K 0x00000100 -#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 -#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 +#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 /* ** CAPI3REF: File Locking Levels @@ -1056,6 +1103,18 @@ SQLITE_API int sqlite3_exec( ** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics. ** If the lower four bits equal SQLITE_SYNC_FULL, that means ** to use Mac OS X style fullsync instead of fsync(). +** +** Do not confuse the SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags +** with the [PRAGMA synchronous]=NORMAL and [PRAGMA synchronous]=FULL +** settings. The [synchronous pragma] determines when calls to the +** xSync VFS method occur and applies uniformly across all platforms. +** The SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags determine how +** energetic or rigorous or forceful the sync operations are and +** only make a difference on Mac OSX for the default SQLite code. +** (Third-party VFS implementations might also make the distinction +** between SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL, but among the +** operating systems natively supported by SQLite, only Mac OSX +** cares about the difference.) */ #define SQLITE_SYNC_NORMAL 0x00002 #define SQLITE_SYNC_FULL 0x00003 @@ -1064,7 +1123,7 @@ SQLITE_API int sqlite3_exec( /* ** CAPI3REF: OS Interface Open File Handle ** -** An [sqlite3_file] object represents an open file in the +** An [sqlite3_file] object represents an open file in the ** [sqlite3_vfs | OS interface layer]. Individual OS interface ** implementations will ** want to subclass this object by appending additional fields @@ -1080,17 +1139,18 @@ struct sqlite3_file { /* ** CAPI3REF: OS Interface File Virtual Methods Object ** -** Every file opened by the [sqlite3_vfs] xOpen method populates an +** Every file opened by the [sqlite3_vfs.xOpen] method populates an ** [sqlite3_file] object (or, more commonly, a subclass of the ** [sqlite3_file] object) with a pointer to an instance of this object. ** This object defines the methods used to perform various operations ** against the open file represented by the [sqlite3_file] object. ** -** If the xOpen method sets the sqlite3_file.pMethods element +** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element ** to a non-NULL pointer, then the sqlite3_io_methods.xClose method -** may be invoked even if the xOpen reported that it failed. The -** only way to prevent a call to xClose following a failed xOpen -** is for the xOpen to set the sqlite3_file.pMethods element to NULL. +** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The +** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen] +** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element +** to NULL. ** ** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or ** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). @@ -1124,7 +1184,9 @@ struct sqlite3_file { ** core reserves all opcodes less than 100 for its own use. ** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. ** Applications that define a custom xFileControl method should use opcodes -** greater than 100 to avoid conflicts. +** greater than 100 to avoid conflicts. VFS implementations should +** return [SQLITE_NOTFOUND] for file control opcodes that they do not +** recognize. ** ** The xSectorSize() method returns the sector size of the ** device that underlies the file. The sector size is the @@ -1179,6 +1241,12 @@ struct sqlite3_io_methods { int (*xFileControl)(sqlite3_file*, int op, void *pArg); int (*xSectorSize)(sqlite3_file*); int (*xDeviceCharacteristics)(sqlite3_file*); + /* Methods above are valid for version 1 */ + int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); + int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); + void (*xShmBarrier)(sqlite3_file*); + int (*xShmUnmap)(sqlite3_file*, int deleteFlag); + /* Methods above are valid for version 2 */ /* Additional methods may be added in future releases */ }; @@ -1196,11 +1264,78 @@ struct sqlite3_io_methods { ** into an integer that the pArg argument points to. This capability ** is used during testing and only needs to be supported when SQLITE_TEST ** is defined. +** +** 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 +** is often close. The underlying VFS might choose to preallocate database +** file space based on this hint in order to help writes to the database +** file run faster. +** +** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS +** extends and truncates the database file in chunks of a size specified +** by the user. The fourth argument to [sqlite3_file_control()] should +** point to an integer (type int) containing the new chunk-size to use +** for the nominated database. Allocating database file space in large +** chunks (say 1MB at a time), may reduce file-system fragmentation and +** improve performance on some systems. +** +** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer +** to the [sqlite3_file] object associated with a particular database +** connection. See the [sqlite3_file_control()] documentation for +** additional information. +** +** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by +** SQLite and sent to all VFSes in place of a call to the xSync method +** when the database connection has [PRAGMA synchronous] set to OFF.)^ +** Some specialized VFSes need this signal in order to operate correctly +** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most +** VFSes do not need this signal and should silently ignore this opcode. +** Applications should not call [sqlite3_file_control()] with this +** opcode as doing so may disrupt the operation of the specialized VFSes +** that do require it. +** +** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic +** retry counts and intervals for certain disk I/O operations for the +** windows [VFS] in order to work to provide robustness against +** anti-virus programs. By default, the windows VFS will retry file read, +** file write, and file delete opertions up to 10 times, with a delay +** of 25 milliseconds before the first retry and with the delay increasing +** by an additional 25 milliseconds with each subsequent retry. This +** opcode allows those to values (10 retries and 25 milliseconds of delay) +** to be adjusted. The values are changed for all database connections +** within the same process. The argument is a pointer to an array of two +** integers where the first integer i the new retry count and the second +** integer is the delay. If either integer is negative, then the setting +** is not changed but instead the prior value of that setting is written +** into the array entry, allowing the current retry settings to be +** interrogated. The zDbName parameter is ignored. +** +** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the +** persistent [WAL | Write AHead Log] setting. By default, the auxiliary +** write ahead log and shared memory files used for transaction control +** are automatically deleted when the latest connection to the database +** closes. Setting persistent WAL mode causes those files to persist after +** close. Persisting the files is useful when other processes that do not +** have write permission on the directory containing the database file want +** to read the database file, as the WAL and shared memory files must exist +** in order for the database to be readable. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable persistent WAL mode or 1 to enable persistent +** WAL mode. If the integer is -1, then it is overwritten with the current +** WAL persistence setting. +** */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_GET_LOCKPROXYFILE 2 #define SQLITE_SET_LOCKPROXYFILE 3 #define SQLITE_LAST_ERRNO 4 +#define SQLITE_FCNTL_SIZE_HINT 5 +#define SQLITE_FCNTL_CHUNK_SIZE 6 +#define SQLITE_FCNTL_FILE_POINTER 7 +#define SQLITE_FCNTL_SYNC_OMITTED 8 +#define SQLITE_FCNTL_WIN32_AV_RETRY 9 +#define SQLITE_FCNTL_PERSIST_WAL 10 /* ** CAPI3REF: Mutex Handle @@ -1219,7 +1354,8 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** ** An instance of the sqlite3_vfs object defines the interface between ** the SQLite core and the underlying operating system. The "vfs" -** in the name of the object stands for "virtual file system". +** in the name of the object stands for "virtual file system". See +** the [VFS | VFS documentation] for further information. ** ** The value of the iVersion field is initially 1 but may be larger in ** future versions of SQLite. Additional fields may be appended to this @@ -1248,26 +1384,31 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** The zName field holds the name of the VFS module. The name must ** be unique across all VFS modules. ** -** SQLite will guarantee that the zFilename parameter to xOpen +** [[sqlite3_vfs.xOpen]] +** ^SQLite guarantees that the zFilename parameter to xOpen ** is either a NULL pointer or string obtained -** from xFullPathname(). SQLite further guarantees that +** from xFullPathname() with an optional suffix added. +** ^If a suffix is added to the zFilename parameter, it will +** consist of a single "-" character followed by no more than +** 10 alphanumeric and/or "-" characters. +** ^SQLite further guarantees that ** the string will be valid and unchanged until xClose() is ** called. Because of the previous sentence, ** the [sqlite3_file] can safely store a pointer to the ** filename if it needs to remember the filename for some reason. -** If the zFilename parameter is xOpen is a NULL pointer then xOpen -** must invent its own temporary name for the file. Whenever the +** If the zFilename parameter to xOpen is a NULL pointer then xOpen +** must invent its own temporary name for the file. ^Whenever the ** xFilename parameter is NULL it will also be the case that the ** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. ** ** The flags argument to xOpen() includes all bits set in ** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] ** or [sqlite3_open16()] is used, then flags includes at least -** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. ** If xOpen() opens a file read-only then it sets *pOutFlags to ** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set. ** -** SQLite will also add one of the following flags to the xOpen() +** ^(SQLite will also add one of the following flags to the xOpen() ** call, depending on the object being opened: ** ** <ul> @@ -1278,7 +1419,8 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** <li> [SQLITE_OPEN_TRANSIENT_DB] ** <li> [SQLITE_OPEN_SUBJOURNAL] ** <li> [SQLITE_OPEN_MASTER_JOURNAL] -** </ul> +** <li> [SQLITE_OPEN_WAL] +** </ul>)^ ** ** The file I/O implementation can use the object type flags to ** change the way it deals with files. For example, an application @@ -1297,19 +1439,20 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** </ul> ** ** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be -** deleted when it is closed. The [SQLITE_OPEN_DELETEONCLOSE] -** will be set for TEMP databases, journals and for subjournals. +** deleted when it is closed. ^The [SQLITE_OPEN_DELETEONCLOSE] +** will be set for TEMP databases and their journals, transient +** databases, and subjournals. ** -** The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction +** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction ** with the [SQLITE_OPEN_CREATE] flag, which are both directly ** analogous to the O_EXCL and O_CREAT flags of the POSIX open() -** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the +** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the ** SQLITE_OPEN_CREATE, is used to indicate that file should always ** be created, and that it is an error if it already exists. -** It is <i>not</i> used to indicate the file should be opened +** It is <i>not</i> used to indicate the file should be opened ** for exclusive access. ** -** At least szOsFile bytes of memory are allocated by SQLite +** ^At least szOsFile bytes of memory are allocated by SQLite ** to hold the [sqlite3_file] structure passed as the third ** argument to xOpen. The xOpen method does not have to ** allocate the structure; it should just fill it in. Note that @@ -1319,33 +1462,54 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** element will be valid after xOpen returns regardless of the success ** or failure of the xOpen call. ** -** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** [[sqlite3_vfs.xAccess]] +** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] ** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to ** test whether a file is readable and writable, or [SQLITE_ACCESS_READ] ** to test whether a file is at least readable. The file can be a ** directory. ** -** SQLite will always allocate at least mxPathname+1 bytes for the +** ^SQLite will always allocate at least mxPathname+1 bytes for the ** output buffer xFullPathname. The exact size of the output buffer ** is also passed as a parameter to both methods. If the output buffer ** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is ** handled as a fatal error by SQLite, vfs implementations should endeavor ** to prevent this by setting mxPathname to a sufficiently large value. ** -** The xRandomness(), xSleep(), and xCurrentTime() interfaces -** are not strictly a part of the filesystem, but they are +** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64() +** interfaces are not strictly a part of the filesystem, but they are ** included in the VFS structure for completeness. ** The xRandomness() function attempts to return nBytes bytes ** of good-quality randomness into zOut. The return value is ** the actual number of bytes of randomness obtained. ** The xSleep() method causes the calling thread to sleep for at -** least the number of microseconds given. The xCurrentTime() -** method returns a Julian Day Number for the current date and time. -** +** least the number of microseconds given. ^The xCurrentTime() +** method returns a Julian Day Number for the current date and time as +** a floating point value. +** ^The xCurrentTimeInt64() method returns, as an integer, the Julian +** Day Number multiplied by 86400000 (the number of milliseconds in +** a 24-hour day). +** ^SQLite will use the xCurrentTimeInt64() method to get the current +** date and time if that method is available (if iVersion is 2 or +** greater and the function pointer is not NULL) and will fall back +** to xCurrentTime() if xCurrentTimeInt64() is unavailable. +** +** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces +** are not used by the SQLite core. These optional interfaces are provided +** by some VFSes to facilitate testing of the VFS code. By overriding +** system calls with functions under its control, a test program can +** simulate faults and error conditions that would otherwise be difficult +** or impossible to induce. The set of system calls that can be overridden +** varies from one VFS to another, and from one version of the same VFS to the +** next. Applications that use these interfaces must be prepared for any +** or all of these interfaces to be NULL or for their behavior to change +** from one release to the next. Applications must not attempt to access +** any of these methods if the iVersion of the VFS is less than 3. */ typedef struct sqlite3_vfs sqlite3_vfs; +typedef void (*sqlite3_syscall_ptr)(void); struct sqlite3_vfs { - int iVersion; /* Structure version number */ + int iVersion; /* Structure version number (currently 3) */ int szOsFile; /* Size of subclassed sqlite3_file */ int mxPathname; /* Maximum file pathname length */ sqlite3_vfs *pNext; /* Next registered VFS */ @@ -1364,8 +1528,23 @@ struct sqlite3_vfs { int (*xSleep)(sqlite3_vfs*, int microseconds); int (*xCurrentTime)(sqlite3_vfs*, double*); int (*xGetLastError)(sqlite3_vfs*, int, char *); - /* New fields may be appended in figure versions. The iVersion - ** value will increment whenever this happens. */ + /* + ** The methods above are in version 1 of the sqlite_vfs object + ** definition. Those that follow are added in version 2 or later + */ + int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); + /* + ** The methods above are in versions 1 and 2 of the sqlite_vfs object. + ** Those below are for version 3 and greater. + */ + int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); + sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); + const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); + /* + ** The methods above are in versions 1 through 3 of the sqlite_vfs object. + ** New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. + */ }; /* @@ -1377,13 +1556,58 @@ struct sqlite3_vfs { ** With SQLITE_ACCESS_EXISTS, the xAccess method ** simply checks whether the file exists. ** With SQLITE_ACCESS_READWRITE, the xAccess method -** checks whether the file is both readable and writable. +** checks whether the named directory is both readable and writable +** (in other words, if files can be added, removed, and renamed within +** the directory). +** The SQLITE_ACCESS_READWRITE constant is currently used only by the +** [temp_store_directory pragma], though this could change in a future +** release of SQLite. ** With SQLITE_ACCESS_READ, the xAccess method -** checks whether the file is readable. +** checks whether the file is readable. The SQLITE_ACCESS_READ constant is +** currently unused, though it might be used in a future release of +** SQLite. */ #define SQLITE_ACCESS_EXISTS 0 -#define SQLITE_ACCESS_READWRITE 1 -#define SQLITE_ACCESS_READ 2 +#define SQLITE_ACCESS_READWRITE 1 /* Used by PRAGMA temp_store_directory */ +#define SQLITE_ACCESS_READ 2 /* Unused */ + +/* +** CAPI3REF: Flags for the xShmLock VFS method +** +** These integer constants define the various locking operations +** allowed by the xShmLock method of [sqlite3_io_methods]. The +** following are the only legal combinations of flags to the +** xShmLock method: +** +** <ul> +** <li> SQLITE_SHM_LOCK | SQLITE_SHM_SHARED +** <li> SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE +** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED +** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE +** </ul> +** +** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as +** was given no the corresponding lock. +** +** The xShmLock method can transition between unlocked and SHARED or +** between unlocked and EXCLUSIVE. It cannot transition between SHARED +** and EXCLUSIVE. +*/ +#define SQLITE_SHM_UNLOCK 1 +#define SQLITE_SHM_LOCK 2 +#define SQLITE_SHM_SHARED 4 +#define SQLITE_SHM_EXCLUSIVE 8 + +/* +** CAPI3REF: Maximum xShmLock index +** +** The xShmLock method on [sqlite3_io_methods] may use values +** between 0 and this upper bound as its "offset" argument. +** The SQLite core will never attempt to acquire or release a +** lock outside of this range +*/ +#define SQLITE_SHM_NLOCK 8 + /* ** CAPI3REF: Initialize The SQLite Library @@ -1485,44 +1709,37 @@ SQLITE_API int sqlite3_os_end(void); ** implementation of an application-defined [sqlite3_os_init()]. ** ** The first argument to sqlite3_config() is an integer -** [SQLITE_CONFIG_SINGLETHREAD | configuration option] that determines +** [configuration option] that determines ** what property of SQLite is to be configured. Subsequent arguments -** vary depending on the [SQLITE_CONFIG_SINGLETHREAD | configuration option] +** vary depending on the [configuration option] ** in the first argument. ** ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. */ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_config(int, ...); +SQLITE_API int sqlite3_config(int, ...); /* ** CAPI3REF: Configure database connections -** EXPERIMENTAL ** ** The sqlite3_db_config() interface is used to make configuration ** changes to a [database connection]. The interface is similar to ** [sqlite3_config()] except that the changes apply to a single -** [database connection] (specified in the first argument). The -** sqlite3_db_config() interface should only be used immediately after -** the database connection is created using [sqlite3_open()], -** [sqlite3_open16()], or [sqlite3_open_v2()]. +** [database connection] (specified in the first argument). ** ** The second argument to sqlite3_db_config(D,V,...) is the -** configuration verb - an integer code that indicates what -** aspect of the [database connection] is being configured. -** The only choice for this value is [SQLITE_DBCONFIG_LOOKASIDE]. -** New verbs are likely to be added in future releases of SQLite. -** Additional arguments depend on the verb. +** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code +** that indicates what aspect of the [database connection] is being configured. +** Subsequent arguments vary depending on the configuration verb. ** ** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if ** the call is considered successful. */ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); +SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); /* ** CAPI3REF: Memory Allocation Routines -** EXPERIMENTAL ** ** An instance of this object defines the interface between SQLite ** and low-level memory allocation routines. @@ -1530,7 +1747,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); ** This object is used in only one place in the SQLite interface. ** A pointer to an instance of this object is the argument to ** [sqlite3_config()] when the configuration option is -** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. +** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. ** By creating an instance of this object ** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) ** during configuration, an application can specify an alternative @@ -1546,16 +1763,10 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); ** order to verify that SQLite recovers gracefully from such ** conditions. ** -** The xMalloc and xFree methods must work like the -** malloc() and free() functions from the standard C library. -** The xRealloc method must work like realloc() from the standard C library -** with the exception that if the second argument to xRealloc is zero, -** xRealloc must be a no-op - it must not perform any allocation or -** deallocation. ^SQLite guarantees that the second argument to +** The xMalloc, xRealloc, and xFree methods must work like the +** malloc(), realloc() and free() functions from the standard C library. +** ^SQLite guarantees that the second argument to ** xRealloc is always a value returned by a prior call to xRoundup. -** And so in cases where xRoundup always returns a positive number, -** xRealloc can perform exactly as the standard library realloc() and -** still be in compliance with this specification. ** ** xSize should return the allocated size of a memory allocation ** previously obtained from xMalloc or xRealloc. The allocated size @@ -1566,7 +1777,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); ** allocators round up memory allocations at least to the next multiple ** of 8. Some allocators round up to a larger multiple or to a power of 2. ** Every memory allocation request coming in through [sqlite3_malloc()] -** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, ** that causes the corresponding memory allocation to fail. ** ** The xInit method initializes the memory allocator. (For example, @@ -1604,7 +1815,7 @@ struct sqlite3_mem_methods { /* ** CAPI3REF: Configuration Options -** EXPERIMENTAL +** KEYWORDS: {configuration option} ** ** These constants are the available integer configuration options that ** can be passed as the first argument to the [sqlite3_config()] interface. @@ -1617,18 +1828,18 @@ struct sqlite3_mem_methods { ** is invoked. ** ** <dl> -** <dt>SQLITE_CONFIG_SINGLETHREAD</dt> +** [[SQLITE_CONFIG_SINGLETHREAD]] <dt>SQLITE_CONFIG_SINGLETHREAD</dt> ** <dd>There are no arguments to this option. ^This option sets the ** [threading mode] to Single-thread. In other words, it disables ** all mutexing and puts SQLite into a mode where it can only be used ** by a single thread. ^If SQLite is compiled with ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then ** it is not possible to change the [threading mode] from its default -** value of Single-thread and so [sqlite3_config()] will return +** value of Single-thread and so [sqlite3_config()] will return ** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD ** configuration option.</dd> ** -** <dt>SQLITE_CONFIG_MULTITHREAD</dt> +** [[SQLITE_CONFIG_MULTITHREAD]] <dt>SQLITE_CONFIG_MULTITHREAD</dt> ** <dd>There are no arguments to this option. ^This option sets the ** [threading mode] to Multi-thread. In other words, it disables ** mutexing on [database connection] and [prepared statement] objects. @@ -1642,7 +1853,7 @@ struct sqlite3_mem_methods { ** [sqlite3_config()] will return [SQLITE_ERROR] if called with the ** SQLITE_CONFIG_MULTITHREAD configuration option.</dd> ** -** <dt>SQLITE_CONFIG_SERIALIZED</dt> +** [[SQLITE_CONFIG_SERIALIZED]] <dt>SQLITE_CONFIG_SERIALIZED</dt> ** <dd>There are no arguments to this option. ^This option sets the ** [threading mode] to Serialized. In other words, this option enables ** all mutexes including the recursive @@ -1658,7 +1869,7 @@ struct sqlite3_mem_methods { ** [sqlite3_config()] will return [SQLITE_ERROR] if called with the ** SQLITE_CONFIG_SERIALIZED configuration option.</dd> ** -** <dt>SQLITE_CONFIG_MALLOC</dt> +** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt> ** <dd> ^(This option takes a single argument which is a pointer to an ** instance of the [sqlite3_mem_methods] structure. The argument specifies ** alternative low-level memory allocation routines to be used in place of @@ -1666,7 +1877,7 @@ struct sqlite3_mem_methods { ** its own private copy of the content of the [sqlite3_mem_methods] structure ** before the [sqlite3_config()] call returns.</dd> ** -** <dt>SQLITE_CONFIG_GETMALLOC</dt> +** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt> ** <dd> ^(This option takes a single argument which is a pointer to an ** instance of the [sqlite3_mem_methods] structure. The [sqlite3_mem_methods] ** structure is filled with the currently defined memory allocation routines.)^ @@ -1674,15 +1885,15 @@ struct sqlite3_mem_methods { ** routines with a wrapper that simulations memory allocation failure or ** tracks memory usage, for example. </dd> ** -** <dt>SQLITE_CONFIG_MEMSTATUS</dt> -** <dd> ^This option takes single argument of type int, interpreted as a -** boolean, which enables or disables the collection of memory allocation -** statistics. ^(When memory allocation statistics are disabled, the +** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt> +** <dd> ^This option takes single argument of type int, interpreted as a +** boolean, which enables or disables the collection of memory allocation +** statistics. ^(When memory allocation statistics are disabled, the ** following SQLite interfaces become non-operational: ** <ul> ** <li> [sqlite3_memory_used()] ** <li> [sqlite3_memory_highwater()] -** <li> [sqlite3_soft_heap_limit()] +** <li> [sqlite3_soft_heap_limit64()] ** <li> [sqlite3_status()] ** </ul>)^ ** ^Memory allocation statistics are enabled by default unless SQLite is @@ -1690,26 +1901,25 @@ struct sqlite3_mem_methods { ** allocation statistics are disabled by default. ** </dd> ** -** <dt>SQLITE_CONFIG_SCRATCH</dt> +** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt> ** <dd> ^This option specifies a static memory buffer that SQLite can use for ** scratch memory. There are three arguments: A pointer an 8-byte -** aligned memory buffer from which the scrach allocations will be +** aligned memory buffer from which the scratch allocations will be ** drawn, the size of each scratch allocation (sz), ** and the maximum number of scratch allocations (N). The sz -** argument must be a multiple of 16. The sz parameter should be a few bytes -** larger than the actual scratch space required due to internal overhead. +** argument must be a multiple of 16. ** The first argument must be a pointer to an 8-byte aligned buffer ** of at least sz*N bytes of memory. -** ^SQLite will use no more than one scratch buffer per thread. So -** N should be set to the expected maximum number of threads. ^SQLite will -** never require a scratch buffer that is more than 6 times the database -** page size. ^If SQLite needs needs additional scratch memory beyond -** what is provided by this configuration option, then +** ^SQLite will use no more than two scratch buffers per thread. So +** N should be set to twice the expected maximum number of threads. +** ^SQLite will never require a scratch buffer that is more than 6 +** times the database page size. ^If SQLite needs needs additional +** scratch memory beyond what is provided by this configuration option, then ** [sqlite3_malloc()] will be used to obtain the memory needed.</dd> ** -** <dt>SQLITE_CONFIG_PAGECACHE</dt> +** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt> ** <dd> ^This option specifies a static memory buffer that SQLite can use for -** the database page cache with the default page cache implemenation. +** the database page cache with the default page cache implementation. ** This configuration should not be used if an application-define page ** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option. ** There are three arguments to this option: A pointer to 8-byte aligned @@ -1724,12 +1934,11 @@ struct sqlite3_mem_methods { ** memory needs for the first N pages that it adds to cache. ^If additional ** page cache memory is needed beyond what is provided by this option, then ** SQLite goes to [sqlite3_malloc()] for the additional storage space. -** ^The implementation might use one or more of the N buffers to hold -** memory accounting information. The pointer in the first argument must +** The pointer in the first argument must ** be aligned to an 8-byte boundary or subsequent behavior of SQLite ** will be undefined.</dd> ** -** <dt>SQLITE_CONFIG_HEAP</dt> +** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt> ** <dd> ^This option specifies a static memory buffer that SQLite will use ** for all of its dynamic memory allocation needs beyond those provided ** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE]. @@ -1742,9 +1951,11 @@ struct sqlite3_mem_methods { ** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory ** allocator is engaged to handle all of SQLites memory allocation needs. ** The first pointer (the memory pointer) must be aligned to an 8-byte -** boundary or subsequent behavior of SQLite will be undefined.</dd> +** boundary or subsequent behavior of SQLite will be undefined. +** The minimum allocation size is capped at 2^12. Reasonable values +** for the minimum allocation size are 2^5 through 2^8.</dd> ** -** <dt>SQLITE_CONFIG_MUTEX</dt> +** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt> ** <dd> ^(This option takes a single argument which is a pointer to an ** instance of the [sqlite3_mutex_methods] structure. The argument specifies ** alternative low-level mutex routines to be used in place @@ -1756,7 +1967,7 @@ struct sqlite3_mem_methods { ** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will ** return [SQLITE_ERROR].</dd> ** -** <dt>SQLITE_CONFIG_GETMUTEX</dt> +** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt> ** <dd> ^(This option takes a single argument which is a pointer to an ** instance of the [sqlite3_mutex_methods] structure. The ** [sqlite3_mutex_methods] @@ -1769,7 +1980,7 @@ struct sqlite3_mem_methods { ** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will ** return [SQLITE_ERROR].</dd> ** -** <dt>SQLITE_CONFIG_LOOKASIDE</dt> +** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt> ** <dd> ^(This option takes two arguments that determine the default ** memory allocation for the lookaside memory allocator on each ** [database connection]. The first argument is the @@ -1779,17 +1990,47 @@ struct sqlite3_mem_methods { ** verb to [sqlite3_db_config()] can be used to change the lookaside ** configuration on individual connections.)^ </dd> ** -** <dt>SQLITE_CONFIG_PCACHE</dt> +** [[SQLITE_CONFIG_PCACHE]] <dt>SQLITE_CONFIG_PCACHE</dt> ** <dd> ^(This option takes a single argument which is a pointer to ** an [sqlite3_pcache_methods] object. This object specifies the interface ** to a custom page cache implementation.)^ ^SQLite makes a copy of the ** object and uses it for page cache memory allocations.</dd> ** -** <dt>SQLITE_CONFIG_GETPCACHE</dt> +** [[SQLITE_CONFIG_GETPCACHE]] <dt>SQLITE_CONFIG_GETPCACHE</dt> ** <dd> ^(This option takes a single argument which is a pointer to an ** [sqlite3_pcache_methods] object. SQLite copies of the current ** page cache implementation into that object.)^ </dd> ** +** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt> +** <dd> ^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a +** function with a call signature of void(*)(void*,int,const char*), +** and a pointer to void. ^If the function pointer is not NULL, it is +** invoked by [sqlite3_log()] to process each logging event. ^If the +** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op. +** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is +** passed through as the first parameter to the application-defined logger +** function whenever that function is invoked. ^The second parameter to +** the logger function is a copy of the first parameter to the corresponding +** [sqlite3_log()] call and is intended to be a [result code] or an +** [extended result code]. ^The third parameter passed to the logger is +** log message after formatting via [sqlite3_snprintf()]. +** The SQLite logging interface is not reentrant; the logger function +** supplied by the application must not invoke any SQLite interface. +** In a multi-threaded application, the application-defined logger +** function must be threadsafe. </dd> +** +** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI +** <dd> This option takes a single argument of type int. If non-zero, then +** URI handling is globally enabled. If the parameter is zero, then URI handling +** is globally disabled. If URI handling is globally enabled, all filenames +** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or +** specified as part of [ATTACH] commands are interpreted as URIs, regardless +** of whether or not the [SQLITE_OPEN_URI] flag is set when the database +** connection is opened. If it is globally disabled, filenames are +** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the +** database connection is opened. By default, URI handling is globally +** disabled. The default value may be changed by compiling with the +** [SQLITE_USE_URI] symbol defined. ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ @@ -1803,15 +2044,15 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ #define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ #define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ -/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ #define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ #define SQLITE_CONFIG_PCACHE 14 /* sqlite3_pcache_methods* */ #define SQLITE_CONFIG_GETPCACHE 15 /* sqlite3_pcache_methods* */ #define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ +#define SQLITE_CONFIG_URI 17 /* int */ /* -** CAPI3REF: Configuration Options -** EXPERIMENTAL +** CAPI3REF: Database Connection Configuration Options ** ** These constants are the available integer configuration options that ** can be passed as the second argument to the [sqlite3_db_config()] interface. @@ -1825,10 +2066,10 @@ struct sqlite3_mem_methods { ** ** <dl> ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt> -** <dd> ^This option takes three additional arguments that determine the +** <dd> ^This option takes three additional arguments that determine the ** [lookaside memory allocator] configuration for the [database connection]. ** ^The first argument (the third parameter to [sqlite3_db_config()] is a -** pointer to an memory buffer to use for lookaside memory. +** pointer to a memory buffer to use for lookaside memory. ** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb ** may be NULL in which case SQLite will allocate the ** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the @@ -1837,12 +2078,40 @@ struct sqlite3_mem_methods { ** or equal to the product of the second and third arguments. The buffer ** must be aligned to an 8-byte boundary. ^If the second argument to ** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally -** rounded down to the next smaller -** multiple of 8. See also: [SQLITE_CONFIG_LOOKASIDE]</dd> +** 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_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].)^</dd> +** +** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt> +** <dd> ^This option is used to enable or disable the enforcement of +** [foreign key constraints]. There should be two additional arguments. +** The first argument is an integer which is 0 to disable FK enforcement, +** positive to enable FK enforcement or negative to leave FK enforcement +** unchanged. The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether FK enforcement is off or on +** following this call. The second parameter may be a NULL pointer, in +** which case the FK enforcement setting is not reported back. </dd> +** +** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt> +** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers]. +** There should be two additional arguments. +** The first argument is an integer which is 0 to disable triggers, +** positive to enable triggers or negative to leave the setting unchanged. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether triggers are disabled or enabled +** following this call. The second parameter may be a NULL pointer, in +** which case the trigger setting is not reported back. </dd> ** ** </dl> */ -#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ +#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ +#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ /* @@ -1866,13 +2135,17 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); ** ** ^This routine returns the [rowid] of the most recent ** successful [INSERT] into the database from the [database connection] -** in the first argument. ^If no successful [INSERT]s +** in the first argument. ^As of SQLite version 3.7.7, this routines +** records the last insert rowid of both ordinary tables and [virtual tables]. +** ^If no successful [INSERT]s ** have ever occurred on that database connection, zero is returned. ** -** ^(If an [INSERT] occurs within a trigger, then the [rowid] of the inserted -** row is returned by this routine as long as the trigger is running. -** But once the trigger terminates, the value returned by this routine -** reverts to the last value inserted before the trigger fired.)^ +** ^(If an [INSERT] occurs within a trigger or within a [virtual table] +** method, then this routine will return the [rowid] of the inserted +** row as long as the trigger or virtual table method is running. +** But once the trigger or virtual table method ends, the value returned +** by this routine reverts to what it was before the trigger or virtual +** table method began.)^ ** ** ^An [INSERT] that fails due to a constraint violation is not a ** successful [INSERT] and does not change the value returned by this @@ -1921,7 +2194,7 @@ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); ** mechanisms do not count as direct row changes.)^ ** ** A "trigger context" is a scope of execution that begins and -** ends with the script of a [CREATE TRIGGER | trigger]. +** ends with the script of a [CREATE TRIGGER | trigger]. ** Most SQL statements are ** evaluated outside of any trigger. This is the "top level" ** trigger context. If a trigger fires from the top level, a @@ -1964,7 +2237,7 @@ SQLITE_API int sqlite3_changes(sqlite3*); ** the count does not include changes used to implement [REPLACE] constraints, ** do rollbacks or ABORT processing, or [DROP TABLE] processing. The ** count does not include rows of views that fire an [INSTEAD OF trigger], -** though if the INSTEAD OF trigger makes changes of its own, those changes +** though if the INSTEAD OF trigger makes changes of its own, those changes ** are counted.)^ ** ^The sqlite3_total_changes() function counts the changes as soon as ** the statement that makes them is completed (when the statement handle @@ -2004,7 +2277,7 @@ SQLITE_API int sqlite3_total_changes(sqlite3*); ** ** ^The sqlite3_interrupt(D) call is in effect until all currently running ** SQL statements on [database connection] D complete. ^Any new SQL statements -** that are started after the sqlite3_interrupt() call and before the +** that are started after the sqlite3_interrupt() call and before the ** running statements reaches zero are interrupted as if they had been ** running prior to the sqlite3_interrupt() call. ^New SQL statements ** that are started after the running statement count reaches zero are @@ -2039,7 +2312,7 @@ SQLITE_API void sqlite3_interrupt(sqlite3*); ** ^These routines do not parse the SQL statements thus ** will not detect syntactically incorrect SQL. ** -** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior +** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior ** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked ** automatically by sqlite3_complete16(). If that initialization fails, ** then the return value from sqlite3_complete16() will be non-zero @@ -2114,7 +2387,7 @@ SQLITE_API int sqlite3_complete16(const void *sql); ** The busy callback should not take any actions which modify the ** database connection that invoked the busy handler. Any such actions ** result in undefined behavior. -** +** ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ @@ -2143,6 +2416,9 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); /* ** CAPI3REF: Convenience Routines For Running Queries ** +** This is a legacy interface that is preserved for backwards compatibility. +** Use of this interface is not recommended. +** ** Definition: A <b>result table</b> is memory data structure created by the ** [sqlite3_get_table()] interface. A result table records the ** complete query results from one or more queries. @@ -2163,7 +2439,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); ** It is not safe to pass a result table directly to [sqlite3_free()]. ** A result table should be deallocated using [sqlite3_free_table()]. ** -** As an example of the result table format, suppose a query result +** ^(As an example of the result table format, suppose a query result ** is as follows: ** ** <blockquote><pre> @@ -2187,7 +2463,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); ** azResult[5] = "28"; ** azResult[6] = "Cindy"; ** azResult[7] = "21"; -** </pre></blockquote> +** </pre></blockquote>)^ ** ** ^The sqlite3_get_table() function evaluates one or more ** semicolon-separated SQL statements in the zero-terminated UTF-8 @@ -2195,19 +2471,19 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); ** pointer given in its 3rd parameter. ** ** After the application has finished with the result from sqlite3_get_table(), -** it should pass the result table pointer to sqlite3_free_table() in order to +** it must pass the result table pointer to sqlite3_free_table() in order to ** release the memory that was malloced. Because of the way the ** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling ** function must not try to call [sqlite3_free()] directly. Only ** [sqlite3_free_table()] is able to release the memory properly and safely. ** -** ^(The sqlite3_get_table() interface is implemented as a wrapper around +** The sqlite3_get_table() interface is implemented as a wrapper around ** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access ** to any internal data structures of SQLite. It uses only the public ** interface defined here. As a consequence, errors that occur in the ** wrapper layer outside of the internal [sqlite3_exec()] call are not ** reflected in subsequent calls to [sqlite3_errcode()] or -** [sqlite3_errmsg()].)^ +** [sqlite3_errmsg()]. */ SQLITE_API int sqlite3_get_table( sqlite3 *db, /* An open database */ @@ -2232,7 +2508,7 @@ SQLITE_API void sqlite3_free_table(char **result); ** NULL pointer if [sqlite3_malloc()] is unable to allocate enough ** memory to hold the resulting string. ** -** ^(In sqlite3_snprintf() routine is similar to "snprintf()" from +** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from ** the standard C library. The result is written into the ** buffer supplied as the second parameter whose size is given by ** the first parameter. Note that the order of the @@ -2251,6 +2527,8 @@ SQLITE_API void sqlite3_free_table(char **result); ** the zero terminator. So the longest string that can be completely ** written will be n-1 characters. ** +** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). +** ** These routines all implement some additional formatting ** options that are useful for constructing SQL statements. ** All of the usual printf() formatting options apply. In addition, there @@ -2314,6 +2592,7 @@ SQLITE_API void sqlite3_free_table(char **result); SQLITE_API char *sqlite3_mprintf(const char*,...); SQLITE_API char *sqlite3_vmprintf(const char*, va_list); SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); +SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list); /* ** CAPI3REF: Memory Allocation Subsystem @@ -2359,7 +2638,9 @@ SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); ** is not freed. ** ** ^The memory returned by sqlite3_malloc() and sqlite3_realloc() -** is always aligned to at least an 8 byte boundary. +** is always aligned to at least an 8 byte boundary, or to a +** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time +** option is used. ** ** In SQLite version 3.5.0 and 3.5.1, it was possible to define ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in @@ -2436,7 +2717,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P); /* ** CAPI3REF: Compile-Time Authorization Callbacks ** -** ^This routine registers a authorizer callback with a particular +** ^This routine registers an authorizer callback with a particular ** [database connection], supplied in the first argument. ** ^The authorizer callback is invoked as SQL statements are being compiled ** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], @@ -2456,7 +2737,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** requested is ok. ^When the callback returns [SQLITE_DENY], the ** [sqlite3_prepare_v2()] or equivalent call that triggered the ** authorizer will fail with an error message explaining that -** access is denied. +** access is denied. ** ** ^The first parameter to the authorizer callback is a copy of the third ** parameter to the sqlite3_set_authorizer() interface. ^The second parameter @@ -2503,7 +2784,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** database connections for the meaning of "modify" in this paragraph. ** ** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the -** statement might be re-prepared during [sqlite3_step()] due to a +** statement might be re-prepared during [sqlite3_step()] due to a ** schema change. Hence, the application should ensure that the ** correct authorizer callback remains in place during the [sqlite3_step()]. ** @@ -2527,6 +2808,9 @@ SQLITE_API int sqlite3_set_authorizer( ** to signal SQLite whether or not the action is permitted. See the ** [sqlite3_set_authorizer | authorizer documentation] for additional ** information. +** +** Note that SQLITE_IGNORE is also used as a [SQLITE_ROLLBACK | return code] +** from the [sqlite3_vtab_on_conflict()] interface. */ #define SQLITE_DENY 1 /* Abort the SQL statement with an error */ #define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ @@ -2587,7 +2871,6 @@ SQLITE_API int sqlite3_set_authorizer( /* ** CAPI3REF: Tracing And Profiling Functions -** EXPERIMENTAL ** ** These routines register callback functions that can be used for ** tracing and profiling the execution of SQL statements. @@ -2603,26 +2886,43 @@ SQLITE_API int sqlite3_set_authorizer( ** ^The callback function registered by sqlite3_profile() is invoked ** as each SQL statement finishes. ^The profile callback contains ** the original statement text and an estimate of wall-clock time -** of how long that statement took to run. -*/ -SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +** of how long that statement took to run. ^The profile callback +** time is in units of nanoseconds, however the current implementation +** is only capable of millisecond resolution so the six least significant +** digits in the time are meaningless. Future versions of SQLite +** might provide greater resolution on the profiler callback. The +** sqlite3_profile() function is considered experimental and is +** subject to change in future versions of SQLite. +*/ +SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, void(*xProfile)(void*,const char*,sqlite3_uint64), void*); /* ** CAPI3REF: Query Progress Callbacks ** -** ^This routine configures a callback function - the -** progress callback - that is invoked periodically during long -** running calls to [sqlite3_exec()], [sqlite3_step()] and -** [sqlite3_get_table()]. An example use for this +** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback +** function X to be invoked periodically during long running calls to +** [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 number of +** [virtual machine instructions] that are evaluated between successive +** invocations of the callback X. +** +** ^Only a single progress handler may be defined at one time per +** [database connection]; setting a new progress handler cancels the +** old one. ^Setting parameter X to NULL disables the progress handler. +** ^The progress handler is also disabled by setting N to a value less +** than 1. +** ** ^If the progress callback returns non-zero, the operation is ** interrupted. This feature can be used to implement a ** "Cancel" button on a GUI progress dialog box. ** -** The progress handler must not do anything that will modify +** 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. @@ -2633,7 +2933,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection ** -** ^These routines open an SQLite database file whose name is given by the +** ^These routines open an SQLite database file as specified by the ** filename argument. ^The filename argument is interpreted as UTF-8 for ** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte ** order for sqlite3_open16(). ^(A [database connection] handle is usually @@ -2658,9 +2958,9 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** except that it accepts two additional parameters for additional control ** over the new database connection. ^(The flags parameter to ** sqlite3_open_v2() can take one of -** the following three values, optionally combined with the +** the following three values, optionally combined with the ** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE], -** and/or [SQLITE_OPEN_PRIVATECACHE] flags:)^ +** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^ ** ** <dl> ** ^(<dt>[SQLITE_OPEN_READONLY]</dt> @@ -2673,15 +2973,14 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** case the database must already exist, otherwise an error is returned.</dd>)^ ** ** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt> -** <dd>The database is opened for reading and writing, and is creates it if +** <dd>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().</dd>)^ ** </dl> ** ** If the 3rd parameter to sqlite3_open_v2() is not one of the -** combinations shown above or one of the combinations shown above combined -** with the [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], -** [SQLITE_OPEN_SHAREDCACHE] and/or [SQLITE_OPEN_SHAREDCACHE] flags, +** combinations shown above optionally combined with other +** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] ** then the behavior is undefined. ** ** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection @@ -2696,6 +2995,11 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not ** participate in [shared cache mode] even if it is enabled. ** +** ^The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system interface that +** the new database connection should use. ^If the fourth parameter is +** a NULL pointer then the default [sqlite3_vfs] object is used. +** ** ^If the filename is ":memory:", then a private, temporary in-memory database ** is created for the connection. ^This in-memory database will vanish when ** the database connection is closed. Future versions of SQLite might @@ -2708,10 +3012,111 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** on-disk database will be created. ^This private database will be ** automatically deleted as soon as the database connection is closed. ** -** ^The fourth parameter to sqlite3_open_v2() is the name of the -** [sqlite3_vfs] object that defines the operating system interface that -** the new database connection should use. ^If the fourth parameter is -** a NULL pointer then the default [sqlite3_vfs] object is used. +** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3> +** +** ^If [URI filename] interpretation is enabled, and the filename argument +** begins with "file:", then the filename is interpreted as a URI. ^URI +** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is +** set in the fourth argument to sqlite3_open_v2(), or if it has +** been enabled globally using the [SQLITE_CONFIG_URI] option with the +** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. +** As of SQLite version 3.7.7, URI filename interpretation is turned off +** by default, but future releases of SQLite might enable URI filename +** interpretation by default. See "[URI filenames]" for additional +** information. +** +** URI filenames are parsed according to RFC 3986. ^If the URI contains an +** authority, then it must be either an empty string or the string +** "localhost". ^If the authority is not an empty string or "localhost", an +** error is returned to the caller. ^The fragment component of a URI, if +** present, is ignored. +** +** ^SQLite uses the path component of the URI as the name of the disk file +** which contains the database. ^If the path begins with a '/' character, +** then it is interpreted as an absolute path. ^If the path does not begin +** with a '/' (meaning that the authority section is omitted from the URI) +** then the path is interpreted as a relative path. +** ^On windows, the first component of an absolute path +** is a drive specification (e.g. "C:"). +** +** [[core URI query parameters]] +** The query component of a URI may contain parameters that are interpreted +** either by SQLite itself, or by a [VFS | custom VFS implementation]. +** SQLite interprets the following three query parameters: +** +** <ul> +** <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of +** a VFS object that provides the operating system interface that should +** be used to access the database file on disk. ^If this option is set to +** an empty string the default VFS object is used. ^Specifying an unknown +** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is +** present, then the VFS specified by the option takes precedence over +** the value passed as the fourth parameter to sqlite3_open_v2(). +** +** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw" or +** "rwc". Attempting to set it to any other value is an error)^. +** ^If "ro" is specified, then the database is opened for read-only +** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the +** third argument to sqlite3_prepare_v2(). ^If the mode option is set to +** "rw", then the database is opened for read-write (but not create) +** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had +** been set. ^Value "rwc" is equivalent to setting both +** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If sqlite3_open_v2() is +** used, it is an error to specify a value for the mode parameter that is +** less restrictive than that specified by the flags passed as the third +** parameter. +** +** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or +** "private". ^Setting it to "shared" is equivalent to setting the +** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to +** sqlite3_open_v2(). ^Setting the cache parameter to "private" is +** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. +** ^If sqlite3_open_v2() is used and the "cache" parameter is present in +** a URI filename, its value overrides any behaviour requested by setting +** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. +** </ul> +** +** ^Specifying an unknown parameter in the query component of a URI is not an +** error. Future versions of SQLite might understand additional query +** parameters. See "[query parameters with special meaning to SQLite]" for +** additional information. +** +** [[URI filename examples]] <h3>URI filename examples</h3> +** +** <table border="1" align=center cellpadding=5> +** <tr><th> URI filenames <th> Results +** <tr><td> file:data.db <td> +** Open the file "data.db" in the current directory. +** <tr><td> file:/home/fred/data.db<br> +** file:///home/fred/data.db <br> +** file://localhost/home/fred/data.db <br> <td> +** Open the database file "/home/fred/data.db". +** <tr><td> file://darkstar/home/fred/data.db <td> +** An error. "darkstar" is not a recognized authority. +** <tr><td style="white-space:nowrap"> +** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db +** <td> Windows only: Open the file "data.db" on fred's desktop on drive +** C:. Note that the %20 escaping in this example is not strictly +** necessary - space characters can be used literally +** in URI filenames. +** <tr><td> file:data.db?mode=ro&cache=private <td> +** Open file "data.db" in the current directory for read-only access. +** Regardless of whether or not shared-cache mode is enabled by +** default, use a private cache. +** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td> +** Open file "/home/fred/data.db". Use the special VFS "unix-nolock". +** <tr><td> file:data.db?mode=readonly <td> +** An error. "readonly" is not a valid option for the "mode" parameter. +** </table> +** +** ^URI hexadecimal escape sequences (%HH) are supported within the path and +** query components of a URI. A hexadecimal escape sequence consists of a +** percent sign - "%" - followed by exactly two hexadecimal digits +** specifying an octet value. ^Before the path or query components of a +** URI filename are interpreted, they are encoded using UTF-8 and all +** hexadecimal escape sequences replaced by a single byte containing the +** corresponding octet. If this process generates an invalid UTF-8 encoding, +** the results are undefined. ** ** <b>Note to Windows users:</b> The encoding used for the filename argument ** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever @@ -2735,6 +3140,26 @@ SQLITE_API int sqlite3_open_v2( ); /* +** CAPI3REF: Obtain Values For URI Parameters +** +** This is a utility routine, useful to VFS implementations, that checks +** to see if a database file was a URI that contained a specific query +** parameter, and if so obtains the value of the query parameter. +** +** The zFilename argument is the filename pointer passed into the xOpen() +** method of a VFS implementation. The zParam argument is the name of the +** query parameter we seek. This routine returns the value of the zParam +** parameter if it exists. If the parameter does not exist, this routine +** returns a NULL pointer. +** +** If the zFilename argument to this function is not a pointer that SQLite +** passed into the xOpen VFS method, then the behavior of this routine +** is undefined and probably undesirable. +*/ +SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); + + +/* ** CAPI3REF: Error Codes And Messages ** ** ^The sqlite3_errcode() interface returns the numeric [result code] or @@ -2742,7 +3167,7 @@ SQLITE_API int sqlite3_open_v2( ** associated with a [database connection]. If a prior API call failed ** but the most recent API call succeeded, the return value from ** sqlite3_errcode() is undefined. ^The sqlite3_extended_errcode() -** interface is the same except that it always returns the +** interface is the same except that it always returns the ** [extended result code] even when extended result codes are ** disabled. ** @@ -2806,17 +3231,22 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** [database connection] whose limit is to be set or queried. The ** second parameter is one of the [limit categories] that define a ** class of constructs to be size limited. The third parameter is the -** new limit for that construct. The function returns the old limit.)^ +** new limit for that construct.)^ ** ** ^If the new limit is a negative number, the limit is unchanged. -** ^(For the limit category of SQLITE_LIMIT_XYZ there is a +** ^(For each limit category SQLITE_LIMIT_<i>NAME</i> there is a ** [limits | hard upper bound] -** set by a compile-time C preprocessor macro named -** [limits | SQLITE_MAX_XYZ]. +** set at compile-time by a C preprocessor macro called +** [limits | SQLITE_MAX_<i>NAME</i>]. ** (The "_LIMIT_" in the name is changed to "_MAX_".))^ ** ^Attempts to increase a limit above its hard upper bound are ** silently truncated to the hard upper bound. ** +** ^Regardless of whether or not the limit was changed, the +** [sqlite3_limit()] interface returns the prior value of the limit. +** ^Hence, to find the current value of a limit without changing it, +** simply invoke this interface with the third parameter set to -1. +** ** Run-time limits are intended for use in applications that manage ** both their own internal database and also databases that are controlled ** by untrusted external sources. An example application might be a @@ -2844,42 +3274,45 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** Additional information is available at [limits | Limits in SQLite]. ** ** <dl> -** ^(<dt>SQLITE_LIMIT_LENGTH</dt> -** <dd>The maximum size of any string or BLOB or table row.<dd>)^ +** [[SQLITE_LIMIT_LENGTH]] ^(<dt>SQLITE_LIMIT_LENGTH</dt> +** <dd>The maximum size of any string or BLOB or table row, in bytes.<dd>)^ ** -** ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt> +** [[SQLITE_LIMIT_SQL_LENGTH]] ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt> ** <dd>The maximum length of an SQL statement, in bytes.</dd>)^ ** -** ^(<dt>SQLITE_LIMIT_COLUMN</dt> +** [[SQLITE_LIMIT_COLUMN]] ^(<dt>SQLITE_LIMIT_COLUMN</dt> ** <dd>The maximum number of columns in a table definition or in the ** result set of a [SELECT] or the maximum number of columns in an index ** or in an ORDER BY or GROUP BY clause.</dd>)^ ** -** ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt> +** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt> ** <dd>The maximum depth of the parse tree on any expression.</dd>)^ ** -** ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt> +** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt> ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^ ** -** ^(<dt>SQLITE_LIMIT_VDBE_OP</dt> +** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt> ** <dd>The maximum number of instructions in a virtual machine program -** used to implement an SQL statement.</dd>)^ +** used to implement an SQL statement. This limit is not currently +** enforced, though that might be added in some future release of +** SQLite.</dd>)^ ** -** ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt> +** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt> ** <dd>The maximum number of arguments on a function.</dd>)^ ** -** ^(<dt>SQLITE_LIMIT_ATTACHED</dt> +** [[SQLITE_LIMIT_ATTACHED]] ^(<dt>SQLITE_LIMIT_ATTACHED</dt> ** <dd>The maximum number of [ATTACH | attached databases].)^</dd> ** +** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]] ** ^(<dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt> ** <dd>The maximum length of the pattern argument to the [LIKE] or ** [GLOB] operators.</dd>)^ ** +** [[SQLITE_LIMIT_VARIABLE_NUMBER]] ** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt> -** <dd>The maximum number of variables in an SQL statement that can -** be bound.</dd>)^ +** <dd>The maximum index number of any [parameter] in an SQL statement.)^ ** -** ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt> +** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt> ** <dd>The maximum depth of recursion for triggers.</dd>)^ ** </dl> */ @@ -2949,12 +3382,7 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** <li> ** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it ** always used to do, [sqlite3_step()] will automatically recompile the SQL -** statement and try to run it again. ^If the schema has changed in -** a way that makes the statement no longer valid, [sqlite3_step()] will still -** return [SQLITE_SCHEMA]. But unlike the legacy behavior, [SQLITE_SCHEMA] is -** now a fatal error. Calling [sqlite3_prepare_v2()] again will not make the -** error go away. Note: use [sqlite3_errmsg()] to find the text -** of the parsing error that results in an [SQLITE_SCHEMA] return. +** statement and try to run it again. ** </li> ** ** <li> @@ -2967,11 +3395,16 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** </li> ** ** <li> -** ^If the value of a [parameter | host parameter] in the WHERE clause might -** change the query plan for a statement, then the statement may be -** automatically recompiled (as if there had been a schema change) on the first -** [sqlite3_step()] call following any change to the -** [sqlite3_bind_text | bindings] of the [parameter]. +** ^If the specific value bound to [parameter | host parameter] in the +** WHERE clause might influence the choice of query plan for a statement, +** then the statement will be automatically recompiled, as if there had been +** a schema change, on the first [sqlite3_step()] call following any change +** to the [sqlite3_bind_text | bindings] of that [parameter]. +** ^The specific value of WHERE-clause [parameter] might influence the +** choice of query plan if the parameter is the left-hand side of a [LIKE] +** or [GLOB] operator or if the parameter is compared to an indexed column +** and the [SQLITE_ENABLE_STAT2] compile-time option is enabled. +** the ** </li> ** </ol> */ @@ -3014,6 +3447,37 @@ SQLITE_API int sqlite3_prepare16_v2( SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); /* +** CAPI3REF: Determine If An SQL Statement Writes The Database +** +** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if +** and only if the [prepared statement] X makes no direct changes to +** the content of the database file. +** +** Note that [application-defined SQL functions] or +** [virtual tables] might change the database indirectly as a side effect. +** ^(For example, if an application defines a function "eval()" that +** calls [sqlite3_exec()], then the following SQL statement would +** change the database file through side-effects: +** +** <blockquote><pre> +** SELECT eval('DELETE FROM t1') FROM t2; +** </pre></blockquote> +** +** But because the [SELECT] statement does not change the database file +** directly, sqlite3_stmt_readonly() would still return true.)^ +** +** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK], +** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true, +** since the statements themselves do not actually modify the database but +** rather they control the timing of when other statements modify the +** database. ^The [ATTACH] and [DETACH] statements also cause +** sqlite3_stmt_readonly() to return true since, while those statements +** change the configuration of a database connection, they do not make +** changes to the content of the database files on disk. +*/ +SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); + +/* ** CAPI3REF: Dynamically Typed Value Object ** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} ** @@ -3029,16 +3493,16 @@ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); ** whether or not it requires a protected sqlite3_value. ** ** The terms "protected" and "unprotected" refer to whether or not -** a mutex is held. A internal mutex is held for a protected +** a mutex is held. An internal mutex is held for a protected ** sqlite3_value object but no mutex is held for an unprotected ** sqlite3_value object. If SQLite is compiled to be single-threaded ** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) -** or if SQLite is run in one of reduced mutex modes +** or if SQLite is run in one of reduced mutex modes ** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] ** then there is no distinction between protected and unprotected ** sqlite3_value objects and they can be used interchangeably. However, ** for maximum code portability it is recommended that applications -** still make the distinction between between protected and unprotected +** still make the distinction between protected and unprotected ** sqlite3_value objects even when not strictly required. ** ** ^The sqlite3_value objects that are passed as parameters into the @@ -3084,7 +3548,7 @@ typedef struct sqlite3_context sqlite3_context; ** </ul> ** ** In the templates above, NNN represents an integer literal, -** and VVV represents an alphanumeric identifer.)^ ^The values of these +** and VVV represents an alphanumeric identifier.)^ ^The values of these ** parameters (also called "host parameter names" or "SQL parameters") ** can be set using the sqlite3_bind_*() routines defined here. ** @@ -3112,7 +3576,10 @@ typedef struct sqlite3_context sqlite3_context; ** ** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or -** string after SQLite has finished with it. ^If the fifth argument is +** string after SQLite has finished with it. ^The destructor is called +** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(), +** sqlite3_bind_text(), or sqlite3_bind_text16() fails. +** ^If the fifth argument is ** the special value [SQLITE_STATIC], then SQLite assumes that the ** information is in static, unmanaged space and does not need to be freed. ** ^If the fifth argument has the value [SQLITE_TRANSIENT], then @@ -3233,6 +3700,8 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); ** ^Return the number of columns in the result set returned by the ** [prepared statement]. ^This routine returns 0 if pStmt is an SQL ** statement that does not return data (for example an [UPDATE]). +** +** See also: [sqlite3_data_count()] */ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); @@ -3248,7 +3717,9 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); ** column number. ^The leftmost column is number 0. ** ** ^The returned string pointer is valid until either the [prepared statement] -** is destroyed by [sqlite3_finalize()] or until the next call to +** is destroyed by [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the next call to ** sqlite3_column_name() or sqlite3_column_name16() on the same column. ** ** ^If sqlite3_malloc() fails during the processing of either routine @@ -3274,7 +3745,9 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); ** the database name, the _table_ routines return the table name, and ** the origin_ routines return the column name. ** ^The returned string is valid until the [prepared statement] is destroyed -** using [sqlite3_finalize()] or until the same information is requested +** using [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the same information is requested ** again in a different encoding. ** ** ^The names returned are the original un-aliased names of the @@ -3368,7 +3841,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** ^[SQLITE_BUSY] means that the database engine was unable to acquire the ** database locks it needs to do its job. ^If the statement is a [COMMIT] ** or occurs outside of an explicit transaction, then you can retry the -** statement. If the statement is not a [COMMIT] and occurs within a +** statement. If the statement is not a [COMMIT] and occurs within an ** explicit transaction then you should rollback the transaction before ** continuing. ** @@ -3398,6 +3871,18 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** be the case that the same database connection is being used by two or ** more threads at the same moment in time. ** +** For all versions of SQLite up to and including 3.6.23.1, a call to +** [sqlite3_reset()] was required after sqlite3_step() returned anything +** other than [SQLITE_ROW] before any subsequent invocation of +** sqlite3_step(). Failure to reset the prepared statement using +** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from +** sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began +** calling [sqlite3_reset()] automatically in this circumstance rather +** than returning [SQLITE_MISUSE]. This is not considered a compatibility +** break because any application that ever receives an SQLITE_MISUSE error +** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option +** can be used to restore the legacy behavior. +** ** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step() ** API always returns a generic error code, [SQLITE_ERROR], following any ** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call @@ -3415,8 +3900,14 @@ SQLITE_API int sqlite3_step(sqlite3_stmt*); /* ** CAPI3REF: Number of columns in a result set ** -** ^The sqlite3_data_count(P) the number of columns in the -** of the result set of [prepared statement] P. +** ^The sqlite3_data_count(P) interface returns the number of columns in the +** current row of the result set of [prepared statement] P. +** ^If prepared statement P does not have results ready to return +** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of +** interfaces) then sqlite3_data_count(P) returns 0. +** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. +** +** See also: [sqlite3_column_count()] */ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); @@ -3496,18 +3987,26 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** ^If the result is a numeric value then sqlite3_column_bytes() uses ** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns ** the number of bytes in that string. -** ^The value returned does not include the zero terminator at the end -** of the string. ^For clarity: the value returned is the number of +** ^If the result is NULL, then sqlite3_column_bytes() returns zero. +** +** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts +** the string to UTF-16 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes16() uses +** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes16() returns zero. +** +** ^The values returned by [sqlite3_column_bytes()] and +** [sqlite3_column_bytes16()] do not include the zero terminators at the end +** of the string. ^For clarity: the values returned by +** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of ** bytes in the string, not the number of characters. ** ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(), ** even empty strings, are always zero terminated. ^The return -** value from sqlite3_column_blob() for a zero-length BLOB is an arbitrary -** pointer, possibly even a NULL pointer. -** -** ^The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes() -** but leaves the result in UTF-16 in native byte order instead of UTF-8. -** ^The zero terminator is not included in this count. +** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. ** ** ^The object returned by [sqlite3_column_value()] is an ** [unprotected sqlite3_value] object. An unprotected sqlite3_value object @@ -3552,10 +4051,10 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** used in the table for brevity and because they are familiar to most ** C programmers. ** -** ^Note that when type conversions occur, pointers returned by prior +** Note that when type conversions occur, pointers returned by prior ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or ** sqlite3_column_text16() may be invalidated. -** ^(Type conversions and pointer invalidations might occur +** Type conversions and pointer invalidations might occur ** in the following cases: ** ** <ul> @@ -3568,22 +4067,22 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** <li> The initial content is UTF-16 text and sqlite3_column_bytes() or ** sqlite3_column_text() is called. The content must be converted ** to UTF-8.</li> -** </ul>)^ +** </ul> ** ** ^Conversions between UTF-16be and UTF-16le are always done in place and do ** not invalidate a prior pointer, though of course the content of the buffer -** that the prior pointer points to will have been modified. Other kinds +** that the prior pointer references will have been modified. Other kinds ** of conversion are done in place when it is possible, but sometimes they ** are not possible and in those cases prior pointers are invalidated. ** -** ^(The safest and easiest to remember policy is to invoke these routines +** The safest and easiest to remember policy is to invoke these routines ** in one of the following ways: ** ** <ul> ** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li> ** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li> ** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li> -** </ul>)^ +** </ul> ** ** In other words, you should call sqlite3_column_text(), ** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result @@ -3621,17 +4120,26 @@ SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); ** CAPI3REF: Destroy A Prepared Statement Object ** ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. -** ^If the statement was executed successfully or not executed at all, then -** SQLITE_OK is returned. ^If execution of the statement failed then an -** [error code] or [extended error code] is returned. -** -** ^This routine can be called at any point during the execution of the -** [prepared statement]. ^If the virtual machine has not -** completed execution when this routine is called, that is like -** encountering an error or an [sqlite3_interrupt | interrupt]. -** ^Incomplete updates may be rolled back and transactions canceled, -** depending on the circumstances, and the -** [error code] returned will be [SQLITE_ABORT]. +** ^If the most recent evaluation of the statement encountered no errors +** or if the statement is never been evaluated, then sqlite3_finalize() returns +** SQLITE_OK. ^If the most recent evaluation of statement S failed, then +** sqlite3_finalize(S) returns the appropriate [error code] or +** [extended error code]. +** +** ^The sqlite3_finalize(S) routine can be called at any point during +** the life cycle of [prepared statement] S: +** before statement S is ever evaluated, after +** one or more calls to [sqlite3_reset()], or after any call +** to [sqlite3_step()] regardless of whether or not the statement has +** completed execution. +** +** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op. +** +** The application must finalize every [prepared statement] in order to avoid +** resource leaks. It is a grievous error for the application to try to use +** a prepared statement after it has been finalized. Any use of a prepared +** statement after it has been finalized can result in undefined and +** undesirable behavior such as segfaults and heap corruption. */ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); @@ -3667,23 +4175,25 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** KEYWORDS: {application-defined SQL function} ** KEYWORDS: {application-defined SQL functions} ** -** ^These two functions (collectively known as "function creation routines") +** ^These functions (collectively known as "function creation routines") ** are used to add SQL functions or aggregates or to redefine the behavior -** of existing SQL functions or aggregates. The only difference between the -** two is that the second parameter, the name of the (scalar) function or -** aggregate, is encoded in UTF-8 for sqlite3_create_function() and UTF-16 -** for sqlite3_create_function16(). +** of existing SQL functions or aggregates. The only differences between +** these routines are the text encoding expected for +** the second parameter (the name of the function being created) +** and the presence or absence of a destructor callback for +** the application data pointer. ** ** ^The first parameter is the [database connection] to which the SQL ** function is to be added. ^If an application uses more than one database ** connection then application-defined SQL functions must be added ** to each database connection separately. ** -** The second parameter is the name of the SQL function to be created or -** redefined. ^The length of the name is limited to 255 bytes, exclusive of -** the zero-terminator. Note that the name length limit is in bytes, not -** characters. ^Any attempt to create a function with a longer name -** will result in [SQLITE_ERROR] being returned. +** ^The second parameter is the name of the SQL function to be created or +** redefined. ^The length of the name is limited to 255 bytes in a UTF-8 +** representation, exclusive of the zero-terminator. ^Note that the name +** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. +** ^Any attempt to create a function with a longer name +** will result in [SQLITE_MISUSE] being returned. ** ** ^The third parameter (nArg) ** is the number of arguments that the SQL function or @@ -3693,10 +4203,10 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** parameter is less than -1 or greater than 127 then the behavior is ** undefined. ** -** The fourth parameter, eTextRep, specifies what +** ^The fourth parameter, eTextRep, specifies what ** [SQLITE_UTF8 | text encoding] this SQL function prefers for -** its parameters. Any SQL function implementation should be able to work -** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be +** its parameters. Every SQL function implementation must be able to work +** with UTF-8, UTF-16le, or UTF-16be. But some implementations may be ** more efficient with one encoding than another. ^An application may ** invoke sqlite3_create_function() or sqlite3_create_function16() multiple ** times with the same function but with different values of eTextRep. @@ -3708,13 +4218,24 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ ** -** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are +** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are ** pointers to C-language functions that implement the SQL function or ** aggregate. ^A scalar SQL function requires an implementation of the xFunc -** callback only; NULL pointers should be passed as the xStep and xFinal +** callback only; NULL pointers must be passed as the xStep and xFinal ** parameters. ^An aggregate SQL function requires an implementation of xStep -** and xFinal and NULL should be passed for xFunc. ^To delete an existing -** SQL function or aggregate, pass NULL for all three function callbacks. +** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing +** SQL function or aggregate, pass NULL pointers for all three function +** callbacks. +** +** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, +** then it is destructor for the application data pointer. +** The destructor is invoked when the function is deleted, either by being +** overloaded or when the database connection closes.)^ +** ^The destructor is also invoked if the call to +** sqlite3_create_function_v2() fails. +** ^When the destructor callback of the tenth parameter is invoked, it +** is passed a single argument which is a copy of the application data +** pointer which was the fifth parameter to sqlite3_create_function_v2(). ** ** ^It is permitted to register multiple implementations of the same ** functions with the same name but with either differing numbers of @@ -3724,17 +4245,12 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** nArg parameter is a better match than a function implementation with ** a negative nArg. ^A function where the preferred text encoding ** matches the database encoding is a better -** match than a function where the encoding is different. +** match than a function where the encoding is different. ** ^A function where the encoding difference is between UTF16le and UTF16be ** is a closer match than a function where the encoding difference is ** between UTF8 and UTF16. ** ** ^Built-in functions may be overloaded by new application-defined functions. -** ^The first application-defined function with a given name overrides all -** built-in functions in the same [database connection] with the same name. -** ^Subsequent application-defined functions of the same name only override -** prior application-defined functions that are an exact match for the -** number of parameters and preferred encoding. ** ** ^An application-defined function is permitted to call other ** SQLite interfaces. However, such calls must not @@ -3761,6 +4277,17 @@ SQLITE_API int sqlite3_create_function16( void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); +SQLITE_API int sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*) +); /* ** CAPI3REF: Text Encodings @@ -3780,7 +4307,7 @@ SQLITE_API int sqlite3_create_function16( ** DEPRECATED ** ** These functions are [deprecated]. In order to maintain -** backwards compatibility with older code, these functions continue +** backwards compatibility with older code, these functions continue ** to be supported. However, new applications should avoid ** the use of these functions. To help encourage people to avoid ** using these functions, we are not going to tell you what they do. @@ -3804,7 +4331,7 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** The xFunc (for scalar functions) or xStep (for aggregates) parameters ** to [sqlite3_create_function()] and [sqlite3_create_function16()] ** define callbacks that implement the SQL functions and aggregates. -** The 4th parameter to these callbacks is an array of pointers to +** The 3rd parameter to these callbacks is an array of pointers to ** [protected sqlite3_value] objects. There is one [sqlite3_value] object for ** each parameter to the SQL function. These routines are used to ** extract values from the [sqlite3_value] objects. @@ -3855,10 +4382,10 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); /* ** CAPI3REF: Obtain Aggregate Function Context ** -** Implementions of aggregate SQL functions use this +** Implementations of aggregate SQL functions use this ** routine to allocate memory for storing their state. ** -** ^The first time the sqlite3_aggregate_context(C,N) routine is called +** ^The first time the sqlite3_aggregate_context(C,N) routine is called ** for a particular aggregate function, SQLite ** allocates N of memory, zeroes out that memory, and returns a pointer ** to the new memory. ^On second and subsequent calls to @@ -3880,7 +4407,7 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); ** the same aggregate function instance will not resize the memory ** allocation.)^ ** -** ^SQLite automatically frees the memory allocated by +** ^SQLite automatically frees the memory allocated by ** sqlite3_aggregate_context() when the aggregate query concludes. ** ** The first parameter must be a copy of the @@ -4107,69 +4634,102 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); /* ** CAPI3REF: Define New Collating Sequences ** -** These functions are used to add new collation sequences to the -** [database connection] specified as the first argument. +** ^These functions add, remove, or modify a [collation] associated +** with the [database connection] specified as the first argument. ** -** ^The name of the new collation sequence is specified as a UTF-8 string +** ^The name of the collation is a UTF-8 string ** for sqlite3_create_collation() and sqlite3_create_collation_v2() -** and a UTF-16 string for sqlite3_create_collation16(). ^In all cases -** the name is passed as the second function argument. -** -** ^The third argument may be one of the constants [SQLITE_UTF8], -** [SQLITE_UTF16LE], or [SQLITE_UTF16BE], indicating that the user-supplied -** routine expects to be passed pointers to strings encoded using UTF-8, -** UTF-16 little-endian, or UTF-16 big-endian, respectively. ^The -** third argument might also be [SQLITE_UTF16] to indicate that the routine -** expects pointers to be UTF-16 strings in the native byte order, or the -** argument can be [SQLITE_UTF16_ALIGNED] if the -** the routine expects pointers to 16-bit word aligned strings -** of UTF-16 in the native byte order. -** -** A pointer to the user supplied routine must be passed as the fifth -** argument. ^If it is NULL, this is the same as deleting the collation -** sequence (so that SQLite cannot call it anymore). -** ^Each time the application supplied function is invoked, it is passed -** as its first parameter a copy of the void* passed as the fourth argument -** to sqlite3_create_collation() or sqlite3_create_collation16(). -** -** ^The remaining arguments to the application-supplied routine are two strings, -** each represented by a (length, data) pair and encoded in the encoding -** that was passed as the third argument when the collation sequence was -** registered. The application defined collation routine should -** return negative, zero or positive if the first string is less than, -** equal to, or greater than the second string. i.e. (STRING1 - STRING2). +** and a UTF-16 string in native byte order for sqlite3_create_collation16(). +** ^Collation names that compare equal according to [sqlite3_strnicmp()] are +** considered to be the same name. +** +** ^(The third argument (eTextRep) must be one of the constants: +** <ul> +** <li> [SQLITE_UTF8], +** <li> [SQLITE_UTF16LE], +** <li> [SQLITE_UTF16BE], +** <li> [SQLITE_UTF16], or +** <li> [SQLITE_UTF16_ALIGNED]. +** </ul>)^ +** ^The eTextRep argument determines the encoding of strings passed +** to the collating function callback, xCallback. +** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep +** force strings to be UTF16 with native byte order. +** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin +** on an even byte address. +** +** ^The fourth argument, pArg, is an application data pointer that is passed +** through as the first argument to the collating function callback. +** +** ^The fifth argument, xCallback, is a pointer to the collating function. +** ^Multiple collating functions can be registered using the same name but +** with different eTextRep parameters and SQLite will use whichever +** function requires the least amount of data transformation. +** ^If the xCallback argument is NULL then the collating function is +** deleted. ^When all collating functions having the same name are deleted, +** that collation is no longer usable. +** +** ^The collating function callback is invoked with a copy of the pArg +** application data pointer and with two strings in the encoding specified +** by the eTextRep argument. The collating function must return an +** integer that is negative, zero, or positive +** if the first string is less than, equal to, or greater than the second, +** respectively. A collating function must always return the same answer +** given the same inputs. If two or more collating functions are registered +** to the same collation name (using different eTextRep values) then all +** must give an equivalent answer when invoked with equivalent strings. +** The collating function must obey the following properties for all +** strings A, B, and C: +** +** <ol> +** <li> If A==B then B==A. +** <li> If A==B and B==C then A==C. +** <li> If A<B THEN B>A. +** <li> If A<B and B<C then A<C. +** </ol> +** +** If a collating function fails any of the above constraints and that +** collating function is registered and used, then the behavior of SQLite +** is undefined. ** ** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation() -** except that it takes an extra argument which is a destructor for -** the collation. ^The destructor is called when the collation is -** destroyed and is passed a copy of the fourth parameter void* pointer -** of the sqlite3_create_collation_v2(). -** ^Collations are destroyed when they are overridden by later calls to the -** collation creation functions or when the [database connection] is closed -** using [sqlite3_close()]. +** with the addition that the xDestroy callback is invoked on pArg when +** the collating function is deleted. +** ^Collating functions are deleted when they are overridden by later +** calls to the collation creation functions or when the +** [database connection] is closed using [sqlite3_close()]. +** +** ^The xDestroy callback is <u>not</u> called if the +** sqlite3_create_collation_v2() function fails. Applications that invoke +** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should +** check the return code and dispose of the application data pointer +** themselves rather than expecting SQLite to deal with it for them. +** This is different from every other SQLite interface. The inconsistency +** is unfortunate but cannot be changed without breaking backwards +** compatibility. ** ** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. */ SQLITE_API int sqlite3_create_collation( - sqlite3*, - const char *zName, - int eTextRep, - void*, + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, int(*xCompare)(void*,int,const void*,int,const void*) ); SQLITE_API int sqlite3_create_collation_v2( - sqlite3*, - const char *zName, - int eTextRep, - void*, + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, int(*xCompare)(void*,int,const void*,int,const void*), void(*xDestroy)(void*) ); SQLITE_API int sqlite3_create_collation16( - sqlite3*, + sqlite3*, const void *zName, - int eTextRep, - void*, + int eTextRep, + void *pArg, int(*xCompare)(void*,int,const void*,int,const void*) ); @@ -4200,17 +4760,17 @@ SQLITE_API int sqlite3_create_collation16( ** [sqlite3_create_collation_v2()]. */ SQLITE_API int sqlite3_collation_needed( - sqlite3*, - void*, + sqlite3*, + void*, void(*)(void*,sqlite3*,int eTextRep,const char*) ); SQLITE_API int sqlite3_collation_needed16( - sqlite3*, + sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const void*) ); -#if SQLITE_HAS_CODEC +#ifdef SQLITE_HAS_CODEC /* ** Specify the key for an encrypted database. This routine should be ** called right after sqlite3_open(). @@ -4237,7 +4797,7 @@ SQLITE_API int sqlite3_rekey( ); /* -** Specify the activation key for a SEE database. Unless +** Specify the activation key for a SEE database. Unless ** activated, none of the SEE routines will work. */ SQLITE_API void sqlite3_activate_see( @@ -4247,7 +4807,7 @@ SQLITE_API void sqlite3_activate_see( #ifdef SQLITE_ENABLE_CEROD /* -** Specify the activation key for a CEROD database. Unless +** Specify the activation key for a CEROD database. Unless ** activated, none of the CEROD routines will work. */ SQLITE_API void sqlite3_activate_cerod( @@ -4258,16 +4818,19 @@ SQLITE_API void sqlite3_activate_cerod( /* ** CAPI3REF: Suspend Execution For A Short Time ** -** ^The sqlite3_sleep() function causes the current thread to suspend execution +** The sqlite3_sleep() function causes the current thread to suspend execution ** for at least a number of milliseconds specified in its parameter. ** -** ^If the operating system does not support sleep requests with +** If the operating system does not support sleep requests with ** millisecond time resolution, then the time will be rounded up to -** the nearest second. ^The number of milliseconds of sleep actually +** the nearest second. The number of milliseconds of sleep actually ** requested from the operating system is returned. ** ** ^SQLite implements this interface by calling the xSleep() -** method of the default [sqlite3_vfs] object. +** method of the default [sqlite3_vfs] object. If the xSleep() method +** of the default VFS is not implemented correctly, or not implemented at +** all, then the behavior of sqlite3_sleep() may deviate from the description +** in the previous paragraphs. */ SQLITE_API int sqlite3_sleep(int); @@ -4293,7 +4856,7 @@ SQLITE_API int sqlite3_sleep(int); ** ^The [temp_store_directory pragma] may modify this variable and cause ** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, ** the [temp_store_directory pragma] always assumes that any string -** that this variable points to is held in memory obtained from +** that this variable points to is held in memory obtained from ** [sqlite3_malloc] and the pragma may attempt to free that memory ** using [sqlite3_free]. ** Hence, if this variable is modified directly, either it should be @@ -4393,8 +4956,6 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); ** an error or constraint causes an implicit rollback to occur. ** ^The rollback callback is not invoked if a transaction is ** automatically rolled back because the database connection is closed. -** ^The rollback callback is not invoked if a transaction is -** rolled back because a commit callback returned non-zero. ** ** See also the [sqlite3_update_hook()] interface. */ @@ -4448,7 +5009,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** interfaces. */ SQLITE_API void *sqlite3_update_hook( - sqlite3*, + sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); @@ -4491,40 +5052,73 @@ SQLITE_API int sqlite3_enable_shared_cache(int); ** pages to improve performance is an example of non-essential memory. ** ^sqlite3_release_memory() returns the number of bytes actually freed, ** which might be more or less than the amount requested. +** ^The sqlite3_release_memory() routine is a no-op returning zero +** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. */ SQLITE_API int sqlite3_release_memory(int); /* ** CAPI3REF: Impose A Limit On Heap Size ** -** ^The sqlite3_soft_heap_limit() interface places a "soft" limit -** on the amount of heap memory that may be allocated by SQLite. -** ^If an internal allocation is requested that would exceed the -** soft heap limit, [sqlite3_release_memory()] is invoked one or -** more times to free up some space before the allocation is performed. +** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the +** soft limit on the amount of heap memory that may be allocated by SQLite. +** ^SQLite strives to keep heap memory utilization below the soft heap +** limit by reducing the number of pages held in the page cache +** as heap memory usages approaches the limit. +** ^The soft heap limit is "soft" because even though SQLite strives to stay +** below the limit, it will exceed the limit rather than generate +** an [SQLITE_NOMEM] error. In other words, the soft heap limit +** is advisory only. ** -** ^The limit is called "soft" because if [sqlite3_release_memory()] -** cannot free sufficient memory to prevent the limit from being exceeded, -** the memory is allocated anyway and the current operation proceeds. +** ^The return value from sqlite3_soft_heap_limit64() is the size of +** the soft heap limit prior to the call. ^If the argument N is negative +** then no change is made to the soft heap limit. Hence, the current +** size of the soft heap limit can be determined by invoking +** sqlite3_soft_heap_limit64() with a negative argument. ** -** ^A negative or zero value for N means that there is no soft heap limit and -** [sqlite3_release_memory()] will only be called when memory is exhausted. -** ^The default value for the soft heap limit is zero. +** ^If the argument N is zero then the soft heap limit is disabled. ** -** ^(SQLite makes a best effort to honor the soft heap limit. -** But if the soft heap limit cannot be honored, execution will -** continue without error or notification.)^ This is why the limit is -** called a "soft" limit. It is advisory only. +** ^(The soft heap limit is not enforced in the current implementation +** if one or more of following conditions are true: ** -** Prior to SQLite version 3.5.0, this routine only constrained the memory -** allocated by a single thread - the same thread in which this routine -** runs. Beginning with SQLite version 3.5.0, the soft heap limit is -** applied to all threads. The value specified for the soft heap limit -** is an upper bound on the total memory allocation for all threads. In -** version 3.5.0 there is no mechanism for limiting the heap usage for -** individual threads. +** <ul> +** <li> The soft heap limit is set to zero. +** <li> Memory accounting is disabled using a combination of the +** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and +** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. +** <li> An alternative page cache implementation is specified using +** [sqlite3_config]([SQLITE_CONFIG_PCACHE],...). +** <li> The page cache allocates from its own memory pool supplied +** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than +** from the heap. +** </ul>)^ +** +** Beginning with SQLite version 3.7.3, the soft heap limit is enforced +** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT] +** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT], +** the soft heap limit is enforced on every memory allocation. Without +** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced +** when memory is allocated by the page cache. Testing suggests that because +** the page cache is the predominate memory user in SQLite, most +** applications will achieve adequate soft heap limit enforcement without +** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** The circumstances under which SQLite will enforce the soft heap limit may +** changes in future releases of SQLite. */ -SQLITE_API void sqlite3_soft_heap_limit(int); +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); + +/* +** CAPI3REF: Deprecated Soft Heap Limit Interface +** DEPRECATED +** +** This is a deprecated version of the [sqlite3_soft_heap_limit64()] +** interface. This routine is provided for historical compatibility +** only. All new applications should use the +** [sqlite3_soft_heap_limit64()] interface rather than this one. +*/ +SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); + /* ** CAPI3REF: Extract Metadata About A Column Of A Table @@ -4648,40 +5242,51 @@ SQLITE_API int sqlite3_load_extension( SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); /* -** CAPI3REF: Automatically Load An Extensions +** CAPI3REF: Automatically Load Statically Linked Extensions +** +** ^This interface causes the xEntryPoint() function to be invoked for +** each new [database connection] that is created. The idea here is that +** xEntryPoint() is the entry point for a statically linked SQLite extension +** that is to be automatically loaded into all new database connections. +** +** ^(Even though the function prototype shows that xEntryPoint() takes +** no arguments and returns void, SQLite invokes xEntryPoint() with three +** arguments and expects and integer result as if the signature of the +** entry point where as follows: +** +** <blockquote><pre> +** int xEntryPoint( +** sqlite3 *db, +** const char **pzErrMsg, +** const struct sqlite3_api_routines *pThunk +** ); +** </pre></blockquote>)^ ** -** ^This API can be invoked at program startup in order to register -** one or more statically linked extensions that will be available -** to all new [database connections]. +** If the xEntryPoint routine encounters an error, it should make *pzErrMsg +** point to an appropriate error message (obtained from [sqlite3_mprintf()]) +** and return an appropriate [error code]. ^SQLite ensures that *pzErrMsg +** is NULL before calling the xEntryPoint(). ^SQLite will invoke +** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns. ^If any +** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()], +** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail. ** -** ^(This routine stores a pointer to the extension entry point -** in an array that is obtained from [sqlite3_malloc()]. That memory -** is deallocated by [sqlite3_reset_auto_extension()].)^ +** ^Calling sqlite3_auto_extension(X) with an entry point X that is already +** on the list of automatic extensions is a harmless no-op. ^No entry point +** will be called more than once for each database connection that is opened. ** -** ^This function registers an extension entry point that is -** automatically invoked whenever a new [database connection] -** is opened using [sqlite3_open()], [sqlite3_open16()], -** or [sqlite3_open_v2()]. -** ^Duplicate extensions are detected so calling this routine -** multiple times with the same extension is harmless. -** ^Automatic extensions apply across all threads. +** See also: [sqlite3_reset_auto_extension()]. */ SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void)); /* ** CAPI3REF: Reset Automatic Extension Loading ** -** ^(This function disables all previously registered automatic -** extensions. It undoes the effect of all prior -** [sqlite3_auto_extension()] calls.)^ -** -** ^This function disables automatic extensions in all threads. +** ^This interface disables all automatic extensions previously +** registered using [sqlite3_auto_extension()]. */ SQLITE_API void sqlite3_reset_auto_extension(void); /* -****** EXPERIMENTAL - subject to change without notice ************** -** ** 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. @@ -4701,10 +5306,9 @@ typedef struct sqlite3_module sqlite3_module; /* ** CAPI3REF: Virtual Table Object ** KEYWORDS: sqlite3_module {virtual table module} -** EXPERIMENTAL ** -** This structure, sometimes called a a "virtual table module", -** defines the implementation of a [virtual tables]. +** This structure, sometimes called a "virtual table module", +** defines the implementation of a [virtual tables]. ** This structure consists mostly of methods for the module. ** ** ^A virtual table module is created by filling in a persistent @@ -4743,14 +5347,19 @@ struct sqlite3_module { void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), void **ppArg); int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); + /* The methods above are in version 1 of the sqlite_module object. Those + ** below are for version 2 and greater. */ + int (*xSavepoint)(sqlite3_vtab *pVTab, int); + int (*xRelease)(sqlite3_vtab *pVTab, int); + int (*xRollbackTo)(sqlite3_vtab *pVTab, int); }; /* ** CAPI3REF: Virtual Table Indexing Information ** KEYWORDS: sqlite3_index_info -** EXPERIMENTAL ** -** The sqlite3_index_info structure and its substructures is used to +** The sqlite3_index_info structure and its substructures is used as part +** of the [virtual table] interface to ** pass information into and receive the reply from the [xBestIndex] ** method of a [virtual table module]. The fields under **Inputs** are the ** inputs to xBestIndex and are read-only. xBestIndex inserts its @@ -4758,10 +5367,12 @@ struct sqlite3_module { ** ** ^(The aConstraint[] array records WHERE clause constraints of the form: ** -** <pre>column OP expr</pre> +** <blockquote>column OP expr</blockquote> ** ** where OP is =, <, <=, >, or >=.)^ ^(The particular operator is -** stored in aConstraint[].op.)^ ^(The index of the column is stored in +** stored in aConstraint[].op using one of the +** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^ +** ^(The index of the column is stored in ** aConstraint[].iColumn.)^ ^(aConstraint[].usable is TRUE if the ** expr on the right-hand side can be evaluated (and thus the constraint ** is usable) and false if it cannot.)^ @@ -4821,6 +5432,15 @@ struct sqlite3_index_info { int orderByConsumed; /* True if output is already ordered */ double estimatedCost; /* Estimated cost of using this index */ }; + +/* +** CAPI3REF: Virtual Table Constraint Operator Codes +** +** These macros defined the allowed values for the +** [sqlite3_index_info].aConstraint[].op field. Each value represents +** an operator that is part of a constraint term in the wHERE clause of +** a query that uses a [virtual table]. +*/ #define SQLITE_INDEX_CONSTRAINT_EQ 2 #define SQLITE_INDEX_CONSTRAINT_GT 4 #define SQLITE_INDEX_CONSTRAINT_LE 8 @@ -4830,7 +5450,6 @@ struct sqlite3_index_info { /* ** CAPI3REF: Register A Virtual Table Implementation -** EXPERIMENTAL ** ** ^These routines are used to register a new [virtual table module] name. ** ^Module names must be registered before @@ -4838,7 +5457,7 @@ struct sqlite3_index_info { ** preexisting [virtual table] for the module. ** ** ^The module name is registered on the [database connection] specified -** by the first parameter. ^The name of the module is given by the +** by the first parameter. ^The name of the module is given by the ** second parameter. ^The third parameter is a pointer to ** the implementation of the [virtual table module]. ^The fourth ** parameter is an arbitrary client data pointer that is passed through @@ -4848,17 +5467,19 @@ struct sqlite3_index_info { ** ^The sqlite3_create_module_v2() interface has a fifth parameter which ** is a pointer to a destructor for the pClientData. ^SQLite will ** invoke the destructor function (if it is not NULL) when SQLite -** no longer needs the pClientData pointer. ^The sqlite3_create_module() +** no longer needs the pClientData pointer. ^The destructor will also +** be invoked if the call to sqlite3_create_module_v2() fails. +** ^The sqlite3_create_module() ** interface is equivalent to sqlite3_create_module_v2() with a NULL ** destructor. */ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module( +SQLITE_API int sqlite3_create_module( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ void *pClientData /* Client data for xCreate/xConnect */ ); -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module_v2( +SQLITE_API int sqlite3_create_module_v2( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ @@ -4869,7 +5490,6 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module_v2( /* ** CAPI3REF: Virtual Table Instance Object ** KEYWORDS: sqlite3_vtab -** EXPERIMENTAL ** ** Every [virtual table module] implementation uses a subclass ** of this object to describe a particular instance @@ -4895,7 +5515,6 @@ struct sqlite3_vtab { /* ** CAPI3REF: Virtual Table Cursor Object ** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor} -** EXPERIMENTAL ** ** Every [virtual table module] implementation uses a subclass of the ** following structure to describe cursors that point into the @@ -4917,21 +5536,19 @@ struct sqlite3_vtab_cursor { /* ** CAPI3REF: Declare The Schema Of A Virtual Table -** EXPERIMENTAL ** ** ^The [xCreate] and [xConnect] methods of a ** [virtual table module] call this interface ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. */ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_declare_vtab(sqlite3*, const char *zSQL); +SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); /* ** CAPI3REF: Overload A Function For A Virtual Table -** EXPERIMENTAL ** ** ^(Virtual tables can provide alternative implementations of functions -** using the [xFindFunction] method of the [virtual table module]. +** using the [xFindFunction] method of the [virtual table module]. ** But global versions of those functions ** must exist in order to be overloaded.)^ ** @@ -4943,7 +5560,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_declare_vtab(sqlite3*, const char *zS ** purpose is to be a placeholder function that can be overloaded ** by a [virtual table]. */ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); +SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); /* ** The interface to the virtual-table mechanism defined above (back up @@ -4953,8 +5570,6 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_overload_function(sqlite3*, const cha ** ** When the virtual-table mechanism stabilizes, we will declare the ** interface fixed, support it indefinitely, and remove this comment. -** -****** EXPERIMENTAL - subject to change without notice ************** */ /* @@ -4984,8 +5599,8 @@ typedef struct sqlite3_blob sqlite3_blob; ** ** ^If the flags parameter is non-zero, then the BLOB is opened for read ** and write access. ^If it is zero, the BLOB is opened for read access. -** ^It is not possible to open a column that is part of an index or primary -** key for writing. ^If [foreign key constraints] are enabled, it is +** ^It is not possible to open a column that is part of an index or primary +** key for writing. ^If [foreign key constraints] are enabled, it is ** not possible to open a column that is part of a [child key] for writing. ** ** ^Note that the database name is not the filename that contains @@ -5009,7 +5624,7 @@ typedef struct sqlite3_blob sqlite3_blob; ** This is true if any column of the row is changed, even a column ** other than the one the BLOB handle is open on.)^ ** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for -** a expired BLOB handle fail with an return code of [SQLITE_ABORT]. +** an expired BLOB handle fail with a return code of [SQLITE_ABORT]. ** ^(Changes written into a BLOB prior to the BLOB expiring are not ** rolled back by the expiration of the BLOB. Such changes will eventually ** commit if the transaction continues to completion.)^ @@ -5038,6 +5653,30 @@ SQLITE_API int sqlite3_blob_open( ); /* +** CAPI3REF: Move a BLOB Handle to a New Row +** +** ^This function is used to move an existing blob handle so that it points +** to a different row of the same database table. ^The new row is identified +** by the rowid value passed as the second argument. Only the row can be +** changed. ^The database, table and column on which the blob handle is open +** remain the same. Moving an existing blob handle to a new row can be +** faster than closing the existing handle and opening a new one. +** +** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - +** it must exist and there must be either a blob or text value stored in +** the nominated column.)^ ^If the new row is not present in the table, or if +** it does not contain a blob or text value, or if another error occurs, an +** SQLite error code is returned and the blob handle is considered aborted. +** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or +** [sqlite3_blob_reopen()] on an aborted blob handle immediately return +** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle +** always returns zero. +** +** ^This function sets the database handle error code and message. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); + +/* ** CAPI3REF: Close A BLOB Handle ** ** ^Closes an open [BLOB handle]. @@ -5064,7 +5703,7 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *); /* ** CAPI3REF: Return The Size Of An Open BLOB ** -** ^Returns the size in bytes of the BLOB accessible via the +** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The ** incremental blob I/O routines can only read or overwriting existing ** blob content; they cannot change the size of a blob. @@ -5297,7 +5936,6 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); /* ** CAPI3REF: Mutex Methods Object -** EXPERIMENTAL ** ** An instance of this structure defines the low-level routines ** used to allocate and use mutexes. @@ -5314,7 +5952,7 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); ** ** ^The xMutexInit method defined by this structure is invoked as ** part of system initialization by the sqlite3_initialize() function. -** ^The xMutexInit routine is calle by SQLite exactly once for each +** ^The xMutexInit routine is called by SQLite exactly once for each ** effective call to [sqlite3_initialize()]. ** ** ^The xMutexEnd method defined by this structure is invoked as @@ -5347,7 +5985,7 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); ** it is passed a NULL pointer). ** ** The xMutexInit() method must be threadsafe. ^It must be harmless to -** invoke xMutexInit() mutiple times within the same process and without +** invoke xMutexInit() multiple times within the same process and without ** intervening calls to xMutexEnd(). Second and subsequent calls to ** xMutexInit() must be no-ops. ** @@ -5396,7 +6034,7 @@ struct sqlite3_mutex_methods { ** ** ^If the argument to sqlite3_mutex_held() is a NULL pointer then ** the routine should return 1. This seems counter-intuitive since -** clearly the mutex cannot be held if it does not exist. But the +** clearly the mutex cannot be held if it does not exist. But ** the reason the mutex does not exist is because the build is not ** using mutexes. And we do not want the assert() containing the ** call to sqlite3_mutex_held() to fail, so a non-zero return is @@ -5426,12 +6064,13 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); #define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ #define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ -#define SQLITE_MUTEX_STATIC_LRU2 7 /* lru page list */ +#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ /* ** CAPI3REF: Retrieve the mutex for a database connection ** -** ^This interface returns a pointer the [sqlite3_mutex] object that +** ^This interface returns a pointer the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this @@ -5445,7 +6084,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); ** ^The [sqlite3_file_control()] interface makes a direct call to the ** xFileControl method for the [sqlite3_io_methods] object associated ** with a particular database identified by the second argument. ^The -** name of the database "main" for the main database or "temp" for the +** name of the database is "main" for the main database or "temp" for the ** TEMP database, or the name that appears after the AS keyword for ** databases that are added using the [ATTACH] SQL command. ** ^A NULL pointer can be used in place of "main" to refer to the @@ -5455,6 +6094,12 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); ** the xFileControl method. ^The return value of the xFileControl ** method becomes the return value of this routine. ** +** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes +** a pointer to the underlying [sqlite3_file] object to be written into +** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER +** case is a short-circuit path which does not actually invoke the +** underlying sqlite3_io_methods.xFileControl method. +** ** ^If the second parameter (zDbName) does not match the name of any ** open database file, then SQLITE_ERROR is returned. ^This error ** code is not remembered and will not be recalled by [sqlite3_errcode()] @@ -5510,17 +6155,19 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_RESERVE 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 -#define SQLITE_TESTCTRL_LAST 16 +#define SQLITE_TESTCTRL_PGHDRSZ 17 +#define SQLITE_TESTCTRL_SCRATCHMALLOC 18 +#define SQLITE_TESTCTRL_LOCALTIME_FAULT 19 +#define SQLITE_TESTCTRL_LAST 19 /* ** CAPI3REF: SQLite Runtime Status -** EXPERIMENTAL ** ** ^This interface is used to retrieve runtime status information -** about the preformance of SQLite, and optionally to reset various +** about the performance of SQLite, and optionally to reset various ** highwater marks. ^The first argument is an integer code for ** the specific parameter to measure. ^(Recognized integer codes -** are of the form [SQLITE_STATUS_MEMORY_USED | SQLITE_STATUS_...].)^ +** are of the form [status parameters | SQLITE_STATUS_...].)^ ** ^The current value of the parameter is returned into *pCurrent. ** ^The highest recorded value is returned in *pHighwater. ^If the ** resetFlag is true, then the highest record value is reset after @@ -5530,7 +6177,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); ** ^(Other parameters record only the highwater mark and not the current ** value. For these latter parameters nothing is written into *pCurrent.)^ ** -** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a +** ^The sqlite3_status() routine returns SQLITE_OK on success and a ** non-zero [error code] on failure. ** ** This routine is threadsafe but is not atomic. This routine can be @@ -5542,18 +6189,18 @@ SQLITE_API int sqlite3_test_control(int op, ...); ** ** See also: [sqlite3_db_status()] */ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); +SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); /* ** CAPI3REF: Status Parameters -** EXPERIMENTAL +** KEYWORDS: {status parameters} ** ** These integer constants designate various run-time status parameters ** that can be returned by [sqlite3_status()]. ** ** <dl> -** ^(<dt>SQLITE_STATUS_MEMORY_USED</dt> +** [[SQLITE_STATUS_MEMORY_USED]] ^(<dt>SQLITE_STATUS_MEMORY_USED</dt> ** <dd>This parameter is the current amount of memory checked out ** using [sqlite3_malloc()], either directly or indirectly. The ** figure includes calls made to [sqlite3_malloc()] by the application @@ -5563,35 +6210,40 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pH ** this parameter. The amount returned is the sum of the allocation ** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^ ** -** ^(<dt>SQLITE_STATUS_MALLOC_SIZE</dt> +** [[SQLITE_STATUS_MALLOC_SIZE]] ^(<dt>SQLITE_STATUS_MALLOC_SIZE</dt> ** <dd>This parameter records the largest memory allocation request ** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their ** internal equivalents). Only the value returned in the -** *pHighwater parameter to [sqlite3_status()] is of interest. +** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.</dd>)^ ** -** ^(<dt>SQLITE_STATUS_PAGECACHE_USED</dt> +** [[SQLITE_STATUS_MALLOC_COUNT]] ^(<dt>SQLITE_STATUS_MALLOC_COUNT</dt> +** <dd>This parameter records the number of separate memory allocations +** currently checked out.</dd>)^ +** +** [[SQLITE_STATUS_PAGECACHE_USED]] ^(<dt>SQLITE_STATUS_PAGECACHE_USED</dt> ** <dd>This parameter returns the number of pages used out of the -** [pagecache memory allocator] that was configured using +** [pagecache memory allocator] that was configured using ** [SQLITE_CONFIG_PAGECACHE]. The ** value returned is in pages, not in bytes.</dd>)^ ** +** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] ** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt> ** <dd>This parameter returns the number of bytes of page cache -** allocation which could not be statisfied by the [SQLITE_CONFIG_PAGECACHE] +** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] ** buffer and where forced to overflow to [sqlite3_malloc()]. The ** returned value includes allocations that overflowed because they ** where too large (they were larger than the "sz" parameter to ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because ** no space was left in the page cache.</dd>)^ ** -** ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt> +** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt> ** <dd>This parameter records the largest memory allocation request ** handed to [pagecache memory allocator]. Only the value returned in the -** *pHighwater parameter to [sqlite3_status()] is of interest. +** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.</dd>)^ ** -** ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt> +** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt> ** <dd>This parameter returns the number of allocations used out of the ** [scratch memory allocator] configured using ** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not @@ -5599,9 +6251,9 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pH ** outstanding at time, this parameter also reports the number of threads ** using scratch memory at the same time.</dd>)^ ** -** ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt> +** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt> ** <dd>This parameter returns the number of bytes of scratch memory -** allocation which could not be statisfied by the [SQLITE_CONFIG_SCRATCH] +** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH] ** buffer and where forced to overflow to [sqlite3_malloc()]. The values ** returned include overflows because the requested allocation was too ** larger (that is, because the requested allocation was larger than the @@ -5609,13 +6261,13 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pH ** slots were available. ** </dd>)^ ** -** ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt> +** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt> ** <dd>This parameter records the largest memory allocation request ** handed to [scratch memory allocator]. Only the value returned in the -** *pHighwater parameter to [sqlite3_status()] is of interest. +** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.</dd>)^ ** -** ^(<dt>SQLITE_STATUS_PARSER_STACK</dt> +** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt> ** <dd>This parameter records the deepest parser stack. It is only ** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^ ** </dl> @@ -5631,30 +6283,35 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pH #define SQLITE_STATUS_PARSER_STACK 6 #define SQLITE_STATUS_PAGECACHE_SIZE 7 #define SQLITE_STATUS_SCRATCH_SIZE 8 +#define SQLITE_STATUS_MALLOC_COUNT 9 /* ** CAPI3REF: Database Connection Status -** EXPERIMENTAL ** -** ^This interface is used to retrieve runtime status information +** ^This interface is used to retrieve runtime status information ** about a single [database connection]. ^The first argument is the ** database connection object to be interrogated. ^The second argument -** is the parameter to interrogate. ^Currently, the only allowed value -** for the second parameter is [SQLITE_DBSTATUS_LOOKASIDE_USED]. -** Additional options will likely appear in future releases of SQLite. +** is an integer constant, taken from the set of +** [SQLITE_DBSTATUS options], that +** determines the parameter to interrogate. The set of +** [SQLITE_DBSTATUS options] is likely +** to grow in future releases of SQLite. ** ** ^The current value of the requested parameter is written into *pCur ** and the highest instantaneous value is written into *pHiwtr. ^If ** the resetFlg is true, then the highest instantaneous value is ** reset back down to the current value. ** +** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a +** non-zero [error code] on failure. +** ** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. */ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); +SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); /* ** CAPI3REF: Status Parameters for database connections -** EXPERIMENTAL +** KEYWORDS: {SQLITE_DBSTATUS options} ** ** These constants are the available integer "verbs" that can be passed as ** the second argument to the [sqlite3_db_status()] interface. @@ -5666,31 +6323,79 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur ** if a discontinued or unsupported verb is invoked. ** ** <dl> -** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt> +** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt> ** <dd>This parameter returns the number of lookaside memory slots currently ** checked out.</dd>)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt> +** <dd>This parameter returns the number malloc attempts that were +** satisfied using lookaside memory. Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] +** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt> +** <dd>This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to the amount of +** memory requested being larger than the lookaside slot size. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] +** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt> +** <dd>This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to all lookaside +** memory already being in use. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt> +** <dd>This parameter returns the approximate number of of bytes of heap +** memory used by all pager caches associated with the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. +** +** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt> +** <dd>This parameter returns the approximate number of of bytes of heap +** memory used to store the schema for all databases associated +** with the connection - main, temp, and any [ATTACH]-ed databases.)^ +** ^The full amount of memory used by the schemas is reported, even if the +** schema memory is shared with other database connections due to +** [shared cache mode] being enabled. +** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. +** +** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt> +** <dd>This parameter returns the approximate number of of bytes of heap +** and lookaside memory used by all prepared statements associated with +** the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. +** </dd> ** </dl> */ -#define SQLITE_DBSTATUS_LOOKASIDE_USED 0 +#define SQLITE_DBSTATUS_LOOKASIDE_USED 0 +#define SQLITE_DBSTATUS_CACHE_USED 1 +#define SQLITE_DBSTATUS_SCHEMA_USED 2 +#define SQLITE_DBSTATUS_STMT_USED 3 +#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 +#define SQLITE_DBSTATUS_MAX 6 /* Largest defined DBSTATUS */ /* ** CAPI3REF: Prepared Statement Status -** EXPERIMENTAL ** ** ^(Each prepared statement maintains various -** [SQLITE_STMTSTATUS_SORT | counters] that measure the number +** [SQLITE_STMTSTATUS counters] that measure the number ** of times it has performed specific operations.)^ These counters can ** be used to monitor the performance characteristics of the prepared ** statements. For example, if the number of table steps greatly exceeds ** the number of table searches or result rows, that would tend to indicate ** that the prepared statement is using a full table scan rather than -** an index. +** an index. ** ** ^(This interface is used to retrieve and reset counter values from ** a [prepared statement]. The first argument is the prepared statement ** object to be interrogated. The second argument -** is an integer code for a specific [SQLITE_STMTSTATUS_SORT | counter] +** is an integer code for a specific [SQLITE_STMTSTATUS counter] ** to be interrogated.)^ ** ^The current value of the requested counter is returned. ** ^If the resetFlg is true, then the counter is reset to zero after this @@ -5698,36 +6403,43 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur ** ** See also: [sqlite3_status()] and [sqlite3_db_status()]. */ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); +SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); /* ** CAPI3REF: Status Parameters for prepared statements -** EXPERIMENTAL +** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters} ** ** These preprocessor macros define integer codes that name counter ** values associated with the [sqlite3_stmt_status()] interface. ** The meanings of the various counters are as follows: ** ** <dl> -** <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt> +** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]] <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt> ** <dd>^This is the number of times that SQLite has stepped forward in ** a table as part of a full table scan. Large numbers for this counter -** may indicate opportunities for performance improvement through +** may indicate opportunities for performance improvement through ** careful use of indices.</dd> ** -** <dt>SQLITE_STMTSTATUS_SORT</dt> +** [[SQLITE_STMTSTATUS_SORT]] <dt>SQLITE_STMTSTATUS_SORT</dt> ** <dd>^This is the number of sort operations that have occurred. ** A non-zero value in this counter may indicate an opportunity to ** improvement performance through careful use of indices.</dd> ** +** [[SQLITE_STMTSTATUS_AUTOINDEX]] <dt>SQLITE_STMTSTATUS_AUTOINDEX</dt> +** <dd>^This is the number of rows inserted into transient indices that +** were created automatically in order to help joins run faster. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance by adding permanent indices that do not +** need to be reinitialized each time the statement is run.</dd> +** ** </dl> */ #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 #define SQLITE_STMTSTATUS_SORT 2 +#define SQLITE_STMTSTATUS_AUTOINDEX 3 /* ** CAPI3REF: Custom Page Cache Object -** EXPERIMENTAL ** ** The sqlite3_pcache type is opaque. It is implemented by ** the pluggable module. The SQLite core has no knowledge of @@ -5742,36 +6454,47 @@ typedef struct sqlite3_pcache sqlite3_pcache; /* ** CAPI3REF: Application Defined Page Cache. ** KEYWORDS: {page cache} -** EXPERIMENTAL ** ** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can -** register an alternative page cache implementation by passing in an -** instance of the sqlite3_pcache_methods structure.)^ The majority of the -** heap memory used by SQLite is used by the page cache to cache data read -** from, or ready to be written to, the database file. By implementing a -** custom page cache using this API, an application can control more -** precisely the amount of memory consumed by SQLite, the way in which -** that memory is allocated and released, and the policies used to -** determine exactly which parts of a database file are cached and for +** register an alternative page cache implementation by passing in an +** instance of the sqlite3_pcache_methods structure.)^ +** In many applications, most of the heap memory allocated by +** SQLite is used for the page cache. +** By implementing a +** custom page cache using this API, an application can better control +** the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to +** determine exactly which parts of a database file are cached and for ** how long. ** +** The alternative page cache mechanism is an +** extreme measure that is only needed by the most demanding applications. +** The built-in page cache is recommended for most uses. +** ** ^(The contents of the sqlite3_pcache_methods structure are copied to an ** internal buffer by SQLite within the call to [sqlite3_config]. Hence ** the application may discard the parameter after the call to ** [sqlite3_config()] returns.)^ ** -** ^The xInit() method is called once for each call to [sqlite3_initialize()] +** [[the xInit() page cache method]] +** ^(The xInit() method is called once for each effective +** call to [sqlite3_initialize()])^ ** (usually only once during the lifetime of the process). ^(The xInit() ** method is passed a copy of the sqlite3_pcache_methods.pArg value.)^ -** ^The xInit() method can set up up global structures and/or any mutexes -** required by the custom page cache implementation. -** -** ^The xShutdown() method is called from within [sqlite3_shutdown()], -** if the application invokes this API. It can be used to clean up +** The intent of the xInit() method is to set up global data structures +** required by the custom page cache implementation. +** ^(If the xInit() method is NULL, then the +** built-in default page cache is used instead of the application defined +** page cache.)^ +** +** [[the xShutdown() page cache method]] +** ^The xShutdown() method is called by [sqlite3_shutdown()]. +** It can be used to clean up ** any outstanding resources before process shutdown, if required. +** ^The xShutdown() method may be NULL. ** -** ^SQLite holds a [SQLITE_MUTEX_RECURSIVE] mutex when it invokes -** the xInit method, so the xInit method need not be threadsafe. ^The +** ^SQLite automatically serializes calls to the xInit method, +** so the xInit method need not be threadsafe. ^The ** xShutdown method is only called from [sqlite3_shutdown()] so it does ** not need to be threadsafe either. All other methods must be threadsafe ** in multithreaded applications. @@ -5779,47 +6502,56 @@ typedef struct sqlite3_pcache sqlite3_pcache; ** ^SQLite will never invoke xInit() more than once without an intervening ** call to xShutdown(). ** -** ^The xCreate() method is used to construct a new cache instance. SQLite -** will typically create one cache instance for each open database file, +** [[the xCreate() page cache methods]] +** ^SQLite invokes the xCreate() method to construct a new cache instance. +** SQLite will typically create one cache instance for each open database file, ** though this is not guaranteed. ^The ** first parameter, szPage, is the size in bytes of the pages that must ** be allocated by the cache. ^szPage will not be a power of two. ^szPage ** will the page size of the database file that is to be cached plus an -** increment (here called "R") of about 100 or 200. ^SQLite will use the +** increment (here called "R") of less than 250. SQLite will use the ** extra R bytes on each page to store metadata about the underlying ** database page on disk. The value of R depends ** on the SQLite version, the target platform, and how SQLite was compiled. -** ^R is constant for a particular build of SQLite. ^The second argument to +** ^(R is constant for a particular build of SQLite. Except, there are two +** distinct values of R when SQLite is compiled with the proprietary +** ZIPVFS extension.)^ ^The second argument to ** xCreate(), bPurgeable, is true if the cache being created will ** be used to cache database pages of a file stored on disk, or -** false if it is used for an in-memory database. ^The cache implementation +** false if it is used for an in-memory database. The cache implementation ** does not have to do anything special based with the value of bPurgeable; ** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will ** never invoke xUnpin() except to deliberately delete a page. -** ^In other words, a cache created with bPurgeable set to false will +** ^In other words, calls to xUnpin() on a cache with bPurgeable set to +** false will always have the "discard" flag set to true. +** ^Hence, a cache created with bPurgeable false will ** never contain any unpinned pages. ** +** [[the xCachesize() page cache method]] ** ^(The xCachesize() method may be called at any time by SQLite to set the ** suggested maximum cache-size (number of pages stored by) the cache ** instance passed as the first argument. This is the value configured using -** the SQLite "[PRAGMA cache_size]" command.)^ ^As with the bPurgeable +** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable ** parameter, the implementation is not required to do anything with this ** value; it is advisory only. ** -** ^The xPagecount() method should return the number of pages currently -** stored in the cache. -** -** ^The xFetch() method is used to fetch a page and return a pointer to it. -** ^A 'page', in this context, is a buffer of szPage bytes aligned at an -** 8-byte boundary. ^The page to be fetched is determined by the key. ^The -** mimimum key value is 1. After it has been retrieved using xFetch, the page +** [[the xPagecount() page cache methods]] +** The xPagecount() method must return the number of pages currently +** stored in the cache, both pinned and unpinned. +** +** [[the xFetch() page cache methods]] +** The xFetch() method locates a page in the cache and returns a pointer to +** the page, or a NULL pointer. +** A "page", in this context, means a buffer of szPage bytes aligned at an +** 8-byte boundary. The page to be fetched is determined by the key. ^The +** minimum key value is 1. After it has been retrieved using xFetch, the page ** is considered to be "pinned". ** -** ^If the requested page is already in the page cache, then the page cache +** If the requested page is already in the page cache, then the page cache ** implementation must return a pointer to the page buffer with its content -** intact. ^(If the requested page is not already in the cache, then the -** behavior of the cache implementation is determined by the value of the -** createFlag parameter passed to xFetch, according to the following table: +** intact. If the requested page is not already in the cache, then the +** cache implementation should use the value of the createFlag +** parameter to help it determined what action to take: ** ** <table border=1 width=85% align=center> ** <tr><th> createFlag <th> Behaviour when page is not already in cache @@ -5828,39 +6560,41 @@ typedef struct sqlite3_pcache sqlite3_pcache; ** Otherwise return NULL. ** <tr><td> 2 <td> Make every effort to allocate a new page. Only return ** NULL if allocating a new page is effectively impossible. -** </table>)^ +** </table> ** -** SQLite will normally invoke xFetch() with a createFlag of 0 or 1. If -** a call to xFetch() with createFlag==1 returns NULL, then SQLite will +** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite +** will only use a createFlag of 2 after a prior call with a createFlag of 1 +** failed.)^ In between the to xFetch() calls, SQLite may ** attempt to unpin one or more cache pages by spilling the content of -** pinned pages to disk and synching the operating system disk cache. After -** attempting to unpin pages, the xFetch() method will be invoked again with -** a createFlag of 2. +** pinned pages to disk and synching the operating system disk cache. ** +** [[the xUnpin() page cache method]] ** ^xUnpin() is called by SQLite with a pointer to a currently pinned page -** as its second argument. ^(If the third parameter, discard, is non-zero, -** then the page should be evicted from the cache. In this case SQLite -** assumes that the next time the page is retrieved from the cache using -** the xFetch() method, it will be zeroed.)^ ^If the discard parameter is -** zero, then the page is considered to be unpinned. ^The cache implementation +** as its second argument. If the third parameter, discard, is non-zero, +** then the page must be evicted from the cache. +** ^If the discard parameter is +** zero, then the page may be discarded or retained at the discretion of +** page cache implementation. ^The page cache implementation ** may choose to evict unpinned pages at any time. ** -** ^(The cache is not required to perform any reference counting. A single -** call to xUnpin() unpins the page regardless of the number of prior calls -** to xFetch().)^ +** The cache must not perform any reference counting. A single +** call to xUnpin() unpins the page regardless of the number of prior calls +** to xFetch(). ** -** ^The xRekey() method is used to change the key value associated with the -** page passed as the second argument from oldKey to newKey. ^If the cache -** previously contains an entry associated with newKey, it should be +** [[the xRekey() page cache methods]] +** The xRekey() method is used to change the key value associated with the +** page passed as the second argument. If the cache +** previously contains an entry associated with newKey, it must be ** discarded. ^Any prior cache entry associated with newKey is guaranteed not ** to be pinned. ** -** ^When SQLite calls the xTruncate() method, the cache must discard all +** When SQLite calls the xTruncate() method, the cache must discard all ** existing cache entries with page numbers (keys) greater than or equal -** to the value of the iLimit parameter passed to xTruncate(). ^If any +** to the value of the iLimit parameter passed to xTruncate(). If any ** of these pages are pinned, they are implicitly unpinned, meaning that ** they can be safely discarded. ** +** [[the xDestroy() page cache method]] ** ^The xDestroy() method is used to delete a cache allocated by xCreate(). ** All resources associated with the specified cache should be freed. ^After ** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] @@ -5884,7 +6618,6 @@ struct sqlite3_pcache_methods { /* ** CAPI3REF: Online Backup Object -** EXPERIMENTAL ** ** The sqlite3_backup object records state information about an ongoing ** online backup operation. ^The sqlite3_backup object is created by @@ -5897,50 +6630,50 @@ typedef struct sqlite3_backup sqlite3_backup; /* ** CAPI3REF: Online Backup API. -** EXPERIMENTAL ** ** The backup API copies the content of one database into another. ** It is useful either for creating backups of databases or -** for copying in-memory databases to or from persistent files. +** for copying in-memory databases to or from persistent files. ** ** See Also: [Using the SQLite Online Backup API] ** -** ^Exclusive access is required to the destination database for the -** duration of the operation. ^However the source database is only -** read-locked while it is actually being read; it is not locked -** continuously for the entire backup operation. ^Thus, the backup may be -** performed on a live source database without preventing other users from +** ^SQLite holds a write transaction open on the destination database file +** for the duration of the backup operation. +** ^The source database is read-locked only while it is being read; +** it is not locked continuously for the entire backup operation. +** ^Thus, the backup may be performed on a live source database without +** preventing other database connections from ** reading or writing to the source database while the backup is underway. -** -** ^(To perform a backup operation: +** +** ^(To perform a backup operation: ** <ol> ** <li><b>sqlite3_backup_init()</b> is called once to initialize the -** backup, -** <li><b>sqlite3_backup_step()</b> is called one or more times to transfer +** backup, +** <li><b>sqlite3_backup_step()</b> is called one or more times to transfer ** the data between the two databases, and finally -** <li><b>sqlite3_backup_finish()</b> is called to release all resources -** associated with the backup operation. +** <li><b>sqlite3_backup_finish()</b> is called to release all resources +** associated with the backup operation. ** </ol>)^ ** There should be exactly one call to sqlite3_backup_finish() for each ** successful call to sqlite3_backup_init(). ** -** <b>sqlite3_backup_init()</b> +** [[sqlite3_backup_init()]] <b>sqlite3_backup_init()</b> ** -** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the -** [database connection] associated with the destination database +** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the +** [database connection] associated with the destination database ** and the database name, respectively. ** ^The database name is "main" for the main database, "temp" for the ** temporary database, or the name specified after the AS keyword in ** an [ATTACH] statement for an attached database. -** ^The S and M arguments passed to +** ^The S and M arguments passed to ** sqlite3_backup_init(D,N,S,M) identify the [database connection] ** and database name of the source database, respectively. ** ^The source and destination [database connections] (parameters S and D) -** must be different or else sqlite3_backup_init(D,N,S,M) will file with +** must be different or else sqlite3_backup_init(D,N,S,M) will fail with ** an error. ** ** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is -** returned and an error code and error message are store3d in the +** returned and an error code and error message are stored in the ** destination [database connection] D. ** ^The error code and message for the failed call to sqlite3_backup_init() ** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or @@ -5948,16 +6681,16 @@ typedef struct sqlite3_backup sqlite3_backup; ** ^A successful call to sqlite3_backup_init() returns a pointer to an ** [sqlite3_backup] object. ** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and -** sqlite3_backup_finish() functions to perform the specified backup +** sqlite3_backup_finish() functions to perform the specified backup ** operation. ** -** <b>sqlite3_backup_step()</b> +** [[sqlite3_backup_step()]] <b>sqlite3_backup_step()</b> ** -** ^Function sqlite3_backup_step(B,N) will copy up to N pages between +** ^Function sqlite3_backup_step(B,N) will copy up to N pages between ** the source and destination databases specified by [sqlite3_backup] object B. -** ^If N is negative, all remaining source pages are copied. +** ^If N is negative, all remaining source pages are copied. ** ^If sqlite3_backup_step(B,N) successfully copies N pages and there -** are still more pages to be copied, then the function resturns [SQLITE_OK]. +** are still more pages to be copied, then the function returns [SQLITE_OK]. ** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages ** from source to destination, then it returns [SQLITE_DONE]. ** ^If an error occurs while running sqlite3_backup_step(B,N), @@ -5966,15 +6699,19 @@ typedef struct sqlite3_backup sqlite3_backup; ** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an ** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code. ** -** ^The sqlite3_backup_step() might return [SQLITE_READONLY] if the destination -** database was opened read-only or if -** the destination is an in-memory database with a different page size -** from the source database. +** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if +** <ol> +** <li> the destination database was opened read-only, or +** <li> the destination database is using write-ahead-log journaling +** and the destination and source page sizes differ, or +** <li> the destination database is an in-memory database and the +** destination and source page sizes differ. +** </ol>)^ ** ** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then ** the [sqlite3_busy_handler | busy-handler function] -** is invoked (if one is specified). ^If the -** busy-handler returns non-zero before the lock is available, then +** is invoked (if one is specified). ^If the +** busy-handler returns non-zero before the lock is available, then ** [SQLITE_BUSY] is returned to the caller. ^In this case the call to ** sqlite3_backup_step() can be retried later. ^If the source ** [database connection] @@ -5982,15 +6719,15 @@ typedef struct sqlite3_backup sqlite3_backup; ** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this ** case the call to sqlite3_backup_step() can be retried later on. ^(If ** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or -** [SQLITE_READONLY] is returned, then -** there is no point in retrying the call to sqlite3_backup_step(). These -** errors are considered fatal.)^ The application must accept -** that the backup operation has failed and pass the backup operation handle +** [SQLITE_READONLY] is returned, then +** there is no point in retrying the call to sqlite3_backup_step(). These +** errors are considered fatal.)^ The application must accept +** that the backup operation has failed and pass the backup operation handle ** to the sqlite3_backup_finish() to release associated resources. ** ** ^The first call to sqlite3_backup_step() obtains an exclusive lock -** on the destination file. ^The exclusive lock is not released until either -** sqlite3_backup_finish() is called or the backup operation is complete +** on the destination file. ^The exclusive lock is not released until either +** sqlite3_backup_finish() is called or the backup operation is complete ** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to ** sqlite3_backup_step() obtains a [shared lock] on the source database that ** lasts for the duration of the sqlite3_backup_step() call. @@ -5999,18 +6736,18 @@ typedef struct sqlite3_backup sqlite3_backup; ** through the backup process. ^If the source database is modified by an ** external process or via a database connection other than the one being ** used by the backup operation, then the backup will be automatically -** restarted by the next call to sqlite3_backup_step(). ^If the source +** restarted by the next call to sqlite3_backup_step(). ^If the source ** database is modified by the using the same database connection as is used ** by the backup operation, then the backup database is automatically ** updated at the same time. ** -** <b>sqlite3_backup_finish()</b> +** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b> ** -** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the +** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the ** application wishes to abandon the backup operation, the application ** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). ** ^The sqlite3_backup_finish() interfaces releases all -** resources associated with the [sqlite3_backup] object. +** resources associated with the [sqlite3_backup] object. ** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any ** active write-transaction on the destination database is rolled back. ** The [sqlite3_backup] object is invalid @@ -6027,11 +6764,12 @@ typedef struct sqlite3_backup sqlite3_backup; ** is not a permanent error and does not affect the return value of ** sqlite3_backup_finish(). ** -** <b>sqlite3_backup_remaining(), sqlite3_backup_pagecount()</b> +** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]] +** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b> ** ** ^Each call to sqlite3_backup_step() sets two values inside ** the [sqlite3_backup] object: the number of pages still to be backed -** up and the total number of pages in the source databae file. +** up and the total number of pages in the source database file. ** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces ** retrieve these two values, respectively. ** @@ -6049,8 +6787,8 @@ typedef struct sqlite3_backup sqlite3_backup; ** connections, then the source database connection may be used concurrently ** from within other threads. ** -** However, the application must guarantee that the destination -** [database connection] is not passed to any other API (by any thread) after +** However, the application must guarantee that the destination +** [database connection] is not passed to any other API (by any thread) after ** 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] @@ -6061,11 +6799,11 @@ typedef struct sqlite3_backup sqlite3_backup; ** 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 +** that the application must guarantee that the disk file being ** backed up to is not accessed by any connection within the process, ** not just the specific connection that was passed to sqlite3_backup_init(). ** -** The [sqlite3_backup] object itself is partially threadsafe. Multiple +** The [sqlite3_backup] object itself is partially threadsafe. Multiple ** threads may safely make multiple concurrent calls to sqlite3_backup_step(). ** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() ** APIs are not strictly speaking threadsafe. If they are invoked at the @@ -6085,13 +6823,12 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); /* ** CAPI3REF: Unlock Notification -** EXPERIMENTAL ** ** ^When running in shared-cache mode, a database operation may fail with ** an [SQLITE_LOCKED] error if the required locks on the shared-cache or ** individual tables within the shared-cache cannot be obtained. See -** [SQLite Shared-Cache Mode] for a description of shared-cache locking. -** ^This API may be used to register a callback that SQLite will invoke +** [SQLite Shared-Cache Mode] for a description of shared-cache locking. +** ^This API may be used to register a callback that SQLite will invoke ** when the connection currently holding the required lock relinquishes it. ** ^This API is only available if the library was compiled with the ** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined. @@ -6099,14 +6836,14 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** See Also: [Using the SQLite Unlock Notification Feature]. ** ** ^Shared-cache locks are released when a database connection concludes -** its current transaction, either by committing it or rolling it back. +** its current transaction, either by committing it or rolling it back. ** ** ^When a connection (known as the blocked connection) fails to obtain a ** shared-cache lock and SQLITE_LOCKED is returned to the caller, the ** identity of the database connection (the blocking connection) that -** has locked the required resource is stored internally. ^After an +** has locked the required resource is stored internally. ^After an ** application receives an SQLITE_LOCKED error, it may call the -** sqlite3_unlock_notify() method with the blocked connection handle as +** sqlite3_unlock_notify() method with the blocked connection handle as ** the first argument to register for a callback that will be invoked ** when the blocking connections current transaction is concluded. ^The ** callback is invoked from within the [sqlite3_step] or [sqlite3_close] @@ -6120,15 +6857,15 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** ** ^If the blocked connection is attempting to obtain a write-lock on a ** shared-cache table, and more than one other connection currently holds -** a read-lock on the same table, then SQLite arbitrarily selects one of +** a read-lock on the same table, then SQLite arbitrarily selects one of ** the other connections to use as the blocking connection. ** -** ^(There may be at most one unlock-notify callback registered by a +** ^(There may be at most one unlock-notify callback registered by a ** blocked connection. If sqlite3_unlock_notify() is called when the ** blocked connection already has a registered unlock-notify callback, ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing -** unlock-notify callback is cancelled. ^The blocked connections +** unlock-notify callback is canceled. ^The blocked connections ** unlock-notify callback may also be canceled by closing the blocked ** connection using [sqlite3_close()]. ** @@ -6141,7 +6878,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** ** <b>Callback Invocation Details</b> ** -** When an unlock-notify callback is registered, the application provides a +** When an unlock-notify callback is registered, the application provides a ** single void* pointer that is passed to the callback when it is invoked. ** However, the signature of the callback function allows SQLite to pass ** it an array of void* context pointers. The first argument passed to @@ -6154,12 +6891,12 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** same callback function, then instead of invoking the callback function ** multiple times, it is invoked once with the set of void* context pointers ** specified by the blocked connections bundled together into an array. -** This gives the application an opportunity to prioritize any actions +** This gives the application an opportunity to prioritize any actions ** related to the set of unblocked database connections. ** ** <b>Deadlock Detection</b> ** -** Assuming that after registering for an unlock-notify callback a +** Assuming that after registering for an unlock-notify callback a ** database waits for the callback to be issued before taking any further ** action (a reasonable assumption), then using this API may cause the ** application to deadlock. For example, if connection X is waiting for @@ -6182,7 +6919,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** ** <b>The "DROP TABLE" Exception</b> ** -** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost +** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost ** always appropriate to call sqlite3_unlock_notify(). There is however, ** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, ** SQLite checks if there are any currently executing SELECT statements @@ -6195,7 +6932,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** One way around this problem is to check the extended error code returned ** by an sqlite3_step() call. ^(If there is a blocking connection, then the ** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in -** the special "DROP TABLE/INDEX" case, the extended error code is just +** the special "DROP TABLE/INDEX" case, the extended error code is just ** SQLITE_LOCKED.)^ */ SQLITE_API int sqlite3_unlock_notify( @@ -6207,23 +6944,21 @@ SQLITE_API int sqlite3_unlock_notify( /* ** CAPI3REF: String Comparison -** EXPERIMENTAL ** ** ^The [sqlite3_strnicmp()] API allows applications and extensions to ** compare the contents of two buffers containing UTF-8 strings in a -** case-indendent fashion, using the same definition of case independence +** case-independent fashion, using the same definition of case independence ** that SQLite uses internally when comparing identifiers. */ SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); /* ** CAPI3REF: Error Logging Interface -** EXPERIMENTAL ** ** ^The [sqlite3_log()] interface writes a message into the error log ** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. ** ^If logging is enabled, the zFormat string and subsequent arguments are -** passed through to [sqlite3_vmprintf()] to generate the final output string. +** used with [sqlite3_snprintf()] to generate the final output string. ** ** The sqlite3_log() interface is intended for use by extensions such as ** virtual tables, collating functions, and SQL functions. While there is @@ -6241,6 +6976,270 @@ SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); /* +** CAPI3REF: Write-Ahead Log Commit Hook +** +** ^The [sqlite3_wal_hook()] function is used to register a callback that +** will be invoked each time a database connection commits data to a +** [write-ahead log] (i.e. whenever a transaction is committed in +** [journal_mode | journal_mode=WAL mode]). +** +** ^The callback is invoked by SQLite after the commit has taken place and +** the associated write-lock on the database released, so the implementation +** may read, write or [checkpoint] the database as required. +** +** ^The first parameter passed to the callback function when it is invoked +** is a copy of the third parameter passed to sqlite3_wal_hook() when +** registering the callback. ^The second is a copy of the database handle. +** ^The third parameter is the name of the database that was written to - +** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter +** is the number of pages currently in the write-ahead log file, +** including those that were just committed. +** +** The callback function should normally return [SQLITE_OK]. ^If an error +** code is returned, that error will propagate back up through the +** SQLite code base to cause the statement that provoked the callback +** to report an error, though the commit will have still occurred. If the +** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value +** that does not correspond to any valid SQLite error code, the results +** are undefined. +** +** A single database handle may have at most a single write-ahead log callback +** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any +** previously registered write-ahead log callback. ^Note that the +** [sqlite3_wal_autocheckpoint()] interface and the +** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will +** those overwrite any prior [sqlite3_wal_hook()] settings. +*/ +SQLITE_API void *sqlite3_wal_hook( + sqlite3*, + int(*)(void *,sqlite3*,const char*,int), + void* +); + +/* +** CAPI3REF: Configure an auto-checkpoint +** +** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around +** [sqlite3_wal_hook()] that causes any database on [database connection] D +** to automatically [checkpoint] +** after committing a transaction if there are N or +** more frames in the [write-ahead log] file. ^Passing zero or +** a negative value as the nFrame parameter disables automatic +** checkpoints entirely. +** +** ^The callback registered by this function replaces any existing callback +** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback +** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism +** configured by this function. +** +** ^The [wal_autocheckpoint pragma] can be used to invoke this interface +** from SQL. +** +** ^Every new [database connection] defaults to having the auto-checkpoint +** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] +** pages. The use of this interface +** is only necessary if the default setting is found to be suboptimal +** for a particular application. +*/ +SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); + +/* +** CAPI3REF: Checkpoint a database +** +** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X +** on [database connection] D to be [checkpointed]. ^If X is NULL or an +** empty string, then a checkpoint is run on all databases of +** connection D. ^If the database connection D is not in +** [WAL | write-ahead log mode] then this interface is a harmless no-op. +** +** ^The [wal_checkpoint pragma] can be used to invoke this interface +** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the +** [wal_autocheckpoint pragma] can be used to cause this interface to be +** run whenever the WAL reaches a certain size threshold. +** +** See also: [sqlite3_wal_checkpoint_v2()] +*/ +SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); + +/* +** CAPI3REF: Checkpoint a database +** +** Run a checkpoint operation on WAL database zDb attached to database +** handle db. The specific operation is determined by the value of the +** eMode parameter: +** +** <dl> +** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> +** Checkpoint as many frames as possible without waiting for any database +** readers or writers to finish. Sync the db file if all frames in the log +** are checkpointed. This mode is the same as calling +** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked. +** +** <dt>SQLITE_CHECKPOINT_FULL<dd> +** This mode blocks (calls the busy-handler callback) until there is no +** database writer and all readers are reading from the most recent database +** snapshot. It then checkpoints all frames in the log file and syncs the +** database file. This call blocks database writers while it is running, +** but not database readers. +** +** <dt>SQLITE_CHECKPOINT_RESTART<dd> +** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after +** checkpointing the log file it blocks (calls the busy-handler callback) +** until all readers are reading from the database file only. This ensures +** that the next client to write to the database file restarts the log file +** from the beginning. This call blocks database writers while it is running, +** but not database readers. +** </dl> +** +** If pnLog is not NULL, then *pnLog is set to the total number of frames in +** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to +** the total number of checkpointed frames (including any that were already +** checkpointed when this function is called). *pnLog and *pnCkpt may be +** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK. +** If no values are available because of an error, they are both set to -1 +** before returning to communicate this to the caller. +** +** All calls obtain an exclusive "checkpoint" lock on the database file. If +** any other process is running a checkpoint operation at the same time, the +** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a +** busy-handler configured, it will not be invoked in this case. +** +** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive +** "writer" lock on the database file. If the writer lock cannot be obtained +** immediately, and a busy-handler is configured, it is invoked and the writer +** lock retried until either the busy-handler returns 0 or the lock is +** successfully obtained. The busy-handler is also invoked while waiting for +** database readers as described above. If the busy-handler returns 0 before +** the writer lock is obtained or while waiting for database readers, the +** checkpoint operation proceeds from that point in the same way as +** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible +** without blocking any further. SQLITE_BUSY is returned in this case. +** +** If parameter zDb is NULL or points to a zero length string, then the +** specified operation is attempted on all WAL databases. In this case the +** values written to output parameters *pnLog and *pnCkpt are undefined. If +** an SQLITE_BUSY error is encountered when processing one or more of the +** attached WAL databases, the operation is still attempted on any remaining +** attached databases and SQLITE_BUSY is returned to the caller. If any other +** error occurs while processing an attached database, processing is abandoned +** and the error code returned to the caller immediately. If no error +** (SQLITE_BUSY or otherwise) is encountered while processing the attached +** databases, SQLITE_OK is returned. +** +** If database zDb is the name of an attached database that is not in WAL +** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If +** zDb is not NULL (or a zero length string) and is not the name of any +** attached database, SQLITE_ERROR is returned to the caller. +*/ +SQLITE_API int sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLITE_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ +); + +/* +** CAPI3REF: Checkpoint operation parameters +** +** These constants can be used as the 3rd parameter to +** [sqlite3_wal_checkpoint_v2()]. See the [sqlite3_wal_checkpoint_v2()] +** documentation for additional information about the meaning and use of +** each of these values. +*/ +#define SQLITE_CHECKPOINT_PASSIVE 0 +#define SQLITE_CHECKPOINT_FULL 1 +#define SQLITE_CHECKPOINT_RESTART 2 + +/* +** CAPI3REF: Virtual Table Interface Configuration +** +** This function may be called by either the [xConnect] or [xCreate] method +** of a [virtual table] implementation to configure +** various facets of the virtual table interface. +** +** If this interface is invoked outside the context of an xConnect or +** xCreate virtual table method then the behavior is undefined. +** +** At present, there is only one option that may be configured using +** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options +** may be added in the future. +*/ +SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Virtual Table Configuration Options +** +** These macros define the various options to the +** [sqlite3_vtab_config()] interface that [virtual table] implementations +** can use to customize and optimize their behavior. +** +** <dl> +** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT +** <dd>Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, +** where X is an integer. If X is zero, then the [virtual table] whose +** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not +** support constraints. In this configuration (which is the default) if +** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire +** statement is rolled back as if [ON CONFLICT | OR ABORT] had been +** specified as part of the users SQL statement, regardless of the actual +** ON CONFLICT mode specified. +** +** If X is non-zero, then the virtual table implementation guarantees +** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before +** any modifications to internal or persistent data structures have been made. +** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite +** is able to roll back a statement or database transaction, and abandon +** or continue processing the current SQL statement as appropriate. +** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns +** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode +** had been ABORT. +** +** Virtual table implementations that are required to handle OR REPLACE +** must do so within the [xUpdate] method. If a call to the +** [sqlite3_vtab_on_conflict()] function indicates that the current ON +** CONFLICT policy is REPLACE, the virtual table implementation should +** silently replace the appropriate rows within the xUpdate callback and +** return SQLITE_OK. Or, if this is not possible, it may return +** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT +** constraint handling. +** </dl> +*/ +#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 + +/* +** CAPI3REF: Determine The Virtual Table Conflict Policy +** +** This function may only be called from within a call to the [xUpdate] method +** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The +** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL], +** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode +** of the SQL statement that triggered the call to the [xUpdate] method of the +** [virtual table]. +*/ +SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); + +/* +** CAPI3REF: Conflict resolution modes +** +** These constants are returned by [sqlite3_vtab_on_conflict()] to +** inform a [virtual table] implementation what the [ON CONFLICT] mode +** is for the SQL statement being evaluated. +** +** Note that the [SQLITE_IGNORE] constant is also used as a potential +** return value from the [sqlite3_set_authorizer()] callback and that +** [SQLITE_ABORT] is also a [result code]. +*/ +#define SQLITE_ROLLBACK 1 +/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */ +#define SQLITE_FAIL 3 +/* #define SQLITE_ABORT 4 // Also an error code */ +#define SQLITE_REPLACE 5 + + + +/* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ @@ -6253,6 +7252,62 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); #endif #endif +/* +** 2010 August 30 +** +** 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. +** +************************************************************************* +*/ + +#ifndef _SQLITE3RTREE_H_ +#define _SQLITE3RTREE_H_ + + +#if 0 +extern "C" { +#endif + +typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; + +/* +** Register a geometry callback named zGeom that can be used as part of an +** R-Tree geometry query as follows: +** +** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) +*/ +SQLITE_API int sqlite3_rtree_geometry_callback( + sqlite3 *db, + const char *zGeom, + int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes), + void *pContext +); + + +/* +** A pointer to a structure of the following type is passed as the first +** argument to callbacks registered using rtree_geometry_callback(). +*/ +struct sqlite3_rtree_geometry { + void *pContext; /* Copy of pContext passed to s_r_g_c() */ + int nParam; /* Size of array aParam[] */ + double *aParam; /* Parameters passed to SQL geom function */ + void *pUser; /* Callback implementation user data */ + void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ +}; + + +#if 0 +} /* end of the 'extern "C"' block */ +#endif + +#endif /* ifndef _SQLITE3RTREE_H_ */ + /************** End of sqlite3.h *********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -6295,7 +7350,7 @@ typedef struct HashElem HashElem; ** element pointed to plus the next _ht.count-1 elements in the list. ** ** Hash.htsize and Hash.ht may be zero. In that case lookup is done -** by a linear search of the global list. For small tables, the +** by a linear search of the global list. For small tables, the ** Hash.ht table is never allocated because if there are few elements ** in the table, it is faster to do a linear search than to manage ** the hash table. @@ -6310,7 +7365,7 @@ struct Hash { } *ht; }; -/* Each element in the hash table is an instance of the following +/* Each element in the hash table is an instance of the following ** structure. All elements are stored on a single doubly-linked list. ** ** Again, this structure is intended to be opaque, but it can't really @@ -6531,6 +7586,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); */ #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite_int64 +# define float sqlite_int64 # define LONGDOUBLE_TYPE sqlite_int64 # ifndef SQLITE_BIG_DBL # define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) @@ -6546,7 +7602,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); /* ** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0 -** afterward. Having this macro allows us to cause the C compiler +** afterward. Having this macro allows us to cause the C compiler ** to omit code used by TEMP tables without messy #ifndef statements. */ #ifdef SQLITE_OMIT_TEMPDB @@ -6689,7 +7745,7 @@ SQLITE_PRIVATE const int sqlite3one; #define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) -/* +/* ** Round up a number to the next larger multiple of 8. This is used ** to force 8-byte alignment on 64-bit architectures. */ @@ -6718,7 +7774,7 @@ SQLITE_PRIVATE const int sqlite3one; /* ** An instance of the following structure is used to store the busy-handler -** callback for a given sqlite handle. +** callback for a given sqlite handle. ** ** The sqlite.busyHandler member of the sqlite struct contains the busy ** callback for the database handle. Each pager opened via the sqlite @@ -6783,16 +7839,16 @@ struct BusyHandler { SQLITE_API int sqlite3_wsd_init(int N, int J); SQLITE_API void *sqlite3_wsd_find(void *K, int L); #else - #define SQLITE_WSD + #define SQLITE_WSD #define GLOBAL(t,v) v #define sqlite3GlobalConfig sqlite3Config #endif /* ** The following macros are used to suppress compiler warnings and to -** make it clear to human readers when a function parameter is deliberately +** make it clear to human readers when a function parameter is deliberately ** left unused within the body of a function. This usually happens when -** a function is called via a function pointer. For example the +** a function is called via a function pointer. For example the ** implementation of an SQL aggregate step callback may not use the ** parameter indicating the number of arguments passed to the aggregate, ** if it knows that this is enforced elsewhere. @@ -6822,6 +7878,7 @@ typedef struct Expr Expr; typedef struct ExprList ExprList; typedef struct ExprSpan ExprSpan; typedef struct FKey FKey; +typedef struct FuncDestructor FuncDestructor; typedef struct FuncDef FuncDef; typedef struct FuncDefHash FuncDefHash; typedef struct IdList IdList; @@ -6847,13 +7904,14 @@ typedef struct TriggerPrg TriggerPrg; typedef struct TriggerStep TriggerStep; typedef struct UnpackedRecord UnpackedRecord; typedef struct VTable VTable; +typedef struct VtabCtx VtabCtx; typedef struct Walker Walker; typedef struct WherePlan WherePlan; typedef struct WhereInfo WhereInfo; typedef struct WhereLevel WhereLevel; /* -** Defer sourcing vdbe.h and btree.h until after the "u8" and +** 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. */ @@ -6900,21 +7958,10 @@ typedef struct WhereLevel WhereLevel; typedef struct Btree Btree; typedef struct BtCursor BtCursor; typedef struct BtShared BtShared; -typedef struct BtreeMutexArray BtreeMutexArray; - -/* -** This structure records all of the Btrees that need to hold -** a mutex before we enter sqlite3VdbeExec(). The Btrees are -** are placed in aBtree[] in order of aBtree[]->pBt. That way, -** we can always lock and unlock them all quickly. -*/ -struct BtreeMutexArray { - int nMutex; - Btree *aBtree[SQLITE_MAX_ATTACHED+1]; -}; SQLITE_PRIVATE int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, /* VFS to use with this b-tree */ const char *zFilename, /* Name of database file to open */ sqlite3 *db, /* Associated database connection */ Btree **ppBtree, /* Return open Btree* here */ @@ -6928,27 +7975,27 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( ** NOTE: These values must match the corresponding PAGER_ values in ** pager.h. */ -#define BTREE_OMIT_JOURNAL 1 /* Do not use journal. No argument */ +#define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ #define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ -#define BTREE_MEMORY 4 /* In-memory DB. No argument */ -#define BTREE_READONLY 8 /* Open the database in read-only mode */ -#define BTREE_READWRITE 16 /* Open for both reading and writing */ -#define BTREE_CREATE 32 /* Create the database if it does not exist */ +#define BTREE_MEMORY 4 /* This is an in-memory DB */ +#define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */ +#define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */ SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); -SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int); +SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int); SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*); SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*); SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int); +SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*); SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int); SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*); SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int); SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *); SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int); SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); -SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*); +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int); SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*); SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*); SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int); @@ -6968,11 +8015,17 @@ SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *); SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *); /* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR -** of the following flags: +** of the flags shown below. +** +** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set. +** With BTREE_INTKEY, the table key is a 64-bit integer and arbitrary data +** is stored in the leaves. (BTREE_INTKEY is used for SQL tables.) With +** BTREE_BLOBKEY, the key is an arbitrary BLOB and no content is stored +** anywhere - the key is the content. (BTREE_BLOBKEY is used for SQL +** indices.) */ #define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */ -#define BTREE_ZERODATA 2 /* Table has keys only - no data */ -#define BTREE_LEAFDATA 4 /* Data stored in leaves only. Implies INTKEY */ +#define BTREE_BLOBKEY 2 /* Table has keys only - no data */ SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*); SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*); @@ -6983,7 +8036,7 @@ SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); /* ** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta -** should be one of the following values. The integer values are assigned +** should be one of the following values. The integer values are assigned ** to constants so that the offset of the corresponding field in an ** SQLite database header may be found using the following formula: ** @@ -7046,6 +8099,8 @@ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *); SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); +SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); + #ifndef NDEBUG SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); #endif @@ -7059,6 +8114,10 @@ SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int); SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*); #endif +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); +#endif + /* ** If we are not using shared cache, then there is no need to ** use mutexes to access the BtShared structures. So make the @@ -7068,35 +8127,33 @@ SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*); SQLITE_PRIVATE void sqlite3BtreeEnter(Btree*); SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3*); #else -# define sqlite3BtreeEnter(X) +# define sqlite3BtreeEnter(X) # define sqlite3BtreeEnterAll(X) #endif #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE +SQLITE_PRIVATE int sqlite3BtreeSharable(Btree*); SQLITE_PRIVATE void sqlite3BtreeLeave(Btree*); SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor*); SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor*); SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3*); -SQLITE_PRIVATE void sqlite3BtreeMutexArrayEnter(BtreeMutexArray*); -SQLITE_PRIVATE void sqlite3BtreeMutexArrayLeave(BtreeMutexArray*); -SQLITE_PRIVATE void sqlite3BtreeMutexArrayInsert(BtreeMutexArray*, Btree*); #ifndef NDEBUG /* These routines are used inside assert() statements only. */ SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree*); SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3*); +SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*); #endif #else +# define sqlite3BtreeSharable(X) 0 # define sqlite3BtreeLeave(X) # define sqlite3BtreeEnterCursor(X) # define sqlite3BtreeLeaveCursor(X) # define sqlite3BtreeLeaveAll(X) -# define sqlite3BtreeMutexArrayEnter(X) -# define sqlite3BtreeMutexArrayLeave(X) -# define sqlite3BtreeMutexArrayInsert(X,Y) # define sqlite3BtreeHoldsMutex(X) 1 # define sqlite3BtreeHoldsAllMutexes(X) 1 +# define sqlite3SchemaMutexHeld(X,Y,Z) 1 #endif @@ -7125,6 +8182,7 @@ SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3*); */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ +/* #include <stdio.h> */ /* ** A single VDBE is an opaque structure named "Vdbe". Only routines @@ -7168,6 +8226,7 @@ struct VdbeOp { KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */ int *ai; /* Used when p4type is P4_INTARRAY */ SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ + int (*xAdvance)(BtCursor *, int *); } p4; #ifdef SQLITE_DEBUG char *zComment; /* Comment to improve readability */ @@ -7188,8 +8247,8 @@ struct SubProgram { int nOp; /* Elements in aOp[] */ int nMem; /* Number of memory cells required */ int nCsr; /* Number of cursors required */ - int nRef; /* Number of pointers to this structure */ void *token; /* id that may be used to recursive triggers */ + SubProgram *pNext; /* Next sub-program already visited */ }; /* @@ -7215,7 +8274,7 @@ typedef struct VdbeOpList VdbeOpList; #define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */ #define P4_VDBEFUNC (-7) /* P4 is a pointer to a VdbeFunc structure */ #define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */ -#define P4_TRANSIENT (-9) /* P4 is a pointer to a transient string */ +#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ #define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */ #define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite3_mprintf() */ #define P4_REAL (-12) /* P4 is a 64-bit floating point value */ @@ -7223,6 +8282,7 @@ typedef struct VdbeOpList VdbeOpList; #define P4_INT32 (-14) /* P4 is a 32-bit signed integer */ #define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ #define P4_SUBPROGRAM (-18) /* P4 is a pointer to a SubProgram structure */ +#define P4_ADVANCE (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */ /* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure ** is made. That copy is freed when the Vdbe is finalized. But if the @@ -7235,7 +8295,7 @@ typedef struct VdbeOpList VdbeOpList; #define P4_KEYINFO_STATIC (-17) /* -** The Vdbe.aColName array contains 5n Mem structures, where n is the +** The Vdbe.aColName array contains 5n Mem structures, where n is the ** number of columns of data returned by the statement. */ #define COLNAME_NAME 0 @@ -7255,7 +8315,7 @@ typedef struct VdbeOpList VdbeOpList; /* ** The following macro converts a relative address in the p2 field -** of a VdbeOp structure into a negative number so that +** of a VdbeOp structure into a negative number so that ** sqlite3VdbeAddOpList() knows that the address is relative. Calling ** the macro again restores the address. */ @@ -7320,102 +8380,105 @@ typedef struct VdbeOpList VdbeOpList; #define OP_Or 68 /* same as TK_OR */ #define OP_Not 19 /* same as TK_NOT */ #define OP_BitNot 93 /* same as TK_BITNOT */ -#define OP_If 26 -#define OP_IfNot 27 +#define OP_Once 26 +#define OP_If 27 +#define OP_IfNot 28 #define OP_IsNull 73 /* same as TK_ISNULL */ #define OP_NotNull 74 /* same as TK_NOTNULL */ -#define OP_Column 28 -#define OP_Affinity 29 -#define OP_MakeRecord 30 -#define OP_Count 31 -#define OP_Savepoint 32 -#define OP_AutoCommit 33 -#define OP_Transaction 34 -#define OP_ReadCookie 35 -#define OP_SetCookie 36 -#define OP_VerifyCookie 37 -#define OP_OpenRead 38 -#define OP_OpenWrite 39 -#define OP_OpenEphemeral 40 -#define OP_OpenPseudo 41 -#define OP_Close 42 -#define OP_SeekLt 43 -#define OP_SeekLe 44 -#define OP_SeekGe 45 -#define OP_SeekGt 46 -#define OP_Seek 47 -#define OP_NotFound 48 -#define OP_Found 49 -#define OP_IsUnique 50 -#define OP_NotExists 51 -#define OP_Sequence 52 -#define OP_NewRowid 53 -#define OP_Insert 54 -#define OP_InsertInt 55 -#define OP_Delete 56 -#define OP_ResetCount 57 -#define OP_RowKey 58 -#define OP_RowData 59 -#define OP_Rowid 60 -#define OP_NullRow 61 -#define OP_Last 62 -#define OP_Sort 63 -#define OP_Rewind 64 -#define OP_Prev 65 -#define OP_Next 66 -#define OP_IdxInsert 67 -#define OP_IdxDelete 70 -#define OP_IdxRowid 71 -#define OP_IdxLT 72 -#define OP_IdxGE 81 -#define OP_Destroy 92 -#define OP_Clear 95 -#define OP_CreateIndex 96 -#define OP_CreateTable 97 -#define OP_ParseSchema 98 -#define OP_LoadAnalysis 99 -#define OP_DropTable 100 -#define OP_DropIndex 101 -#define OP_DropTrigger 102 -#define OP_IntegrityCk 103 -#define OP_RowSetAdd 104 -#define OP_RowSetRead 105 -#define OP_RowSetTest 106 -#define OP_Program 107 -#define OP_Param 108 -#define OP_FkCounter 109 -#define OP_FkIfZero 110 -#define OP_MemMax 111 -#define OP_IfPos 112 -#define OP_IfNeg 113 -#define OP_IfZero 114 -#define OP_AggStep 115 -#define OP_AggFinal 116 -#define OP_Vacuum 117 -#define OP_IncrVacuum 118 -#define OP_Expire 119 -#define OP_TableLock 120 -#define OP_VBegin 121 -#define OP_VCreate 122 -#define OP_VDestroy 123 -#define OP_VOpen 124 -#define OP_VFilter 125 -#define OP_VColumn 126 -#define OP_VNext 127 -#define OP_VRename 128 -#define OP_VUpdate 129 -#define OP_Pagecount 131 -#define OP_Trace 132 -#define OP_Noop 133 -#define OP_Explain 134 - -/* The following opcode values are never used */ -#define OP_NotUsed_135 135 -#define OP_NotUsed_136 136 -#define OP_NotUsed_137 137 -#define OP_NotUsed_138 138 -#define OP_NotUsed_139 139 -#define OP_NotUsed_140 140 +#define OP_Column 29 +#define OP_Affinity 30 +#define OP_MakeRecord 31 +#define OP_Count 32 +#define OP_Savepoint 33 +#define OP_AutoCommit 34 +#define OP_Transaction 35 +#define OP_ReadCookie 36 +#define OP_SetCookie 37 +#define OP_VerifyCookie 38 +#define OP_OpenRead 39 +#define OP_OpenWrite 40 +#define OP_OpenAutoindex 41 +#define OP_OpenEphemeral 42 +#define OP_SorterOpen 43 +#define OP_OpenPseudo 44 +#define OP_Close 45 +#define OP_SeekLt 46 +#define OP_SeekLe 47 +#define OP_SeekGe 48 +#define OP_SeekGt 49 +#define OP_Seek 50 +#define OP_NotFound 51 +#define OP_Found 52 +#define OP_IsUnique 53 +#define OP_NotExists 54 +#define OP_Sequence 55 +#define OP_NewRowid 56 +#define OP_Insert 57 +#define OP_InsertInt 58 +#define OP_Delete 59 +#define OP_ResetCount 60 +#define OP_SorterCompare 61 +#define OP_SorterData 62 +#define OP_RowKey 63 +#define OP_RowData 64 +#define OP_Rowid 65 +#define OP_NullRow 66 +#define OP_Last 67 +#define OP_SorterSort 70 +#define OP_Sort 71 +#define OP_Rewind 72 +#define OP_SorterNext 81 +#define OP_Prev 92 +#define OP_Next 95 +#define OP_SorterInsert 96 +#define OP_IdxInsert 97 +#define OP_IdxDelete 98 +#define OP_IdxRowid 99 +#define OP_IdxLT 100 +#define OP_IdxGE 101 +#define OP_Destroy 102 +#define OP_Clear 103 +#define OP_CreateIndex 104 +#define OP_CreateTable 105 +#define OP_ParseSchema 106 +#define OP_LoadAnalysis 107 +#define OP_DropTable 108 +#define OP_DropIndex 109 +#define OP_DropTrigger 110 +#define OP_IntegrityCk 111 +#define OP_RowSetAdd 112 +#define OP_RowSetRead 113 +#define OP_RowSetTest 114 +#define OP_Program 115 +#define OP_Param 116 +#define OP_FkCounter 117 +#define OP_FkIfZero 118 +#define OP_MemMax 119 +#define OP_IfPos 120 +#define OP_IfNeg 121 +#define OP_IfZero 122 +#define OP_AggStep 123 +#define OP_AggFinal 124 +#define OP_Checkpoint 125 +#define OP_JournalMode 126 +#define OP_Vacuum 127 +#define OP_IncrVacuum 128 +#define OP_Expire 129 +#define OP_TableLock 131 +#define OP_VBegin 132 +#define OP_VCreate 133 +#define OP_VDestroy 134 +#define OP_VOpen 135 +#define OP_VFilter 136 +#define OP_VColumn 137 +#define OP_VNext 138 +#define OP_VRename 139 +#define OP_VUpdate 140 +#define OP_Pagecount 146 +#define OP_MaxPgcnt 147 +#define OP_Trace 148 +#define OP_Noop 149 +#define OP_Explain 150 /* Properties such as "out2" or "jump" that are specified in @@ -7431,24 +8494,24 @@ typedef struct VdbeOpList VdbeOpList; #define OPFLG_OUT3 0x0040 /* out3: P3 is an output */ #define OPFLG_INITIALIZER {\ /* 0 */ 0x00, 0x01, 0x05, 0x04, 0x04, 0x10, 0x00, 0x02,\ -/* 8 */ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x24, 0x24,\ +/* 8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x24, 0x24,\ /* 16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\ -/* 24 */ 0x00, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02,\ -/* 32 */ 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00,\ -/* 40 */ 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x08,\ -/* 48 */ 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x00, 0x00,\ -/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x01,\ -/* 64 */ 0x01, 0x01, 0x01, 0x08, 0x4c, 0x4c, 0x00, 0x02,\ +/* 24 */ 0x00, 0x01, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00,\ +/* 32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\ +/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\ +/* 48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\ +/* 56 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 64 */ 0x00, 0x02, 0x00, 0x01, 0x4c, 0x4c, 0x01, 0x01,\ /* 72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\ /* 80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\ -/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x02, 0x24, 0x02, 0x00,\ -/* 96 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 104 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\ -/* 112 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00,\ -/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,\ -/* 128 */ 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,\ -/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04,\ -/* 144 */ 0x04, 0x04,} +/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01,\ +/* 96 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\ +/* 104 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 112 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\ +/* 120 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00,\ +/* 128 */ 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 136 */ 0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x04,\ +/* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,} /************** End of opcodes.h *********************************************/ /************** Continuing where we left off in vdbe.h ***********************/ @@ -7465,19 +8528,21 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp); -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 sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); +SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1); +SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2); +SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3); SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5); SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr); -SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N); +SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr); SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); -SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int,int); +SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); @@ -7486,6 +8551,7 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*); #endif SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); @@ -7494,16 +8560,19 @@ SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int); SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); -SQLITE_PRIVATE void sqlite3VdbeProgramDelete(sqlite3 *, SubProgram *, int); SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8); SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); #ifndef SQLITE_OMIT_TRACE SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif -SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,char*,int); -SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*); +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); + +#ifndef SQLITE_OMIT_TRIGGER +SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); +#endif #ifndef NDEBUG @@ -7542,8 +8611,8 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); #define _PAGER_H_ /* -** Default maximum size for persistent journal files. A negative -** value means no limit. This value may be overridden using the +** Default maximum size for persistent journal files. A negative +** value means no limit. This value may be overridden using the ** sqlite3PagerJournalSizeLimit() API. See also "PRAGMA journal_size_limit". */ #ifndef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT @@ -7569,9 +8638,9 @@ typedef struct PgHdr DbPage; /* ** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is ** reserved for working around a windows/posix incompatibility). It is -** used in the journal to signify that the remainder of the journal file +** used in the journal to signify that the remainder of the journal file ** is devoted to storing a master journal name - there are no more pages to -** roll back. See comments for function writeMasterJournal() in pager.c +** roll back. See comments for function writeMasterJournal() in pager.c ** for details. */ #define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1)) @@ -7583,6 +8652,7 @@ typedef struct PgHdr DbPage; */ #define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ #define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */ +#define PAGER_MEMORY 0x0004 /* In-memory database */ /* ** Valid values for the second argument to sqlite3PagerLockingMode(). @@ -7592,22 +8662,23 @@ typedef struct PgHdr DbPage; #define PAGER_LOCKINGMODE_EXCLUSIVE 1 /* -** Valid values for the second argument to sqlite3PagerJournalMode(). +** Numeric constants that encode the journalmode. */ -#define PAGER_JOURNALMODE_QUERY -1 +#define PAGER_JOURNALMODE_QUERY (-1) /* Query the value of journalmode */ #define PAGER_JOURNALMODE_DELETE 0 /* Commit by deleting journal file */ #define PAGER_JOURNALMODE_PERSIST 1 /* Commit by zeroing journal header */ #define PAGER_JOURNALMODE_OFF 2 /* Journal omitted. */ #define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */ #define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */ +#define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ /* ** The remainder of this file contains the declarations of the functions -** that make up the Pager sub-system API. See source code comments for +** that make up the Pager sub-system API. See source code comments for ** a detailed description of each routine. */ -/* Open and close a Pager connection. */ +/* Open and close a Pager connection. */ SQLITE_PRIVATE int sqlite3PagerOpen( sqlite3_vfs*, Pager **ppPager, @@ -7622,16 +8693,18 @@ SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); /* Functions used to configure a Pager object. */ SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); -SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u16*, int); +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int); SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int); SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int); -SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int); +SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int,int); SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int); -SQLITE_PRIVATE int sqlite3PagerJournalMode(Pager *, int); +SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int); +SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*); +SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*); SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64); SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*); -/* Functions used to obtain and release page references. */ +/* Functions used to obtain and release page references. */ SQLITE_PRIVATE int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); #define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0) SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno); @@ -7643,13 +8716,14 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*); SQLITE_PRIVATE void sqlite3PagerDontWrite(DbPage*); SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int); SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage*); -SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *); -SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *); +SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *); +SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *); /* Functions used to manage pager transactions and savepoints. */ -SQLITE_PRIVATE int sqlite3PagerPagecount(Pager*, int*); +SQLITE_PRIVATE void sqlite3PagerPagecount(Pager*, int*); SQLITE_PRIVATE int sqlite3PagerBegin(Pager*, int exFlag, int); SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int); +SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager*); SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager); SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*); SQLITE_PRIVATE int sqlite3PagerRollback(Pager*); @@ -7657,9 +8731,16 @@ SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n); SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint); SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*); +SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); +SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager); + /* Functions used to query pager state and configuration. */ SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*); SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*); +SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*); SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*); SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*); SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); @@ -7671,6 +8752,10 @@ SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); /* Functions used to truncate the database file. */ SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); +#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL) +SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *); +#endif + /* Functions to support testing and debugging. */ #if !defined(NDEBUG) || defined(SQLITE_TEST) SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage*); @@ -7704,7 +8789,7 @@ SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*); ** ************************************************************************* ** This header file defines the interface that the sqlite page cache -** subsystem. +** subsystem. */ #ifndef _PCACHE_H_ @@ -7777,7 +8862,7 @@ SQLITE_PRIVATE void sqlite3PcacheSetPageSize(PCache *, int); SQLITE_PRIVATE int sqlite3PcacheSize(void); /* One release per successful fetch. Page is pinned until released. -** Reference counted. +** Reference counted. */ SQLITE_PRIVATE int sqlite3PcacheFetch(PCache*, Pgno, int createFlag, PgHdr**); SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr*); @@ -7818,7 +8903,7 @@ SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*); #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) /* Iterate through all dirty pages currently stored in the cache. This -** interface is only available if SQLITE_CHECK_PAGES is defined when the +** interface is only available if SQLITE_CHECK_PAGES is defined when the ** library is built. */ SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)); @@ -7878,8 +8963,8 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); /* ** 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, SQLITE_OS_OS2, and SQLITE_OS_OTHER -** will defined to either 1 or 0. One of the four will be 1. The other +** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER +** will defined to either 1 or 0. One of the four will be 1. The other ** three will be 0. */ #if defined(SQLITE_OS_OTHER) @@ -7981,10 +9066,10 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); ** 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 +** 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" +** 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 @@ -8025,9 +9110,9 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); ** 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 +** 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 @@ -8046,7 +9131,7 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); ** 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. +** shared locks begins at SHARED_FIRST. ** ** The same locking strategy and ** byte ranges are used for Unix. This leaves open the possiblity of having @@ -8062,7 +9147,7 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); ** 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 +** 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 @@ -8072,7 +9157,11 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); ** 1GB boundary. ** */ -#define PENDING_BYTE sqlite3PendingByte +#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 @@ -8082,8 +9171,8 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); */ SQLITE_PRIVATE int sqlite3OsInit(void); -/* -** Functions for accessing sqlite3_file methods +/* +** Functions for accessing sqlite3_file methods */ SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file*); SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); @@ -8098,9 +9187,13 @@ SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*); #define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); +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); -/* -** Functions for accessing sqlite3_vfs methods +/* +** 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); @@ -8114,10 +9207,10 @@ 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 sqlite3OsCurrentTime(sqlite3_vfs *, double*); +SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); /* -** Convenience functions for opening and closing files using +** 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*); @@ -8194,8 +9287,8 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *); #define sqlite3_mutex_enter(X) #define sqlite3_mutex_try(X) SQLITE_OK #define sqlite3_mutex_leave(X) -#define sqlite3_mutex_held(X) 1 -#define sqlite3_mutex_notheld(X) 1 +#define sqlite3_mutex_held(X) ((void)(X),1) +#define sqlite3_mutex_notheld(X) ((void)(X),1) #define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8) #define sqlite3MutexInit() SQLITE_OK #define sqlite3MutexEnd() @@ -8223,16 +9316,23 @@ struct Db { /* ** An instance of the following structure stores a database schema. ** -** If there are no virtual tables configured in this schema, the -** Schema.db variable is set to NULL. After the first virtual table -** has been added, it is set to point to the database connection -** used to create the connection. Once a virtual table has been -** added to the Schema structure and the Schema.db variable populated, -** only that database connection may use the Schema to prepare -** statements. +** Most Schema objects are associated with a Btree. The exception is +** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing. +** In shared cache mode, a single Schema object can be shared by multiple +** Btrees that refer to the same underlying BtShared object. +** +** Schema objects are automatically deallocated when the last Btree that +** references them is destroyed. The TEMP Schema is manually freed by +** sqlite3_close(). +* +** A thread must be holding a mutex on the corresponding Btree in order +** to access Schema content. This implies that the thread must also be +** holding a mutex on the sqlite3 connection pointer that owns the Btree. +** For a TEMP Schema, only the connection mutex is required. */ struct Schema { int schema_cookie; /* Database schema version number for this file */ + int iGeneration; /* Generation counter. Incremented with each change */ Hash tblHash; /* All tables indexed by name */ Hash idxHash; /* All (named) indices indexed by name */ Hash trigHash; /* All triggers indexed by name */ @@ -8242,13 +9342,10 @@ struct Schema { u8 enc; /* Text encoding used by this database */ u16 flags; /* Flags associated with this schema */ int cache_size; /* Number of pages to use in the cache */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3 *db; /* "Owner" connection. See comment above */ -#endif }; /* -** These macros can be used to test, set, or clear bits in the +** These macros can be used to test, set, or clear bits in the ** Db.pSchema->flags field. */ #define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))==(P)) @@ -8302,6 +9399,7 @@ struct Lookaside { u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ int nOut; /* Number of buffers currently checked out */ int mxOut; /* Highwater mark for nOut */ + int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ LookasideSlot *pFree; /* List of available buffers */ void *pStart; /* First byte of available memory space */ void *pEnd; /* First byte past end of available space */ @@ -8351,16 +9449,16 @@ struct sqlite3 { int nDb; /* Number of backends currently in use */ Db *aDb; /* All backends */ int flags; /* Miscellaneous flags. See below */ - int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ + unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ u8 dfltLockMode; /* Default locking-mode for attached dbs */ - u8 dfltJournalMode; /* Default journal mode for attached dbs */ signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ u8 suppressErr; /* Do not issue error messages if true */ + u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ int nextPagesize; /* Pagesize after VACUUM if >0 */ int nTable; /* Number of tables in the database */ CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ @@ -8381,16 +9479,21 @@ struct sqlite3 { struct Vdbe *pVdbe; /* List of active virtual machines */ int activeVdbeCnt; /* Number of VDBEs currently executing */ int writeVdbeCnt; /* Number of active VDBEs that are writing */ + int vdbeExecCnt; /* Number of nested calls to VdbeExec() */ void (*xTrace)(void*,const char*); /* Trace function */ void *pTraceArg; /* Argument to the trace function */ void (*xProfile)(void*,const char*,u64); /* Profiling function */ void *pProfileArg; /* Argument to profile function */ - void *pCommitArg; /* Argument to xCommitCallback() */ + void *pCommitArg; /* Argument to xCommitCallback() */ int (*xCommitCallback)(void*); /* Invoked at every commit. */ - void *pRollbackArg; /* Argument to xRollbackCallback() */ + void *pRollbackArg; /* Argument to xRollbackCallback() */ void (*xRollbackCallback)(void*); /* Invoked at every commit. */ void *pUpdateArg; void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64); +#ifndef SQLITE_OMIT_WAL + int (*xWalCallback)(void *, sqlite3 *, const char *, int); + void *pWalArg; +#endif void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); void *pCollNeededArg; @@ -8414,7 +9517,7 @@ struct sqlite3 { #endif #ifndef SQLITE_OMIT_VIRTUALTABLE Hash aModule; /* populated by sqlite3_create_module() */ - Table *pVTab; /* vtab with active Connect/Create method */ + VtabCtx *pVtabCtx; /* Context for active vtab connect/create */ VTable **aVTrans; /* Virtual tables with open transactions */ int nVTrans; /* Allocated size of aVTrans */ VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ @@ -8429,10 +9532,11 @@ struct sqlite3 { int nStatement; /* Number of nested statement-transactions */ u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ i64 nDeferredCons; /* Net deferred constraints this transaction. */ + int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY - /* The following variables are all protected by the STATIC_MASTER - ** mutex, not by sqlite3.mutex. They are used by code in notify.c. + /* The following variables are all protected by the STATIC_MASTER + ** mutex, not by sqlite3.mutex. They are used by code in notify.c. ** ** When X.pUnlockConnection==Y, that means that X is waiting for Y to ** unlock so that it can proceed. @@ -8469,17 +9573,21 @@ struct sqlite3 { #define SQLITE_SqlTrace 0x00004000 /* Debug print SQL as it executes */ #define SQLITE_VdbeListing 0x00008000 /* Debug listings of VDBE programs */ #define SQLITE_WriteSchema 0x00010000 /* OK to update SQLITE_MASTER */ -#define SQLITE_NoReadlock 0x00020000 /* Readlocks are omitted when +#define SQLITE_NoReadlock 0x00020000 /* Readlocks are omitted when ** accessing read-only databases */ #define SQLITE_IgnoreChecks 0x00040000 /* Do not enforce check constraints */ #define SQLITE_ReadUncommitted 0x0080000 /* For shared-cache mode */ #define SQLITE_LegacyFileFmt 0x00100000 /* Create new databases in format 1 */ #define SQLITE_FullFSync 0x00200000 /* Use full fsync on the backend */ -#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */ +#define SQLITE_CkptFullFSync 0x00400000 /* Use full fsync for checkpoint */ #define SQLITE_RecoveryMode 0x00800000 /* Ignore schema errors */ #define SQLITE_ReverseOrder 0x01000000 /* Reverse unordered SELECTs */ #define SQLITE_RecTriggers 0x02000000 /* Enable recursive triggers */ #define SQLITE_ForeignKeys 0x04000000 /* Enforce foreign key constraints */ +#define SQLITE_AutoIndex 0x08000000 /* Enable automatic indexes */ +#define SQLITE_PreferBuiltin 0x10000000 /* Preference to built-in funcs */ +#define SQLITE_LoadExtension 0x20000000 /* Enable load_extension */ +#define SQLITE_EnableTrigger 0x40000000 /* True to enable triggers */ /* ** Bits of the sqlite3.flags field that are used by the @@ -8491,7 +9599,11 @@ struct sqlite3 { #define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */ #define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */ #define SQLITE_IndexCover 0x10 /* Disable index covering table */ -#define SQLITE_OptMask 0x1f /* Mask of all disablable opts */ +#define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */ +#define SQLITE_FactorOutConst 0x40 /* Disable factoring out constants */ +#define SQLITE_IdxRealAsInt 0x80 /* Store REAL as INT in indices */ +#define SQLITE_DistinctOpt 0x80 /* DISTINCT using indexes */ +#define SQLITE_OptMask 0xff /* Mask of all disablable opts */ /* ** Possible values for the sqlite.magic field. @@ -8521,6 +9633,27 @@ struct FuncDef { void (*xFinalize)(sqlite3_context*); /* Aggregate finalizer */ char *zName; /* SQL name of the function. */ FuncDef *pHash; /* Next with a different name but the same hash */ + FuncDestructor *pDestructor; /* Reference counted destructor function */ +}; + +/* +** This structure encapsulates a user-function destructor callback (as +** configured using create_function_v2()) and a reference counter. When +** create_function_v2() is called to create a function with a destructor, +** a single object of this type is allocated. FuncDestructor.nRef is set to +** the number of FuncDef objects created (either 1 or 3, depending on whether +** or not the specified encoding is SQLITE_ANY). The FuncDef.pDestructor +** member of each of the new FuncDef objects is set to point to the allocated +** FuncDestructor. +** +** Thereafter, when one of the FuncDef objects is deleted, the reference +** count on this object is decremented. When it reaches 0, the destructor +** is invoked and the FuncDestructor structure freed. +*/ +struct FuncDestructor { + int nRef; + void (*xDestroy)(void *); + void *pUserData; }; /* @@ -8539,10 +9672,10 @@ struct FuncDef { ** used to create the initializers for the FuncDef structures. ** ** FUNCTION(zName, nArg, iArg, bNC, xFunc) -** Used to create a scalar function definition of a function zName +** Used to create a scalar function definition of a function zName ** implemented by C function xFunc that accepts nArg arguments. The ** value passed as iArg is cast to a (void*) and made available -** as the user-data (sqlite3_user_data()) for the function. If +** as the user-data (sqlite3_user_data()) for the function. If ** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set. ** ** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal) @@ -8552,8 +9685,8 @@ struct FuncDef { ** FUNCTION(). ** ** LIKEFUNC(zName, nArg, pArg, flags) -** Used to create a scalar function definition of a function zName -** that accepts nArg arguments and is implemented by a call to C +** Used to create a scalar function definition of a function zName +** that accepts nArg arguments and is implemented by a call to C ** function likeFunc. Argument pArg is cast to a (void *) and made ** available as the function user-data (sqlite3_user_data()). The ** FuncDef.flags variable is set to the value passed as the flags @@ -8561,15 +9694,15 @@ struct FuncDef { */ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0} + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \ - pArg, 0, xFunc, 0, 0, #zName, 0} + pArg, 0, xFunc, 0, 0, #zName, 0, 0} #define LIKEFUNC(zName, nArg, arg, flags) \ - {nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0} + {nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} #define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ {nArg, SQLITE_UTF8, nc*SQLITE_FUNC_NEEDCOLL, \ - SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0} + SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} /* ** All current savepoints are stored in a linked list starting at @@ -8671,7 +9804,7 @@ struct CollSeq { ** ** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and ** 't' for SQLITE_AFF_TEXT. But we can save a little space and improve -** the speed a little by numbering the values consecutively. +** the speed a little by numbering the values consecutively. ** ** But rather than start with 0 or 1, we begin with 'a'. That way, ** when multiple affinity types are concatenated into a string and @@ -8690,7 +9823,7 @@ struct CollSeq { /* ** The SQLITE_AFF_MASK values masks off the significant bits of an -** affinity value. +** affinity value. */ #define SQLITE_AFF_MASK 0x67 @@ -8704,20 +9837,20 @@ struct CollSeq { /* ** An object of this type is created for each virtual table present in -** the database schema. +** the database schema. ** ** If the database schema is shared, then there is one instance of this ** structure for each database connection (sqlite3*) that uses the shared ** schema. This is because each database connection requires its own unique -** instance of the sqlite3_vtab* handle used to access the virtual table -** implementation. sqlite3_vtab* handles can not be shared between -** database connections, even when the rest of the in-memory database +** instance of the sqlite3_vtab* handle used to access the virtual table +** implementation. sqlite3_vtab* handles can not be shared between +** database connections, even when the rest of the in-memory database ** schema is shared, as the implementation often stores the database ** connection handle passed to it via the xConnect() or xCreate() method ** during initialization internally. This database connection handle may -** then used by the virtual table implementation to access real tables -** within the database. So that they appear as part of the callers -** transaction, these accesses need to be made via the same database +** then be used by the virtual table implementation to access real tables +** within the database. So that they appear as part of the callers +** transaction, these accesses need to be made via the same database ** connection as that used to execute SQL operations on the virtual table. ** ** All VTable objects that correspond to a single table in a shared @@ -8729,19 +9862,19 @@ struct CollSeq { ** sqlite3_vtab* handle in the compiled query. ** ** When an in-memory Table object is deleted (for example when the -** schema is being reloaded for some reason), the VTable objects are not -** deleted and the sqlite3_vtab* handles are not xDisconnect()ed +** schema is being reloaded for some reason), the VTable objects are not +** deleted and the sqlite3_vtab* handles are not xDisconnect()ed ** immediately. Instead, they are moved from the Table.pVTable list to ** another linked list headed by the sqlite3.pDisconnect member of the -** corresponding sqlite3 structure. They are then deleted/xDisconnected +** corresponding sqlite3 structure. They are then deleted/xDisconnected ** next time a statement is prepared using said sqlite3*. This is done ** to avoid deadlock issues involving multiple sqlite3.mutex mutexes. ** Refer to comments above function sqlite3VtabUnlockList() for an ** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect ** list without holding the corresponding sqlite3.mutex mutex. ** -** The memory for objects of this type is always allocated by -** sqlite3DbMalloc(), using the connection handle stored in VTable.db as +** The memory for objects of this type is always allocated by +** sqlite3DbMalloc(), using the connection handle stored in VTable.db as ** the first argument. */ struct VTable { @@ -8749,6 +9882,8 @@ struct VTable { Module *pMod; /* Pointer to module implementation */ sqlite3_vtab *pVtab; /* Pointer to vtab instance */ int nRef; /* Number of pointers to this structure */ + u8 bConstraint; /* True if constraints are supported */ + int iSavepoint; /* Depth of the SAVEPOINT stack */ VTable *pNext; /* Next in linked list (see above) */ }; @@ -8776,20 +9911,20 @@ struct VTable { ** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that ** holds temporary tables and indices. If TF_Ephemeral is set ** then the table is stored in a file that is automatically deleted -** when the VDBE cursor to the table is closed. In this case Table.tnum +** when the VDBE cursor to the table is closed. In this case Table.tnum ** refers VDBE cursor number that holds the table open, not to the root ** page number. Transient tables are used to hold the results of a -** sub-query that appears instead of a real table name in the FROM clause +** sub-query that appears instead of a real table name in the FROM clause ** of a SELECT statement. */ struct Table { - sqlite3 *dbMem; /* DB connection used for lookaside allocations. */ char *zName; /* Name of the table or view */ int iPKey; /* If not negative, use aCol[iPKey] as the primary key */ int nCol; /* Number of columns in this table */ Column *aCol; /* Information about each column */ Index *pIndex; /* List of SQL indexes on this table. */ int tnum; /* Root BTree node for this table (see note above) */ + unsigned nRowEst; /* Estimated rows in table - from sqlite_stat1 table */ Select *pSelect; /* NULL for tables. Points to definition if a view. */ u16 nRef; /* Number of pointers to this Table */ u8 tabFlags; /* Mask of TF_* values */ @@ -8894,7 +10029,7 @@ struct FKey { ** key is set to NULL. CASCADE means that a DELETE or UPDATE of the ** referenced table row is propagated into the row that holds the ** foreign key. -** +** ** The following symbolic values are used to record which type ** of action to take. */ @@ -8915,14 +10050,14 @@ struct FKey { /* ** An instance of the following structure is passed as the first -** argument to sqlite3VdbeKeyCompare and is used to control the +** argument to sqlite3VdbeKeyCompare and is used to control the ** comparison of the two index keys. */ struct KeyInfo { sqlite3 *db; /* The database connection */ - u8 enc; /* Text encoding - one of the TEXT_Utf* values */ + u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ u16 nField; /* Number of entries in aColl[] */ - u8 *aSortOrder; /* If defined an aSortOrder[i] is true, sort DESC */ + u8 *aSortOrder; /* Sort order for each column. May be NULL */ CollSeq *aColl[1]; /* Collating sequence for each term of the key */ }; @@ -8972,7 +10107,7 @@ struct UnpackedRecord { ** In the Table structure describing Ex1, nCol==3 because there are ** three columns in the table. In the Index structure describing ** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed. -** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the +** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the ** first column to be indexed (c3) has an index of 2 in Ex1.aCol[]. ** The second column to be indexed (c1) has an index of 0 in ** Ex1.aCol[], hence Ex2.aiColumn[1]==0. @@ -8980,7 +10115,7 @@ struct UnpackedRecord { ** 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 indicate the which conflict resolution +** 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. */ @@ -8993,6 +10128,7 @@ struct Index { int tnum; /* Page containing root of this index in database file */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */ + u8 bUnordered; /* Use this index for == or IN queries only */ char *zColAff; /* String defining the affinity of each column */ Index *pNext; /* The next index associated with the same table */ Schema *pSchema; /* Schema containing this index */ @@ -9002,7 +10138,7 @@ struct Index { }; /* -** Each sample stored in the sqlite_stat2 table is represented in memory +** Each sample stored in the sqlite_stat2 table is represented in memory ** using a structure of this type. */ struct IndexSample { @@ -9046,6 +10182,7 @@ struct AggInfo { u8 useSortingIdx; /* In direct mode, reference the sorting index rather ** than the source table */ int sortingIdx; /* Cursor number of the sorting index */ + int sortingIdxPTab; /* Cursor number of pseudo-table */ ExprList *pGroupBy; /* The group by clause */ int nSortingColumn; /* Number of columns in the sorting index */ struct AggInfo_col { /* For each column used in source tables */ @@ -9097,9 +10234,9 @@ typedef int ynVar; ** to represent the greater-than-or-equal-to operator in the expression ** tree. ** -** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB, +** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB, ** or TK_STRING), then Expr.token contains the text of the SQL literal. If -** the expression is a variable (TK_VARIABLE), then Expr.token contains the +** the expression is a variable (TK_VARIABLE), then Expr.token contains the ** variable name. Finally, if the expression is an SQL function (TK_FUNCTION), ** then Expr.token contains the name of the function. ** @@ -9110,7 +10247,7 @@ typedef int ynVar; ** a CASE expression or an IN expression of the form "<lhs> IN (<y>, <z>...)". ** Expr.x.pSelect is used if the expression is a sub-select or an expression of ** the form "<lhs> IN (SELECT ...)". If the EP_xIsSelect bit is set in the -** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is +** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is ** valid. ** ** An expression of the form ID or ID.ID refers to a column in a table. @@ -9121,8 +10258,8 @@ typedef int ynVar; ** value is also stored in the Expr.iAgg column in the aggregate so that ** it can be accessed after all aggregates are computed. ** -** If the expression is an unbound variable marker (a question mark -** character '?' in the original SQL) then the Expr.iTable holds the index +** If the expression is an unbound variable marker (a question mark +** character '?' in the original SQL) then the Expr.iTable holds the index ** number for that variable. ** ** If the expression is a subquery then Expr.iColumn holds an integer @@ -9156,12 +10293,12 @@ struct Expr { u16 flags; /* Various flags. EP_* See below */ union { char *zToken; /* Token value. Zero terminated and dequoted */ - int iValue; /* Integer value if EP_IntValue */ + int iValue; /* Non-negative integer value if EP_IntValue */ } u; /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no ** space is allocated for the fields below this point. An attempt to - ** access them will result in a segfault or malfunction. + ** access them will result in a segfault or malfunction. *********************************************************************/ Expr *pLeft; /* Left subnode */ @@ -9232,7 +10369,7 @@ struct Expr { #endif /* -** These macros can be used to test, set, or clear bits in the +** These macros can be used to test, set, or clear bits in the ** Expr.flags field. */ #define ExprHasProperty(E,P) (((E)->flags&(P))==(P)) @@ -9241,8 +10378,8 @@ struct Expr { #define ExprClearProperty(E,P) (E)->flags&=~(P) /* -** Macros to determine the number of bytes required by a normal Expr -** struct, an Expr struct with the EP_Reduced flag set in Expr.flags +** Macros to determine the number of bytes required by a normal Expr +** struct, an Expr struct with the EP_Reduced flag set in Expr.flags ** and an Expr struct with the EP_TokenOnly flag set. */ #define EXPR_FULLSIZE sizeof(Expr) /* Full size */ @@ -9250,7 +10387,7 @@ struct Expr { #define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */ /* -** Flags passed to the sqlite3ExprDup() function. See the header comment +** Flags passed to the sqlite3ExprDup() function. See the header comment ** above sqlite3ExprDup() for details. */ #define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */ @@ -9342,6 +10479,9 @@ typedef u64 Bitmask; ** 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 { i16 nSrc; /* Number of tables or subqueries in the FROM clause */ @@ -9352,9 +10492,14 @@ struct SrcList { char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ Table *pTab; /* An SQL table corresponding to zName */ Select *pSelect; /* A SELECT statement used in place of a table name */ - u8 isPopulated; /* Temporary table associated with SELECT is populated */ + int addrFillSub; /* Address of subroutine to manifest a subquery */ + int regReturn; /* Register holding return address of addrFillSub */ u8 jointype; /* Type of join between this able and the previous */ u8 notIndexed; /* True if there is a NOT INDEXED clause */ + u8 isCorrelated; /* True if sub-query is correlated */ +#ifndef SQLITE_OMIT_EXPLAIN + u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */ +#endif int iCursor; /* The VDBE cursor number used to access this table */ Expr *pOn; /* The ON clause of a join */ IdList *pUsing; /* The USING clause of a join */ @@ -9393,6 +10538,7 @@ struct SrcList { struct WherePlan { u32 wsFlags; /* WHERE_* flags that describe the strategy */ u32 nEq; /* Number of == constraints */ + double nRow; /* Estimated number of rows (for EQP) */ union { Index *pIdx; /* Index when WHERE_INDEXED is true */ struct WhereTerm *pTerm; /* WHERE clause term for OR-search */ @@ -9453,7 +10599,7 @@ struct WhereLevel { #define WHERE_ORDERBY_MAX 0x0002 /* ORDER BY processing for max() func */ #define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */ #define WHERE_DUPLICATES_OK 0x0008 /* Ok to return a row more than once */ -#define WHERE_OMIT_OPEN 0x0010 /* Table cursor are already open */ +#define WHERE_OMIT_OPEN 0x0010 /* Table cursors are already open */ #define WHERE_OMIT_CLOSE 0x0020 /* Omit close of table & index cursors */ #define WHERE_FORCE_TABLE 0x0040 /* Do not use an index-only search */ #define WHERE_ONETABLE_ONLY 0x0080 /* Only code the 1st table in pTabList */ @@ -9470,15 +10616,21 @@ struct WhereInfo { u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE or DELETE */ u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ + u8 eDistinct; SrcList *pTabList; /* List of tables in the join */ int iTop; /* The very beginning of the WHERE loop */ int iContinue; /* Jump here to continue with next record */ int iBreak; /* Jump here to break out of the loop */ int nLevel; /* Number of nested loop */ struct WhereClause *pWC; /* Decomposition of the WHERE clause */ + double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ + double nRowOut; /* Estimated number of output rows */ WhereLevel a[1]; /* Information about each nest loop in WHERE */ }; +#define WHERE_DISTINCT_UNIQUE 1 +#define WHERE_DISTINCT_ORDERED 2 + /* ** A NameContext defines a context in which to resolve table and column ** names. The context consists of a list of tables (the pSrcList) field and @@ -9488,12 +10640,12 @@ struct WhereInfo { ** pEList corresponds to the result set of a SELECT and is NULL for ** other statements. ** -** NameContexts can be nested. When resolving names, the inner-most +** NameContexts can be nested. When resolving names, the inner-most ** context is searched first. If no match is found, the next outer ** context is checked. If there is still no match, the next context ** is checked. This process continues until either a match is found ** or all contexts are check. When a match is found, the nRef member of -** the context containing the match is incremented. +** the context containing the match is incremented. ** ** Each subquery gets a new NameContext. The pNext field points to the ** NameContext in the parent query. Thus the process of scanning the @@ -9551,6 +10703,7 @@ struct Select { Expr *pOffset; /* OFFSET expression. NULL means not used. */ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */ + double nSelectRow; /* Estimated number of result rows */ }; /* @@ -9563,6 +10716,7 @@ struct Select { #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ +#define SF_UseSorter 0x0040 /* Sort using a sorter */ /* @@ -9598,7 +10752,7 @@ struct SelectDest { }; /* -** During code generation of statements that do inserts into AUTOINCREMENT +** During code generation of statements that do inserts into AUTOINCREMENT ** tables, the following information is attached to the Table.u.autoInc.p ** pointer of each autoincrement table to record some side information that ** the code generator needs. We have to keep per-table autoincrement @@ -9621,7 +10775,7 @@ struct AutoincInfo { #endif /* -** At least one instance of the following structure is created for each +** At least one instance of the following structure is created for each ** trigger that may be fired while parsing an INSERT, UPDATE or DELETE ** statement. All such objects are stored in the linked list headed at ** Parse.pTriggerPrg and deleted once statement compilation has been @@ -9634,7 +10788,7 @@ struct AutoincInfo { ** values for both pTrigger and orconf. ** ** The TriggerPrg.aColmask[0] variable is set to a mask of old.* columns -** accessed (or set to 0 for triggers fired as a result of INSERT +** accessed (or set to 0 for triggers fired as a result of INSERT ** statements). Similarly, the TriggerPrg.aColmask[1] variable is set to ** a mask of new.* columns used by the program. */ @@ -9647,6 +10801,15 @@ struct TriggerPrg { }; /* +** The yDbMask datatype for the bitmask of all attached databases. +*/ +#if SQLITE_MAX_ATTACHED>30 + typedef sqlite3_uint64 yDbMask; +#else + typedef unsigned int yDbMask; +#endif + +/* ** An SQL parser context. A copy of this structure is passed through ** the parser and down into all the parser action routine in order to ** carry around information that is global to the entire parse. @@ -9656,7 +10819,7 @@ struct TriggerPrg { ** is constant but the second part is reset at the beginning and end of ** each recursion. ** -** The nTableLock and aTableLock variables are only used if the shared-cache +** The nTableLock and aTableLock variables are only used if the shared-cache ** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are ** used to store the set of table-locks required by the statement being ** compiled. Function sqlite3TableLock() is used to add entries to the @@ -9694,8 +10857,8 @@ struct Parse { int iReg; /* Reg with value of this column. 0 means none. */ int lru; /* Least recently used entry has the smallest value */ } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ - u32 writeMask; /* Start a write transaction on these databases */ - u32 cookieMask; /* Bitmask of schema verified databases */ + yDbMask writeMask; /* Start a write transaction on these databases */ + yDbMask cookieMask; /* Bitmask of schema verified databases */ u8 isMultiWrite; /* True if statement may affect/insert multiple rows */ u8 mayAbort; /* True if statement may throw an ABORT exception */ int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ @@ -9717,14 +10880,14 @@ struct Parse { u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ + double nQueryLoop; /* Estimated number of iterations of a query */ /* Above is constant between recursions. Below is reset before and after ** each recursion */ int nVar; /* Number of '?' variables seen in the SQL so far */ - int nVarExpr; /* Number of used slots in apVarExpr[] */ - int nVarExprAlloc; /* Number of allocated slots in apVarExpr[] */ - Expr **apVarExpr; /* Pointers to :aaa and $aaaa wildcard expressions */ + int nzVar; /* Number of available slots in azVar[] */ + char **azVar; /* Pointers to names of parameters */ Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ int nAlias; /* Number of aliased result set columns */ int nAliasAlloc; /* Number of allocated slots for aAlias[] */ @@ -9745,6 +10908,11 @@ struct Parse { int nHeight; /* Expression tree height of current sub-select */ Table *pZombieTab; /* List of Table objects to delete after code gen */ TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ + +#ifndef SQLITE_OMIT_EXPLAIN + int iSelectId; + int iNextSelectId; +#endif }; #ifdef SQLITE_OMIT_VIRTUALTABLE @@ -9774,10 +10942,10 @@ struct AuthContext { /* * Each trigger present in the database schema is stored as an instance of - * struct Trigger. + * struct Trigger. * * Pointers to instances of struct Trigger are stored in two ways. - * 1. In the "trigHash" hash table (part of the sqlite3* that represents the + * 1. In the "trigHash" hash table (part of the sqlite3* that represents the * database). This allows Trigger structures to be retrieved by name. * 2. All triggers associated with a single table form a linked list, using the * pNext member of struct Trigger. A pointer to the first element of the @@ -9803,7 +10971,7 @@ struct Trigger { /* ** A trigger is either a BEFORE or an AFTER trigger. The following constants -** determine which. +** determine which. ** ** If there are multiple triggers, you might of some BEFORE and some AFTER. ** In that cases, the constants below can be ORed together. @@ -9813,15 +10981,15 @@ struct Trigger { /* * An instance of struct TriggerStep is used to store a single SQL statement - * that is a part of a trigger-program. + * that is a part of a trigger-program. * * Instances of struct TriggerStep are stored in a singly linked list (linked - * using the "pNext" member) referenced by the "step_list" member of the + * using the "pNext" member) referenced by the "step_list" member of the * associated struct Trigger instance. The first element of the linked list is * the first step of the trigger-program. - * + * * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or - * "SELECT" statement. The meanings of the other members is determined by the + * "SELECT" statement. The meanings of the other members is determined by the * value of "op" as follows: * * (op == TK_INSERT) @@ -9831,7 +10999,7 @@ struct Trigger { * target -> A token holding the quoted name of the table to insert into. * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then * this stores values to be inserted. Otherwise NULL. - * pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ... + * pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ... * statement, then this stores the column-names to be * inserted into. * @@ -9839,7 +11007,7 @@ struct Trigger { * target -> A token holding the quoted name of the table to delete from. * pWhere -> The WHERE clause of the DELETE statement if one is specified. * Otherwise NULL. - * + * * (op == TK_UPDATE) * target -> A token holding the quoted name of the table to update rows of. * pWhere -> The WHERE clause of the UPDATE statement if one is specified. @@ -9847,7 +11015,7 @@ struct Trigger { * pExprList -> A list of the columns to update and the expressions to update * them to. See sqlite3Update() documentation of "pChanges" * argument. - * + * */ struct TriggerStep { u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */ @@ -9865,7 +11033,7 @@ struct TriggerStep { /* ** The following structure contains information used by the sqliteFix... ** routines as they walk the parse tree to make database references -** explicit. +** explicit. */ typedef struct DbFixer DbFixer; struct DbFixer { @@ -9887,7 +11055,7 @@ struct StrAccum { int nAlloc; /* Amount of space allocated in zText */ int mxAlloc; /* Maximum allowed string length */ u8 mallocFailed; /* Becomes true if any memory allocation fails */ - u8 useMalloc; /* True if zText is enlargeable using realloc */ + u8 useMalloc; /* 0: none, 1: sqlite3DbMalloc, 2: sqlite3_malloc */ u8 tooBig; /* Becomes true if string size exceeds limits */ }; @@ -9911,6 +11079,7 @@ struct Sqlite3Config { int bMemstat; /* True to enable memory status */ int bCoreMutex; /* True to enable core mutexing */ int bFullMutex; /* True to enable full mutexing */ + int bOpenUri; /* True to interpret filenames as URIs */ int mxStrlen; /* Maximum string length */ int szLookaside; /* Default lookaside buffer size */ int nLookaside; /* Default lookaside buffer count */ @@ -9939,6 +11108,7 @@ struct Sqlite3Config { int nRefInitMutex; /* Number of users of pInitMutex */ void (*xLog)(void*,int,const char*); /* Function for logging */ void *pLogArg; /* First argument to xLog() */ + int bLocaltimeFault; /* True to fail localtime() calls */ }; /* @@ -10039,7 +11209,6 @@ SQLITE_PRIVATE int sqlite3CantopenError(int); ** Internal function prototypes */ SQLITE_PRIVATE int sqlite3StrICmp(const char *, const char *); -SQLITE_PRIVATE int sqlite3IsNumber(const char*, int*, u8); SQLITE_PRIVATE int sqlite3Strlen30(const char*); #define sqlite3StrNICmp sqlite3_strnicmp @@ -10063,7 +11232,7 @@ SQLITE_PRIVATE void *sqlite3PageMalloc(int); SQLITE_PRIVATE void sqlite3PageFree(void*); SQLITE_PRIVATE void sqlite3MemSetDefault(void); SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void)); -SQLITE_PRIVATE int sqlite3MemoryAlarm(void (*)(void*, sqlite3_int64, int), void*, sqlite3_int64); +SQLITE_PRIVATE int sqlite3HeapNearlyFull(void); /* ** On systems with ample stack space and that support alloca(), make @@ -10076,7 +11245,7 @@ SQLITE_PRIVATE int sqlite3MemoryAlarm(void (*)(void*, sqlite3_int64, int), void* #ifdef SQLITE_USE_ALLOCA # define sqlite3StackAllocRaw(D,N) alloca(N) # define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N) -# define sqlite3StackFree(D,P) +# define sqlite3StackFree(D,P) #else # define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N) # define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N) @@ -10092,7 +11261,8 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void); #ifndef SQLITE_MUTEX_OMIT -SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void); +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void); +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void); SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int); SQLITE_PRIVATE int sqlite3MutexInit(void); SQLITE_PRIVATE int sqlite3MutexEnd(void); @@ -10160,6 +11330,8 @@ SQLITE_PRIVATE void sqlite3AddColumnType(Parse*,Token*); SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*); SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,Select*); +SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, + sqlite3_vfs**,char**,char **); SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32); SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32); @@ -10184,7 +11356,7 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*); #endif SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); -SQLITE_PRIVATE void sqlite3DeleteTable(Table*); +SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); #ifndef SQLITE_OMIT_AUTOINCREMENT SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse); @@ -10221,9 +11393,10 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, E #endif SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); -SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**, u16); +SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**,ExprList*,u16); SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int); +SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int); @@ -10232,7 +11405,6 @@ SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*, int); SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int); SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*); SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int); -SQLITE_PRIVATE void sqlite3ExprHardCopy(Parse*,int,int); SQLITE_PRIVATE int sqlite3ExprCode(Parse*, Expr*, int); SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*); SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int); @@ -10250,6 +11422,7 @@ SQLITE_PRIVATE void sqlite3Vacuum(Parse*); SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*); SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*); SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*); +SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*); SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*); @@ -10258,6 +11431,7 @@ SQLITE_PRIVATE void sqlite3PrngRestoreState(void); SQLITE_PRIVATE void sqlite3PrngResetState(void); SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*); SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int); +SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb); SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int); SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*); SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*); @@ -10351,26 +11525,24 @@ SQLITE_PRIVATE int sqlite3AuthReadCol(Parse*, const char *, const char *, int) #endif SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*); SQLITE_PRIVATE void sqlite3Detach(Parse*, Expr*); -SQLITE_PRIVATE int sqlite3BtreeFactory(sqlite3 *db, const char *zFilename, - int omitJournal, int nCache, int flags, Btree **ppBtree); SQLITE_PRIVATE int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*); SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*); SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*); SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*); SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); -SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*); +SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8); SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); -SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *, int); +SQLITE_PRIVATE int sqlite3Atoi(const char*); SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); -SQLITE_PRIVATE int sqlite3Utf8Read(const u8*, const u8**); +SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8*, const u8**); /* ** Routines to read and write variable-length integers. These used to ** be defined locally, but now we use the varint routines in the util.c ** file. Code should use the MACRO forms below, as the Varint32 versions -** are coded to assume the single byte case is already handled (which +** are coded to assume the single byte case is already handled (which ** the MACRO form does). */ SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64); @@ -10407,23 +11579,35 @@ SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *, Table *); SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2); SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); -SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*); +SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...); SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); +SQLITE_PRIVATE u8 sqlite3HexToInt(int h); SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); SQLITE_PRIVATE const char *sqlite3ErrStr(int); SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); -SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Parse *pParse, Expr *, Token *); +SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr*, CollSeq*); +SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*); SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *); SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int); +SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64); +SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64); +SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64); +SQLITE_PRIVATE int sqlite3AbsInt32(int); +#ifdef SQLITE_ENABLE_8_3_NAMES +SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); +#else +# define sqlite3FileSuffix3(X,Y) +#endif +SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z); SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); -SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, +SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*); SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *); @@ -10437,13 +11621,16 @@ SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[]; +SQLITE_PRIVATE const Token sqlite3IntTokens[]; SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config; SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions; +#ifndef SQLITE_OMIT_WSD SQLITE_PRIVATE int sqlite3PendingByte; #endif -SQLITE_PRIVATE void sqlite3RootPageMoved(Db*, int, int); +#endif +SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, int, int); SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*); -SQLITE_PRIVATE void sqlite3AlterFunctions(sqlite3*); +SQLITE_PRIVATE void sqlite3AlterFunctions(void); SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *); SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); @@ -10463,18 +11650,20 @@ SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*); SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*); SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *); SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB); -SQLITE_PRIVATE void sqlite3DeleteIndexSamples(Index*); +SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*); SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*); SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int); SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int); -SQLITE_PRIVATE void sqlite3SchemaFree(void *); +SQLITE_PRIVATE void sqlite3SchemaClear(void *); SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *); SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *); SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *); -SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, +SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, void (*)(sqlite3_context*,int,sqlite3_value **), - void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*)); + void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*), + FuncDestructor *pDestructor +); SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); @@ -10521,17 +11710,19 @@ SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char*); # define sqlite3VtabRollback(X) # define sqlite3VtabCommit(X) # define sqlite3VtabInSync(db) 0 -# define sqlite3VtabLock(X) +# define sqlite3VtabLock(X) # define sqlite3VtabUnlock(X) # define sqlite3VtabUnlockList(X) +# define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK #else -SQLITE_PRIVATE void sqlite3VtabClear(Table*); +SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*); SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **); SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db); SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db); SQLITE_PRIVATE void sqlite3VtabLock(VTable *); SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *); SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*); +SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int); # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) #endif SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*); @@ -10552,12 +11743,15 @@ SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*); SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*); +SQLITE_PRIVATE const char *sqlite3JournalModename(int); +SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); +SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); /* Declarations for functions in fkey.c. All of these are replaced by ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign ** key functionality is available. If OMIT_TRIGGER is defined but ** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In -** this case foreign keys are parsed, but no other functionality is +** this case foreign keys are parsed, but no other functionality is ** provided (enforcement of FK constraints requires the triggers sub-system). */ #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) @@ -10575,9 +11769,9 @@ SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *); #define sqlite3FkRequired(a,b,c,d) 0 #endif #ifndef SQLITE_OMIT_FOREIGN_KEY -SQLITE_PRIVATE void sqlite3FkDelete(Table*); +SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*); #else - #define sqlite3FkDelete(a) + #define sqlite3FkDelete(a,b) #endif @@ -10647,7 +11841,7 @@ SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *); /* ** If the SQLITE_ENABLE IOTRACE exists then the global variable ** sqlite3IoTrace is a pointer to a printf-like routine used to -** print I/O tracing messages. +** print I/O tracing messages. */ #ifdef SQLITE_ENABLE_IOTRACE # define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; } @@ -10658,7 +11852,50 @@ SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*,...); # define sqlite3VdbeIOTraceSql(X) #endif +/* +** These routines are available for the mem2.c debugging memory allocator +** only. They are used to verify that different "types" of memory +** allocations are properly tracked by the system. +** +** sqlite3MemdebugSetType() sets the "type" of an allocation to one of +** the MEMTYPE_* macros defined below. The type must be a bitmask with +** a single bit set. +** +** sqlite3MemdebugHasType() returns true if any of the bits in its second +** argument match the type set by the previous sqlite3MemdebugSetType(). +** sqlite3MemdebugHasType() is intended for use inside assert() statements. +** +** sqlite3MemdebugNoType() returns true if none of the bits in its second +** argument match the type set by the previous sqlite3MemdebugSetType(). +** +** Perhaps the most important point is the difference between MEMTYPE_HEAP +** and MEMTYPE_LOOKASIDE. If an allocation is MEMTYPE_LOOKASIDE, that means +** it might have been allocated by lookaside, except the allocation was +** too large or lookaside was already full. It is important to verify +** that allocations that might have been satisfied by lookaside are not +** passed back to non-lookaside free() routines. Asserts such as the +** example above are placed on the non-lookaside free() routines to verify +** this constraint. +** +** All of this is no-op for a production build. It only comes into +** play when the SQLITE_MEMDEBUG compile-time option is used. +*/ +#ifdef SQLITE_MEMDEBUG +SQLITE_PRIVATE void sqlite3MemdebugSetType(void*,u8); +SQLITE_PRIVATE int sqlite3MemdebugHasType(void*,u8); +SQLITE_PRIVATE int sqlite3MemdebugNoType(void*,u8); +#else +# define sqlite3MemdebugSetType(X,Y) /* no-op */ +# define sqlite3MemdebugHasType(X,Y) 1 +# define sqlite3MemdebugNoType(X,Y) 1 #endif +#define MEMTYPE_HEAP 0x01 /* General heap allocations */ +#define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */ +#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ +#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ +#define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */ + +#endif /* _SQLITEINT_H_ */ /************** End of sqliteInt.h *******************************************/ /************** Begin file global.c ******************************************/ @@ -10678,7 +11915,7 @@ SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*,...); */ /* An array to map all upper-case characters into their corresponding -** lower-case character. +** lower-case character. ** ** SQLite only considers US-ASCII (or EBCDIC) characters. We do not ** handle case conversions for the UTF character set since the tables @@ -10744,7 +11981,7 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = { ** Standard function tolower() is implemented using the sqlite3UpperToLower[] ** array. tolower() is used more often than toupper() by SQLite. ** -** Bit 0x40 is set if the character non-alphanumeric and can be used in an +** Bit 0x40 is set if the character non-alphanumeric and can be used in an ** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any ** non-ASCII UTF character. Hence the test for whether or not a character is ** part of an identifier is 0x46. @@ -10792,7 +12029,9 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = { }; #endif - +#ifndef SQLITE_USE_URI +# define SQLITE_USE_URI 0 +#endif /* ** The following singleton contains the global configuration for @@ -10802,8 +12041,9 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ 1, /* bCoreMutex */ SQLITE_THREADSAFE==1, /* bFullMutex */ + SQLITE_USE_URI, /* bOpenUri */ 0x7ffffffe, /* mxStrlen */ - 100, /* szLookaside */ + 128, /* szLookaside */ 500, /* nLookaside */ {0,0,0,0,0,0,0,0}, /* m */ {0,0,0,0,0,0,0,0,0}, /* mutex */ @@ -10829,6 +12069,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, /* nRefInitMutex */ 0, /* xLog */ 0, /* pLogArg */ + 0, /* bLocaltimeFault */ }; @@ -10840,6 +12081,15 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions; /* +** Constant tokens for values 0 and 1. +*/ +SQLITE_PRIVATE const Token sqlite3IntTokens[] = { + { "0", 1 }, + { "1", 1 } +}; + + +/* ** The value of the "pending" byte must be 0x40000000 (1 byte past the ** 1-gibabyte boundary) in a compatible database. SQLite never uses ** the database page that contains the pending byte. It never attempts @@ -10857,13 +12107,15 @@ SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions; ** Changing the pending byte during operating results in undefined ** and dileterious behavior. */ +#ifndef SQLITE_OMIT_WSD SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000; +#endif /* ** Properties of opcodes. The OPFLG_INITIALIZER macro is ** created by mkopcodeh.awk during compilation. Data is obtained ** from the comments following the "case OP_xxxx:" statements in -** the vdbe.c file. +** the vdbe.c file. */ SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER; @@ -10889,7 +12141,7 @@ SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER; /* -** An array of names of all compile-time options. This array should +** An array of names of all compile-time options. This array should ** be sorted A-Z. ** ** This array looks large, but in a typical installation actually uses @@ -11014,6 +12266,9 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_LOCK_TRACE "LOCK_TRACE", #endif +#ifdef SQLITE_MAX_SCHEMA_RETRY + "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), +#endif #ifdef SQLITE_MEMDEBUG "MEMDEBUG", #endif @@ -11041,6 +12296,12 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_OMIT_AUTOINIT "OMIT_AUTOINIT", #endif +#ifdef SQLITE_OMIT_AUTOMATIC_INDEX + "OMIT_AUTOMATIC_INDEX", +#endif +#ifdef SQLITE_OMIT_AUTORESET + "OMIT_AUTORESET", +#endif #ifdef SQLITE_OMIT_AUTOVACUUM "OMIT_AUTOVACUUM", #endif @@ -11062,9 +12323,11 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_OMIT_CHECK "OMIT_CHECK", #endif -#ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS - "OMIT_COMPILEOPTION_DIAGS", -#endif +/* // redundant +** #ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS +** "OMIT_COMPILEOPTION_DIAGS", +** #endif +*/ #ifdef SQLITE_OMIT_COMPLETE "OMIT_COMPLETE", #endif @@ -11098,9 +12361,6 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_OMIT_GET_TABLE "OMIT_GET_TABLE", #endif -#ifdef SQLITE_OMIT_GLOBALRECOVER - "OMIT_GLOBALRECOVER", -#endif #ifdef SQLITE_OMIT_INCRBLOB "OMIT_INCRBLOB", #endif @@ -11122,6 +12382,9 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_OMIT_MEMORYDB "OMIT_MEMORYDB", #endif +#ifdef SQLITE_OMIT_MERGE_SORT + "OMIT_MERGE_SORT", +#endif #ifdef SQLITE_OMIT_OR_OPTIMIZATION "OMIT_OR_OPTIMIZATION", #endif @@ -11179,12 +12442,18 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_OMIT_VIRTUALTABLE "OMIT_VIRTUALTABLE", #endif +#ifdef SQLITE_OMIT_WAL + "OMIT_WAL", +#endif #ifdef SQLITE_OMIT_WSD "OMIT_WSD", #endif #ifdef SQLITE_OMIT_XFER_OPT "OMIT_XFER_OPT", #endif +#ifdef SQLITE_PAGECACHE_BLOCKALLOC + "PAGECACHE_BLOCKALLOC", +#endif #ifdef SQLITE_PERFORMANCE_TRACE "PERFORMANCE_TRACE", #endif @@ -11271,14 +12540,467 @@ SQLITE_API const char *sqlite3_compileoption_get(int N){ ** This module implements the sqlite3_status() interface and related ** functionality. */ +/************** Include vdbeInt.h in the middle of status.c ******************/ +/************** Begin file vdbeInt.h *****************************************/ +/* +** 2003 September 6 +** +** 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 is the header file for information that is private to the +** VDBE. This information used to all be at the top of the single +** source code file "vdbe.c". When that file became too big (over +** 6000 lines long) it was split up into several smaller files and +** this header information was factored out. +*/ +#ifndef _VDBEINT_H_ +#define _VDBEINT_H_ + +/* +** SQL is translated into a sequence of instructions to be +** executed by a virtual machine. Each instruction is an instance +** of the following structure. +*/ +typedef struct VdbeOp Op; + +/* +** Boolean values +*/ +typedef unsigned char Bool; + +/* Opaque type used by code in vdbesort.c */ +typedef struct VdbeSorter VdbeSorter; + +/* +** A cursor is a pointer into a single BTree within a database file. +** The cursor can seek to a BTree entry with a particular key, or +** loop over all entries of the Btree. You can also insert new BTree +** entries or retrieve the key or data from the entry that the cursor +** is currently pointing to. +** +** Every cursor that the virtual machine has open is represented by an +** instance of the following structure. +*/ +struct VdbeCursor { + BtCursor *pCursor; /* The cursor structure of the backend */ + Btree *pBt; /* Separate file holding temporary table */ + KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ + int iDb; /* Index of cursor database in db->aDb[] (or -1) */ + int pseudoTableReg; /* Register holding pseudotable content. */ + int nField; /* Number of fields in the header */ + Bool zeroed; /* True if zeroed out and ready for reuse */ + Bool rowidIsValid; /* True if lastRowid is valid */ + Bool atFirst; /* True if pointing to first entry */ + Bool useRandomRowid; /* Generate new record numbers semi-randomly */ + Bool nullRow; /* True if pointing to a row with no data */ + Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ + Bool isTable; /* True if a table requiring integer keys */ + Bool isIndex; /* True if an index containing keys only - no data */ + Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */ + Bool isSorter; /* True if a new-style sorter */ + sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ + const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ + i64 seqCount; /* Sequence counter */ + i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ + i64 lastRowid; /* Last rowid from a Next or NextIdx operation */ + VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ + + /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or + ** OP_IsUnique opcode on this cursor. */ + int seekResult; + + /* Cached information about the header for the data record that the + ** cursor is currently pointing to. Only valid if cacheStatus matches + ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of + ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that + ** the cache is out of date. + ** + ** aRow might point to (ephemeral) data for the current row, or it might + ** be NULL. + */ + u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ + int payloadSize; /* Total number of bytes in the record */ + u32 *aType; /* Type values for all entries in the record */ + u32 *aOffset; /* Cached offsets to the start of each columns data */ + u8 *aRow; /* Data for the current row, if all on one page */ +}; +typedef struct VdbeCursor VdbeCursor; + +/* +** When a sub-program is executed (OP_Program), a structure of this type +** is allocated to store the current value of the program counter, as +** well as the current memory cell array and various other frame specific +** values stored in the Vdbe struct. When the sub-program is finished, +** these values are copied back to the Vdbe from the VdbeFrame structure, +** restoring the state of the VM to as it was before the sub-program +** began executing. +** +** The memory for a VdbeFrame object is allocated and managed by a memory +** cell in the parent (calling) frame. When the memory cell is deleted or +** overwritten, the VdbeFrame object is not freed immediately. Instead, it +** is linked into the Vdbe.pDelFrame list. The contents of the Vdbe.pDelFrame +** list is deleted when the VM is reset in VdbeHalt(). The reason for doing +** this instead of deleting the VdbeFrame immediately is to avoid recursive +** calls to sqlite3VdbeMemRelease() when the memory cells belonging to the +** child frame are released. +** +** The currently executing frame is stored in Vdbe.pFrame. Vdbe.pFrame is +** set to NULL if the currently executing frame is the main program. +*/ +typedef struct VdbeFrame VdbeFrame; +struct VdbeFrame { + Vdbe *v; /* VM this frame belongs to */ + int pc; /* Program Counter in parent (calling) frame */ + Op *aOp; /* Program instructions for parent frame */ + int nOp; /* Size of aOp array */ + Mem *aMem; /* Array of memory cells for parent frame */ + int nMem; /* Number of entries in aMem */ + VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ + u16 nCursor; /* Number of entries in apCsr */ + void *token; /* Copy of SubProgram.token */ + int nChildMem; /* Number of memory cells for child frame */ + int nChildCsr; /* Number of cursors for child frame */ + i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ + int nChange; /* Statement changes (Vdbe.nChanges) */ + VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */ +}; + +#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))]) + +/* +** A value for VdbeCursor.cacheValid that means the cache is always invalid. +*/ +#define CACHE_STALE 0 + +/* +** Internally, the vdbe manipulates nearly all SQL values as Mem +** structures. Each Mem struct may cache multiple representations (string, +** integer etc.) of the same value. +*/ +struct Mem { + sqlite3 *db; /* The associated database connection */ + char *z; /* String or BLOB value */ + double r; /* Real value */ + union { + i64 i; /* Integer value used when MEM_Int is set in flags */ + int nZero; /* Used when bit MEM_Zero is set in flags */ + FuncDef *pDef; /* Used only when flags==MEM_Agg */ + RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ + VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ + } u; + int n; /* Number of characters in string value, excluding '\0' */ + u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ + u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */ + u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ +#ifdef SQLITE_DEBUG + Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ + void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */ +#endif + void (*xDel)(void *); /* If not null, call this function to delete Mem.z */ + char *zMalloc; /* Dynamic buffer allocated by sqlite3_malloc() */ +}; + +/* One or more of the following flags are set to indicate the validOK +** representations of the value stored in the Mem struct. +** +** If the MEM_Null flag is set, then the value is an SQL NULL value. +** No other flags may be set in this case. +** +** If the MEM_Str flag is set then Mem.z points at a string representation. +** Usually this is encoded in the same unicode encoding as the main +** database (see below for exceptions). If the MEM_Term flag is also +** set, then the string is nul terminated. The MEM_Int and MEM_Real +** flags may coexist with the MEM_Str flag. +*/ +#define MEM_Null 0x0001 /* Value is NULL */ +#define MEM_Str 0x0002 /* Value is a string */ +#define MEM_Int 0x0004 /* Value is an integer */ +#define MEM_Real 0x0008 /* Value is a real number */ +#define MEM_Blob 0x0010 /* Value is a BLOB */ +#define MEM_RowSet 0x0020 /* Value is a RowSet object */ +#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ +#define MEM_Invalid 0x0080 /* Value is undefined */ +#define MEM_TypeMask 0x00ff /* Mask of type bits */ + +/* Whenever Mem contains a valid string or blob representation, one of +** the following flags must be set to determine the memory management +** policy for Mem.z. The MEM_Term flag tells us whether or not the +** string is \000 or \u0000 terminated +*/ +#define MEM_Term 0x0200 /* String rep is nul terminated */ +#define MEM_Dyn 0x0400 /* Need to call sqliteFree() on Mem.z */ +#define MEM_Static 0x0800 /* Mem.z points to a static string */ +#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */ +#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */ +#define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */ +#ifdef SQLITE_OMIT_INCRBLOB + #undef MEM_Zero + #define MEM_Zero 0x0000 +#endif + +/* +** Clear any existing type flags from a Mem and replace them with f +*/ +#define MemSetTypeFlag(p, f) \ + ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f) + +/* +** Return true if a memory cell is not marked as invalid. This macro +** is for use inside assert() statements only. +*/ +#ifdef SQLITE_DEBUG +#define memIsValid(M) ((M)->flags & MEM_Invalid)==0 +#endif + + +/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains +** additional information about auxiliary information bound to arguments +** of the function. This is used to implement the sqlite3_get_auxdata() +** and sqlite3_set_auxdata() APIs. The "auxdata" is some auxiliary data +** that can be associated with a constant argument to a function. This +** allows functions such as "regexp" to compile their constant regular +** expression argument once and reused the compiled code for multiple +** invocations. +*/ +struct VdbeFunc { + FuncDef *pFunc; /* The definition of the function */ + int nAux; /* Number of entries allocated for apAux[] */ + struct AuxData { + void *pAux; /* Aux data for the i-th argument */ + void (*xDelete)(void *); /* Destructor for the aux data */ + } apAux[1]; /* One slot for each function argument */ +}; + +/* +** The "context" argument for a installable function. A pointer to an +** instance of this structure is the first argument to the routines used +** implement the SQL functions. +** +** There is a typedef for this structure in sqlite.h. So all routines, +** even the public interface to SQLite, can use a pointer to this structure. +** But this file is the only place where the internal details of this +** structure are known. +** +** This structure is defined inside of vdbeInt.h because it uses substructures +** (Mem) which are only defined there. +*/ +struct sqlite3_context { + FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */ + VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */ + Mem s; /* The return value is stored here */ + Mem *pMem; /* Memory cell used to store aggregate context */ + int isError; /* Error code returned by the function. */ + CollSeq *pColl; /* Collating sequence */ +}; + +/* +** An instance of the virtual machine. This structure contains the complete +** state of the virtual machine. +** +** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare() +** is really a pointer to an instance of this structure. +** +** The Vdbe.inVtabMethod variable is set to non-zero for the duration of +** any virtual table method invocations made by the vdbe program. It is +** set to 2 for xDestroy method calls and 1 for all other methods. This +** variable is used for two purposes: to allow xDestroy methods to execute +** "DROP TABLE" statements and to prevent some nasty side effects of +** malloc failure when SQLite is invoked recursively by a virtual table +** method function. +*/ +struct Vdbe { + sqlite3 *db; /* The database connection that owns this statement */ + Op *aOp; /* Space to hold the virtual machine's program */ + Mem *aMem; /* The memory locations */ + Mem **apArg; /* Arguments to currently executing user function */ + Mem *aColName; /* Column names to return */ + Mem *pResultSet; /* Pointer to an array of results */ + int nMem; /* Number of memory locations currently allocated */ + int nOp; /* Number of instructions in the program */ + int nOpAlloc; /* Number of slots allocated for aOp[] */ + int nLabel; /* Number of labels used */ + int nLabelAlloc; /* Number of slots allocated in aLabel[] */ + int *aLabel; /* Space to hold the labels */ + u16 nResColumn; /* Number of columns in one row of the result set */ + u16 nCursor; /* Number of slots in apCsr[] */ + u32 magic; /* Magic number for sanity checking */ + char *zErrMsg; /* Error message written here */ + Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ + VdbeCursor **apCsr; /* One element of this array for each open cursor */ + Mem *aVar; /* Values for the OP_Variable opcode. */ + char **azVar; /* Name of variables */ + ynVar nVar; /* Number of entries in aVar[] */ + ynVar nzVar; /* Number of entries in azVar[] */ + u32 cacheCtr; /* VdbeCursor row cache generation counter */ + int pc; /* The program counter */ + int rc; /* Value to return */ + u8 errorAction; /* Recovery action to do in case of an error */ + u8 explain; /* True if EXPLAIN present on SQL command */ + u8 changeCntOn; /* True to update the change-counter */ + u8 expired; /* True if the VM needs to be recompiled */ + u8 runOnlyOnce; /* Automatically expire on reset */ + u8 minWriteFileFormat; /* Minimum file format for writable database files */ + u8 inVtabMethod; /* See comments above */ + u8 usesStmtJournal; /* True if uses a statement journal */ + u8 readOnly; /* True for read-only statements */ + u8 isPrepareV2; /* True if prepared with prepare_v2() */ + int nChange; /* Number of db changes made since last reset */ + yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ + yDbMask lockMask; /* Subset of btreeMask that requires a lock */ + int iStatement; /* Statement number (or 0 if has not opened stmt) */ + int aCounter[3]; /* Counters used by sqlite3_stmt_status() */ +#ifndef SQLITE_OMIT_TRACE + i64 startTime; /* Time when query started - used for profiling */ +#endif + i64 nFkConstraint; /* Number of imm. FK constraints this VM */ + i64 nStmtDefCons; /* Number of def. constraints when stmt started */ + char *zSql; /* Text of the SQL statement that generated this */ + void *pFree; /* Free this when deleting the vdbe */ +#ifdef SQLITE_DEBUG + FILE *trace; /* Write an execution trace here, if not NULL */ +#endif + VdbeFrame *pFrame; /* Parent frame */ + VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */ + int nFrame; /* Number of frames in pFrame list */ + u32 expmask; /* Binding to these vars invalidates VM */ + SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ +}; + +/* +** The following are allowed values for Vdbe.magic +*/ +#define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */ +#define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */ +#define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */ +#define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */ + +/* +** Function prototypes +*/ +SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); +void sqliteVdbePopStack(Vdbe*,int); +SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*); +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) +SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*); +#endif +SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); +SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int); +SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int); +SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); +SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int); + +int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); +SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*); +SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *); +SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); +SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int); +SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*); +SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); +SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*)); +SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64); +#ifdef SQLITE_OMIT_FLOATING_POINT +# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64 +#else +SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double); +#endif +SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); +SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); +SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, int); +SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); +SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); +SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*); +SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); +SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p); +#define MemReleaseExt(X) \ + if((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame)) \ + sqlite3VdbeMemReleaseExternal(X); +SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); +SQLITE_PRIVATE const char *sqlite3OpcodeName(int); +SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); +SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); +SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); +SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); +SQLITE_PRIVATE void sqlite3VdbeMemStoreType(Mem *pMem); + +#ifdef SQLITE_OMIT_MERGE_SORT +# define sqlite3VdbeSorterInit(Y,Z) SQLITE_OK +# define sqlite3VdbeSorterWrite(X,Y,Z) SQLITE_OK +# define sqlite3VdbeSorterClose(Y,Z) +# define sqlite3VdbeSorterRowkey(Y,Z) SQLITE_OK +# define sqlite3VdbeSorterRewind(X,Y,Z) SQLITE_OK +# define sqlite3VdbeSorterNext(X,Y,Z) SQLITE_OK +# define sqlite3VdbeSorterCompare(X,Y,Z) SQLITE_OK +#else +SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); +SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); +SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *); +SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *); +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *); +SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, Mem *); +SQLITE_PRIVATE int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *); +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 +SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); +#else +# define sqlite3VdbeEnter(X) +# define sqlite3VdbeLeave(X) +#endif + +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE void sqlite3VdbeMemPrepareToChange(Vdbe*,Mem*); +#endif + +#ifndef SQLITE_OMIT_FOREIGN_KEY +SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int); +#else +# define sqlite3VdbeCheckFk(p,i) 0 +#endif + +SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf); +#endif +SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem); + +#ifndef SQLITE_OMIT_INCRBLOB +SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *); +#else + #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK +#endif + +#endif /* !defined(_VDBEINT_H_) */ + +/************** End of vdbeInt.h *********************************************/ +/************** Continuing where we left off in status.c *********************/ /* ** Variables in which to record status information. */ typedef struct sqlite3StatType sqlite3StatType; static SQLITE_WSD struct sqlite3StatType { - int nowValue[9]; /* Current value */ - int mxValue[9]; /* Maximum value */ + int nowValue[10]; /* Current value */ + int mxValue[10]; /* Maximum value */ } sqlite3Stat = { {0,}, {0,} }; @@ -11360,6 +13082,8 @@ SQLITE_API int sqlite3_db_status( int *pHighwater, /* Write high-water mark here */ int resetFlag /* Reset high-water mark if true */ ){ + int rc = SQLITE_OK; /* Return code */ + sqlite3_mutex_enter(db->mutex); switch( op ){ case SQLITE_DBSTATUS_LOOKASIDE_USED: { *pCurrent = db->lookaside.nOut; @@ -11369,11 +13093,115 @@ SQLITE_API int sqlite3_db_status( } break; } + + case SQLITE_DBSTATUS_LOOKASIDE_HIT: + case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE: + case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: { + testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT ); + testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE ); + testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL ); + assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 ); + assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 ); + *pCurrent = 0; + *pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT]; + if( resetFlag ){ + db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0; + } + break; + } + + /* + ** Return an approximation for the amount of memory currently used + ** by all pagers associated with the given database connection. The + ** highwater mark is meaningless and is returned as zero. + */ + case SQLITE_DBSTATUS_CACHE_USED: { + int totalUsed = 0; + int i; + sqlite3BtreeEnterAll(db); + for(i=0; i<db->nDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + Pager *pPager = sqlite3BtreePager(pBt); + totalUsed += sqlite3PagerMemUsed(pPager); + } + } + sqlite3BtreeLeaveAll(db); + *pCurrent = totalUsed; + *pHighwater = 0; + break; + } + + /* + ** *pCurrent gets an accurate estimate of the amount of memory used + ** to store the schema for all databases (main, temp, and any ATTACHed + ** databases. *pHighwater is set to zero. + */ + case SQLITE_DBSTATUS_SCHEMA_USED: { + int i; /* Used to iterate through schemas */ + int nByte = 0; /* Used to accumulate return value */ + + sqlite3BtreeEnterAll(db); + db->pnBytesFreed = &nByte; + for(i=0; i<db->nDb; i++){ + Schema *pSchema = db->aDb[i].pSchema; + if( ALWAYS(pSchema!=0) ){ + HashElem *p; + + nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * ( + pSchema->tblHash.count + + pSchema->trigHash.count + + pSchema->idxHash.count + + pSchema->fkeyHash.count + ); + nByte += sqlite3MallocSize(pSchema->tblHash.ht); + nByte += sqlite3MallocSize(pSchema->trigHash.ht); + nByte += sqlite3MallocSize(pSchema->idxHash.ht); + nByte += sqlite3MallocSize(pSchema->fkeyHash.ht); + + for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){ + sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p)); + } + for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ + sqlite3DeleteTable(db, (Table *)sqliteHashData(p)); + } + } + } + db->pnBytesFreed = 0; + sqlite3BtreeLeaveAll(db); + + *pHighwater = 0; + *pCurrent = nByte; + break; + } + + /* + ** *pCurrent gets an accurate estimate of the amount of memory used + ** to store all prepared statements. + ** *pHighwater is set to zero. + */ + case SQLITE_DBSTATUS_STMT_USED: { + struct Vdbe *pVdbe; /* Used to iterate through VMs */ + int nByte = 0; /* Used to accumulate return value */ + + db->pnBytesFreed = &nByte; + for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ + sqlite3VdbeDeleteObject(db, pVdbe); + } + db->pnBytesFreed = 0; + + *pHighwater = 0; + *pCurrent = nByte; + + break; + } + default: { - return SQLITE_ERROR; + rc = SQLITE_ERROR; } } - return SQLITE_OK; + sqlite3_mutex_leave(db->mutex); + return rc; } /************** End of status.c **********************************************/ @@ -11390,7 +13218,7 @@ SQLITE_API int sqlite3_db_status( ** ************************************************************************* ** This file contains the C functions that implement date and time -** functions for SQLite. +** functions for SQLite. ** ** There is only one exported symbol in this file - the function ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. @@ -11399,7 +13227,7 @@ SQLITE_API int sqlite3_db_status( ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon ** in Greenwich on November 24, 4714 B.C. according to the Gregorian -** calendar system. +** calendar system. ** ** 1970-01-01 00:00:00 is JD 2440587.5 ** 2000-01-01 00:00:00 is JD 2451544.5 @@ -11423,26 +13251,12 @@ SQLITE_API int sqlite3_db_status( ** Willmann-Bell, Inc ** Richmond, Virginia (USA) */ +/* #include <stdlib.h> */ +/* #include <assert.h> */ #include <time.h> #ifndef SQLITE_OMIT_DATETIME_FUNCS -/* -** On recent Windows platforms, the localtime_s() function is available -** as part of the "Secure CRT". It is essentially equivalent to -** localtime_r() available under most POSIX platforms, except that the -** order of the parameters is reversed. -** -** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. -** -** If the user has not indicated to use localtime_r() or localtime_s() -** already, check for an MSVC build environment that provides -** localtime_s(). -*/ -#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ - defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) -#define HAVE_LOCALTIME_S 1 -#endif /* ** A structure for holding a single date and time. @@ -11511,12 +13325,6 @@ end_getDigits: } /* -** Read text from z[] and convert into a floating point number. Return -** the number of digits converted. -*/ -#define getValue sqlite3AtoF - -/* ** Parse a timezone extension on the end of a date-time. ** The extension is of the form: ** @@ -11691,10 +13499,8 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ ** Set the time to the current time reported by the VFS */ static void setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ - double r; sqlite3 *db = sqlite3_context_db_handle(context); - sqlite3OsCurrentTime(db->pVfs, &r); - p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); + sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD); p->validJD = 1; } @@ -11705,7 +13511,7 @@ static void setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ ** The following are acceptable forms for the input string: ** ** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM -** DDDD.DD +** DDDD.DD ** now ** ** In the first form, the +/-HH:MM is always optional. The fractional @@ -11715,11 +13521,11 @@ static void setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ ** as there is a year and date. */ static int parseDateOrTime( - sqlite3_context *context, - const char *zDate, + sqlite3_context *context, + const char *zDate, DateTime *p ){ - int isRealNum; /* Return from sqlite3IsNumber(). Not used */ + double r; if( parseYyyyMmDd(zDate,p)==0 ){ return 0; }else if( parseHhMmSs(zDate, p)==0 ){ @@ -11727,9 +13533,7 @@ static int parseDateOrTime( }else if( sqlite3StrICmp(zDate,"now")==0){ setDateTimeToCurrent(context, p); return 0; - }else if( sqlite3IsNumber(zDate, &isRealNum, SQLITE_UTF8) ){ - double r; - getValue(zDate, &r); + }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){ p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); p->validJD = 1; return 0; @@ -11798,15 +13602,85 @@ static void clearYMD_HMS_TZ(DateTime *p){ p->validTZ = 0; } +/* +** On recent Windows platforms, the localtime_s() function is available +** as part of the "Secure CRT". It is essentially equivalent to +** localtime_r() available under most POSIX platforms, except that the +** order of the parameters is reversed. +** +** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. +** +** If the user has not indicated to use localtime_r() or localtime_s() +** already, check for an MSVC build environment that provides +** localtime_s(). +*/ +#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ + defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) +#define HAVE_LOCALTIME_S 1 +#endif + #ifndef SQLITE_OMIT_LOCALTIME /* -** Compute the difference (in milliseconds) -** between localtime and UTC (a.k.a. GMT) -** for the time value p where p is in UTC. +** The following routine implements the rough equivalent of localtime_r() +** using whatever operating-system specific localtime facility that +** is available. This routine returns 0 on success and +** non-zero on any kind of error. +** +** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this +** routine will always fail. */ -static sqlite3_int64 localtimeOffset(DateTime *p){ +static int osLocaltime(time_t *t, struct tm *pTm){ + int rc; +#if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \ + && (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S) + struct tm *pX; +#if SQLITE_THREADSAFE>0 + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); +#endif + sqlite3_mutex_enter(mutex); + pX = localtime(t); +#ifndef SQLITE_OMIT_BUILTIN_TEST + if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0; +#endif + if( pX ) *pTm = *pX; + sqlite3_mutex_leave(mutex); + rc = pX==0; +#else +#ifndef SQLITE_OMIT_BUILTIN_TEST + if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; +#endif +#if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R + rc = localtime_r(t, pTm)==0; +#else + rc = localtime_s(pTm, t); +#endif /* HAVE_LOCALTIME_R */ +#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */ + return rc; +} +#endif /* SQLITE_OMIT_LOCALTIME */ + + +#ifndef SQLITE_OMIT_LOCALTIME +/* +** Compute the difference (in milliseconds) between localtime and UTC +** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs, +** return this value and set *pRc to SQLITE_OK. +** +** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value +** is undefined in this case. +*/ +static sqlite3_int64 localtimeOffset( + DateTime *p, /* Date at which to calculate offset */ + sqlite3_context *pCtx, /* Write error here if one occurs */ + int *pRc /* OUT: Error code. SQLITE_OK or ERROR */ +){ DateTime x, y; time_t t; + struct tm sLocal; + + /* Initialize the contents of sLocal to avoid a compiler warning. */ + memset(&sLocal, 0, sizeof(sLocal)); + x = *p; computeYMD_HMS(&x); if( x.Y<1971 || x.Y>=2038 ){ @@ -11824,47 +13698,23 @@ static sqlite3_int64 localtimeOffset(DateTime *p){ x.validJD = 0; computeJD(&x); t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); -#ifdef HAVE_LOCALTIME_R - { - struct tm sLocal; - localtime_r(&t, &sLocal); - y.Y = sLocal.tm_year + 1900; - y.M = sLocal.tm_mon + 1; - y.D = sLocal.tm_mday; - y.h = sLocal.tm_hour; - y.m = sLocal.tm_min; - y.s = sLocal.tm_sec; - } -#elif defined(HAVE_LOCALTIME_S) && HAVE_LOCALTIME_S - { - struct tm sLocal; - localtime_s(&sLocal, &t); - y.Y = sLocal.tm_year + 1900; - y.M = sLocal.tm_mon + 1; - y.D = sLocal.tm_mday; - y.h = sLocal.tm_hour; - y.m = sLocal.tm_min; - y.s = sLocal.tm_sec; - } -#else - { - struct tm *pTm; - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); - pTm = localtime(&t); - y.Y = pTm->tm_year + 1900; - y.M = pTm->tm_mon + 1; - y.D = pTm->tm_mday; - y.h = pTm->tm_hour; - y.m = pTm->tm_min; - y.s = pTm->tm_sec; - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); + if( osLocaltime(&t, &sLocal) ){ + sqlite3_result_error(pCtx, "local time unavailable", -1); + *pRc = SQLITE_ERROR; + return 0; } -#endif + y.Y = sLocal.tm_year + 1900; + y.M = sLocal.tm_mon + 1; + y.D = sLocal.tm_mday; + y.h = sLocal.tm_hour; + y.m = sLocal.tm_min; + y.s = sLocal.tm_sec; y.validYMD = 1; y.validHMS = 1; y.validJD = 0; y.validTZ = 0; computeJD(&y); + *pRc = SQLITE_OK; return y.iJD - x.iJD; } #endif /* SQLITE_OMIT_LOCALTIME */ @@ -11888,9 +13738,12 @@ static sqlite3_int64 localtimeOffset(DateTime *p){ ** localtime ** utc ** -** Return 0 on success and 1 if there is any kind of error. +** Return 0 on success and 1 if there is any kind of error. If the error +** is in a system call (i.e. localtime()), then an error message is written +** to context pCtx. If the error is an unrecognized modifier, no error is +** written to pCtx. */ -static int parseModifier(const char *zMod, DateTime *p){ +static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ int rc = 1; int n; double r; @@ -11910,9 +13763,8 @@ static int parseModifier(const char *zMod, DateTime *p){ */ if( strcmp(z, "localtime")==0 ){ computeJD(p); - p->iJD += localtimeOffset(p); + p->iJD += localtimeOffset(p, pCtx, &rc); clearYMD_HMS_TZ(p); - rc = 0; } break; } @@ -11933,11 +13785,12 @@ static int parseModifier(const char *zMod, DateTime *p){ else if( strcmp(z, "utc")==0 ){ sqlite3_int64 c1; computeJD(p); - c1 = localtimeOffset(p); - p->iJD -= c1; - clearYMD_HMS_TZ(p); - p->iJD += c1 - localtimeOffset(p); - rc = 0; + c1 = localtimeOffset(p, pCtx, &rc); + if( rc==SQLITE_OK ){ + p->iJD -= c1; + clearYMD_HMS_TZ(p); + p->iJD += c1 - localtimeOffset(p, pCtx, &rc); + } } #endif break; @@ -11950,8 +13803,9 @@ static int parseModifier(const char *zMod, DateTime *p){ ** 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( strncmp(z, "weekday ", 8)==0 && getValue(&z[8],&r)>0 - && (n=(int)r)==r && n>=0 && r<7 ){ + if( strncmp(z, "weekday ", 8)==0 + && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8) + && (n=(int)r)==r && n>=0 && r<7 ){ sqlite3_int64 Z; computeYMD_HMS(p); p->validTZ = 0; @@ -12006,8 +13860,11 @@ static int parseModifier(const char *zMod, DateTime *p){ case '8': case '9': { double rRounder; - n = getValue(z, &r); - assert( n>=1 ); + for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} + if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){ + rc = 1; + break; + } if( z[n]==':' ){ /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the ** specified number of hours, minutes, seconds, and fractional seconds @@ -12092,9 +13949,9 @@ static int parseModifier(const char *zMod, DateTime *p){ ** then assume a default value of "now" for argv[0]. */ static int isDate( - sqlite3_context *context, - int argc, - sqlite3_value **argv, + sqlite3_context *context, + int argc, + sqlite3_value **argv, DateTime *p ){ int i; @@ -12114,9 +13971,8 @@ static int isDate( } } for(i=1; i<argc; i++){ - if( (z = sqlite3_value_text(argv[i]))==0 || parseModifier((char*)z, p) ){ - return 1; - } + z = sqlite3_value_text(argv[i]); + if( z==0 || parseModifier(context, (char*)z, p) ) return 1; } return 0; } @@ -12415,22 +14271,15 @@ static void currentTimeFunc( time_t t; char *zFormat = (char *)sqlite3_user_data(context); sqlite3 *db; - double rT; + sqlite3_int64 iT; char zBuf[20]; UNUSED_PARAMETER(argc); UNUSED_PARAMETER(argv); db = sqlite3_context_db_handle(context); - sqlite3OsCurrentTime(db->pVfs, &rT); -#ifndef SQLITE_OMIT_FLOATING_POINT - t = 86400.0*(rT - 2440587.5) + 0.5; -#else - /* without floating point support, rT will have - ** already lost fractional day precision. - */ - t = 86400 * (rT - 2440587) - 43200; -#endif + sqlite3OsCurrentTimeInt64(db->pVfs, &iT); + t = iT/1000 - 10000*(sqlite3_int64)21086676; #ifdef HAVE_GMTIME_R { struct tm sNow; @@ -12509,7 +14358,7 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ ** So we test the effects of a malloc() failing and the sqlite3OsXXX() ** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro. ** -** The following functions are instrumented for malloc() failure +** The following functions are instrumented for malloc() failure ** testing: ** ** sqlite3OsOpen() @@ -12519,8 +14368,10 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ ** sqlite3OsLock() ** */ -#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0) - #define DO_OS_MALLOC_TEST(x) if (!x || !sqlite3IsMemJournal(x)) { \ +#if defined(SQLITE_TEST) +SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1; + #define DO_OS_MALLOC_TEST(x) \ + if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) { \ void *pTstAlloc = sqlite3Malloc(10); \ if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ sqlite3_free(pTstAlloc); \ @@ -12583,25 +14434,43 @@ SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){ SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ return id->pMethods->xDeviceCharacteristics(id); } +SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){ + return id->pMethods->xShmLock(id, offset, n, flags); +} +SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id){ + id->pMethods->xShmBarrier(id); +} +SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){ + return id->pMethods->xShmUnmap(id, deleteFlag); +} +SQLITE_PRIVATE int sqlite3OsShmMap( + sqlite3_file *id, /* Database file handle */ + int iPage, + int pgsz, + int bExtend, /* True to extend file if necessary */ + void volatile **pp /* OUT: Pointer to mapping */ +){ + return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); +} /* ** The next group of routines are convenience wrappers around the ** VFS methods. */ SQLITE_PRIVATE int sqlite3OsOpen( - sqlite3_vfs *pVfs, - const char *zPath, - sqlite3_file *pFile, - int flags, + sqlite3_vfs *pVfs, + const char *zPath, + sqlite3_file *pFile, + int flags, int *pFlagsOut ){ int rc; DO_OS_MALLOC_TEST(0); - /* 0x7f3f is a mask of SQLITE_OPEN_ flags that are valid to be passed + /* 0x87f3f 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. */ - rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x7f3f, pFlagsOut); + rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut); assert( rc==SQLITE_OK || pFile->pMethods==0 ); return rc; } @@ -12609,18 +14478,18 @@ SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dir return pVfs->xDelete(pVfs, zPath, dirSync); } SQLITE_PRIVATE int sqlite3OsAccess( - sqlite3_vfs *pVfs, - const char *zPath, - int flags, + sqlite3_vfs *pVfs, + const char *zPath, + int flags, int *pResOut ){ DO_OS_MALLOC_TEST(0); return pVfs->xAccess(pVfs, zPath, flags, pResOut); } SQLITE_PRIVATE int sqlite3OsFullPathname( - sqlite3_vfs *pVfs, - const char *zPath, - int nPathOut, + sqlite3_vfs *pVfs, + const char *zPath, + int nPathOut, char *zPathOut ){ zPathOut[0] = 0; @@ -12646,20 +14515,34 @@ SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufO SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ return pVfs->xSleep(pVfs, nMicro); } -SQLITE_PRIVATE int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ - return pVfs->xCurrentTime(pVfs, pTimeOut); +SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ + int rc; + /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64() + ** method to get the current date and time if that method is available + ** (if iVersion is 2 or greater and the function pointer is not NULL) and + ** will fall back to xCurrentTime() if xCurrentTimeInt64() is + ** unavailable. + */ + if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){ + rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut); + }else{ + double r; + rc = pVfs->xCurrentTime(pVfs, &r); + *pTimeOut = (sqlite3_int64)(r*86400000.0); + } + return rc; } SQLITE_PRIVATE int sqlite3OsOpenMalloc( - sqlite3_vfs *pVfs, - const char *zFile, - sqlite3_file **ppFile, + sqlite3_vfs *pVfs, + const char *zFile, + sqlite3_file **ppFile, int flags, int *pOutFlags ){ int rc = SQLITE_NOMEM; sqlite3_file *pFile; - pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile); + pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile); if( pFile ){ rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); if( rc!=SQLITE_OK ){ @@ -12795,17 +14678,17 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ ** ************************************************************************* ** -** This file contains code to support the concept of "benign" +** This file contains code to support the concept of "benign" ** malloc failures (when the xMalloc() or xRealloc() method of the ** sqlite3_mem_methods structure fails to allocate a block of memory -** and returns 0). +** and returns 0). ** ** Most malloc failures are non-benign. After they occur, SQLite ** abandons the current operation and returns an error code (usually ** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily -** fatal. For example, if a malloc fails while resizing a hash table, this -** is completely recoverable simply by not carrying out the resize. The -** hash table will continue to function normally. So a malloc failure +** fatal. For example, if a malloc fails while resizing a hash table, this +** is completely recoverable simply by not carrying out the resize. The +** hash table will continue to function normally. So a malloc failure ** during a hash table resize is a benign fault. */ @@ -13023,7 +14906,7 @@ static int sqlite3MemSize(void *pPrior){ static void *sqlite3MemRealloc(void *pPrior, int nByte){ sqlite3_int64 *p = (sqlite3_int64*)pPrior; assert( pPrior!=0 && nByte>0 ); - nByte = ROUND8(nByte); + assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */ p--; p = realloc(p, nByte+8 ); if( p ){ @@ -13123,6 +15006,7 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){ # define backtrace(A,B) 1 # define backtrace_symbols_fd(A,B,C) #endif +/* #include <stdio.h> */ /* ** Each memory allocation looks like this: @@ -13142,7 +15026,8 @@ struct MemBlockHdr { struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */ char nBacktrace; /* Number of backtraces on this alloc */ char nBacktraceSlots; /* Available backtrace slots */ - short nTitle; /* Bytes of title; includes '\0' */ + u8 nTitle; /* Bytes of title; includes '\0' */ + u8 eType; /* Allocation type code */ int iForeGuard; /* Guard word for sanity */ }; @@ -13164,7 +15049,7 @@ struct MemBlockHdr { ** when this module is combined with other in the amalgamation. */ static struct { - + /* ** Mutex to control access to the memory allocation subsystem. */ @@ -13175,7 +15060,7 @@ static struct { */ struct MemBlockHdr *pFirst; struct MemBlockHdr *pLast; - + /* ** The number of levels of backtrace to save in new allocations. */ @@ -13188,7 +15073,7 @@ static struct { int nTitle; /* Bytes of zTitle to save. Includes '\0' and padding */ char zTitle[100]; /* The title text */ - /* + /* ** sqlite3MallocDisallow() increments the following counter. ** sqlite3MallocAllow() decrements it. */ @@ -13247,7 +15132,7 @@ static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){ pU8 = (u8*)pAllocation; assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD ); /* This checks any of the "extra" bytes allocated due - ** to rounding up to an 8 byte boundary to ensure + ** to rounding up to an 8 byte boundary to ensure ** they haven't been overwritten. */ while( nReserve-- > p->iSize ) assert( pU8[nReserve]==0x65 ); @@ -13350,6 +15235,7 @@ static void *sqlite3MemMalloc(int nByte){ } mem.pLast = pHdr; pHdr->iForeGuard = FOREGUARD; + pHdr->eType = MEMTYPE_HEAP; pHdr->nBacktraceSlots = mem.nBacktrace; pHdr->nTitle = mem.nTitle; if( mem.nBacktrace ){ @@ -13375,7 +15261,7 @@ static void *sqlite3MemMalloc(int nByte){ p = (void*)pInt; } sqlite3_mutex_leave(mem.mutex); - return p; + return p; } /* @@ -13385,7 +15271,7 @@ static void sqlite3MemFree(void *pPrior){ struct MemBlockHdr *pHdr; void **pBt; char *z; - assert( sqlite3GlobalConfig.bMemstat || sqlite3GlobalConfig.bCoreMutex==0 + assert( sqlite3GlobalConfig.bMemstat || sqlite3GlobalConfig.bCoreMutex==0 || mem.mutex!=0 ); pHdr = sqlite3MemsysGetHeader(pPrior); pBt = (void**)pHdr; @@ -13411,15 +15297,15 @@ static void sqlite3MemFree(void *pPrior){ randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + pHdr->iSize + sizeof(int) + pHdr->nTitle); free(z); - sqlite3_mutex_leave(mem.mutex); + sqlite3_mutex_leave(mem.mutex); } /* ** Change the size of an existing memory allocation. ** ** For this debugging implementation, we *always* make a copy of the -** allocation into a new place in memory. In this way, if the -** higher level code is using pointer to the old allocation, it is +** allocation into a new place in memory. In this way, if the +** higher level code is using pointer to the old allocation, it is ** much more likely to break and we are much more liking to find ** the error. */ @@ -13427,6 +15313,7 @@ static void *sqlite3MemRealloc(void *pPrior, int nByte){ struct MemBlockHdr *pOldHdr; void *pNew; assert( mem.disallow==0 ); + assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */ pOldHdr = sqlite3MemsysGetHeader(pPrior); pNew = sqlite3MemMalloc(nByte); if( pNew ){ @@ -13458,6 +15345,62 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){ } /* +** Set the "type" of an allocation. +*/ +SQLITE_PRIVATE void sqlite3MemdebugSetType(void *p, u8 eType){ + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ + struct MemBlockHdr *pHdr; + pHdr = sqlite3MemsysGetHeader(p); + assert( pHdr->iForeGuard==FOREGUARD ); + pHdr->eType = eType; + } +} + +/* +** Return TRUE if the mask of type in eType matches the type of the +** allocation p. Also return true if p==NULL. +** +** This routine is designed for use within an assert() statement, to +** verify the type of an allocation. For example: +** +** assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); +*/ +SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){ + int rc = 1; + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ + struct MemBlockHdr *pHdr; + pHdr = sqlite3MemsysGetHeader(p); + assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ + if( (pHdr->eType&eType)==0 ){ + rc = 0; + } + } + return rc; +} + +/* +** Return TRUE if the mask of type in eType matches no bits of the type of the +** allocation p. Also return true if p==NULL. +** +** This routine is designed for use within an assert() statement, to +** verify the type of an allocation. For example: +** +** assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); +*/ +SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){ + int rc = 1; + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ + struct MemBlockHdr *pHdr; + pHdr = sqlite3MemsysGetHeader(p); + assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ + if( (pHdr->eType&eType)!=0 ){ + rc = 0; + } + } + return rc; +} + +/* ** Set the number of backtrace levels kept for each allocation. ** A value of zero turns off backtracing. The number is always rounded ** up to a multiple of 2. @@ -13496,7 +15439,7 @@ SQLITE_PRIVATE void sqlite3MemdebugSync(){ } /* -** Open the file indicated and write a log of all unfreed memory +** Open the file indicated and write a log of all unfreed memory ** allocations into that log. */ SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){ @@ -13513,7 +15456,7 @@ SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){ for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ char *z = (char*)pHdr; z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle; - fprintf(out, "**** %lld bytes at %p from %s ****\n", + fprintf(out, "**** %lld bytes at %p from %s ****\n", pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???"); if( pHdr->nBacktrace ){ fflush(out); @@ -13526,7 +15469,7 @@ SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){ fprintf(out, "COUNTS:\n"); for(i=0; i<NCSIZE-1; i++){ if( mem.nAlloc[i] ){ - fprintf(out, " %5d: %10d %10d %10d\n", + fprintf(out, " %5d: %10d %10d %10d\n", i*8, mem.nAlloc[i], mem.nCurrent[i], mem.mxCurrent[i]); } } @@ -13567,12 +15510,12 @@ SQLITE_PRIVATE int sqlite3MemdebugMallocCount(){ ** ************************************************************************* ** This file contains the C functions that implement a memory -** allocation subsystem for use by SQLite. +** allocation subsystem for use by SQLite. ** ** This version of the memory allocation subsystem omits all ** use of malloc(). The SQLite user supplies a block of memory ** before calling sqlite3_initialize() from which allocations -** are made and returned by the xMalloc() and xRealloc() +** are made and returned by the xMalloc() and xRealloc() ** implementations. Once sqlite3_initialize() has been called, ** the amount of memory available to SQLite is fixed and cannot ** be changed. @@ -13602,8 +15545,8 @@ SQLITE_PRIVATE int sqlite3MemdebugMallocCount(){ #define N_HASH 61 /* -** A memory allocation (also called a "chunk") consists of two or -** more blocks where each block is 8 bytes. The first 8 bytes are +** A memory allocation (also called a "chunk") consists of two or +** more blocks where each block is 8 bytes. The first 8 bytes are ** a header that is not returned to the user. ** ** A chunk is two or more blocks that is either checked out or @@ -13626,10 +15569,10 @@ SQLITE_PRIVATE int sqlite3MemdebugMallocCount(){ ** ** The second block of free chunks is of the form u.list. The ** two fields form a double-linked list of chunks of related sizes. -** Pointers to the head of the list are stored in mem3.aiSmall[] +** Pointers to the head of the list are stored in mem3.aiSmall[] ** for smaller chunks and mem3.aiHash[] for larger chunks. ** -** The second block of a chunk is user data if the chunk is checked +** The second block of a chunk is user data if the chunk is checked ** out. If a chunk is checked out, the user data may extend into ** the u.hdr.prevSize value of the following chunk. */ @@ -13665,12 +15608,12 @@ static SQLITE_WSD struct Mem3Global { ** True if we are evaluating an out-of-memory callback. */ int alarmBusy; - + /* ** Mutex to control access to the memory allocation subsystem. */ sqlite3_mutex *mutex; - + /* ** The minimum amount of free space that we have seen. */ @@ -13686,7 +15629,7 @@ static SQLITE_WSD struct Mem3Global { u32 szMaster; /* - ** Array of lists of free blocks according to the block size + ** Array of lists of free blocks according to the block size ** for smaller chunks, or a hash on the block size for larger ** chunks. */ @@ -13717,7 +15660,7 @@ static void memsys3UnlinkFromList(u32 i, u32 *pRoot){ } /* -** Unlink the chunk at index i from +** Unlink the chunk at index i from ** whatever list is currently a member of. */ static void memsys3Unlink(u32 i){ @@ -13801,8 +15744,8 @@ static void memsys3OutOfMemory(int nByte){ /* -** Chunk i is a free chunk that has been unlinked. Adjust its -** size parameters for check-out and return a pointer to the +** Chunk i is a free chunk that has been unlinked. Adjust its +** size parameters for check-out and return a pointer to the ** user portion of the chunk. */ static void *memsys3Checkout(u32 i, u32 nBlock){ @@ -13855,12 +15798,12 @@ static void *memsys3FromMaster(u32 nBlock){ /* ** *pRoot is the head of a list of free chunks of the same size ** or same size hash. In other words, *pRoot is an entry in either -** mem3.aiSmall[] or mem3.aiHash[]. +** mem3.aiSmall[] or mem3.aiHash[]. ** ** This routine examines all entries on the given list and tries -** to coalesce each entries with adjacent free chunks. +** to coalesce each entries with adjacent free chunks. ** -** If it sees a chunk that is larger than mem3.iMaster, it replaces +** If it sees a chunk that is larger than mem3.iMaster, it replaces ** the current mem3.iMaster with the new larger chunk. In order for ** this mem3.iMaster replacement to work, the master chunk must be ** linked into the hash tables. That is not the normal state of @@ -13951,7 +15894,7 @@ static void *memsys3MallocUnsafe(int nByte){ } - /* STEP 3: + /* STEP 3: ** Loop through the entire memory pool. Coalesce adjacent free ** chunks. Recompute the master chunk as the largest free chunk. ** Then try again to satisfy the allocation by carving a piece off @@ -13989,7 +15932,7 @@ static void *memsys3MallocUnsafe(int nByte){ ** This function assumes that the necessary mutexes, if any, are ** already held by the caller. Hence "Unsafe". */ -void memsys3FreeUnsafe(void *pOld){ +static void memsys3FreeUnsafe(void *pOld){ Mem3Block *p = (Mem3Block*)pOld; int i; u32 size, x; @@ -14058,13 +16001,13 @@ static void *memsys3Malloc(int nBytes){ memsys3Enter(); p = memsys3MallocUnsafe(nBytes); memsys3Leave(); - return (void*)p; + return (void*)p; } /* ** Free memory. */ -void memsys3Free(void *pPrior){ +static void memsys3Free(void *pPrior){ assert( pPrior ); memsys3Enter(); memsys3FreeUnsafe(pPrior); @@ -14074,7 +16017,7 @@ void memsys3Free(void *pPrior){ /* ** Change the size of an existing memory allocation */ -void *memsys3Realloc(void *pPrior, int nBytes){ +static void *memsys3Realloc(void *pPrior, int nBytes){ int nOld; void *p; if( pPrior==0 ){ @@ -14139,7 +16082,7 @@ static void memsys3Shutdown(void *NotUsed){ /* -** Open the file indicated and write a log of all unfreed memory +** Open the file indicated and write a log of all unfreed memory ** allocations into that log. */ SQLITE_PRIVATE void sqlite3Memsys3Dump(const char *zFilename){ @@ -14190,7 +16133,7 @@ SQLITE_PRIVATE void sqlite3Memsys3Dump(const char *zFilename){ fprintf(out, " %p(%d)", &mem3.aPool[j], (mem3.aPool[j-1].u.hdr.size4x/4)*8-8); } - fprintf(out, "\n"); + fprintf(out, "\n"); } for(i=0; i<N_HASH; i++){ if( mem3.aiHash[i]==0 ) continue; @@ -14199,7 +16142,7 @@ SQLITE_PRIVATE void sqlite3Memsys3Dump(const char *zFilename){ fprintf(out, " %p(%d)", &mem3.aPool[j], (mem3.aPool[j-1].u.hdr.size4x/4)*8-8); } - fprintf(out, "\n"); + fprintf(out, "\n"); } fprintf(out, "master=%d\n", mem3.iMaster); fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8); @@ -14216,7 +16159,7 @@ SQLITE_PRIVATE void sqlite3Memsys3Dump(const char *zFilename){ } /* -** This routine is the only routine in this file with external +** This routine is the only routine in this file with external ** linkage. ** ** Populate the low-level memory allocation function pointers in @@ -14256,12 +16199,12 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){ ** ************************************************************************* ** This file contains the C functions that implement a memory -** allocation subsystem for use by SQLite. +** allocation subsystem for use by SQLite. ** ** This version of the memory allocation subsystem omits all ** use of malloc(). The application gives SQLite a block of memory ** before calling sqlite3_initialize() from which allocations -** are made and returned by the xMalloc() and xRealloc() +** are made and returned by the xMalloc() and xRealloc() ** implementations. Once sqlite3_initialize() has been called, ** the amount of memory available to SQLite is fixed and cannot ** be changed. @@ -14281,12 +16224,12 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){ ** This algorithm is described in: J. M. Robson. "Bounds for Some Functions ** Concerning Dynamic Storage Allocation". Journal of the Association for ** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499. -** +** ** Let n be the size of the largest allocation divided by the minimum ** allocation size (after rounding all sizes up to a power of 2.) Let M ** be the maximum amount of memory ever outstanding at one time. Let ** N be the total amount of memory available for allocation. Robson -** proved that this memory allocator will never breakdown due to +** proved that this memory allocator will never breakdown due to ** fragmentation as long as the following constraint holds: ** ** N >= M*(1 + log2(n)/2) - n + 1 @@ -14296,7 +16239,7 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){ */ /* -** This version of the memory allocator is used only when +** This version of the memory allocator is used only when ** SQLITE_ENABLE_MEMSYS5 is defined. */ #ifdef SQLITE_ENABLE_MEMSYS5 @@ -14341,7 +16284,7 @@ static SQLITE_WSD struct Mem5Global { int szAtom; /* Smallest possible allocation in bytes */ int nBlock; /* Number of szAtom sized blocks in zPool */ u8 *zPool; /* Memory available to be allocated */ - + /* ** Mutex to control access to the memory allocation subsystem. */ @@ -14358,7 +16301,7 @@ static SQLITE_WSD struct Mem5Global { u32 maxOut; /* Maximum instantaneous currentOut */ u32 maxCount; /* Maximum instantaneous currentCount */ u32 maxRequest; /* Largest allocation (exclusive of internal frag) */ - + /* ** Lists of free blocks. aiFreelist[0] is a list of free blocks of ** size mem5.szAtom. aiFreelist[1] holds blocks of size szAtom*2. @@ -14372,7 +16315,7 @@ static SQLITE_WSD struct Mem5Global { */ u8 *aCtrl; -} mem5 = { 0 }; +} mem5; /* ** Access the static variable through a macro for SQLITE_OMIT_WSD @@ -14456,7 +16399,7 @@ static int memsys5Size(void *p){ /* ** Find the first entry on the freelist iLogsize. Unlink that -** entry and return its index. +** entry and return its index. */ static int memsys5UnlinkFirst(int iLogsize){ int i; @@ -14549,7 +16492,7 @@ static void memsys5FreeUnsafe(void *pOld){ u32 size, iLogsize; int iBlock; - /* Set iBlock to the index of the block pointed to by pOld in + /* Set iBlock to the index of the block pointed to by pOld in ** the array of mem5.szAtom byte blocks pointed to by mem5.zPool. */ iBlock = ((u8 *)pOld-mem5.zPool)/mem5.szAtom; @@ -14608,7 +16551,7 @@ static void *memsys5Malloc(int nBytes){ p = memsys5MallocUnsafe(nBytes); memsys5Leave(); } - return (void*)p; + return (void*)p; } /* @@ -14621,14 +16564,14 @@ static void memsys5Free(void *pPrior){ assert( pPrior!=0 ); memsys5Enter(); memsys5FreeUnsafe(pPrior); - memsys5Leave(); + memsys5Leave(); } /* ** Change the size of an existing memory allocation. ** ** The outer layer memory allocator prevents this routine from -** being called with pPrior==0. +** being called with pPrior==0. ** ** nBytes is always a value obtained from a prior call to ** memsys5Round(). Hence nBytes is always a non-negative power @@ -14640,7 +16583,7 @@ static void *memsys5Realloc(void *pPrior, int nBytes){ int nOld; void *p; assert( pPrior!=0 ); - assert( (nBytes&(nBytes-1))==0 ); + assert( (nBytes&(nBytes-1))==0 ); /* EV: R-46199-30249 */ assert( nBytes>=0 ); if( nBytes==0 ){ return 0; @@ -14687,7 +16630,7 @@ static int memsys5Roundup(int n){ */ static int memsys5Log(int iValue){ int iLog; - for(iLog=0; (1<<iLog)<iValue; iLog++); + for(iLog=0; (iLog<(int)((sizeof(int)*8)-1)) && (1<<iLog)<iValue; iLog++); return iLog; } @@ -14718,6 +16661,7 @@ static int memsys5Init(void *NotUsed){ zByte = (u8*)sqlite3GlobalConfig.pHeap; assert( zByte!=0 ); /* sqlite3_config() does not allow otherwise */ + /* boundaries on sqlite3GlobalConfig.mnReq are enforced in sqlite3_config() */ nMinLog = memsys5Log(sqlite3GlobalConfig.mnReq); mem5.szAtom = (1<<nMinLog); while( (int)sizeof(Mem5Link)>mem5.szAtom ){ @@ -14762,7 +16706,7 @@ static void memsys5Shutdown(void *NotUsed){ #ifdef SQLITE_TEST /* -** Open the file indicated and write a log of all unfreed memory +** Open the file indicated and write a log of all unfreed memory ** allocations into that log. */ SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){ @@ -14804,7 +16748,7 @@ SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){ #endif /* -** This routine is the only routine in this file with external +** This routine is the only routine in this file with external ** linkage. It returns a pointer to a static sqlite3_mem_methods ** struct populated with the memsys5 methods. */ @@ -14856,25 +16800,28 @@ static SQLITE_WSD int mutexIsInit = 0; /* ** Initialize the mutex system. */ -SQLITE_PRIVATE int sqlite3MutexInit(void){ +SQLITE_PRIVATE int sqlite3MutexInit(void){ int rc = SQLITE_OK; - if( sqlite3GlobalConfig.bCoreMutex ){ - if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){ - /* If the xMutexAlloc method has not been set, then the user did not - ** install a mutex implementation via sqlite3_config() prior to - ** sqlite3_initialize() being called. This block copies pointers to - ** the default implementation into the sqlite3GlobalConfig structure. - */ - sqlite3_mutex_methods *pFrom = sqlite3DefaultMutex(); - sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex; + if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){ + /* If the xMutexAlloc method has not been set, then the user did not + ** install a mutex implementation via sqlite3_config() prior to + ** sqlite3_initialize() being called. This block copies pointers to + ** the default implementation into the sqlite3GlobalConfig structure. + */ + sqlite3_mutex_methods const *pFrom; + sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex; - memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc)); - memcpy(&pTo->xMutexFree, &pFrom->xMutexFree, - sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree)); - pTo->xMutexAlloc = pFrom->xMutexAlloc; + if( sqlite3GlobalConfig.bCoreMutex ){ + pFrom = sqlite3DefaultMutex(); + }else{ + pFrom = sqlite3NoopMutex(); } - rc = sqlite3GlobalConfig.mutex.xMutexInit(); + memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc)); + memcpy(&pTo->xMutexFree, &pFrom->xMutexFree, + sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree)); + pTo->xMutexAlloc = pFrom->xMutexAlloc; } + rc = sqlite3GlobalConfig.mutex.xMutexInit(); #ifdef SQLITE_DEBUG GLOBAL(int, mutexIsInit) = 1; @@ -14951,7 +16898,7 @@ SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){ /* ** The sqlite3_mutex_leave() routine exits a mutex that was previously -** entered by the same thread. The behavior is undefined if the mutex +** entered by the same thread. The behavior is undefined if the mutex ** is not currently entered. If a NULL pointer is passed as an argument ** this function is a no-op. */ @@ -15006,25 +16953,30 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ ** called correctly. */ +#ifndef SQLITE_MUTEX_OMIT -#if defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG) +#ifndef SQLITE_DEBUG /* ** Stub routines for all mutex methods. ** ** This routines provide no mutual exclusion or error checking. */ -static int noopMutexHeld(sqlite3_mutex *p){ return 1; } -static int noopMutexNotheld(sqlite3_mutex *p){ return 1; } static int noopMutexInit(void){ return SQLITE_OK; } static int noopMutexEnd(void){ return SQLITE_OK; } -static sqlite3_mutex *noopMutexAlloc(int id){ return (sqlite3_mutex*)8; } -static void noopMutexFree(sqlite3_mutex *p){ return; } -static void noopMutexEnter(sqlite3_mutex *p){ return; } -static int noopMutexTry(sqlite3_mutex *p){ return SQLITE_OK; } -static void noopMutexLeave(sqlite3_mutex *p){ return; } - -SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ - static sqlite3_mutex_methods sMutex = { +static sqlite3_mutex *noopMutexAlloc(int id){ + UNUSED_PARAMETER(id); + return (sqlite3_mutex*)8; +} +static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } +static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } +static int noopMutexTry(sqlite3_mutex *p){ + UNUSED_PARAMETER(p); + return SQLITE_OK; +} +static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } + +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){ + static const sqlite3_mutex_methods sMutex = { noopMutexInit, noopMutexEnd, noopMutexAlloc, @@ -15033,15 +16985,15 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ noopMutexTry, noopMutexLeave, - noopMutexHeld, - noopMutexNotheld + 0, + 0, }; return &sMutex; } -#endif /* defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG) */ +#endif /* !SQLITE_DEBUG */ -#if defined(SQLITE_MUTEX_NOOP) && defined(SQLITE_DEBUG) +#ifdef SQLITE_DEBUG /* ** In this implementation, error checking is provided for testing ** and debugging purposes. The mutexes still do not provide any @@ -15051,19 +17003,21 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ /* ** The mutex object */ -struct sqlite3_mutex { +typedef struct sqlite3_debug_mutex { int id; /* The mutex type */ int cnt; /* Number of entries without a matching leave */ -}; +} sqlite3_debug_mutex; /* ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use inside assert() statements. */ -static int debugMutexHeld(sqlite3_mutex *p){ +static int debugMutexHeld(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; return p==0 || p->cnt>0; } -static int debugMutexNotheld(sqlite3_mutex *p){ +static int debugMutexNotheld(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; return p==0 || p->cnt==0; } @@ -15076,11 +17030,11 @@ static int debugMutexEnd(void){ return SQLITE_OK; } /* ** The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL -** that means that a mutex could not be allocated. +** that means that a mutex could not be allocated. */ static sqlite3_mutex *debugMutexAlloc(int id){ - static sqlite3_mutex aStatic[6]; - sqlite3_mutex *pNew = 0; + static sqlite3_debug_mutex aStatic[6]; + sqlite3_debug_mutex *pNew = 0; switch( id ){ case SQLITE_MUTEX_FAST: case SQLITE_MUTEX_RECURSIVE: { @@ -15099,13 +17053,14 @@ static sqlite3_mutex *debugMutexAlloc(int id){ break; } } - return pNew; + return (sqlite3_mutex*)pNew; } /* ** This routine deallocates a previously allocated mutex. */ -static void debugMutexFree(sqlite3_mutex *p){ +static void debugMutexFree(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; assert( p->cnt==0 ); assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); sqlite3_free(p); @@ -15122,12 +17077,14 @@ static void debugMutexFree(sqlite3_mutex *p){ ** can enter. If the same thread tries to enter any other kind of mutex ** more than once, the behavior is undefined. */ -static void debugMutexEnter(sqlite3_mutex *p){ - assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) ); +static void debugMutexEnter(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); p->cnt++; } -static int debugMutexTry(sqlite3_mutex *p){ - assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) ); +static int debugMutexTry(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); p->cnt++; return SQLITE_OK; } @@ -15138,14 +17095,15 @@ static int debugMutexTry(sqlite3_mutex *p){ ** is undefined if the mutex is not currently entered or ** is not currently allocated. SQLite will never do either. */ -static void debugMutexLeave(sqlite3_mutex *p){ - assert( debugMutexHeld(p) ); +static void debugMutexLeave(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( debugMutexHeld(pX) ); p->cnt--; - assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); } -SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ - static sqlite3_mutex_methods sMutex = { +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){ + static const sqlite3_mutex_methods sMutex = { debugMutexInit, debugMutexEnd, debugMutexAlloc, @@ -15160,7 +17118,18 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ return &sMutex; } -#endif /* defined(SQLITE_MUTEX_NOOP) && defined(SQLITE_DEBUG) */ +#endif /* SQLITE_DEBUG */ + +/* +** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation +** is used regardless of the run-time threadsafety setting. +*/ +#ifdef SQLITE_MUTEX_NOOP +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + return sqlite3NoopMutex(); +} +#endif /* SQLITE_MUTEX_NOOP */ +#endif /* SQLITE_MUTEX_OMIT */ /************** End of mutex_noop.c ******************************************/ /************** Begin file mutex_os2.c ***************************************/ @@ -15196,11 +17165,16 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ struct sqlite3_mutex { HMTX mutex; /* Mutex controlling the lock */ int id; /* Mutex type */ - int nRef; /* Number of references */ - TID owner; /* Thread holding this mutex */ +#ifdef SQLITE_DEBUG + int trace; /* True to trace changes */ +#endif }; -#define OS2_MUTEX_INITIALIZER 0,0,0,0 +#ifdef SQLITE_DEBUG +#define SQLITE3_MUTEX_INITIALIZER { 0, 0, 0 } +#else +#define SQLITE3_MUTEX_INITIALIZER { 0, 0 } +#endif /* ** Initialize and deinitialize the mutex subsystem. @@ -15211,16 +17185,19 @@ static int os2MutexEnd(void){ return SQLITE_OK; } /* ** The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL -** that means that a mutex could not be allocated. +** that means that a mutex could not be allocated. ** SQLite will unwind its stack and return an error. The argument ** to sqlite3_mutex_alloc() is one of these integer constants: ** ** <ul> -** <li> SQLITE_MUTEX_FAST 0 -** <li> SQLITE_MUTEX_RECURSIVE 1 -** <li> SQLITE_MUTEX_STATIC_MASTER 2 -** <li> SQLITE_MUTEX_STATIC_MEM 3 -** <li> SQLITE_MUTEX_STATIC_PRNG 4 +** <li> SQLITE_MUTEX_FAST +** <li> SQLITE_MUTEX_RECURSIVE +** <li> SQLITE_MUTEX_STATIC_MASTER +** <li> SQLITE_MUTEX_STATIC_MEM +** <li> SQLITE_MUTEX_STATIC_MEM2 +** <li> SQLITE_MUTEX_STATIC_PRNG +** <li> SQLITE_MUTEX_STATIC_LRU +** <li> SQLITE_MUTEX_STATIC_LRU2 ** </ul> ** ** The first two constants cause sqlite3_mutex_alloc() to create @@ -15234,7 +17211,7 @@ static int os2MutexEnd(void){ return SQLITE_OK; } ** might return such a mutex in response to SQLITE_MUTEX_FAST. ** ** The other allowed parameters to sqlite3_mutex_alloc() each return -** a pointer to a static preexisting mutex. Three static mutexes are +** a pointer to a static preexisting mutex. Six static mutexes are ** used by the current version of SQLite. Future versions of SQLite ** may add additional static mutexes. Static mutexes are for internal ** use by SQLite only. Applications that use SQLite mutexes should @@ -15264,13 +17241,13 @@ static sqlite3_mutex *os2MutexAlloc(int iType){ } default: { static volatile int isInit = 0; - static sqlite3_mutex staticMutexes[] = { - { OS2_MUTEX_INITIALIZER, }, - { OS2_MUTEX_INITIALIZER, }, - { OS2_MUTEX_INITIALIZER, }, - { OS2_MUTEX_INITIALIZER, }, - { OS2_MUTEX_INITIALIZER, }, - { OS2_MUTEX_INITIALIZER, }, + static sqlite3_mutex staticMutexes[6] = { + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, }; if ( !isInit ){ APIRET rc; @@ -15316,9 +17293,14 @@ static sqlite3_mutex *os2MutexAlloc(int iType){ ** SQLite is careful to deallocate every mutex that it allocates. */ static void os2MutexFree(sqlite3_mutex *p){ - if( p==0 ) return; - assert( p->nRef==0 ); +#ifdef SQLITE_DEBUG + TID tid; + PID pid; + ULONG ulCount; + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + assert( ulCount==0 ); assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); +#endif DosCloseMutexSem( p->mutex ); sqlite3_free( p ); } @@ -15333,26 +17315,29 @@ static int os2MutexHeld(sqlite3_mutex *p){ PID pid; ULONG ulCount; PTIB ptib; - if( p!=0 ) { - DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); - } else { - DosGetInfoBlocks(&ptib, NULL); - tid = ptib->tib_ptib2->tib2_ultid; - } - return p==0 || (p->nRef!=0 && p->owner==tid); + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + if( ulCount==0 || ( ulCount>1 && p->id!=SQLITE_MUTEX_RECURSIVE ) ) + return 0; + DosGetInfoBlocks(&ptib, NULL); + return tid==ptib->tib_ptib2->tib2_ultid; } static int os2MutexNotheld(sqlite3_mutex *p){ TID tid; PID pid; ULONG ulCount; PTIB ptib; - if( p!= 0 ) { - DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); - } else { - DosGetInfoBlocks(&ptib, NULL); - tid = ptib->tib_ptib2->tib2_ultid; - } - return p==0 || p->nRef==0 || p->owner!=tid; + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + if( ulCount==0 ) + return 1; + DosGetInfoBlocks(&ptib, NULL); + return tid!=ptib->tib_ptib2->tib2_ultid; +} +static void os2MutexTrace(sqlite3_mutex *p, char *pAction){ + TID tid; + PID pid; + ULONG ulCount; + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + printf("%s mutex %p (%d) with nRef=%ld\n", pAction, (void*)p, p->trace, ulCount); } #endif @@ -15368,32 +17353,21 @@ static int os2MutexNotheld(sqlite3_mutex *p){ ** more than once, the behavior is undefined. */ static void os2MutexEnter(sqlite3_mutex *p){ - TID tid; - PID holder1; - ULONG holder2; - if( p==0 ) return; assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) ); DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT); - DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); - p->owner = tid; - p->nRef++; +#ifdef SQLITE_DEBUG + if( p->trace ) os2MutexTrace(p, "enter"); +#endif } static int os2MutexTry(sqlite3_mutex *p){ - int rc; - TID tid; - PID holder1; - ULONG holder2; - if( p==0 ) return SQLITE_OK; + int rc = SQLITE_BUSY; assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) ); - if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR) { - DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); - p->owner = tid; - p->nRef++; + if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR ) { rc = SQLITE_OK; - } else { - rc = SQLITE_BUSY; +#ifdef SQLITE_DEBUG + if( p->trace ) os2MutexTrace(p, "try"); +#endif } - return rc; } @@ -15404,20 +17378,15 @@ static int os2MutexTry(sqlite3_mutex *p){ ** is not currently allocated. SQLite will never do either. */ static void os2MutexLeave(sqlite3_mutex *p){ - TID tid; - PID holder1; - ULONG holder2; - if( p==0 ) return; - assert( p->nRef>0 ); - DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); - assert( p->owner==tid ); - p->nRef--; - assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); + assert( os2MutexHeld(p) ); DosReleaseMutexSem(p->mutex); +#ifdef SQLITE_DEBUG + if( p->trace ) os2MutexTrace(p, "leave"); +#endif } -SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ - static sqlite3_mutex_methods sMutex = { +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + static const sqlite3_mutex_methods sMutex = { os2MutexInit, os2MutexEnd, os2MutexAlloc, @@ -15428,6 +17397,9 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ #ifdef SQLITE_DEBUG os2MutexHeld, os2MutexNotheld +#else + 0, + 0 #endif }; @@ -15462,23 +17434,33 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ #include <pthread.h> +/* +** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields +** are necessary under two condidtions: (1) Debug builds and (2) using +** home-grown mutexes. Encapsulate these conditions into a single #define. +*/ +#if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX) +# define SQLITE_MUTEX_NREF 1 +#else +# define SQLITE_MUTEX_NREF 0 +#endif /* ** Each recursive mutex is an instance of the following structure. */ struct sqlite3_mutex { pthread_mutex_t mutex; /* Mutex controlling the lock */ +#if SQLITE_MUTEX_NREF int id; /* Mutex type */ - int nRef; /* Number of entrances */ - pthread_t owner; /* Thread that is within this mutex */ -#ifdef SQLITE_DEBUG + volatile int nRef; /* Number of entrances */ + volatile pthread_t owner; /* Thread that is within this mutex */ int trace; /* True to trace changes */ #endif }; -#ifdef SQLITE_DEBUG +#if SQLITE_MUTEX_NREF #define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 } #else -#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0 } +#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } #endif /* @@ -15487,7 +17469,7 @@ struct sqlite3_mutex { ** there might be race conditions that can cause these routines to ** deliver incorrect results. In particular, if pthread_equal() is ** not an atomic operation, then these routines might delivery -** incorrect results. On most platforms, pthread_equal() is a +** incorrect results. On most platforms, pthread_equal() is a ** comparison of two integers and is therefore atomic. But we are ** told that HPUX is not such a platform. If so, then these routines ** will not always work correctly on HPUX. @@ -15527,7 +17509,7 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; } ** <li> SQLITE_MUTEX_STATIC_MEM2 ** <li> SQLITE_MUTEX_STATIC_PRNG ** <li> SQLITE_MUTEX_STATIC_LRU -** <li> SQLITE_MUTEX_STATIC_LRU2 +** <li> SQLITE_MUTEX_STATIC_PMEM ** </ul> ** ** The first two constants cause sqlite3_mutex_alloc() to create @@ -15550,7 +17532,7 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; } ** ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() -** returns a different mutex on every call. But for the static +** returns a different mutex on every call. But for the static ** mutex types, the same mutex is returned on every call that has ** the same type number. */ @@ -15580,14 +17562,18 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){ pthread_mutex_init(&p->mutex, &recursiveAttr); pthread_mutexattr_destroy(&recursiveAttr); #endif +#if SQLITE_MUTEX_NREF p->id = iType; +#endif } break; } case SQLITE_MUTEX_FAST: { p = sqlite3MallocZero( sizeof(*p) ); if( p ){ +#if SQLITE_MUTEX_NREF p->id = iType; +#endif pthread_mutex_init(&p->mutex, 0); } break; @@ -15596,7 +17582,9 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){ assert( iType-2 >= 0 ); assert( iType-2 < ArraySize(staticMutexes) ); p = &staticMutexes[iType-2]; +#if SQLITE_MUTEX_NREF p->id = iType; +#endif break; } } @@ -15636,7 +17624,7 @@ static void pthreadMutexEnter(sqlite3_mutex *p){ ** is atomic - that it cannot be deceived into thinking self ** and p->owner are equal if p->owner changes between two values ** that are not equal to self while the comparison is taking place. - ** This implementation also assumes a coherent cache - that + ** This implementation also assumes a coherent cache - that ** separate processes cannot read different values from the same ** address at the same time. If either of these two conditions ** are not met, then the mutexes will fail and problems will result. @@ -15656,9 +17644,12 @@ static void pthreadMutexEnter(sqlite3_mutex *p){ /* Use the built-in recursive mutexes if they are available. */ pthread_mutex_lock(&p->mutex); +#if SQLITE_MUTEX_NREF + assert( p->nRef>0 || p->owner==0 ); p->owner = pthread_self(); p->nRef++; #endif +#endif #ifdef SQLITE_DEBUG if( p->trace ){ @@ -15676,7 +17667,7 @@ static int pthreadMutexTry(sqlite3_mutex *p){ ** is atomic - that it cannot be deceived into thinking self ** and p->owner are equal if p->owner changes between two values ** that are not equal to self while the comparison is taking place. - ** This implementation also assumes a coherent cache - that + ** This implementation also assumes a coherent cache - that ** separate processes cannot read different values from the same ** address at the same time. If either of these two conditions ** are not met, then the mutexes will fail and problems will result. @@ -15699,8 +17690,10 @@ static int pthreadMutexTry(sqlite3_mutex *p){ /* Use the built-in recursive mutexes if they are available. */ if( pthread_mutex_trylock(&p->mutex)==0 ){ +#if SQLITE_MUTEX_NREF p->owner = pthread_self(); p->nRef++; +#endif rc = SQLITE_OK; }else{ rc = SQLITE_BUSY; @@ -15723,7 +17716,10 @@ static int pthreadMutexTry(sqlite3_mutex *p){ */ static void pthreadMutexLeave(sqlite3_mutex *p){ assert( pthreadMutexHeld(p) ); +#if SQLITE_MUTEX_NREF p->nRef--; + if( p->nRef==0 ) p->owner = 0; +#endif assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX @@ -15741,8 +17737,8 @@ static void pthreadMutexLeave(sqlite3_mutex *p){ #endif } -SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ - static sqlite3_mutex_methods sMutex = { +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + static const sqlite3_mutex_methods sMutex = { pthreadMutexInit, pthreadMutexEnd, pthreadMutexAlloc, @@ -15792,9 +17788,9 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ struct sqlite3_mutex { CRITICAL_SECTION mutex; /* Mutex controlling the lock */ int id; /* Mutex type */ - int nRef; /* Number of enterances */ - DWORD owner; /* Thread holding this mutex */ #ifdef SQLITE_DEBUG + volatile int nRef; /* Number of enterances */ + volatile DWORD owner; /* Thread holding this mutex */ int trace; /* True to trace changes */ #endif }; @@ -15802,7 +17798,7 @@ struct sqlite3_mutex { #ifdef SQLITE_DEBUG #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0, 0 } #else -#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0 } +#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 } #endif /* @@ -15817,9 +17813,9 @@ struct sqlite3_mutex { ** the LockFileEx() API. ** ** mutexIsNT() is only used for the TryEnterCriticalSection() API call, -** which is only available if your application was compiled with +** which is only available if your application was compiled with ** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only -** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef +** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef ** this out as well. */ #if 0 @@ -15851,7 +17847,7 @@ static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ return p->nRef==0 || p->owner!=tid; } static int winMutexNotheld(sqlite3_mutex *p){ - DWORD tid = GetCurrentThreadId(); + DWORD tid = GetCurrentThreadId(); return winMutexNotheld2(p, tid); } #endif @@ -15876,7 +17872,7 @@ static int winMutex_isInit = 0; */ static long winMutex_lock = 0; -static int winMutexInit(void){ +static int winMutexInit(void){ /* The first to increment to 1 does actual initialization */ if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ int i; @@ -15890,11 +17886,11 @@ static int winMutexInit(void){ Sleep(1); } } - return SQLITE_OK; + return SQLITE_OK; } -static int winMutexEnd(void){ - /* The first to decrement to 0 does actual shutdown +static int winMutexEnd(void){ + /* The first to decrement to 0 does actual shutdown ** (which should be the last to shutdown.) */ if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){ if( winMutex_isInit==1 ){ @@ -15905,7 +17901,7 @@ static int winMutexEnd(void){ winMutex_isInit = 0; } } - return SQLITE_OK; + return SQLITE_OK; } /* @@ -15923,7 +17919,7 @@ static int winMutexEnd(void){ ** <li> SQLITE_MUTEX_STATIC_MEM2 ** <li> SQLITE_MUTEX_STATIC_PRNG ** <li> SQLITE_MUTEX_STATIC_LRU -** <li> SQLITE_MUTEX_STATIC_LRU2 +** <li> SQLITE_MUTEX_STATIC_PMEM ** </ul> ** ** The first two constants cause sqlite3_mutex_alloc() to create @@ -15946,7 +17942,7 @@ static int winMutexEnd(void){ ** ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() -** returns a different mutex on every call. But for the static +** returns a different mutex on every call. But for the static ** mutex types, the same mutex is returned on every call that has ** the same type number. */ @@ -15957,8 +17953,10 @@ static sqlite3_mutex *winMutexAlloc(int iType){ case SQLITE_MUTEX_FAST: case SQLITE_MUTEX_RECURSIVE: { p = sqlite3MallocZero( sizeof(*p) ); - if( p ){ + if( p ){ +#ifdef SQLITE_DEBUG p->id = iType; +#endif InitializeCriticalSection(&p->mutex); } break; @@ -15968,7 +17966,9 @@ static sqlite3_mutex *winMutexAlloc(int iType){ assert( iType-2 >= 0 ); assert( iType-2 < ArraySize(winMutex_staticMutexes) ); p = &winMutex_staticMutexes[iType-2]; +#ifdef SQLITE_DEBUG p->id = iType; +#endif break; } } @@ -15983,7 +17983,7 @@ static sqlite3_mutex *winMutexAlloc(int iType){ */ static void winMutexFree(sqlite3_mutex *p){ assert( p ); - assert( p->nRef==0 ); + assert( p->nRef==0 && p->owner==0 ); assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); DeleteCriticalSection(&p->mutex); sqlite3_free(p); @@ -16001,12 +18001,15 @@ static void winMutexFree(sqlite3_mutex *p){ ** more than once, the behavior is undefined. */ static void winMutexEnter(sqlite3_mutex *p){ - DWORD tid = GetCurrentThreadId(); +#ifdef SQLITE_DEBUG + DWORD tid = GetCurrentThreadId(); assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); +#endif EnterCriticalSection(&p->mutex); - p->owner = tid; - p->nRef++; #ifdef SQLITE_DEBUG + assert( p->nRef>0 || p->owner==0 ); + p->owner = tid; + p->nRef++; if( p->trace ){ printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); } @@ -16014,14 +18017,14 @@ static void winMutexEnter(sqlite3_mutex *p){ } static int winMutexTry(sqlite3_mutex *p){ #ifndef NDEBUG - DWORD tid = GetCurrentThreadId(); + DWORD tid = GetCurrentThreadId(); #endif int rc = SQLITE_BUSY; assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); /* ** The sqlite3_mutex_try() routine is very rarely used, and when it ** is used it is merely an optimization. So it is OK for it to always - ** fail. + ** fail. ** ** The TryEnterCriticalSection() interface is only available on WinNT. ** And some windows compilers complain if you try to use it without @@ -16040,7 +18043,7 @@ static int winMutexTry(sqlite3_mutex *p){ #endif #ifdef SQLITE_DEBUG if( rc==SQLITE_OK && p->trace ){ - printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); } #endif return rc; @@ -16055,11 +18058,12 @@ static int winMutexTry(sqlite3_mutex *p){ static void winMutexLeave(sqlite3_mutex *p){ #ifndef NDEBUG DWORD tid = GetCurrentThreadId(); -#endif assert( p->nRef>0 ); assert( p->owner==tid ); p->nRef--; + if( p->nRef==0 ) p->owner = 0; assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); +#endif LeaveCriticalSection(&p->mutex); #ifdef SQLITE_DEBUG if( p->trace ){ @@ -16068,8 +18072,8 @@ static void winMutexLeave(sqlite3_mutex *p){ #endif } -SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ - static sqlite3_mutex_methods sMutex = { +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + static const sqlite3_mutex_methods sMutex = { winMutexInit, winMutexEnd, winMutexAlloc, @@ -16106,46 +18110,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ ** ** Memory allocation functions used throughout sqlite. */ - -/* -** This routine runs when the memory allocator sees that the -** total memory allocation is about to exceed the soft heap -** limit. -*/ -static void softHeapLimitEnforcer( - void *NotUsed, - sqlite3_int64 NotUsed2, - int allocSize -){ - UNUSED_PARAMETER2(NotUsed, NotUsed2); - sqlite3_release_memory(allocSize); -} - -/* -** Set the soft heap-size limit for the library. Passing a zero or -** negative value indicates no limit. -*/ -SQLITE_API void sqlite3_soft_heap_limit(int n){ - sqlite3_uint64 iLimit; - int overage; - if( n<0 ){ - iLimit = 0; - }else{ - iLimit = n; - } -#ifndef SQLITE_OMIT_AUTOINIT - sqlite3_initialize(); -#endif - if( iLimit>0 ){ - sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, iLimit); - }else{ - sqlite3MemoryAlarm(0, 0, 0); - } - overage = (int)(sqlite3_memory_used() - (i64)n); - if( overage>0 ){ - sqlite3_release_memory(overage); - } -} +/* #include <stdarg.h> */ /* ** Attempt to release up to n bytes of non-essential memory currently @@ -16154,23 +18119,28 @@ SQLITE_API void sqlite3_soft_heap_limit(int n){ */ SQLITE_API int sqlite3_release_memory(int n){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - int nRet = 0; - nRet += sqlite3PcacheReleaseMemory(n-nRet); - return nRet; + return sqlite3PcacheReleaseMemory(n); #else + /* IMPLEMENTATION-OF: R-34391-24921 The sqlite3_release_memory() routine + ** is a no-op returning zero if SQLite is not compiled with + ** SQLITE_ENABLE_MEMORY_MANAGEMENT. */ UNUSED_PARAMETER(n); - return SQLITE_OK; + return 0; #endif } /* +** An instance of the following object records the location of +** each unused scratch buffer. +*/ +typedef struct ScratchFreeslot { + struct ScratchFreeslot *pNext; /* Next unused scratch buffer */ +} ScratchFreeslot; + +/* ** State information local to the memory allocation subsystem. */ static SQLITE_WSD struct Mem0Global { - /* Number of free pages for scratch and page-cache memory */ - u32 nScratchFree; - u32 nPageFree; - sqlite3_mutex *mutex; /* Mutex to serialize access */ /* @@ -16184,17 +18154,100 @@ static SQLITE_WSD struct Mem0Global { void *alarmArg; /* - ** Pointers to the end of sqlite3GlobalConfig.pScratch and - ** sqlite3GlobalConfig.pPage to a block of memory that records - ** which pages are available. + ** Pointers to the end of sqlite3GlobalConfig.pScratch memory + ** (so that a range test can be used to determine if an allocation + ** being freed came from pScratch) and a pointer to the list of + ** unused scratch allocations. + */ + void *pScratchEnd; + ScratchFreeslot *pScratchFree; + u32 nScratchFree; + + /* + ** True if heap is nearly "full" where "full" is defined by the + ** sqlite3_soft_heap_limit() setting. */ - u32 *aScratchFree; - u32 *aPageFree; + int nearlyFull; } mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 }; #define mem0 GLOBAL(struct Mem0Global, mem0) /* +** This routine runs when the memory allocator sees that the +** total memory allocation is about to exceed the soft heap +** limit. +*/ +static void softHeapLimitEnforcer( + void *NotUsed, + sqlite3_int64 NotUsed2, + int allocSize +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + sqlite3_release_memory(allocSize); +} + +/* +** Change the alarm callback +*/ +static int sqlite3MemoryAlarm( + void(*xCallback)(void *pArg, sqlite3_int64 used,int N), + void *pArg, + sqlite3_int64 iThreshold +){ + int nUsed; + sqlite3_mutex_enter(mem0.mutex); + mem0.alarmCallback = xCallback; + mem0.alarmArg = pArg; + mem0.alarmThreshold = iThreshold; + nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + mem0.nearlyFull = (iThreshold>0 && iThreshold<=nUsed); + sqlite3_mutex_leave(mem0.mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Deprecated external interface. Internal/core SQLite code +** should call sqlite3MemoryAlarm. +*/ +SQLITE_API int sqlite3_memory_alarm( + void(*xCallback)(void *pArg, sqlite3_int64 used,int N), + void *pArg, + sqlite3_int64 iThreshold +){ + return sqlite3MemoryAlarm(xCallback, pArg, iThreshold); +} +#endif + +/* +** Set the soft heap-size limit for the library. Passing a zero or +** negative value indicates no limit. +*/ +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ + sqlite3_int64 priorLimit; + sqlite3_int64 excess; +#ifndef SQLITE_OMIT_AUTOINIT + sqlite3_initialize(); +#endif + sqlite3_mutex_enter(mem0.mutex); + priorLimit = mem0.alarmThreshold; + sqlite3_mutex_leave(mem0.mutex); + if( n<0 ) return priorLimit; + if( n>0 ){ + sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n); + }else{ + sqlite3MemoryAlarm(0, 0, 0); + } + excess = sqlite3_memory_used() - n; + if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff)); + return priorLimit; +} +SQLITE_API void sqlite3_soft_heap_limit(int n){ + if( n<0 ) n = 0; + sqlite3_soft_heap_limit64(n); +} + +/* ** Initialize the memory allocation subsystem. */ SQLITE_PRIVATE int sqlite3MallocInit(void){ @@ -16206,37 +18259,46 @@ SQLITE_PRIVATE int sqlite3MallocInit(void){ mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); } if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100 - && sqlite3GlobalConfig.nScratch>=0 ){ - int i; - sqlite3GlobalConfig.szScratch = ROUNDDOWN8(sqlite3GlobalConfig.szScratch-4); - mem0.aScratchFree = (u32*)&((char*)sqlite3GlobalConfig.pScratch) - [sqlite3GlobalConfig.szScratch*sqlite3GlobalConfig.nScratch]; - for(i=0; i<sqlite3GlobalConfig.nScratch; i++){ mem0.aScratchFree[i] = i; } - mem0.nScratchFree = sqlite3GlobalConfig.nScratch; + && sqlite3GlobalConfig.nScratch>0 ){ + int i, n, sz; + ScratchFreeslot *pSlot; + sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch); + sqlite3GlobalConfig.szScratch = sz; + pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch; + n = sqlite3GlobalConfig.nScratch; + mem0.pScratchFree = pSlot; + mem0.nScratchFree = n; + for(i=0; i<n-1; i++){ + pSlot->pNext = (ScratchFreeslot*)(sz+(char*)pSlot); + pSlot = pSlot->pNext; + } + pSlot->pNext = 0; + mem0.pScratchEnd = (void*)&pSlot[1]; }else{ + mem0.pScratchEnd = 0; sqlite3GlobalConfig.pScratch = 0; sqlite3GlobalConfig.szScratch = 0; + sqlite3GlobalConfig.nScratch = 0; } - if( sqlite3GlobalConfig.pPage && sqlite3GlobalConfig.szPage>=512 - && sqlite3GlobalConfig.nPage>=1 ){ - int i; - int overhead; - int sz = ROUNDDOWN8(sqlite3GlobalConfig.szPage); - int n = sqlite3GlobalConfig.nPage; - overhead = (4*n + sz - 1)/sz; - sqlite3GlobalConfig.nPage -= overhead; - mem0.aPageFree = (u32*)&((char*)sqlite3GlobalConfig.pPage) - [sqlite3GlobalConfig.szPage*sqlite3GlobalConfig.nPage]; - for(i=0; i<sqlite3GlobalConfig.nPage; i++){ mem0.aPageFree[i] = i; } - mem0.nPageFree = sqlite3GlobalConfig.nPage; - }else{ + if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512 + || sqlite3GlobalConfig.nPage<1 ){ sqlite3GlobalConfig.pPage = 0; sqlite3GlobalConfig.szPage = 0; + sqlite3GlobalConfig.nPage = 0; } return sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData); } /* +** Return true if the heap is currently under memory pressure - in other +** words if the amount of heap used is close to the limit set by +** sqlite3_soft_heap_limit(). +*/ +SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){ + return mem0.nearlyFull; +} + +/* ** Deinitialize the memory allocation subsystem. */ SQLITE_PRIVATE void sqlite3MallocEnd(void){ @@ -16271,37 +18333,7 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){ } /* -** Change the alarm callback -*/ -SQLITE_PRIVATE int sqlite3MemoryAlarm( - void(*xCallback)(void *pArg, sqlite3_int64 used,int N), - void *pArg, - sqlite3_int64 iThreshold -){ - sqlite3_mutex_enter(mem0.mutex); - mem0.alarmCallback = xCallback; - mem0.alarmArg = pArg; - mem0.alarmThreshold = iThreshold; - sqlite3_mutex_leave(mem0.mutex); - return SQLITE_OK; -} - -#ifndef SQLITE_OMIT_DEPRECATED -/* -** Deprecated external interface. Internal/core SQLite code -** should call sqlite3MemoryAlarm. -*/ -SQLITE_API int sqlite3_memory_alarm( - void(*xCallback)(void *pArg, sqlite3_int64 used,int N), - void *pArg, - sqlite3_int64 iThreshold -){ - return sqlite3MemoryAlarm(xCallback, pArg, iThreshold); -} -#endif - -/* -** Trigger the alarm +** Trigger the alarm */ static void sqlite3MallocAlarm(int nByte){ void (*xCallback)(void*,sqlite3_int64,int); @@ -16331,18 +18363,24 @@ static int mallocWithAlarm(int n, void **pp){ sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n); if( mem0.alarmCallback!=0 ){ int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); - if( nUsed+nFull >= mem0.alarmThreshold ){ + if( nUsed >= mem0.alarmThreshold - nFull ){ + mem0.nearlyFull = 1; sqlite3MallocAlarm(nFull); + }else{ + mem0.nearlyFull = 0; } } p = sqlite3GlobalConfig.m.xMalloc(nFull); +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT if( p==0 && mem0.alarmCallback ){ sqlite3MallocAlarm(nFull); p = sqlite3GlobalConfig.m.xMalloc(nFull); } +#endif if( p ){ nFull = sqlite3MallocSize(p); sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull); + sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1); } *pp = p; return nFull; @@ -16354,7 +18392,9 @@ static int mallocWithAlarm(int n, void **pp){ */ SQLITE_PRIVATE void *sqlite3Malloc(int n){ void *p; - if( n<=0 || n>=0x7fffff00 ){ + if( n<=0 /* IMP: R-65312-04917 */ + || 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 @@ -16368,6 +18408,7 @@ SQLITE_PRIVATE void *sqlite3Malloc(int n){ }else{ p = sqlite3GlobalConfig.m.xMalloc(n); } + assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-04675-44850 */ return p; } @@ -16406,88 +18447,79 @@ SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){ void *p; assert( n>0 ); -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) - /* Verify that no more than one scratch allocation per thread - ** is outstanding at one time. (This is only checked in the - ** single-threaded case since checking in the multi-threaded case - ** would be much more complicated.) */ - assert( scratchAllocOut==0 ); -#endif - - if( sqlite3GlobalConfig.szScratch<n ){ - goto scratch_overflow; + sqlite3_mutex_enter(mem0.mutex); + if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){ + p = mem0.pScratchFree; + mem0.pScratchFree = mem0.pScratchFree->pNext; + mem0.nScratchFree--; + sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1); + sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n); + sqlite3_mutex_leave(mem0.mutex); }else{ - sqlite3_mutex_enter(mem0.mutex); - if( mem0.nScratchFree==0 ){ + if( sqlite3GlobalConfig.bMemstat ){ + sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n); + n = mallocWithAlarm(n, &p); + if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n); sqlite3_mutex_leave(mem0.mutex); - goto scratch_overflow; }else{ - int i; - i = mem0.aScratchFree[--mem0.nScratchFree]; - i *= sqlite3GlobalConfig.szScratch; - sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1); - sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n); sqlite3_mutex_leave(mem0.mutex); - p = (void*)&((char*)sqlite3GlobalConfig.pScratch)[i]; - assert( (((u8*)p - (u8*)0) & 7)==0 ); + p = sqlite3GlobalConfig.m.xMalloc(n); } + sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH); } -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) - scratchAllocOut = p!=0; -#endif + assert( sqlite3_mutex_notheld(mem0.mutex) ); - return p; -scratch_overflow: - if( sqlite3GlobalConfig.bMemstat ){ - sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n); - n = mallocWithAlarm(n, &p); - if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n); - sqlite3_mutex_leave(mem0.mutex); - }else{ - p = sqlite3GlobalConfig.m.xMalloc(n); - } #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) - scratchAllocOut = p!=0; + /* Verify that no more than two scratch allocations per thread + ** are outstanding at one time. (This is only checked in the + ** single-threaded case since checking in the multi-threaded case + ** would be much more complicated.) */ + assert( scratchAllocOut<=1 ); + if( p ) scratchAllocOut++; #endif + return p; } SQLITE_PRIVATE void sqlite3ScratchFree(void *p){ if( p ){ #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) - /* Verify that no more than one scratch allocation per thread + /* Verify that no more than two scratch allocation per thread ** is outstanding at one time. (This is only checked in the ** single-threaded case since checking in the multi-threaded case ** would be much more complicated.) */ - assert( scratchAllocOut==1 ); - scratchAllocOut = 0; + assert( scratchAllocOut>=1 && scratchAllocOut<=2 ); + scratchAllocOut--; #endif - if( sqlite3GlobalConfig.pScratch==0 - || p<sqlite3GlobalConfig.pScratch - || p>=(void*)mem0.aScratchFree ){ + if( p>=sqlite3GlobalConfig.pScratch && p<mem0.pScratchEnd ){ + /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */ + ScratchFreeslot *pSlot; + pSlot = (ScratchFreeslot*)p; + sqlite3_mutex_enter(mem0.mutex); + pSlot->pNext = mem0.pScratchFree; + mem0.pScratchFree = pSlot; + mem0.nScratchFree++; + assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch ); + sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1); + sqlite3_mutex_leave(mem0.mutex); + }else{ + /* Release memory back to the heap */ + assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); + assert( sqlite3MemdebugNoType(p, ~MEMTYPE_SCRATCH) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); if( sqlite3GlobalConfig.bMemstat ){ int iSize = sqlite3MallocSize(p); sqlite3_mutex_enter(mem0.mutex); sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize); sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize); + sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1); sqlite3GlobalConfig.m.xFree(p); sqlite3_mutex_leave(mem0.mutex); }else{ sqlite3GlobalConfig.m.xFree(p); } - }else{ - int i; - i = (int)((u8*)p - (u8*)sqlite3GlobalConfig.pScratch); - i /= sqlite3GlobalConfig.szScratch; - assert( i>=0 && i<sqlite3GlobalConfig.nScratch ); - sqlite3_mutex_enter(mem0.mutex); - assert( mem0.nScratchFree<(u32)sqlite3GlobalConfig.nScratch ); - mem0.aScratchFree[mem0.nScratchFree++] = i; - sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1); - sqlite3_mutex_leave(mem0.mutex); } } } @@ -16497,7 +18529,7 @@ SQLITE_PRIVATE void sqlite3ScratchFree(void *p){ */ #ifndef SQLITE_OMIT_LOOKASIDE static int isLookaside(sqlite3 *db, void *p){ - return db && p && p>=db->lookaside.pStart && p<db->lookaside.pEnd; + return p && p>=db->lookaside.pStart && p<db->lookaside.pEnd; } #else #define isLookaside(A,B) 0 @@ -16508,13 +18540,18 @@ static int isLookaside(sqlite3 *db, void *p){ ** sqlite3Malloc() or sqlite3_malloc(). */ SQLITE_PRIVATE int sqlite3MallocSize(void *p){ + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); return sqlite3GlobalConfig.m.xSize(p); } SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ assert( db==0 || sqlite3_mutex_held(db->mutex) ); - if( isLookaside(db, p) ){ + if( db && isLookaside(db, p) ){ return db->lookaside.sz; }else{ + assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); + assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); return sqlite3GlobalConfig.m.xSize(p); } } @@ -16523,10 +18560,13 @@ SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ ** Free memory previously obtained from sqlite3Malloc(). */ SQLITE_API void sqlite3_free(void *p){ - if( p==0 ) return; + if( p==0 ) return; /* IMP: R-49053-54554 */ + assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p)); + sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1); sqlite3GlobalConfig.m.xFree(p); sqlite3_mutex_leave(mem0.mutex); }else{ @@ -16540,27 +18580,37 @@ SQLITE_API void sqlite3_free(void *p){ */ SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ assert( db==0 || sqlite3_mutex_held(db->mutex) ); - if( isLookaside(db, p) ){ - LookasideSlot *pBuf = (LookasideSlot*)p; - pBuf->pNext = db->lookaside.pFree; - db->lookaside.pFree = pBuf; - db->lookaside.nOut--; - }else{ - sqlite3_free(p); + if( db ){ + if( db->pnBytesFreed ){ + *db->pnBytesFreed += sqlite3DbMallocSize(db, p); + return; + } + if( isLookaside(db, p) ){ + LookasideSlot *pBuf = (LookasideSlot*)p; + pBuf->pNext = db->lookaside.pFree; + db->lookaside.pFree = pBuf; + db->lookaside.nOut--; + return; + } } + assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); + assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + sqlite3_free(p); } /* ** Change the size of an existing memory allocation */ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){ - int nOld, nNew; + int nOld, nNew, nDiff; void *pNew; if( pOld==0 ){ - return sqlite3Malloc(nBytes); + return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */ } if( nBytes<=0 ){ - sqlite3_free(pOld); + sqlite3_free(pOld); /* IMP: R-31593-10574 */ return 0; } if( nBytes>=0x7fffff00 ){ @@ -16568,16 +18618,22 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){ return 0; } nOld = sqlite3MallocSize(pOld); + /* IMPLEMENTATION-OF: R-46199-30249 SQLite guarantees that the second + ** argument to xRealloc is always a value returned by a prior call to + ** xRoundup. */ nNew = sqlite3GlobalConfig.m.xRoundup(nBytes); if( nOld==nNew ){ pNew = pOld; }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes); - if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= - mem0.alarmThreshold ){ - sqlite3MallocAlarm(nNew-nOld); + nDiff = nNew - nOld; + if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= + mem0.alarmThreshold-nDiff ){ + sqlite3MallocAlarm(nDiff); } + assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) ); pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); if( pNew==0 && mem0.alarmCallback ){ sqlite3MallocAlarm(nBytes); @@ -16591,6 +18647,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){ }else{ pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); } + assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-04675-44850 */ return pNew; } @@ -16608,7 +18665,7 @@ SQLITE_API void *sqlite3_realloc(void *pOld, int n){ /* ** Allocate and zero memory. -*/ +*/ SQLITE_PRIVATE void *sqlite3MallocZero(int n){ void *p = sqlite3Malloc(n); if( p ){ @@ -16650,20 +18707,27 @@ SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, int n){ SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){ void *p; assert( db==0 || sqlite3_mutex_held(db->mutex) ); + assert( db==0 || db->pnBytesFreed==0 ); #ifndef SQLITE_OMIT_LOOKASIDE if( db ){ LookasideSlot *pBuf; if( db->mallocFailed ){ return 0; } - if( db->lookaside.bEnabled && n<=db->lookaside.sz - && (pBuf = db->lookaside.pFree)!=0 ){ - db->lookaside.pFree = pBuf->pNext; - db->lookaside.nOut++; - if( db->lookaside.nOut>db->lookaside.mxOut ){ - db->lookaside.mxOut = db->lookaside.nOut; + if( db->lookaside.bEnabled ){ + if( n>db->lookaside.sz ){ + db->lookaside.anStat[1]++; + }else if( (pBuf = db->lookaside.pFree)==0 ){ + db->lookaside.anStat[2]++; + }else{ + db->lookaside.pFree = pBuf->pNext; + db->lookaside.nOut++; + db->lookaside.anStat[0]++; + if( db->lookaside.nOut>db->lookaside.mxOut ){ + db->lookaside.mxOut = db->lookaside.nOut; + } + return (void*)pBuf; } - return (void*)pBuf; } } #else @@ -16675,6 +18739,8 @@ SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){ if( !p && db ){ db->mallocFailed = 1; } + sqlite3MemdebugSetType(p, MEMTYPE_DB | + ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); return p; } @@ -16700,10 +18766,16 @@ SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){ sqlite3DbFree(db, p); } }else{ + assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); pNew = sqlite3_realloc(p, n); if( !pNew ){ + sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP); db->mallocFailed = 1; } + sqlite3MemdebugSetType(pNew, MEMTYPE_DB | + (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); } } return pNew; @@ -16723,9 +18795,9 @@ SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, int n){ } /* -** Make a copy of a string in memory obtained from sqliteMalloc(). These +** Make a copy of a string in memory obtained from sqliteMalloc(). These ** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This -** is because when memory debugging is turned on, these two functions are +** is because when memory debugging is turned on, these two functions are ** called via macros that record the current file and line number in the ** ThreadData structure. */ @@ -16775,13 +18847,13 @@ SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat /* -** This function must be called before exiting any API function (i.e. +** This function must be called before exiting any API function (i.e. ** returning control to the user) that has called sqlite3_malloc or ** sqlite3_realloc. ** ** The returned value is normally a copy of the second argument to this ** function. However, if a malloc() failure has occurred since the previous -** invocation SQLITE_NOMEM is returned instead. +** invocation SQLITE_NOMEM is returned instead. ** ** If the first argument, db, is not NULL and a malloc() error has occurred, ** then the connection error-code (the value returned by sqlite3_errcode()) @@ -16789,7 +18861,7 @@ SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat */ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ /* If the db handle is not NULL, then we must hold the connection handle - ** mutex here. Otherwise the read (and possible write) of db->mallocFailed + ** mutex here. Otherwise the read (and possible write) of db->mallocFailed ** is unsafe, as is the call to sqlite3Error(). */ assert( !db || sqlite3_mutex_held(db->mutex) ); @@ -17082,7 +19154,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf( break; } /* Find out what flags are present */ - flag_leftjustify = flag_plussign = flag_blanksign = + flag_leftjustify = flag_plussign = flag_blanksign = flag_alternateform = flag_altform2 = flag_zeropad = 0; done = 0; do{ @@ -17204,7 +19276,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf( v = va_arg(ap,int); } if( v<0 ){ - longvalue = -v; + if( v==SMALLEST_INT64 ){ + longvalue = ((u64)1)<<63; + }else{ + longvalue = -v; + } prefix = '-'; }else{ longvalue = v; @@ -17567,6 +19643,7 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ return; } }else{ + char *zOld = (p->zText==p->zBase ? 0 : p->zText); i64 szNew = p->nChar; szNew += N + 1; if( szNew > p->mxAlloc ){ @@ -17576,10 +19653,13 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ }else{ p->nAlloc = (int)szNew; } - zNew = sqlite3DbMallocRaw(p->db, p->nAlloc ); + if( p->useMalloc==1 ){ + zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); + }else{ + zNew = sqlite3_realloc(zOld, p->nAlloc); + } if( zNew ){ - memcpy(zNew, p->zText, p->nChar); - sqlite3StrAccumReset(p); + if( zOld==0 ) memcpy(zNew, p->zText, p->nChar); p->zText = zNew; }else{ p->mallocFailed = 1; @@ -17601,7 +19681,11 @@ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ if( p->zText ){ p->zText[p->nChar] = 0; if( p->useMalloc && p->zText==p->zBase ){ - p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); + if( p->useMalloc==1 ){ + p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); + }else{ + p->zText = sqlite3_malloc(p->nChar+1); + } if( p->zText ){ memcpy(p->zText, p->zBase, p->nChar+1); }else{ @@ -17617,7 +19701,11 @@ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ */ SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){ if( p->zText!=p->zBase ){ - sqlite3DbFree(p->db, p->zText); + if( p->useMalloc==1 ){ + sqlite3DbFree(p->db, p->zText); + }else{ + sqlite3_free(p->zText); + } } p->zText = 0; } @@ -17699,6 +19787,7 @@ SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){ if( sqlite3_initialize() ) return 0; #endif sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); + acc.useMalloc = 2; sqlite3VXPrintf(&acc, 0, zFormat, ap); z = sqlite3StrAccumFinish(&acc); return z; @@ -17725,21 +19814,28 @@ SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){ ** current locale settings. This is important for SQLite because we ** are not able to use a "," as the decimal point in place of "." as ** specified by some locales. +** +** Oops: The first two arguments of sqlite3_snprintf() are backwards +** from the snprintf() standard. Unfortunately, it is too late to change +** this without breaking compatibility, so we just have to live with the +** mistake. +** +** sqlite3_vsnprintf() is the varargs version. */ -SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ - char *z; - va_list ap; +SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ StrAccum acc; - - if( n<=0 ){ - return zBuf; - } + if( n<=0 ) return zBuf; sqlite3StrAccumInit(&acc, zBuf, n, 0); acc.useMalloc = 0; - va_start(ap,zFormat); sqlite3VXPrintf(&acc, 0, zFormat, ap); + return sqlite3StrAccumFinish(&acc); +} +SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ + char *z; + va_list ap; + va_start(ap,zFormat); + z = sqlite3_vsnprintf(n, zBuf, zFormat, ap); va_end(ap); - z = sqlite3StrAccumFinish(&acc); return z; } @@ -17968,7 +20064,7 @@ SQLITE_PRIVATE void sqlite3PrngResetState(void){ ** May you share freely, never taking more than you give. ** ************************************************************************* -** This file contains routines used to translate between UTF-8, +** This file contains routines used to translate between UTF-8, ** UTF-16, UTF-16BE, and UTF-16LE. ** ** Notes on UTF-8: @@ -17992,429 +20088,7 @@ SQLITE_PRIVATE void sqlite3PrngResetState(void){ ** 0xfe 0xff big-endian utf-16 follows ** */ -/************** Include vdbeInt.h in the middle of utf.c *********************/ -/************** Begin file vdbeInt.h *****************************************/ -/* -** 2003 September 6 -** -** 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 is the header file for information that is private to the -** VDBE. This information used to all be at the top of the single -** source code file "vdbe.c". When that file became too big (over -** 6000 lines long) it was split up into several smaller files and -** this header information was factored out. -*/ -#ifndef _VDBEINT_H_ -#define _VDBEINT_H_ - -/* -** SQL is translated into a sequence of instructions to be -** executed by a virtual machine. Each instruction is an instance -** of the following structure. -*/ -typedef struct VdbeOp Op; - -/* -** Boolean values -*/ -typedef unsigned char Bool; - -/* -** A cursor is a pointer into a single BTree within a database file. -** The cursor can seek to a BTree entry with a particular key, or -** loop over all entries of the Btree. You can also insert new BTree -** entries or retrieve the key or data from the entry that the cursor -** is currently pointing to. -** -** Every cursor that the virtual machine has open is represented by an -** instance of the following structure. -** -** If the VdbeCursor.isTriggerRow flag is set it means that this cursor is -** really a single row that represents the NEW or OLD pseudo-table of -** a row trigger. The data for the row is stored in VdbeCursor.pData and -** the rowid is in VdbeCursor.iKey. -*/ -struct VdbeCursor { - BtCursor *pCursor; /* The cursor structure of the backend */ - int iDb; /* Index of cursor database in db->aDb[] (or -1) */ - i64 lastRowid; /* Last rowid from a Next or NextIdx operation */ - Bool zeroed; /* True if zeroed out and ready for reuse */ - Bool rowidIsValid; /* True if lastRowid is valid */ - Bool atFirst; /* True if pointing to first entry */ - Bool useRandomRowid; /* Generate new record numbers semi-randomly */ - Bool nullRow; /* True if pointing to a row with no data */ - Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ - Bool isTable; /* True if a table requiring integer keys */ - Bool isIndex; /* True if an index containing keys only - no data */ - i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ - Btree *pBt; /* Separate file holding temporary table */ - int pseudoTableReg; /* Register holding pseudotable content. */ - KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ - int nField; /* Number of fields in the header */ - i64 seqCount; /* Sequence counter */ - sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ - const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ - - /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or - ** OP_IsUnique opcode on this cursor. */ - int seekResult; - - /* Cached information about the header for the data record that the - ** cursor is currently pointing to. Only valid if cacheStatus matches - ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of - ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that - ** the cache is out of date. - ** - ** aRow might point to (ephemeral) data for the current row, or it might - ** be NULL. - */ - u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ - int payloadSize; /* Total number of bytes in the record */ - u32 *aType; /* Type values for all entries in the record */ - u32 *aOffset; /* Cached offsets to the start of each columns data */ - u8 *aRow; /* Data for the current row, if all on one page */ -}; -typedef struct VdbeCursor VdbeCursor; - -/* -** When a sub-program is executed (OP_Program), a structure of this type -** is allocated to store the current value of the program counter, as -** well as the current memory cell array and various other frame specific -** values stored in the Vdbe struct. When the sub-program is finished, -** these values are copied back to the Vdbe from the VdbeFrame structure, -** restoring the state of the VM to as it was before the sub-program -** began executing. -** -** Frames are stored in a linked list headed at Vdbe.pParent. Vdbe.pParent -** is the parent of the current frame, or zero if the current frame -** is the main Vdbe program. -*/ -typedef struct VdbeFrame VdbeFrame; -struct VdbeFrame { - Vdbe *v; /* VM this frame belongs to */ - int pc; /* Program Counter */ - Op *aOp; /* Program instructions */ - int nOp; /* Size of aOp array */ - Mem *aMem; /* Array of memory cells */ - int nMem; /* Number of entries in aMem */ - VdbeCursor **apCsr; /* Element of Vdbe cursors */ - u16 nCursor; /* Number of entries in apCsr */ - void *token; /* Copy of SubProgram.token */ - int nChildMem; /* Number of memory cells for child frame */ - int nChildCsr; /* Number of cursors for child frame */ - i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ - int nChange; /* Statement changes (Vdbe.nChanges) */ - VdbeFrame *pParent; /* Parent of this frame */ -}; - -#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))]) - -/* -** A value for VdbeCursor.cacheValid that means the cache is always invalid. -*/ -#define CACHE_STALE 0 - -/* -** Internally, the vdbe manipulates nearly all SQL values as Mem -** structures. Each Mem struct may cache multiple representations (string, -** integer etc.) of the same value. A value (and therefore Mem structure) -** has the following properties: -** -** Each value has a manifest type. The manifest type of the value stored -** in a Mem struct is returned by the MemType(Mem*) macro. The type is -** one of SQLITE_NULL, SQLITE_INTEGER, SQLITE_REAL, SQLITE_TEXT or -** SQLITE_BLOB. -*/ -struct Mem { - union { - i64 i; /* Integer value. */ - int nZero; /* Used when bit MEM_Zero is set in flags */ - FuncDef *pDef; /* Used only when flags==MEM_Agg */ - RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ - VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ - } u; - double r; /* Real value */ - sqlite3 *db; /* The associated database connection */ - char *z; /* String or BLOB value */ - int n; /* Number of characters in string value, excluding '\0' */ - u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ - u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */ - u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ - void (*xDel)(void *); /* If not null, call this function to delete Mem.z */ - char *zMalloc; /* Dynamic buffer allocated by sqlite3_malloc() */ -}; - -/* One or more of the following flags are set to indicate the validOK -** representations of the value stored in the Mem struct. -** -** If the MEM_Null flag is set, then the value is an SQL NULL value. -** No other flags may be set in this case. -** -** If the MEM_Str flag is set then Mem.z points at a string representation. -** Usually this is encoded in the same unicode encoding as the main -** database (see below for exceptions). If the MEM_Term flag is also -** set, then the string is nul terminated. The MEM_Int and MEM_Real -** flags may coexist with the MEM_Str flag. -** -** Multiple of these values can appear in Mem.flags. But only one -** at a time can appear in Mem.type. -*/ -#define MEM_Null 0x0001 /* Value is NULL */ -#define MEM_Str 0x0002 /* Value is a string */ -#define MEM_Int 0x0004 /* Value is an integer */ -#define MEM_Real 0x0008 /* Value is a real number */ -#define MEM_Blob 0x0010 /* Value is a BLOB */ -#define MEM_RowSet 0x0020 /* Value is a RowSet object */ -#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ -#define MEM_TypeMask 0x00ff /* Mask of type bits */ - -/* Whenever Mem contains a valid string or blob representation, one of -** the following flags must be set to determine the memory management -** policy for Mem.z. The MEM_Term flag tells us whether or not the -** string is \000 or \u0000 terminated -*/ -#define MEM_Term 0x0200 /* String rep is nul terminated */ -#define MEM_Dyn 0x0400 /* Need to call sqliteFree() on Mem.z */ -#define MEM_Static 0x0800 /* Mem.z points to a static string */ -#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */ -#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */ -#define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */ - -#ifdef SQLITE_OMIT_INCRBLOB - #undef MEM_Zero - #define MEM_Zero 0x0000 -#endif - - -/* -** Clear any existing type flags from a Mem and replace them with f -*/ -#define MemSetTypeFlag(p, f) \ - ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f) - - -/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains -** additional information about auxiliary information bound to arguments -** of the function. This is used to implement the sqlite3_get_auxdata() -** and sqlite3_set_auxdata() APIs. The "auxdata" is some auxiliary data -** that can be associated with a constant argument to a function. This -** allows functions such as "regexp" to compile their constant regular -** expression argument once and reused the compiled code for multiple -** invocations. -*/ -struct VdbeFunc { - FuncDef *pFunc; /* The definition of the function */ - int nAux; /* Number of entries allocated for apAux[] */ - struct AuxData { - void *pAux; /* Aux data for the i-th argument */ - void (*xDelete)(void *); /* Destructor for the aux data */ - } apAux[1]; /* One slot for each function argument */ -}; - -/* -** The "context" argument for a installable function. A pointer to an -** instance of this structure is the first argument to the routines used -** implement the SQL functions. -** -** There is a typedef for this structure in sqlite.h. So all routines, -** even the public interface to SQLite, can use a pointer to this structure. -** But this file is the only place where the internal details of this -** structure are known. -** -** This structure is defined inside of vdbeInt.h because it uses substructures -** (Mem) which are only defined there. -*/ -struct sqlite3_context { - FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */ - VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */ - Mem s; /* The return value is stored here */ - Mem *pMem; /* Memory cell used to store aggregate context */ - int isError; /* Error code returned by the function. */ - CollSeq *pColl; /* Collating sequence */ -}; - -/* -** A Set structure is used for quick testing to see if a value -** is part of a small set. Sets are used to implement code like -** this: -** x.y IN ('hi','hoo','hum') -*/ -typedef struct Set Set; -struct Set { - Hash hash; /* A set is just a hash table */ - HashElem *prev; /* Previously accessed hash elemen */ -}; - -/* -** An instance of the virtual machine. This structure contains the complete -** state of the virtual machine. -** -** The "sqlite3_stmt" structure pointer that is returned by sqlite3_compile() -** is really a pointer to an instance of this structure. -** -** The Vdbe.inVtabMethod variable is set to non-zero for the duration of -** any virtual table method invocations made by the vdbe program. It is -** set to 2 for xDestroy method calls and 1 for all other methods. This -** variable is used for two purposes: to allow xDestroy methods to execute -** "DROP TABLE" statements and to prevent some nasty side effects of -** malloc failure when SQLite is invoked recursively by a virtual table -** method function. -*/ -struct Vdbe { - sqlite3 *db; /* The database connection that owns this statement */ - Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ - int nOp; /* Number of instructions in the program */ - int nOpAlloc; /* Number of slots allocated for aOp[] */ - Op *aOp; /* Space to hold the virtual machine's program */ - int nLabel; /* Number of labels used */ - int nLabelAlloc; /* Number of slots allocated in aLabel[] */ - int *aLabel; /* Space to hold the labels */ - Mem **apArg; /* Arguments to currently executing user function */ - Mem *aColName; /* Column names to return */ - Mem *pResultSet; /* Pointer to an array of results */ - u16 nResColumn; /* Number of columns in one row of the result set */ - u16 nCursor; /* Number of slots in apCsr[] */ - VdbeCursor **apCsr; /* One element of this array for each open cursor */ - u8 errorAction; /* Recovery action to do in case of an error */ - u8 okVar; /* True if azVar[] has been initialized */ - ynVar nVar; /* Number of entries in aVar[] */ - Mem *aVar; /* Values for the OP_Variable opcode. */ - char **azVar; /* Name of variables */ - u32 magic; /* Magic number for sanity checking */ - int nMem; /* Number of memory locations currently allocated */ - Mem *aMem; /* The memory locations */ - u32 cacheCtr; /* VdbeCursor row cache generation counter */ - int pc; /* The program counter */ - int rc; /* Value to return */ - char *zErrMsg; /* Error message written here */ - u8 explain; /* True if EXPLAIN present on SQL command */ - u8 changeCntOn; /* True to update the change-counter */ - u8 expired; /* True if the VM needs to be recompiled */ - u8 runOnlyOnce; /* Automatically expire on reset */ - u8 minWriteFileFormat; /* Minimum file format for writable database files */ - u8 inVtabMethod; /* See comments above */ - u8 usesStmtJournal; /* True if uses a statement journal */ - u8 readOnly; /* True for read-only statements */ - u8 isPrepareV2; /* True if prepared with prepare_v2() */ - int nChange; /* Number of db changes made since last reset */ - int btreeMask; /* Bitmask of db->aDb[] entries referenced */ - i64 startTime; /* Time when query started - used for profiling */ - BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */ - int aCounter[2]; /* Counters used by sqlite3_stmt_status() */ - char *zSql; /* Text of the SQL statement that generated this */ - void *pFree; /* Free this when deleting the vdbe */ - i64 nFkConstraint; /* Number of imm. FK constraints this VM */ - i64 nStmtDefCons; /* Number of def. constraints when stmt started */ - int iStatement; /* Statement number (or 0 if has not opened stmt) */ -#ifdef SQLITE_DEBUG - FILE *trace; /* Write an execution trace here, if not NULL */ -#endif - VdbeFrame *pFrame; /* Parent frame */ - int nFrame; /* Number of frames in pFrame list */ - u32 expmask; /* Binding to these vars invalidates VM */ -}; - -/* -** The following are allowed values for Vdbe.magic -*/ -#define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */ -#define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */ -#define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */ -#define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */ - -/* -** Function prototypes -*/ -SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); -void sqliteVdbePopStack(Vdbe*,int); -SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*); -#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) -SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*); -#endif -SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); -SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int); -SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int); -SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); -SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int); - -int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); -SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*); -SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *); -SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); -SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); -SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); -SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); -SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int); -SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*); -SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); -SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*)); -SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64); -#ifdef SQLITE_OMIT_FLOATING_POINT -# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64 -#else -SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double); -#endif -SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); -SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); -SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, int); -SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); -SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); -SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*); -SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); -SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p); -SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); -SQLITE_PRIVATE const char *sqlite3OpcodeName(int); -SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); -SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); -SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); -SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); -SQLITE_PRIVATE void sqlite3VdbeMemStoreType(Mem *pMem); - -#ifndef SQLITE_OMIT_FOREIGN_KEY -SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int); -#else -# define sqlite3VdbeCheckFk(p,i) 0 -#endif - -#ifndef SQLITE_OMIT_SHARED_CACHE -SQLITE_PRIVATE void sqlite3VdbeMutexArrayEnter(Vdbe *p); -#else -# define sqlite3VdbeMutexArrayEnter(p) -#endif - -SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8); -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe*); -SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf); -#endif -SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem); - -#ifndef SQLITE_OMIT_INCRBLOB -SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *); -#else - #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK -#endif - -#endif /* !defined(_VDBEINT_H_) */ - -/************** End of vdbeInt.h *********************************************/ -/************** Continuing where we left off in utf.c ************************/ +/* #include <assert.h> */ #ifndef SQLITE_AMALGAMATION /* @@ -18542,11 +20216,11 @@ static const unsigned char sqlite3Utf8Trans1[] = { || (c&0xFFFFF800)==0xD800 \ || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ } -SQLITE_PRIVATE int sqlite3Utf8Read( +SQLITE_PRIVATE u32 sqlite3Utf8Read( const unsigned char *zIn, /* First byte of UTF-8 character */ const unsigned char **pzNext /* Write first byte past UTF-8 char here */ ){ - int c; + unsigned int c; /* Same as READ_UTF8() above but without the zTerm parameter. ** For this routine, we assume the UTF8 string is always zero-terminated. @@ -18571,7 +20245,7 @@ SQLITE_PRIVATE int sqlite3Utf8Read( /* ** If the TRANSLATE_TRACE macro is defined, the value of each Mem is ** printed on stderr on the way into and out of sqlite3VdbeMemTranslate(). -*/ +*/ /* #define TRANSLATE_TRACE 1 */ #ifndef SQLITE_OMIT_UTF16 @@ -18602,7 +20276,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ } #endif - /* If the translation is between UTF-16 little and big endian, then + /* If the translation is between UTF-16 little and big endian, then ** all that is required is to swap the byte order. This case is handled ** differently from the others. */ @@ -18682,13 +20356,13 @@ SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ if( pMem->enc==SQLITE_UTF16LE ){ /* UTF-16 Little-endian -> UTF-8 */ while( zIn<zTerm ){ - READ_UTF16LE(zIn, zIn<zTerm, c); + READ_UTF16LE(zIn, zIn<zTerm, c); WRITE_UTF8(z, c); } }else{ /* UTF-16 Big-endian -> UTF-8 */ while( zIn<zTerm ){ - READ_UTF16BE(zIn, zIn<zTerm, c); + READ_UTF16BE(zIn, zIn<zTerm, c); WRITE_UTF8(z, c); } } @@ -18716,7 +20390,7 @@ translate_out: } /* -** This routine checks for a byte-order mark at the beginning of the +** This routine checks for a byte-order mark at the beginning of the ** UTF-16 string stored in *pMem. If one is present, it is removed and ** the encoding of the Mem adjusted. This routine does not do any ** byte-swapping, it just sets Mem.enc appropriately. @@ -18739,7 +20413,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem){ bom = SQLITE_UTF16LE; } } - + if( bom ){ rc = sqlite3VdbeMemMakeWriteable(pMem); if( rc==SQLITE_OK ){ @@ -18759,7 +20433,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem){ ** pZ is a UTF-8 encoded unicode string. If nByte is less than zero, ** return the number of unicode characters in pZ up to (but not including) ** the first 0x00 byte. If nByte is not less than zero, return the -** number of unicode characters in the first nByte of pZ (or up to +** number of unicode characters in the first nByte of pZ (or up to ** the first 0x00, whichever comes first). */ SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *zIn, int nByte){ @@ -18779,7 +20453,7 @@ SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *zIn, int nByte){ return r; } -/* This test function is not currently used by the automated test-suite. +/* This test function is not currently used by the automated test-suite. ** Hence it is only available in debug builds. */ #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) @@ -18789,15 +20463,15 @@ SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *zIn, int nByte){ ** This has the effect of making sure that the string is well-formed ** UTF-8. Miscoded characters are removed. ** -** The translation is done in-place (since it is impossible for the -** correct UTF-8 encoding to be longer than a malformed encoding). +** The translation is done in-place and aborted if the output +** overruns the input. */ SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char *zIn){ unsigned char *zOut = zIn; unsigned char *zStart = zIn; u32 c; - while( zIn[0] ){ + while( zIn[0] && zOut<=zIn ){ c = sqlite3Utf8Read(zIn, (const u8**)&zIn); if( c!=0xfffd ){ WRITE_UTF8(zOut, c); @@ -18839,7 +20513,7 @@ SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 e ** is set to the length of the returned string in bytes. The call should ** arrange to call sqlite3DbFree() on the returned pointer when it is ** no longer required. -** +** ** If a malloc failure occurs, NULL is returned and the db.mallocFailed ** flag set. */ @@ -18868,7 +20542,7 @@ SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){ int c; unsigned char const *z = zIn; int n = 0; - + if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){ while( n<nChar ){ READ_UTF16BE(z, 1, c); @@ -18957,6 +20631,7 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){ ** strings, and stuff like that. ** */ +/* #include <stdarg.h> */ #ifdef SQLITE_HAVE_ISNAN # include <math.h> #endif @@ -18966,8 +20641,8 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){ */ #ifdef SQLITE_COVERAGE_TEST SQLITE_PRIVATE void sqlite3Coverage(int x){ - static int dummy = 0; - dummy += x; + static unsigned dummy = 0; + dummy += (unsigned)x; } #endif @@ -18993,15 +20668,15 @@ SQLITE_PRIVATE int sqlite3IsNaN(double x){ ** ** This option [-ffast-math] should never be turned on by any ** -O option since it can result in incorrect output for programs - ** which depend on an exact implementation of IEEE or ISO + ** which depend on an exact implementation of IEEE or ISO ** rules/specifications for math functions. ** ** Under MSVC, this NaN test may fail if compiled with a floating- - ** point precision mode other than /fp:precise. From the MSDN + ** point precision mode other than /fp:precise. From the MSDN ** documentation: ** - ** The compiler [with /fp:precise] will properly handle comparisons - ** involving NaN. For example, x != x evaluates to true if x is NaN + ** The compiler [with /fp:precise] will properly handle comparisons + ** involving NaN. For example, x != x evaluates to true if x is NaN ** ... */ #ifdef __FAST_MATH__ @@ -19155,6 +20830,12 @@ SQLITE_PRIVATE int sqlite3Dequote(char *z){ /* ** Some systems have stricmp(). Others have strcasecmp(). Because ** there is no consistency, we will define our own. +** +** IMPLEMENTATION-OF: R-20522-24639 The sqlite3_strnicmp() API allows +** applications and extensions to compare the contents of two buffers +** containing UTF-8 strings in a case-independent fashion, using the same +** definition of case independence that SQLite uses internally when +** comparing identifiers. */ SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){ register unsigned char *a, *b; @@ -19172,121 +20853,111 @@ SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ } /* -** Return TRUE if z is a pure numeric string. Return FALSE and leave -** *realnum unchanged if the string contains any character which is not -** part of a number. +** The string z[] is an text representation of a real number. +** Convert this string to a double and write it into *pResult. ** -** If the string is pure numeric, set *realnum to TRUE if the string -** contains the '.' character or an "E+000" style exponentiation suffix. -** Otherwise set *realnum to FALSE. Note that just becaue *realnum is -** false does not mean that the number can be successfully converted into -** an integer - it might be too big. +** The string z[] is length bytes in length (bytes, not characters) and +** uses the encoding enc. The string is not necessarily zero-terminated. ** -** An empty string is considered non-numeric. -*/ -SQLITE_PRIVATE int sqlite3IsNumber(const char *z, int *realnum, u8 enc){ - int incr = (enc==SQLITE_UTF8?1:2); - if( enc==SQLITE_UTF16BE ) z++; - if( *z=='-' || *z=='+' ) z += incr; - if( !sqlite3Isdigit(*z) ){ - return 0; - } - z += incr; - *realnum = 0; - while( sqlite3Isdigit(*z) ){ z += incr; } -#ifndef SQLITE_OMIT_FLOATING_POINT - if( *z=='.' ){ - z += incr; - if( !sqlite3Isdigit(*z) ) return 0; - while( sqlite3Isdigit(*z) ){ z += incr; } - *realnum = 1; - } - if( *z=='e' || *z=='E' ){ - z += incr; - if( *z=='+' || *z=='-' ) z += incr; - if( !sqlite3Isdigit(*z) ) return 0; - while( sqlite3Isdigit(*z) ){ z += incr; } - *realnum = 1; - } -#endif - return *z==0; -} - -/* -** The string z[] is an ASCII representation of a real number. -** Convert this string to a double. +** Return TRUE if the result is a valid real number (or integer) and FALSE +** if the string is empty or contains extraneous text. Valid numbers +** are in one of these formats: ** -** This routine assumes that z[] really is a valid number. If it -** is not, the result is undefined. +** [+-]digits[E[+-]digits] +** [+-]digits.[digits][E[+-]digits] +** [+-].digits[E[+-]digits] ** -** This routine is used instead of the library atof() function because -** the library atof() might want to use "," as the decimal point instead -** of "." depending on how locale is set. But that would cause problems -** for SQL. So this routine always uses "." regardless of locale. +** Leading and trailing whitespace is ignored for the purpose of determining +** validity. +** +** If some prefix of the input string is a valid number, this routine +** returns FALSE but it still converts the prefix and writes the result +** into *pResult. */ -SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult){ +SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ #ifndef SQLITE_OMIT_FLOATING_POINT - const char *zBegin = z; + int incr = (enc==SQLITE_UTF8?1:2); + const char *zEnd = z + length; /* sign * significand * (10 ^ (esign * exponent)) */ - int sign = 1; /* sign of significand */ - i64 s = 0; /* significand */ - int d = 0; /* adjust exponent for shifting decimal point */ - int esign = 1; /* sign of exponent */ - int e = 0; /* exponent */ + int sign = 1; /* sign of significand */ + i64 s = 0; /* significand */ + int d = 0; /* adjust exponent for shifting decimal point */ + int esign = 1; /* sign of exponent */ + int e = 0; /* exponent */ + int eValid = 1; /* True exponent is either not used or is well-formed */ double result; int nDigits = 0; + *pResult = 0.0; /* Default return value, in case of an error */ + + if( enc==SQLITE_UTF16BE ) z++; + /* skip leading spaces */ - while( sqlite3Isspace(*z) ) z++; + while( z<zEnd && sqlite3Isspace(*z) ) z+=incr; + if( z>=zEnd ) return 0; + /* get sign of significand */ if( *z=='-' ){ sign = -1; - z++; + z+=incr; }else if( *z=='+' ){ - z++; + z+=incr; } + /* skip leading zeroes */ - while( z[0]=='0' ) z++, nDigits++; + while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++; /* copy max significant digits to significand */ - while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ + while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ s = s*10 + (*z - '0'); - z++, nDigits++; + z+=incr, nDigits++; } + /* skip non-significant significand digits ** (increase exponent by d to shift decimal left) */ - while( sqlite3Isdigit(*z) ) z++, nDigits++, d++; + while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++, d++; + if( z>=zEnd ) goto do_atof_calc; /* if decimal point is present */ if( *z=='.' ){ - z++; + z+=incr; /* copy digits from after decimal to significand ** (decrease exponent by d to shift decimal right) */ - while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ + while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ s = s*10 + (*z - '0'); - z++, nDigits++, d--; + z+=incr, nDigits++, d--; } /* skip non-significant digits */ - while( sqlite3Isdigit(*z) ) z++, nDigits++; + while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++; } + if( z>=zEnd ) goto do_atof_calc; /* if exponent is present */ if( *z=='e' || *z=='E' ){ - z++; + z+=incr; + eValid = 0; + if( z>=zEnd ) goto do_atof_calc; /* get sign of exponent */ if( *z=='-' ){ esign = -1; - z++; + z+=incr; }else if( *z=='+' ){ - z++; + z+=incr; } /* copy digits to exponent */ - while( sqlite3Isdigit(*z) ){ + while( z<zEnd && sqlite3Isdigit(*z) ){ e = e*10 + (*z - '0'); - z++; + z+=incr; + eValid = 1; } } + /* skip trailing spaces */ + if( nDigits && eValid ){ + while( z<zEnd && sqlite3Isspace(*z) ) z+=incr; + } + +do_atof_calc: /* adjust exponent by d, and update sign */ e = (e*esign) + d; if( e<0 ) { @@ -19327,7 +20998,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult){ result *= 1.0e+308; } }else{ - /* 1.0e+22 is the largest power of 10 than can be + /* 1.0e+22 is the largest power of 10 than can be ** represented exactly. */ while( e%22 ) { scale *= 1.0e+1; e -= 1; } while( e>0 ) { scale *= 1.0e+22; e -= 22; } @@ -19345,10 +21016,10 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult){ /* store the result */ *pResult = result; - /* return number of characters used */ - return (int)(z - zBegin); + /* return true if number and no extra non-whitespace chracters after */ + return z>=zEnd && nDigits>0 && eValid; #else - return sqlite3Atoi64(z, pResult); + return !sqlite3Atoi64(z, pResult, length, enc); #endif /* SQLITE_OMIT_FLOATING_POINT */ } @@ -19356,20 +21027,26 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult){ ** Compare the 19-character string zNum against the text representation ** value 2^63: 9223372036854775808. Return negative, zero, or positive ** if zNum is less than, equal to, or greater than the string. +** Note that zNum must contain exactly 19 characters. ** ** Unlike memcmp() this routine is guaranteed to return the difference ** in the values of the last digit if the only difference is in the ** last digit. So, for example, ** -** compare2pow63("9223372036854775800") +** compare2pow63("9223372036854775800", 1) ** ** will return -8. */ -static int compare2pow63(const char *zNum){ - int c; - c = memcmp(zNum,"922337203685477580",18)*10; +static int compare2pow63(const char *zNum, int incr){ + int c = 0; + int i; + /* 012345678901234567 */ + const char *pow63 = "922337203685477580"; + for(i=0; c==0 && i<18; i++){ + c = (zNum[i*incr]-pow63[i])*10; + } if( c==0 ){ - c = zNum[18] - '8'; + c = zNum[18*incr] - '8'; testcase( c==(-1) ); testcase( c==0 ); testcase( c==(+1) ); @@ -19379,94 +21056,80 @@ static int compare2pow63(const char *zNum){ /* -** Return TRUE if zNum is a 64-bit signed integer and write -** the value of the integer into *pNum. If zNum is not an integer -** or is an integer that is too large to be expressed with 64 bits, -** then return false. +** Convert zNum to a 64-bit signed integer. ** -** When this routine was originally written it dealt with only -** 32-bit numbers. At that time, it was much faster than the -** atoi() library routine in RedHat 7.2. -*/ -SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum){ - i64 v = 0; - int neg; - int i, c; - const char *zStart; - while( sqlite3Isspace(*zNum) ) zNum++; - if( *zNum=='-' ){ - neg = 1; - zNum++; - }else if( *zNum=='+' ){ - neg = 0; - zNum++; - }else{ - neg = 0; - } - zStart = zNum; - while( zNum[0]=='0' ){ zNum++; } /* Skip over leading zeros. Ticket #2454 */ - for(i=0; (c=zNum[i])>='0' && c<='9'; i++){ - v = v*10 + c - '0'; - } - *pNum = neg ? -v : v; - testcase( i==18 ); - testcase( i==19 ); - testcase( i==20 ); - if( c!=0 || (i==0 && zStart==zNum) || i>19 ){ - /* zNum is empty or contains non-numeric text or is longer - ** than 19 digits (thus guaranting that it is too large) */ - return 0; - }else if( i<19 ){ - /* Less than 19 digits, so we know that it fits in 64 bits */ - return 1; - }else{ - /* 19-digit numbers must be no larger than 9223372036854775807 if positive - ** or 9223372036854775808 if negative. Note that 9223372036854665808 - ** is 2^63. */ - return compare2pow63(zNum)<neg; - } -} - -/* -** The string zNum represents an unsigned integer. The zNum string -** consists of one or more digit characters and is terminated by -** a zero character. Any stray characters in zNum result in undefined -** behavior. +** If the zNum value is representable as a 64-bit twos-complement +** integer, then write that value into *pNum and return 0. ** -** If the unsigned integer that zNum represents will fit in a -** 64-bit signed integer, return TRUE. Otherwise return FALSE. +** If zNum is exactly 9223372036854665808, return 2. This special +** case is broken out because while 9223372036854665808 cannot be a +** signed 64-bit integer, its negative -9223372036854665808 can be. ** -** If the negFlag parameter is true, that means that zNum really represents -** a negative number. (The leading "-" is omitted from zNum.) This -** parameter is needed to determine a boundary case. A string -** of "9223373036854775808" returns false if negFlag is false or true -** if negFlag is true. +** If zNum is too big for a 64-bit integer and is not +** 9223372036854665808 then return 1. ** -** Leading zeros are ignored. +** length is the number of bytes in the string (bytes, not characters). +** The string is not necessarily zero-terminated. The encoding is +** given by enc. */ -SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *zNum, int negFlag){ +SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ + int incr = (enc==SQLITE_UTF8?1:2); + u64 u = 0; + int neg = 0; /* assume positive */ int i; - int neg = 0; - - assert( zNum[0]>='0' && zNum[0]<='9' ); /* zNum is an unsigned number */ - - if( negFlag ) neg = 1-neg; - while( *zNum=='0' ){ - zNum++; /* Skip leading zeros. Ticket #2454 */ + int c = 0; + const char *zStart; + const char *zEnd = zNum + length; + if( enc==SQLITE_UTF16BE ) zNum++; + while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr; + if( zNum<zEnd ){ + if( *zNum=='-' ){ + neg = 1; + zNum+=incr; + }else if( *zNum=='+' ){ + zNum+=incr; + } + } + zStart = zNum; + while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */ + for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){ + u = u*10 + c - '0'; + } + if( u>LARGEST_INT64 ){ + *pNum = SMALLEST_INT64; + }else if( neg ){ + *pNum = -(i64)u; + }else{ + *pNum = (i64)u; } - for(i=0; zNum[i]; i++){ assert( zNum[i]>='0' && zNum[i]<='9' ); } testcase( i==18 ); testcase( i==19 ); testcase( i==20 ); - if( i<19 ){ - /* Guaranteed to fit if less than 19 digits */ + if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){ + /* zNum is empty or contains non-numeric text or is longer + ** than 19 digits (thus guaranteeing that it is too large) */ return 1; - }else if( i>19 ){ - /* Guaranteed to be too big if greater than 19 digits */ + }else if( i<19*incr ){ + /* Less than 19 digits, so we know that it fits in 64 bits */ + assert( u<=LARGEST_INT64 ); return 0; }else{ - /* Compare against 2^63. */ - return compare2pow63(zNum)<neg; + /* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */ + c = compare2pow63(zNum, incr); + if( c<0 ){ + /* zNum is less than 9223372036854775808 so it fits */ + assert( u<=LARGEST_INT64 ); + return 0; + }else if( c>0 ){ + /* zNum is greater than 9223372036854775808 so it overflows */ + return 1; + }else{ + /* zNum is exactly 9223372036854775808. Fits if negative. The + ** special case 2 overflow if positive */ + assert( u-1==LARGEST_INT64 ); + assert( (*pNum)==SMALLEST_INT64 ); + return neg ? 0 : 2; + } } } @@ -19514,6 +21177,16 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){ } /* +** Return a 32-bit integer value extracted from a string. If the +** string is not an integer, just return 0. +*/ +SQLITE_PRIVATE int sqlite3Atoi(const char *z){ + int x = 0; + if( z ) sqlite3GetInt32(z, &x); + return x; +} + +/* ** The variable-length integer encoding is as follows: ** ** KEY: @@ -19553,7 +21226,7 @@ SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){ v >>= 7; } return 9; - } + } n = 0; do{ buf[n++] = (u8)((v & 0x7f) | 0x80); @@ -19773,8 +21446,8 @@ SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ ** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned ** integer, then set *v to 0xffffffff. ** -** A MACRO version, getVarint32, is provided which inlines the -** single-byte case. All code should use the MACRO version as +** A MACRO version, getVarint32, is provided which inlines the +** single-byte case. All code should use the MACRO version as ** this function assumes the single-byte case has already been handled. */ SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){ @@ -19925,13 +21598,12 @@ SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){ -#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) /* ** Translate a single byte of Hex into an integer. ** This routine only works if h really is a valid hexadecimal ** character: 0..9a..fA..F */ -static u8 hexToInt(int h){ +SQLITE_PRIVATE u8 sqlite3HexToInt(int h){ assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); #ifdef SQLITE_ASCII h += 9*(1&(h>>6)); @@ -19941,7 +21613,6 @@ static u8 hexToInt(int h){ #endif return (u8)(h & 0xf); } -#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */ #if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) /* @@ -19958,7 +21629,7 @@ SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ n--; if( zBlob ){ for(i=0; i<n; i+=2){ - zBlob[i/2] = (hexToInt(z[i])<<4) | hexToInt(z[i+1]); + zBlob[i/2] = (sqlite3HexToInt(z[i])<<4) | sqlite3HexToInt(z[i+1]); } zBlob[i/2] = 0; } @@ -19972,7 +21643,7 @@ SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ ** argument. The zType is a word like "NULL" or "closed" or "invalid". */ static void logBadConnection(const char *zType){ - sqlite3_log(SQLITE_MISUSE, + sqlite3_log(SQLITE_MISUSE, "API call with %s database connection pointer", zType ); @@ -20023,6 +21694,106 @@ SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ } } +/* +** Attempt to add, substract, or multiply the 64-bit signed value iB against +** the other 64-bit signed integer at *pA and store the result in *pA. +** Return 0 on success. Or if the operation would have resulted in an +** overflow, leave *pA unchanged and return 1. +*/ +SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){ + i64 iA = *pA; + testcase( iA==0 ); testcase( iA==1 ); + testcase( iB==-1 ); testcase( iB==0 ); + if( iB>=0 ){ + testcase( iA>0 && LARGEST_INT64 - iA == iB ); + testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 ); + if( iA>0 && LARGEST_INT64 - iA < iB ) return 1; + *pA += iB; + }else{ + testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 ); + testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 ); + if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1; + *pA += iB; + } + return 0; +} +SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){ + testcase( iB==SMALLEST_INT64+1 ); + if( iB==SMALLEST_INT64 ){ + testcase( (*pA)==(-1) ); testcase( (*pA)==0 ); + if( (*pA)>=0 ) return 1; + *pA -= iB; + return 0; + }else{ + return sqlite3AddInt64(pA, -iB); + } +} +#define TWOPOWER32 (((i64)1)<<32) +#define TWOPOWER31 (((i64)1)<<31) +SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){ + i64 iA = *pA; + i64 iA1, iA0, iB1, iB0, r; + + iA1 = iA/TWOPOWER32; + iA0 = iA % TWOPOWER32; + iB1 = iB/TWOPOWER32; + iB0 = iB % TWOPOWER32; + if( iA1*iB1 != 0 ) return 1; + assert( iA1*iB0==0 || iA0*iB1==0 ); + r = iA1*iB0 + iA0*iB1; + testcase( r==(-TWOPOWER31)-1 ); + testcase( r==(-TWOPOWER31) ); + testcase( r==TWOPOWER31 ); + testcase( r==TWOPOWER31-1 ); + if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1; + r *= TWOPOWER32; + if( sqlite3AddInt64(&r, iA0*iB0) ) return 1; + *pA = r; + return 0; +} + +/* +** Compute the absolute value of a 32-bit signed integer, of possible. Or +** if the integer has a value of -2147483648, return +2147483647 +*/ +SQLITE_PRIVATE int sqlite3AbsInt32(int x){ + if( x>=0 ) return x; + if( x==(int)0x80000000 ) return 0x7fffffff; + return -x; +} + +#ifdef SQLITE_ENABLE_8_3_NAMES +/* +** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database +** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and +** if filename in z[] has a suffix (a.k.a. "extension") that is longer than +** three characters, then shorten the suffix on z[] to be the last three +** characters of the original suffix. +** +** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always +** do the suffix shortening regardless of URI parameter. +** +** Examples: +** +** test.db-journal => test.nal +** test.db-wal => test.wal +** test.db-shm => test.shm +*/ +SQLITE_PRIVATE void sqlite3FileSuffix3(const char *zBaseFilename, char *z){ +#if SQLITE_ENABLE_8_3_NAMES<2 + const char *zOk; + zOk = sqlite3_uri_parameter(zBaseFilename, "8_3_names"); + if( zOk && sqlite3GetBoolean(zOk) ) +#endif + { + int i, sz; + sz = sqlite3Strlen30(z); + for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} + if( z[i]=='.' && ALWAYS(sz>i+4) ) memcpy(&z[i+1], &z[sz-3], 4); + } +} +#endif + /************** End of util.c ************************************************/ /************** Begin file hash.c ********************************************/ /* @@ -20039,6 +21810,7 @@ SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ ** This is the implementation of generic hash-tables ** used in SQLite. */ +/* #include <assert.h> */ /* Turn bulk memory into a hash table object by initializing the ** fields of the Hash structure. @@ -20179,7 +21951,7 @@ static HashElem *findElementGivenHash( count = pH->count; } while( count-- && ALWAYS(elem) ){ - if( elem->nKey==nKey && sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ + if( elem->nKey==nKey && sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ return elem; } elem = elem->next; @@ -20197,7 +21969,7 @@ static void removeElementGivenHash( ){ struct _ht *pEntry; if( elem->prev ){ - elem->prev->next = elem->next; + elem->prev->next = elem->next; }else{ pH->first = elem->next; } @@ -20333,53 +22105,53 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 23 */ "Permutation", /* 24 */ "Compare", /* 25 */ "Jump", - /* 26 */ "If", - /* 27 */ "IfNot", - /* 28 */ "Column", - /* 29 */ "Affinity", - /* 30 */ "MakeRecord", - /* 31 */ "Count", - /* 32 */ "Savepoint", - /* 33 */ "AutoCommit", - /* 34 */ "Transaction", - /* 35 */ "ReadCookie", - /* 36 */ "SetCookie", - /* 37 */ "VerifyCookie", - /* 38 */ "OpenRead", - /* 39 */ "OpenWrite", - /* 40 */ "OpenEphemeral", - /* 41 */ "OpenPseudo", - /* 42 */ "Close", - /* 43 */ "SeekLt", - /* 44 */ "SeekLe", - /* 45 */ "SeekGe", - /* 46 */ "SeekGt", - /* 47 */ "Seek", - /* 48 */ "NotFound", - /* 49 */ "Found", - /* 50 */ "IsUnique", - /* 51 */ "NotExists", - /* 52 */ "Sequence", - /* 53 */ "NewRowid", - /* 54 */ "Insert", - /* 55 */ "InsertInt", - /* 56 */ "Delete", - /* 57 */ "ResetCount", - /* 58 */ "RowKey", - /* 59 */ "RowData", - /* 60 */ "Rowid", - /* 61 */ "NullRow", - /* 62 */ "Last", - /* 63 */ "Sort", - /* 64 */ "Rewind", - /* 65 */ "Prev", - /* 66 */ "Next", - /* 67 */ "IdxInsert", + /* 26 */ "Once", + /* 27 */ "If", + /* 28 */ "IfNot", + /* 29 */ "Column", + /* 30 */ "Affinity", + /* 31 */ "MakeRecord", + /* 32 */ "Count", + /* 33 */ "Savepoint", + /* 34 */ "AutoCommit", + /* 35 */ "Transaction", + /* 36 */ "ReadCookie", + /* 37 */ "SetCookie", + /* 38 */ "VerifyCookie", + /* 39 */ "OpenRead", + /* 40 */ "OpenWrite", + /* 41 */ "OpenAutoindex", + /* 42 */ "OpenEphemeral", + /* 43 */ "SorterOpen", + /* 44 */ "OpenPseudo", + /* 45 */ "Close", + /* 46 */ "SeekLt", + /* 47 */ "SeekLe", + /* 48 */ "SeekGe", + /* 49 */ "SeekGt", + /* 50 */ "Seek", + /* 51 */ "NotFound", + /* 52 */ "Found", + /* 53 */ "IsUnique", + /* 54 */ "NotExists", + /* 55 */ "Sequence", + /* 56 */ "NewRowid", + /* 57 */ "Insert", + /* 58 */ "InsertInt", + /* 59 */ "Delete", + /* 60 */ "ResetCount", + /* 61 */ "SorterCompare", + /* 62 */ "SorterData", + /* 63 */ "RowKey", + /* 64 */ "RowData", + /* 65 */ "Rowid", + /* 66 */ "NullRow", + /* 67 */ "Last", /* 68 */ "Or", /* 69 */ "And", - /* 70 */ "IdxDelete", - /* 71 */ "IdxRowid", - /* 72 */ "IdxLT", + /* 70 */ "SorterSort", + /* 71 */ "Sort", + /* 72 */ "Rewind", /* 73 */ "IsNull", /* 74 */ "NotNull", /* 75 */ "Ne", @@ -20388,7 +22160,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 78 */ "Le", /* 79 */ "Lt", /* 80 */ "Ge", - /* 81 */ "IdxGE", + /* 81 */ "SorterNext", /* 82 */ "BitAnd", /* 83 */ "BitOr", /* 84 */ "ShiftLeft", @@ -20399,60 +22171,65 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 89 */ "Divide", /* 90 */ "Remainder", /* 91 */ "Concat", - /* 92 */ "Destroy", + /* 92 */ "Prev", /* 93 */ "BitNot", /* 94 */ "String8", - /* 95 */ "Clear", - /* 96 */ "CreateIndex", - /* 97 */ "CreateTable", - /* 98 */ "ParseSchema", - /* 99 */ "LoadAnalysis", - /* 100 */ "DropTable", - /* 101 */ "DropIndex", - /* 102 */ "DropTrigger", - /* 103 */ "IntegrityCk", - /* 104 */ "RowSetAdd", - /* 105 */ "RowSetRead", - /* 106 */ "RowSetTest", - /* 107 */ "Program", - /* 108 */ "Param", - /* 109 */ "FkCounter", - /* 110 */ "FkIfZero", - /* 111 */ "MemMax", - /* 112 */ "IfPos", - /* 113 */ "IfNeg", - /* 114 */ "IfZero", - /* 115 */ "AggStep", - /* 116 */ "AggFinal", - /* 117 */ "Vacuum", - /* 118 */ "IncrVacuum", - /* 119 */ "Expire", - /* 120 */ "TableLock", - /* 121 */ "VBegin", - /* 122 */ "VCreate", - /* 123 */ "VDestroy", - /* 124 */ "VOpen", - /* 125 */ "VFilter", - /* 126 */ "VColumn", - /* 127 */ "VNext", - /* 128 */ "VRename", - /* 129 */ "VUpdate", + /* 95 */ "Next", + /* 96 */ "SorterInsert", + /* 97 */ "IdxInsert", + /* 98 */ "IdxDelete", + /* 99 */ "IdxRowid", + /* 100 */ "IdxLT", + /* 101 */ "IdxGE", + /* 102 */ "Destroy", + /* 103 */ "Clear", + /* 104 */ "CreateIndex", + /* 105 */ "CreateTable", + /* 106 */ "ParseSchema", + /* 107 */ "LoadAnalysis", + /* 108 */ "DropTable", + /* 109 */ "DropIndex", + /* 110 */ "DropTrigger", + /* 111 */ "IntegrityCk", + /* 112 */ "RowSetAdd", + /* 113 */ "RowSetRead", + /* 114 */ "RowSetTest", + /* 115 */ "Program", + /* 116 */ "Param", + /* 117 */ "FkCounter", + /* 118 */ "FkIfZero", + /* 119 */ "MemMax", + /* 120 */ "IfPos", + /* 121 */ "IfNeg", + /* 122 */ "IfZero", + /* 123 */ "AggStep", + /* 124 */ "AggFinal", + /* 125 */ "Checkpoint", + /* 126 */ "JournalMode", + /* 127 */ "Vacuum", + /* 128 */ "IncrVacuum", + /* 129 */ "Expire", /* 130 */ "Real", - /* 131 */ "Pagecount", - /* 132 */ "Trace", - /* 133 */ "Noop", - /* 134 */ "Explain", - /* 135 */ "NotUsed_135", - /* 136 */ "NotUsed_136", - /* 137 */ "NotUsed_137", - /* 138 */ "NotUsed_138", - /* 139 */ "NotUsed_139", - /* 140 */ "NotUsed_140", + /* 131 */ "TableLock", + /* 132 */ "VBegin", + /* 133 */ "VCreate", + /* 134 */ "VDestroy", + /* 135 */ "VOpen", + /* 136 */ "VFilter", + /* 137 */ "VColumn", + /* 138 */ "VNext", + /* 139 */ "VRename", + /* 140 */ "VUpdate", /* 141 */ "ToText", /* 142 */ "ToBlob", /* 143 */ "ToNumeric", /* 144 */ "ToInt", /* 145 */ "ToReal", + /* 146 */ "Pagecount", + /* 147 */ "MaxPgcnt", + /* 148 */ "Trace", + /* 149 */ "Noop", + /* 150 */ "Explain", }; return azName[i]; } @@ -20547,25 +22324,14 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." #endif -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE int sqlite3OSTrace = 0; -#define OSTRACE1(X) if( sqlite3OSTrace ) sqlite3DebugPrintf(X) -#define OSTRACE2(X,Y) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y) -#define OSTRACE3(X,Y,Z) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z) -#define OSTRACE4(X,Y,Z,A) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A) -#define OSTRACE5(X,Y,Z,A,B) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A,B) -#define OSTRACE6(X,Y,Z,A,B,C) \ - if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C) -#define OSTRACE7(X,Y,Z,A,B,C,D) \ - if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D) +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +# ifndef SQLITE_DEBUG_OS_TRACE +# define SQLITE_DEBUG_OS_TRACE 0 +# endif + int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; +# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X #else -#define OSTRACE1(X) -#define OSTRACE2(X,Y) -#define OSTRACE3(X,Y,Z) -#define OSTRACE4(X,Y,Z,A) -#define OSTRACE5(X,Y,Z,A,B) -#define OSTRACE6(X,Y,Z,A,B,C) -#define OSTRACE7(X,Y,Z,A,B,C,D) +# define OSTRACE(X) #endif /* @@ -20574,8 +22340,8 @@ SQLITE_PRIVATE int sqlite3OSTrace = 0; */ #ifdef SQLITE_PERFORMANCE_TRACE -/* -** hwtime.h contains inline assembler code for implementing +/* +** hwtime.h contains inline assembler code for implementing ** high-performance timing routines. */ /************** Include hwtime.h in the middle of os_common.h ****************/ @@ -20633,7 +22399,7 @@ SQLITE_PRIVATE int sqlite3OSTrace = 0; __asm__ __volatile__ ("rdtsc" : "=A" (val)); return val; } - + #elif (defined(__GNUC__) && defined(__ppc__)) __inline__ sqlite_uint64 sqlite3Hwtime(void){ @@ -20735,20 +22501,35 @@ SQLITE_API int sqlite3_open_file_count = 0; /************** End of os_common.h *******************************************/ /************** Continuing where we left off in os_os2.c *********************/ +/* Forward references */ +typedef struct os2File os2File; /* The file structure */ +typedef struct os2ShmNode os2ShmNode; /* A shared descritive memory node */ +typedef struct os2ShmLink os2ShmLink; /* A connection to shared-memory */ + /* ** The os2File structure is subclass of sqlite3_file specific for the OS/2 ** protability layer. */ -typedef struct os2File os2File; struct os2File { const sqlite3_io_methods *pMethod; /* Always the first entry */ HFILE h; /* Handle for accessing the file */ - char* pathToDel; /* Name of file to delete on close, NULL if not */ - unsigned char locktype; /* Type of lock currently held on this file */ + int flags; /* Flags provided to os2Open() */ + int locktype; /* Type of lock currently held on this file */ + int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ + char *zFullPathCp; /* Full path name of this file */ + os2ShmLink *pShmLink; /* Instance of shared memory on this file */ }; #define LOCK_TIMEOUT 10L /* the default locking timeout */ +/* +** Missing from some versions of the OS/2 toolkit - +** used to allocate from high memory if possible +*/ +#ifndef OBJ_ANY +# define OBJ_ANY 0x00000400 +#endif + /***************************************************************************** ** The next group of routines implement the I/O methods specified ** by the sqlite3_io_methods object. @@ -20758,21 +22539,24 @@ struct os2File { ** Close a file. */ static int os2Close( sqlite3_file *id ){ - APIRET rc = NO_ERROR; - os2File *pFile; - if( id && (pFile = (os2File*)id) != 0 ){ - OSTRACE2( "CLOSE %d\n", pFile->h ); - rc = DosClose( pFile->h ); - pFile->locktype = NO_LOCK; - if( pFile->pathToDel != NULL ){ - rc = DosForceDelete( (PSZ)pFile->pathToDel ); - free( pFile->pathToDel ); - pFile->pathToDel = NULL; - } - id = 0; - OpenCounter( -1 ); - } + APIRET rc; + os2File *pFile = (os2File*)id; + + assert( id!=0 ); + OSTRACE(( "CLOSE %d (%s)\n", pFile->h, pFile->zFullPathCp )); + rc = DosClose( pFile->h ); + + if( pFile->flags & SQLITE_OPEN_DELETEONCLOSE ) + DosForceDelete( (PSZ)pFile->zFullPathCp ); + + free( pFile->zFullPathCp ); + pFile->zFullPathCp = NULL; + pFile->locktype = NO_LOCK; + pFile->h = (HFILE)-1; + pFile->flags = 0; + + OpenCounter( -1 ); return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; } @@ -20792,7 +22576,7 @@ static int os2Read( os2File *pFile = (os2File*)id; assert( id!=0 ); SimulateIOError( return SQLITE_IOERR_READ ); - OSTRACE3( "READ %d lock=%d\n", pFile->h, pFile->locktype ); + OSTRACE(( "READ %d lock=%d\n", pFile->h, pFile->locktype )); if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){ return SQLITE_IOERR; } @@ -20825,7 +22609,7 @@ static int os2Write( assert( id!=0 ); SimulateIOError( return SQLITE_IOERR_WRITE ); SimulateDiskfullError( return SQLITE_FULL ); - OSTRACE3( "WRITE %d lock=%d\n", pFile->h, pFile->locktype ); + OSTRACE(( "WRITE %d lock=%d\n", pFile->h, pFile->locktype )); if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){ return SQLITE_IOERR; } @@ -20845,10 +22629,21 @@ static int os2Write( ** Truncate an open file to a specified size */ static int os2Truncate( sqlite3_file *id, i64 nByte ){ - APIRET rc = NO_ERROR; + APIRET rc; os2File *pFile = (os2File*)id; - OSTRACE3( "TRUNCATE %d %lld\n", pFile->h, nByte ); + assert( id!=0 ); + OSTRACE(( "TRUNCATE %d %lld\n", pFile->h, nByte )); SimulateIOError( return SQLITE_IOERR_TRUNCATE ); + + /* If the user has configured a chunk-size for this file, truncate the + ** file so that it consists of an integer number of chunks (i.e. the + ** actual file size after the operation may be larger than the requested + ** size). + */ + if( pFile->szChunk ){ + nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; + } + rc = DosSetFileSize( pFile->h, nByte ); return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_TRUNCATE; } @@ -20867,7 +22662,7 @@ SQLITE_API int sqlite3_fullsync_count = 0; */ static int os2Sync( sqlite3_file *id, int flags ){ os2File *pFile = (os2File*)id; - OSTRACE3( "SYNC %d lock=%d\n", pFile->h, pFile->locktype ); + OSTRACE(( "SYNC %d lock=%d\n", pFile->h, pFile->locktype )); #ifdef SQLITE_TEST if( flags & SQLITE_SYNC_FULL){ sqlite3_fullsync_count++; @@ -20917,7 +22712,7 @@ static int getReadLock( os2File *pFile ){ UnlockArea.lOffset = 0L; UnlockArea.lRange = 0L; res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L ); - OSTRACE3( "GETREADLOCK %d res=%d\n", pFile->h, res ); + OSTRACE(( "GETREADLOCK %d res=%d\n", pFile->h, res )); return res; } @@ -20935,7 +22730,7 @@ static int unlockReadLock( os2File *id ){ UnlockArea.lOffset = SHARED_FIRST; UnlockArea.lRange = SHARED_SIZE; res = DosSetFileLocks( id->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L ); - OSTRACE3( "UNLOCK-READLOCK file handle=%d res=%d?\n", id->h, res ); + OSTRACE(( "UNLOCK-READLOCK file handle=%d res=%d?\n", id->h, res )); return res; } @@ -20976,14 +22771,14 @@ static int os2Lock( sqlite3_file *id, int locktype ){ memset(&LockArea, 0, sizeof(LockArea)); memset(&UnlockArea, 0, sizeof(UnlockArea)); assert( pFile!=0 ); - OSTRACE4( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype ); + OSTRACE(( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype )); /* If there is already a lock of this type or more restrictive on the ** os2File, do nothing. Don't use the end_lock: exit path, as ** sqlite3_mutex_enter() hasn't been called yet. */ if( pFile->locktype>=locktype ){ - OSTRACE3( "LOCK %d %d ok (already held)\n", pFile->h, locktype ); + OSTRACE(( "LOCK %d %d ok (already held)\n", pFile->h, locktype )); return SQLITE_OK; } @@ -21010,7 +22805,7 @@ static int os2Lock( sqlite3_file *id, int locktype ){ res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 100L, 0L ); if( res == NO_ERROR ){ gotPendingLock = 1; - OSTRACE3( "LOCK %d pending lock boolean set. res=%d\n", pFile->h, res ); + OSTRACE(( "LOCK %d pending lock boolean set. res=%d\n", pFile->h, res )); } } @@ -21022,7 +22817,7 @@ static int os2Lock( sqlite3_file *id, int locktype ){ if( res == NO_ERROR ){ newLocktype = SHARED_LOCK; } - OSTRACE3( "LOCK %d acquire shared lock. res=%d\n", pFile->h, res ); + OSTRACE(( "LOCK %d acquire shared lock. res=%d\n", pFile->h, res )); } /* Acquire a RESERVED lock @@ -21037,7 +22832,7 @@ static int os2Lock( sqlite3_file *id, int locktype ){ if( res == NO_ERROR ){ newLocktype = RESERVED_LOCK; } - OSTRACE3( "LOCK %d acquire reserved lock. res=%d\n", pFile->h, res ); + OSTRACE(( "LOCK %d acquire reserved lock. res=%d\n", pFile->h, res )); } /* Acquire a PENDING lock @@ -21045,7 +22840,8 @@ static int os2Lock( sqlite3_file *id, int locktype ){ if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){ newLocktype = PENDING_LOCK; gotPendingLock = 0; - OSTRACE2( "LOCK %d acquire pending lock. pending lock boolean unset.\n", pFile->h ); + OSTRACE(( "LOCK %d acquire pending lock. pending lock boolean unset.\n", + pFile->h )); } /* Acquire an EXCLUSIVE lock @@ -21053,7 +22849,7 @@ static int os2Lock( sqlite3_file *id, int locktype ){ if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){ assert( pFile->locktype>=SHARED_LOCK ); res = unlockReadLock(pFile); - OSTRACE2( "unreadlock = %d\n", res ); + OSTRACE(( "unreadlock = %d\n", res )); LockArea.lOffset = SHARED_FIRST; LockArea.lRange = SHARED_SIZE; UnlockArea.lOffset = 0L; @@ -21062,10 +22858,10 @@ static int os2Lock( sqlite3_file *id, int locktype ){ if( res == NO_ERROR ){ newLocktype = EXCLUSIVE_LOCK; }else{ - OSTRACE2( "OS/2 error-code = %d\n", res ); + OSTRACE(( "OS/2 error-code = %d\n", res )); getReadLock(pFile); } - OSTRACE3( "LOCK %d acquire exclusive lock. res=%d\n", pFile->h, res ); + OSTRACE(( "LOCK %d acquire exclusive lock. res=%d\n", pFile->h, res )); } /* If we are holding a PENDING lock that ought to be released, then @@ -21078,7 +22874,7 @@ static int os2Lock( sqlite3_file *id, int locktype ){ UnlockArea.lOffset = PENDING_BYTE; UnlockArea.lRange = 1L; r = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - OSTRACE3( "LOCK %d unlocking pending/is shared. r=%d\n", pFile->h, r ); + OSTRACE(( "LOCK %d unlocking pending/is shared. r=%d\n", pFile->h, r )); } /* Update the state of the lock has held in the file descriptor then @@ -21087,12 +22883,12 @@ static int os2Lock( sqlite3_file *id, int locktype ){ if( res == NO_ERROR ){ rc = SQLITE_OK; }else{ - OSTRACE4( "LOCK FAILED %d trying for %d but got %d\n", pFile->h, - locktype, newLocktype ); + OSTRACE(( "LOCK FAILED %d trying for %d but got %d\n", pFile->h, + locktype, newLocktype )); rc = SQLITE_BUSY; } pFile->locktype = newLocktype; - OSTRACE3( "LOCK %d now %d\n", pFile->h, pFile->locktype ); + OSTRACE(( "LOCK %d now %d\n", pFile->h, pFile->locktype )); return rc; } @@ -21107,7 +22903,7 @@ static int os2CheckReservedLock( sqlite3_file *id, int *pOut ){ assert( pFile!=0 ); if( pFile->locktype>=RESERVED_LOCK ){ r = 1; - OSTRACE3( "TEST WR-LOCK %d %d (local)\n", pFile->h, r ); + OSTRACE(( "TEST WR-LOCK %d %d (local)\n", pFile->h, r )); }else{ FILELOCK LockArea, UnlockArea; @@ -21119,7 +22915,7 @@ static int os2CheckReservedLock( sqlite3_file *id, int *pOut ){ UnlockArea.lOffset = 0L; UnlockArea.lRange = 0L; rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - OSTRACE3( "TEST WR-LOCK %d lock reserved byte rc=%d\n", pFile->h, rc ); + OSTRACE(( "TEST WR-LOCK %d lock reserved byte rc=%d\n", pFile->h, rc )); if( rc == NO_ERROR ){ APIRET rcu = NO_ERROR; /* return code for unlocking */ LockArea.lOffset = 0L; @@ -21127,10 +22923,10 @@ static int os2CheckReservedLock( sqlite3_file *id, int *pOut ){ UnlockArea.lOffset = RESERVED_BYTE; UnlockArea.lRange = 1L; rcu = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - OSTRACE3( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, rcu ); + OSTRACE(( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, rcu )); } r = !(rc == NO_ERROR); - OSTRACE3( "TEST WR-LOCK %d %d (remote)\n", pFile->h, r ); + OSTRACE(( "TEST WR-LOCK %d %d (remote)\n", pFile->h, r )); } *pOut = r; return SQLITE_OK; @@ -21158,7 +22954,7 @@ static int os2Unlock( sqlite3_file *id, int locktype ){ memset(&UnlockArea, 0, sizeof(UnlockArea)); assert( pFile!=0 ); assert( locktype<=SHARED_LOCK ); - OSTRACE4( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype ); + OSTRACE(( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype )); type = pFile->locktype; if( type>=EXCLUSIVE_LOCK ){ LockArea.lOffset = 0L; @@ -21166,11 +22962,11 @@ static int os2Unlock( sqlite3_file *id, int locktype ){ UnlockArea.lOffset = SHARED_FIRST; UnlockArea.lRange = SHARED_SIZE; res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - OSTRACE3( "UNLOCK %d exclusive lock res=%d\n", pFile->h, res ); + OSTRACE(( "UNLOCK %d exclusive lock res=%d\n", pFile->h, res )); if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){ /* This should never happen. We should always be able to ** reacquire the read lock */ - OSTRACE3( "UNLOCK %d to %d getReadLock() failed\n", pFile->h, locktype ); + OSTRACE(( "UNLOCK %d to %d getReadLock() failed\n", pFile->h, locktype )); rc = SQLITE_IOERR_UNLOCK; } } @@ -21180,11 +22976,12 @@ static int os2Unlock( sqlite3_file *id, int locktype ){ UnlockArea.lOffset = RESERVED_BYTE; UnlockArea.lRange = 1L; res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - OSTRACE3( "UNLOCK %d reserved res=%d\n", pFile->h, res ); + OSTRACE(( "UNLOCK %d reserved res=%d\n", pFile->h, res )); } if( locktype==NO_LOCK && type>=SHARED_LOCK ){ res = unlockReadLock(pFile); - OSTRACE5( "UNLOCK %d is %d want %d res=%d\n", pFile->h, type, locktype, res ); + OSTRACE(( "UNLOCK %d is %d want %d res=%d\n", + pFile->h, type, locktype, res )); } if( type>=PENDING_LOCK ){ LockArea.lOffset = 0L; @@ -21192,10 +22989,10 @@ static int os2Unlock( sqlite3_file *id, int locktype ){ UnlockArea.lOffset = PENDING_BYTE; UnlockArea.lRange = 1L; res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); - OSTRACE3( "UNLOCK %d pending res=%d\n", pFile->h, res ); + OSTRACE(( "UNLOCK %d pending res=%d\n", pFile->h, res )); } pFile->locktype = locktype; - OSTRACE3( "UNLOCK %d now %d\n", pFile->h, pFile->locktype ); + OSTRACE(( "UNLOCK %d now %d\n", pFile->h, pFile->locktype )); return rc; } @@ -21206,11 +23003,26 @@ static int os2FileControl(sqlite3_file *id, int op, void *pArg){ switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = ((os2File*)id)->locktype; - OSTRACE3( "FCNTL_LOCKSTATE %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype ); + OSTRACE(( "FCNTL_LOCKSTATE %d lock=%d\n", + ((os2File*)id)->h, ((os2File*)id)->locktype )); + return SQLITE_OK; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + ((os2File*)id)->szChunk = *(int*)pArg; + return SQLITE_OK; + } + case SQLITE_FCNTL_SIZE_HINT: { + sqlite3_int64 sz = *(sqlite3_int64*)pArg; + SimulateIOErrorBenign(1); + os2Truncate(id, sz); + SimulateIOErrorBenign(0); + return SQLITE_OK; + } + case SQLITE_FCNTL_SYNC_OMITTED: { return SQLITE_OK; } } - return SQLITE_ERROR; + return SQLITE_NOTFOUND; } /* @@ -21224,6 +23036,7 @@ static int os2FileControl(sqlite3_file *id, int op, void *pArg){ ** same for both. */ static int os2SectorSize(sqlite3_file *id){ + UNUSED_PARAMETER(id); return SQLITE_DEFAULT_SECTOR_SIZE; } @@ -21231,7 +23044,8 @@ static int os2SectorSize(sqlite3_file *id){ ** Return a vector of device characteristics. */ static int os2DeviceCharacteristics(sqlite3_file *id){ - return 0; + UNUSED_PARAMETER(id); + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN; } @@ -21318,26 +23132,682 @@ char *convertCpPathToUtf8( const char *in ){ return out; } + +#ifndef SQLITE_OMIT_WAL + +/* +** Use main database file for interprocess locking. If un-defined +** a separate file is created for this purpose. The file will be +** used only to set file locks. There will be no data written to it. +*/ +#define SQLITE_OS2_NO_WAL_LOCK_FILE + +#if 0 +static void _ERR_TRACE( const char *fmt, ... ) { + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fflush(stderr); +} +#define ERR_TRACE(rc, msg) \ + if( (rc) != SQLITE_OK ) _ERR_TRACE msg; +#else +#define ERR_TRACE(rc, msg) +#endif + +/* +** Helper functions to obtain and relinquish the global mutex. The +** global mutex is used to protect os2ShmNodeList. +** +** Function os2ShmMutexHeld() is used to assert() that the global mutex +** is held when required. This function is only used as part of assert() +** statements. e.g. +** +** os2ShmEnterMutex() +** assert( os2ShmMutexHeld() ); +** os2ShmLeaveMutex() +*/ +static void os2ShmEnterMutex(void){ + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +static void os2ShmLeaveMutex(void){ + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +#ifdef SQLITE_DEBUG +static int os2ShmMutexHeld(void) { + return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +int GetCurrentProcessId(void) { + PPIB pib; + DosGetInfoBlocks(NULL, &pib); + return (int)pib->pib_ulpid; +} +#endif + +/* +** Object used to represent a the shared memory area for a single log file. +** When multiple threads all reference the same log-summary, each thread has +** its own os2File object, but they all point to a single instance of this +** object. In other words, each log-summary is opened only once per process. +** +** os2ShmMutexHeld() must be true when creating or destroying +** this object or while reading or writing the following fields: +** +** nRef +** pNext +** +** The following fields are read-only after the object is created: +** +** szRegion +** hLockFile +** shmBaseName +** +** Either os2ShmNode.mutex must be held or os2ShmNode.nRef==0 and +** os2ShmMutexHeld() is true when reading or writing any other field +** in this structure. +** +*/ +struct os2ShmNode { + sqlite3_mutex *mutex; /* Mutex to access this object */ + os2ShmNode *pNext; /* Next in list of all os2ShmNode objects */ + + int szRegion; /* Size of shared-memory regions */ + + int nRegion; /* Size of array apRegion */ + void **apRegion; /* Array of pointers to shared-memory regions */ + + int nRef; /* Number of os2ShmLink objects pointing to this */ + os2ShmLink *pFirst; /* First os2ShmLink object pointing to this */ + + HFILE hLockFile; /* File used for inter-process memory locking */ + char shmBaseName[1]; /* Name of the memory object !!! must last !!! */ +}; + + +/* +** Structure used internally by this VFS to record the state of an +** open shared memory connection. +** +** The following fields are initialized when this object is created and +** are read-only thereafter: +** +** os2Shm.pShmNode +** os2Shm.id +** +** All other fields are read/write. The os2Shm.pShmNode->mutex must be held +** while accessing any read/write fields. +*/ +struct os2ShmLink { + os2ShmNode *pShmNode; /* The underlying os2ShmNode object */ + os2ShmLink *pNext; /* Next os2Shm with the same os2ShmNode */ + u32 sharedMask; /* Mask of shared locks held */ + u32 exclMask; /* Mask of exclusive locks held */ +#ifdef SQLITE_DEBUG + u8 id; /* Id of this connection with its os2ShmNode */ +#endif +}; + + +/* +** A global list of all os2ShmNode objects. +** +** The os2ShmMutexHeld() must be true while reading or writing this list. +*/ +static os2ShmNode *os2ShmNodeList = NULL; + +/* +** Constants used for locking +*/ +#ifdef SQLITE_OS2_NO_WAL_LOCK_FILE +#define OS2_SHM_BASE (PENDING_BYTE + 0x10000) /* first lock byte */ +#else +#define OS2_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ +#endif + +#define OS2_SHM_DMS (OS2_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ + +/* +** Apply advisory locks for all n bytes beginning at ofst. +*/ +#define _SHM_UNLCK 1 /* no lock */ +#define _SHM_RDLCK 2 /* shared lock, no wait */ +#define _SHM_WRLCK 3 /* exlusive lock, no wait */ +#define _SHM_WRLCK_WAIT 4 /* exclusive lock, wait */ +static int os2ShmSystemLock( + os2ShmNode *pNode, /* Apply locks to this open shared-memory segment */ + int lockType, /* _SHM_UNLCK, _SHM_RDLCK, _SHM_WRLCK or _SHM_WRLCK_WAIT */ + int ofst, /* Offset to first byte to be locked/unlocked */ + int nByte /* Number of bytes to lock or unlock */ +){ + APIRET rc; + FILELOCK area; + ULONG mode, timeout; + + /* Access to the os2ShmNode object is serialized by the caller */ + assert( sqlite3_mutex_held(pNode->mutex) || pNode->nRef==0 ); + + mode = 1; /* shared lock */ + timeout = 0; /* no wait */ + area.lOffset = ofst; + area.lRange = nByte; + + switch( lockType ) { + case _SHM_WRLCK_WAIT: + timeout = (ULONG)-1; /* wait forever */ + case _SHM_WRLCK: + mode = 0; /* exclusive lock */ + case _SHM_RDLCK: + rc = DosSetFileLocks(pNode->hLockFile, + NULL, &area, timeout, mode); + break; + /* case _SHM_UNLCK: */ + default: + rc = DosSetFileLocks(pNode->hLockFile, + &area, NULL, 0, 0); + break; + } + + OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", + pNode->hLockFile, + rc==SQLITE_OK ? "ok" : "failed", + lockType==_SHM_UNLCK ? "Unlock" : "Lock", + rc)); + + ERR_TRACE(rc, ("os2ShmSystemLock: %d %s\n", rc, pNode->shmBaseName)) + + return ( rc == 0 ) ? SQLITE_OK : SQLITE_BUSY; +} + +/* +** Find an os2ShmNode in global list or allocate a new one, if not found. +** +** This is not a VFS shared-memory method; it is a utility function called +** by VFS shared-memory methods. +*/ +static int os2OpenSharedMemory( os2File *fd, int szRegion ) { + os2ShmLink *pLink; + os2ShmNode *pNode; + int cbShmName, rc = SQLITE_OK; + char shmName[CCHMAXPATH + 30]; +#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE + ULONG action; +#endif + + /* We need some additional space at the end to append the region number */ + cbShmName = sprintf(shmName, "\\SHAREMEM\\%s", fd->zFullPathCp ); + if( cbShmName >= CCHMAXPATH-8 ) + return SQLITE_IOERR_SHMOPEN; + + /* Replace colon in file name to form a valid shared memory name */ + shmName[10+1] = '!'; + + /* Allocate link object (we free it later in case of failure) */ + pLink = sqlite3_malloc( sizeof(*pLink) ); + if( !pLink ) + return SQLITE_NOMEM; + + /* Access node list */ + os2ShmEnterMutex(); + + /* Find node by it's shared memory base name */ + for( pNode = os2ShmNodeList; + pNode && stricmp(shmName, pNode->shmBaseName) != 0; + pNode = pNode->pNext ) ; + + /* Not found: allocate a new node */ + if( !pNode ) { + pNode = sqlite3_malloc( sizeof(*pNode) + cbShmName ); + if( pNode ) { + memset(pNode, 0, sizeof(*pNode) ); + pNode->szRegion = szRegion; + pNode->hLockFile = (HFILE)-1; + strcpy(pNode->shmBaseName, shmName); + +#ifdef SQLITE_OS2_NO_WAL_LOCK_FILE + if( DosDupHandle(fd->h, &pNode->hLockFile) != 0 ) { +#else + sprintf(shmName, "%s-lck", fd->zFullPathCp); + if( DosOpen((PSZ)shmName, &pNode->hLockFile, &action, 0, FILE_NORMAL, + OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW, + OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | + OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR, + NULL) != 0 ) { +#endif + sqlite3_free(pNode); + rc = SQLITE_IOERR; + } else { + pNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( !pNode->mutex ) { + sqlite3_free(pNode); + rc = SQLITE_NOMEM; + } + } + } else { + rc = SQLITE_NOMEM; + } + + if( rc == SQLITE_OK ) { + pNode->pNext = os2ShmNodeList; + os2ShmNodeList = pNode; + } else { + pNode = NULL; + } + } else if( pNode->szRegion != szRegion ) { + rc = SQLITE_IOERR_SHMSIZE; + pNode = NULL; + } + + if( pNode ) { + sqlite3_mutex_enter(pNode->mutex); + + memset(pLink, 0, sizeof(*pLink)); + + pLink->pShmNode = pNode; + pLink->pNext = pNode->pFirst; + pNode->pFirst = pLink; + pNode->nRef++; + + fd->pShmLink = pLink; + + sqlite3_mutex_leave(pNode->mutex); + + } else { + /* Error occured. Free our link object. */ + sqlite3_free(pLink); + } + + os2ShmLeaveMutex(); + + ERR_TRACE(rc, ("os2OpenSharedMemory: %d %s\n", rc, fd->zFullPathCp)) + + return rc; +} + +/* +** Purge the os2ShmNodeList list of all entries with nRef==0. +** +** This is not a VFS shared-memory method; it is a utility function called +** by VFS shared-memory methods. +*/ +static void os2PurgeShmNodes( int deleteFlag ) { + os2ShmNode *pNode; + os2ShmNode **ppNode; + + os2ShmEnterMutex(); + + ppNode = &os2ShmNodeList; + + while( *ppNode ) { + pNode = *ppNode; + + if( pNode->nRef == 0 ) { + *ppNode = pNode->pNext; + + if( pNode->apRegion ) { + /* Prevent other processes from resizing the shared memory */ + os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1); + + while( pNode->nRegion-- ) { +#ifdef SQLITE_DEBUG + int rc = +#endif + DosFreeMem(pNode->apRegion[pNode->nRegion]); + + OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n", + (int)GetCurrentProcessId(), pNode->nRegion, + rc == 0 ? "ok" : "failed")); + } + + /* Allow other processes to resize the shared memory */ + os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1); + + sqlite3_free(pNode->apRegion); + } + + DosClose(pNode->hLockFile); + +#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE + if( deleteFlag ) { + char fileName[CCHMAXPATH]; + /* Skip "\\SHAREMEM\\" */ + sprintf(fileName, "%s-lck", pNode->shmBaseName + 10); + /* restore colon */ + fileName[1] = ':'; + + DosForceDelete(fileName); + } +#endif + + sqlite3_mutex_free(pNode->mutex); + + sqlite3_free(pNode); + + } else { + ppNode = &pNode->pNext; + } + } + + os2ShmLeaveMutex(); +} + +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file id. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the bExtend parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** bExtend is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int os2ShmMap( + sqlite3_file *id, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int bExtend, /* True to extend block if necessary */ + void volatile **pp /* OUT: Mapped memory */ +){ + PVOID pvTemp; + void **apRegion; + os2ShmNode *pNode; + int n, rc = SQLITE_OK; + char shmName[CCHMAXPATH]; + os2File *pFile = (os2File*)id; + + *pp = NULL; + + if( !pFile->pShmLink ) + rc = os2OpenSharedMemory( pFile, szRegion ); + + if( rc == SQLITE_OK ) { + pNode = pFile->pShmLink->pShmNode ; + + sqlite3_mutex_enter(pNode->mutex); + + assert( szRegion==pNode->szRegion ); + + /* Unmapped region ? */ + if( iRegion >= pNode->nRegion ) { + /* Prevent other processes from resizing the shared memory */ + os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1); + + apRegion = sqlite3_realloc( + pNode->apRegion, (iRegion + 1) * sizeof(apRegion[0])); + + if( apRegion ) { + pNode->apRegion = apRegion; + + while( pNode->nRegion <= iRegion ) { + sprintf(shmName, "%s-%u", + pNode->shmBaseName, pNode->nRegion); + + if( DosGetNamedSharedMem(&pvTemp, (PSZ)shmName, + PAG_READ | PAG_WRITE) != NO_ERROR ) { + if( !bExtend ) + break; + + if( DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion, + PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_ANY) != NO_ERROR && + DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion, + PAG_READ | PAG_WRITE | PAG_COMMIT) != NO_ERROR ) { + rc = SQLITE_NOMEM; + break; + } + } + + apRegion[pNode->nRegion++] = pvTemp; + } + + /* zero out remaining entries */ + for( n = pNode->nRegion; n <= iRegion; n++ ) + pNode->apRegion[n] = NULL; + + /* Return this region (maybe zero) */ + *pp = pNode->apRegion[iRegion]; + } else { + rc = SQLITE_NOMEM; + } + + /* Allow other processes to resize the shared memory */ + os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1); + + } else { + /* Region has been mapped previously */ + *pp = pNode->apRegion[iRegion]; + } + + sqlite3_mutex_leave(pNode->mutex); + } + + ERR_TRACE(rc, ("os2ShmMap: %s iRgn = %d, szRgn = %d, bExt = %d : %d\n", + pFile->zFullPathCp, iRegion, szRegion, bExtend, rc)) + + return rc; +} + +/* +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. +** +** If there is no shared memory associated with the connection then this +** routine is a harmless no-op. +*/ +static int os2ShmUnmap( + sqlite3_file *id, /* The underlying database file */ + int deleteFlag /* Delete shared-memory if true */ +){ + os2File *pFile = (os2File*)id; + os2ShmLink *pLink = pFile->pShmLink; + + if( pLink ) { + int nRef = -1; + os2ShmLink **ppLink; + os2ShmNode *pNode = pLink->pShmNode; + + sqlite3_mutex_enter(pNode->mutex); + + for( ppLink = &pNode->pFirst; + *ppLink && *ppLink != pLink; + ppLink = &(*ppLink)->pNext ) ; + + assert(*ppLink); + + if( *ppLink ) { + *ppLink = pLink->pNext; + nRef = --pNode->nRef; + } else { + ERR_TRACE(1, ("os2ShmUnmap: link not found ! %s\n", + pNode->shmBaseName)) + } + + pFile->pShmLink = NULL; + sqlite3_free(pLink); + + sqlite3_mutex_leave(pNode->mutex); + + if( nRef == 0 ) + os2PurgeShmNodes( deleteFlag ); + } + + return SQLITE_OK; +} + +/* +** Change the lock state for a shared-memory segment. +** +** Note that the relationship between SHAREd and EXCLUSIVE locks is a little +** different here than in posix. In xShmLock(), one can go from unlocked +** to shared and back or from unlocked to exclusive and back. But one may +** not go from shared to exclusive or from exclusive to shared. +*/ +static int os2ShmLock( + sqlite3_file *id, /* Database file holding the shared memory */ + int ofst, /* First lock to acquire or release */ + int n, /* Number of locks to acquire or release */ + int flags /* What to do with the lock */ +){ + u32 mask; /* Mask of locks to take or release */ + int rc = SQLITE_OK; /* Result code */ + os2File *pFile = (os2File*)id; + os2ShmLink *p = pFile->pShmLink; /* The shared memory being locked */ + os2ShmLink *pX; /* For looping over all siblings */ + os2ShmNode *pShmNode = p->pShmNode; /* Our node */ + + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); + assert( n>=1 ); + assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); + assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + + mask = (u32)((1U<<(ofst+n)) - (1U<<ofst)); + assert( n>1 || mask==(1<<ofst) ); + + + sqlite3_mutex_enter(pShmNode->mutex); + + if( flags & SQLITE_SHM_UNLOCK ){ + u32 allMask = 0; /* Mask of locks held by siblings */ + + /* See if any siblings hold this same lock */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( pX==p ) continue; + assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); + allMask |= pX->sharedMask; + } + + /* Unlock the system-level locks */ + if( (mask & allMask)==0 ){ + rc = os2ShmSystemLock(pShmNode, _SHM_UNLCK, ofst+OS2_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + + /* Undo the local locks */ + if( rc==SQLITE_OK ){ + p->exclMask &= ~mask; + p->sharedMask &= ~mask; + } + }else if( flags & SQLITE_SHM_SHARED ){ + u32 allShared = 0; /* Union of locks held by connections other than "p" */ + + /* Find out which shared locks are already held by sibling connections. + ** If any sibling already holds an exclusive lock, go ahead and return + ** SQLITE_BUSY. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + allShared |= pX->sharedMask; + } + + /* Get shared locks at the system level, if necessary */ + if( rc==SQLITE_OK ){ + if( (allShared & mask)==0 ){ + rc = os2ShmSystemLock(pShmNode, _SHM_RDLCK, ofst+OS2_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + } + + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + } + }else{ + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + } + + /* Get the exclusive locks at the system level. Then if successful + ** also mark the local connection as being locked. + */ + if( rc==SQLITE_OK ){ + rc = os2ShmSystemLock(pShmNode, _SHM_WRLCK, ofst+OS2_SHM_BASE, n); + if( rc==SQLITE_OK ){ + assert( (p->sharedMask & mask)==0 ); + p->exclMask |= mask; + } + } + } + + sqlite3_mutex_leave(pShmNode->mutex); + + OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n", + p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask, + rc ? "failed" : "ok")); + + ERR_TRACE(rc, ("os2ShmLock: ofst = %d, n = %d, flags = 0x%x -> %d \n", + ofst, n, flags, rc)) + + return rc; +} + +/* +** Implement a memory barrier or memory fence on shared memory. +** +** All loads and stores begun before the barrier must complete before +** any load or store begun after the barrier. +*/ +static void os2ShmBarrier( + sqlite3_file *id /* Database file holding the shared memory */ +){ + UNUSED_PARAMETER(id); + os2ShmEnterMutex(); + os2ShmLeaveMutex(); +} + +#else +# define os2ShmMap 0 +# define os2ShmLock 0 +# define os2ShmBarrier 0 +# define os2ShmUnmap 0 +#endif /* #ifndef SQLITE_OMIT_WAL */ + + /* ** This vector defines all the methods that can operate on an ** sqlite3_file for os2. */ static const sqlite3_io_methods os2IoMethod = { - 1, /* iVersion */ - os2Close, - os2Read, - os2Write, - os2Truncate, - os2Sync, - os2FileSize, - os2Lock, - os2Unlock, - os2CheckReservedLock, - os2FileControl, - os2SectorSize, - os2DeviceCharacteristics + 2, /* iVersion */ + os2Close, /* xClose */ + os2Read, /* xRead */ + os2Write, /* xWrite */ + os2Truncate, /* xTruncate */ + os2Sync, /* xSync */ + os2FileSize, /* xFileSize */ + os2Lock, /* xLock */ + os2Unlock, /* xUnlock */ + os2CheckReservedLock, /* xCheckReservedLock */ + os2FileControl, /* xFileControl */ + os2SectorSize, /* xSectorSize */ + os2DeviceCharacteristics, /* xDeviceCharacteristics */ + os2ShmMap, /* xShmMap */ + os2ShmLock, /* xShmLock */ + os2ShmBarrier, /* xShmBarrier */ + os2ShmUnmap /* xShmUnmap */ }; + /*************************************************************************** ** Here ends the I/O methods that form the sqlite3_io_methods object. ** @@ -21349,51 +23819,58 @@ static const sqlite3_io_methods os2IoMethod = { ** hold at pVfs->mxPathname characters. */ static int getTempname(int nBuf, char *zBuf ){ - static const unsigned char zChars[] = + static const char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; int i, j; - char zTempPathBuf[3]; - PSZ zTempPath = (PSZ)&zTempPathBuf; - if( sqlite3_temp_directory ){ - zTempPath = sqlite3_temp_directory; - }else{ - if( DosScanEnv( (PSZ)"TEMP", &zTempPath ) ){ - if( DosScanEnv( (PSZ)"TMP", &zTempPath ) ){ - if( DosScanEnv( (PSZ)"TMPDIR", &zTempPath ) ){ - ULONG ulDriveNum = 0, ulDriveMap = 0; - DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ); - sprintf( (char*)zTempPath, "%c:", (char)( 'A' + ulDriveNum - 1 ) ); - } - } - } + PSZ zTempPathCp; + char zTempPath[CCHMAXPATH]; + ULONG ulDriveNum, ulDriveMap; + + /* 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. + */ + SimulateIOError( return SQLITE_IOERR ); + + if( sqlite3_temp_directory ) { + sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", sqlite3_temp_directory); + } else if( DosScanEnv( (PSZ)"TEMP", &zTempPathCp ) == NO_ERROR || + DosScanEnv( (PSZ)"TMP", &zTempPathCp ) == NO_ERROR || + DosScanEnv( (PSZ)"TMPDIR", &zTempPathCp ) == NO_ERROR ) { + char *zTempPathUTF = convertCpPathToUtf8( (char *)zTempPathCp ); + sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", zTempPathUTF); + free( zTempPathUTF ); + } else if( DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ) == NO_ERROR ) { + zTempPath[0] = (char)('A' + ulDriveNum - 1); + zTempPath[1] = ':'; + zTempPath[2] = '\0'; + } else { + zTempPath[0] = '\0'; } + /* Strip off a trailing slashes or backslashes, otherwise we would get * * multiple (back)slashes which causes DosOpen() to fail. * * Trailing spaces are not allowed, either. */ j = sqlite3Strlen30(zTempPath); - while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' - || zTempPath[j-1] == ' ' ) ){ + while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' || + zTempPath[j-1] == ' ' ) ){ j--; } zTempPath[j] = '\0'; - if( !sqlite3_temp_directory ){ - char *zTempPathUTF = convertCpPathToUtf8( zTempPath ); - sqlite3_snprintf( nBuf-30, zBuf, - "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPathUTF ); - free( zTempPathUTF ); - }else{ - sqlite3_snprintf( nBuf-30, zBuf, - "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath ); - } - j = sqlite3Strlen30( zBuf ); + + /* We use 20 bytes to randomize the name */ + sqlite3_snprintf(nBuf-22, zBuf, + "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); + j = sqlite3Strlen30(zBuf); sqlite3_randomness( 20, &zBuf[j] ); for( i = 0; i < 20; i++, j++ ){ - zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; + zBuf[j] = zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; - OSTRACE2( "TEMP FILENAME: %s\n", zBuf ); + + OSTRACE(( "TEMP FILENAME: %s\n", zBuf )); return SQLITE_OK; } @@ -21412,8 +23889,8 @@ static int os2FullPathname( char *zRelativeCp = convertUtf8PathToCp( zRelative ); char zFullCp[CCHMAXPATH] = "\0"; char *zFullUTF; - APIRET rc = DosQueryPathInfo( zRelativeCp, FIL_QUERYFULLNAME, zFullCp, - CCHMAXPATH ); + APIRET rc = DosQueryPathInfo( (PSZ)zRelativeCp, FIL_QUERYFULLNAME, + zFullCp, CCHMAXPATH ); free( zRelativeCp ); zFullUTF = convertCpPathToUtf8( zFullCp ); sqlite3_snprintf( nFull, zFull, zFullUTF ); @@ -21427,99 +23904,127 @@ static int os2FullPathname( */ static int os2Open( sqlite3_vfs *pVfs, /* Not used */ - const char *zName, /* Name of the file */ + const char *zName, /* Name of the file (UTF-8) */ sqlite3_file *id, /* Write the SQLite file handle here */ int flags, /* Open mode flags */ int *pOutFlags /* Status return flags */ ){ HFILE h; - ULONG ulFileAttribute = FILE_NORMAL; ULONG ulOpenFlags = 0; ULONG ulOpenMode = 0; + ULONG ulAction = 0; + ULONG rc; os2File *pFile = (os2File*)id; - APIRET rc = NO_ERROR; - ULONG ulAction; + const char *zUtf8Name = zName; char *zNameCp; - char zTmpname[CCHMAXPATH+1]; /* Buffer to hold name of temp file */ + char zTmpname[CCHMAXPATH]; - /* If the second argument to this function is NULL, generate a - ** temporary file name to use + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); + int isCreate = (flags & SQLITE_OPEN_CREATE); + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); +#ifndef NDEBUG + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); + int isReadonly = (flags & SQLITE_OPEN_READONLY); + int eType = (flags & 0xFFFFFF00); + int isOpenJournal = (isCreate && ( + eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_WAL + )); +#endif + + UNUSED_PARAMETER(pVfs); + assert( id!=0 ); + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. */ - if( !zName ){ - int rc = getTempname(CCHMAXPATH+1, zTmpname); - if( rc!=SQLITE_OK ){ - return rc; - } - zName = zTmpname; - } + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); + assert(isCreate==0 || isReadWrite); + assert(isExclusive==0 || isCreate); + assert(isDelete==0 || isCreate); + /* The main DB, main journal, WAL file and master journal are never + ** automatically deleted. Nor are they ever temporary files. */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); + + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL + ); memset( pFile, 0, sizeof(*pFile) ); + pFile->h = (HFILE)-1; - OSTRACE2( "OPEN want %d\n", flags ); + /* If the second argument to this function is NULL, generate a + ** temporary file name to use + */ + if( !zUtf8Name ){ + assert(isDelete && !isOpenJournal); + rc = getTempname(CCHMAXPATH, zTmpname); + if( rc!=SQLITE_OK ){ + return rc; + } + zUtf8Name = zTmpname; + } - if( flags & SQLITE_OPEN_READWRITE ){ + if( isReadWrite ){ ulOpenMode |= OPEN_ACCESS_READWRITE; - OSTRACE1( "OPEN read/write\n" ); }else{ ulOpenMode |= OPEN_ACCESS_READONLY; - OSTRACE1( "OPEN read only\n" ); - } - - if( flags & SQLITE_OPEN_CREATE ){ - ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW; - OSTRACE1( "OPEN open new/create\n" ); - }else{ - ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW; - OSTRACE1( "OPEN open existing\n" ); } - if( flags & SQLITE_OPEN_MAIN_DB ){ - ulOpenMode |= OPEN_SHARE_DENYNONE; - OSTRACE1( "OPEN share read/write\n" ); - }else{ - ulOpenMode |= OPEN_SHARE_DENYWRITE; - OSTRACE1( "OPEN share read only\n" ); - } + /* Open in random access mode for possibly better speed. Allow full + ** sharing because file locks will provide exclusive access when needed. + ** The handle should not be inherited by child processes and we don't + ** want popups from the critical error handler. + */ + ulOpenMode |= OPEN_FLAGS_RANDOM | OPEN_SHARE_DENYNONE | + OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR; - if( flags & SQLITE_OPEN_DELETEONCLOSE ){ - char pathUtf8[CCHMAXPATH]; -#ifdef NDEBUG /* when debugging we want to make sure it is deleted */ - ulFileAttribute = FILE_HIDDEN; -#endif - os2FullPathname( pVfs, zName, CCHMAXPATH, pathUtf8 ); - pFile->pathToDel = convertUtf8PathToCp( pathUtf8 ); - OSTRACE1( "OPEN hidden/delete on close file attributes\n" ); + /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is + ** created. SQLite doesn't use it to indicate "exclusive access" + ** as it is usually understood. + */ + if( isExclusive ){ + /* Creates a new file, only if it does not already exist. */ + /* If the file exists, it fails. */ + ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS; + }else if( isCreate ){ + /* Open existing file, or create if it doesn't exist */ + ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; }else{ - pFile->pathToDel = NULL; - OSTRACE1( "OPEN normal file attribute\n" ); + /* Opens a file, only if it exists. */ + ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; } - /* always open in random access mode for possibly better speed */ - ulOpenMode |= OPEN_FLAGS_RANDOM; - ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR; - ulOpenMode |= OPEN_FLAGS_NOINHERIT; - - zNameCp = convertUtf8PathToCp( zName ); + zNameCp = convertUtf8PathToCp( zUtf8Name ); rc = DosOpen( (PSZ)zNameCp, &h, &ulAction, 0L, - ulFileAttribute, + FILE_NORMAL, ulOpenFlags, ulOpenMode, (PEAOP2)NULL ); free( zNameCp ); + if( rc != NO_ERROR ){ - OSTRACE7( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n", - rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode ); - if( pFile->pathToDel ) - free( pFile->pathToDel ); - pFile->pathToDel = NULL; - if( flags & SQLITE_OPEN_READWRITE ){ - OSTRACE2( "OPEN %d Invalid handle\n", ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE) ); + OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n", + rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode )); + + if( isReadWrite ){ return os2Open( pVfs, zName, id, - ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE), + ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags ); }else{ return SQLITE_CANTOPEN; @@ -21527,13 +24032,17 @@ static int os2Open( } if( pOutFlags ){ - *pOutFlags = flags & SQLITE_OPEN_READWRITE ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY; + *pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY; } + os2FullPathname( pVfs, zUtf8Name, sizeof( zTmpname ), zTmpname ); + pFile->zFullPathCp = convertUtf8PathToCp( zTmpname ); pFile->pMethod = &os2IoMethod; + pFile->flags = flags; pFile->h = h; + OpenCounter(+1); - OSTRACE3( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags ); + OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags )); return SQLITE_OK; } @@ -21545,13 +24054,16 @@ static int os2Delete( const char *zFilename, /* Name of file to delete */ int syncDir /* Not used on os2 */ ){ - APIRET rc = NO_ERROR; - char *zFilenameCp = convertUtf8PathToCp( zFilename ); + APIRET rc; + char *zFilenameCp; SimulateIOError( return SQLITE_IOERR_DELETE ); + zFilenameCp = convertUtf8PathToCp( zFilename ); rc = DosDelete( (PSZ)zFilenameCp ); free( zFilenameCp ); - OSTRACE2( "DELETE \"%s\"\n", zFilename ); - return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_DELETE; + OSTRACE(( "DELETE \"%s\"\n", zFilename )); + return (rc == NO_ERROR || + rc == ERROR_FILE_NOT_FOUND || + rc == ERROR_PATH_NOT_FOUND ) ? SQLITE_OK : SQLITE_IOERR_DELETE; } /* @@ -21563,30 +24075,42 @@ static int os2Access( int flags, /* Type of test to make on this file */ int *pOut /* Write results here */ ){ + APIRET rc; FILESTATUS3 fsts3ConfigInfo; - APIRET rc = NO_ERROR; - char *zFilenameCp = convertUtf8PathToCp( zFilename ); + char *zFilenameCp; - memset( &fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo) ); + UNUSED_PARAMETER(pVfs); + SimulateIOError( return SQLITE_IOERR_ACCESS; ); + + zFilenameCp = convertUtf8PathToCp( zFilename ); rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD, &fsts3ConfigInfo, sizeof(FILESTATUS3) ); free( zFilenameCp ); - OSTRACE4( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n", - fsts3ConfigInfo.attrFile, flags, rc ); + OSTRACE(( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n", + fsts3ConfigInfo.attrFile, flags, rc )); + switch( flags ){ - case SQLITE_ACCESS_READ: case SQLITE_ACCESS_EXISTS: - rc = (rc == NO_ERROR); - OSTRACE3( "ACCESS %s access of read and exists rc=%d\n", zFilename, rc ); + /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file + ** as if it does not exist. + */ + if( fsts3ConfigInfo.cbFile == 0 ) + rc = ERROR_FILE_NOT_FOUND; + break; + case SQLITE_ACCESS_READ: break; case SQLITE_ACCESS_READWRITE: - rc = (rc == NO_ERROR) && ( (fsts3ConfigInfo.attrFile & FILE_READONLY) == 0 ); - OSTRACE3( "ACCESS %s access of read/write rc=%d\n", zFilename, rc ); + if( fsts3ConfigInfo.attrFile & FILE_READONLY ) + rc = ERROR_ACCESS_DENIED; break; default: + rc = ERROR_FILE_NOT_FOUND; assert( !"Invalid flags argument" ); } - *pOut = rc; + + *pOut = (rc == NO_ERROR); + OSTRACE(( "ACCESS %s flags %d: rc=%d\n", zFilename, flags, *pOut )); + return SQLITE_OK; } @@ -21601,11 +24125,10 @@ static int os2Access( ** within the shared library, and closing the shared library. */ static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){ - UCHAR loadErr[256]; HMODULE hmod; APIRET rc; char *zFilenameCp = convertUtf8PathToCp(zFilename); - rc = DosLoadModule((PSZ)loadErr, sizeof(loadErr), zFilenameCp, &hmod); + rc = DosLoadModule(NULL, 0, (PSZ)zFilenameCp, &hmod); free(zFilenameCp); return rc != NO_ERROR ? 0 : (void*)hmod; } @@ -21616,19 +24139,19 @@ static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){ static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ /* no-op */ } -static void *os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ +static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){ PFN pfn; APIRET rc; - rc = DosQueryProcAddr((HMODULE)pHandle, 0L, zSymbol, &pfn); + rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)zSymbol, &pfn); if( rc != NO_ERROR ){ /* if the symbol itself was not found, search again for the same * symbol with an extra underscore, that might be needed depending * on the calling convention */ char _zSymbol[256] = "_"; - strncat(_zSymbol, zSymbol, 255); - rc = DosQueryProcAddr((HMODULE)pHandle, 0L, _zSymbol, &pfn); + strncat(_zSymbol, zSymbol, 254); + rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)_zSymbol, &pfn); } - return rc != NO_ERROR ? 0 : (void*)pfn; + return rc != NO_ERROR ? 0 : (void(*)(void))pfn; } static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){ DosFreeModule((HMODULE)pHandle); @@ -21650,54 +24173,39 @@ static int os2Randomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf ){ n = nBuf; memset(zBuf, 0, nBuf); #else - int sizeofULong = sizeof(ULONG); - if( (int)sizeof(DATETIME) <= nBuf - n ){ - DATETIME x; - DosGetDateTime(&x); - memcpy(&zBuf[n], &x, sizeof(x)); - n += sizeof(x); - } - - if( sizeofULong <= nBuf - n ){ - PPIB ppib; - DosGetInfoBlocks(NULL, &ppib); - memcpy(&zBuf[n], &ppib->pib_ulpid, sizeofULong); - n += sizeofULong; - } - - if( sizeofULong <= nBuf - n ){ - PTIB ptib; - DosGetInfoBlocks(&ptib, NULL); - memcpy(&zBuf[n], &ptib->tib_ptib2->tib2_ultid, sizeofULong); - n += sizeofULong; - } - - /* if we still haven't filled the buffer yet the following will */ - /* grab everything once instead of making several calls for a single item */ - if( sizeofULong <= nBuf - n ){ - ULONG ulSysInfo[QSV_MAX]; - DosQuerySysInfo(1L, QSV_MAX, ulSysInfo, sizeofULong * QSV_MAX); - - memcpy(&zBuf[n], &ulSysInfo[QSV_MS_COUNT - 1], sizeofULong); - n += sizeofULong; - - if( sizeofULong <= nBuf - n ){ - memcpy(&zBuf[n], &ulSysInfo[QSV_TIMER_INTERVAL - 1], sizeofULong); - n += sizeofULong; - } - if( sizeofULong <= nBuf - n ){ - memcpy(&zBuf[n], &ulSysInfo[QSV_TIME_LOW - 1], sizeofULong); - n += sizeofULong; - } - if( sizeofULong <= nBuf - n ){ - memcpy(&zBuf[n], &ulSysInfo[QSV_TIME_HIGH - 1], sizeofULong); - n += sizeofULong; - } - if( sizeofULong <= nBuf - n ){ - memcpy(&zBuf[n], &ulSysInfo[QSV_TOTAVAILMEM - 1], sizeofULong); - n += sizeofULong; - } - } + int i; + PPIB ppib; + PTIB ptib; + DATETIME dt; + static unsigned c = 0; + /* Ordered by variation probability */ + static ULONG svIdx[6] = { QSV_MS_COUNT, QSV_TIME_LOW, + QSV_MAXPRMEM, QSV_MAXSHMEM, + QSV_TOTAVAILMEM, QSV_TOTRESMEM }; + + /* 8 bytes; timezone and weekday don't increase the randomness much */ + if( (int)sizeof(dt)-3 <= nBuf - n ){ + c += 0x0100; + DosGetDateTime(&dt); + dt.year = (USHORT)((dt.year - 1900) | c); + memcpy(&zBuf[n], &dt, sizeof(dt)-3); + n += sizeof(dt)-3; + } + + /* 4 bytes; PIDs and TIDs are 16 bit internally, so combine them */ + if( (int)sizeof(ULONG) <= nBuf - n ){ + DosGetInfoBlocks(&ptib, &ppib); + *(PULONG)&zBuf[n] = MAKELONG(ppib->pib_ulpid, + ptib->tib_ptib2->tib2_ultid); + n += sizeof(ULONG); + } + + /* Up to 6 * 4 bytes; variables depend on the system state */ + for( i = 0; i < 6 && (int)sizeof(ULONG) <= nBuf - n; i++ ){ + DosQuerySysInfo(svIdx[i], svIdx[i], + (PULONG)&zBuf[n], sizeof(ULONG)); + n += sizeof(ULONG); + } #endif return n; @@ -21725,46 +24233,98 @@ SQLITE_API int sqlite3_current_time = 0; #endif /* -** Find the current time (in Universal Coordinated Time). Write the -** current time and date as a Julian Day number into *prNow and -** return 0. Return 1 if the time and date cannot be found. +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return 0. Return 1 if the time and date cannot be found. */ -int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){ - double now; - SHORT minute; /* needs to be able to cope with negative timezone offset */ - USHORT second, hour, - day, month, year; +static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ +#ifdef SQLITE_TEST + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; +#endif + int year, month, datepart, timepart; + DATETIME dt; DosGetDateTime( &dt ); - second = (USHORT)dt.seconds; - minute = (SHORT)dt.minutes + dt.timezone; - hour = (USHORT)dt.hours; - day = (USHORT)dt.day; - month = (USHORT)dt.month; - year = (USHORT)dt.year; + + year = dt.year; + month = dt.month; /* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html - http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c */ - /* Calculate the Julian days */ - now = day - 32076 + + ** http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c + ** Calculate the Julian days + */ + datepart = (int)dt.day - 32076 + 1461*(year + 4800 + (month - 14)/12)/4 + 367*(month - 2 - (month - 14)/12*12)/12 - 3*((year + 4900 + (month - 14)/12)/100)/4; - /* Add the fractional hours, mins and seconds */ - now += (hour + 12.0)/24.0; - now += minute/1440.0; - now += second/86400.0; - *prNow = now; + /* Time in milliseconds, hours to noon added */ + timepart = 12*3600*1000 + dt.hundredths*10 + dt.seconds*1000 + + ((int)dt.minutes + dt.timezone)*60*1000 + dt.hours*3600*1000; + + *piNow = (sqlite3_int64)datepart*86400*1000 + timepart; + #ifdef SQLITE_TEST if( sqlite3_current_time ){ - *prNow = sqlite3_current_time/86400.0 + 2440587.5; + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; } #endif + + UNUSED_PARAMETER(pVfs); return 0; } +/* +** Find the current time (in Universal Coordinated Time). Write the +** current time and date as a Julian Day number into *prNow and +** return 0. Return 1 if the time and date cannot be found. +*/ +static int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){ + int rc; + sqlite3_int64 i; + rc = os2CurrentTimeInt64(pVfs, &i); + if( !rc ){ + *prNow = i/86400000.0; + } + return rc; +} + +/* +** The idea is that this function works like a combination of +** GetLastError() and FormatMessage() on windows (or errno and +** strerror_r() on unix). After an error is returned by an OS +** function, SQLite calls this function with zBuf pointing to +** a buffer of nBuf bytes. The OS layer should populate the +** buffer with a nul-terminated UTF-8 encoded error message +** describing the last IO error to have occurred within the calling +** thread. +** +** If the error message is too large for the supplied buffer, +** it should be truncated. The return value of xGetLastError +** is zero if the error message fits in the buffer, or non-zero +** otherwise (if the message was truncated). If non-zero is returned, +** then it is not necessary to include the nul-terminator character +** in the output buffer. +** +** Not supplying an error message will have no adverse effect +** on SQLite. It is fine to have an implementation that never +** returns an error message: +** +** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ +** assert(zBuf[0]=='\0'); +** return 0; +** } +** +** However if an error message is supplied, it will be incorporated +** by sqlite into the error message available to the user using +** sqlite3_errmsg(), possibly making IO errors easier to debug. +*/ static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ + assert(zBuf[0]=='\0'); return 0; } @@ -21773,7 +24333,7 @@ static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ */ SQLITE_API int sqlite3_os_init(void){ static sqlite3_vfs os2Vfs = { - 1, /* iVersion */ + 3, /* iVersion */ sizeof(os2File), /* szOsFile */ CCHMAXPATH, /* mxPathname */ 0, /* pNext */ @@ -21791,10 +24351,15 @@ SQLITE_API int sqlite3_os_init(void){ os2Randomness, /* xRandomness */ os2Sleep, /* xSleep */ os2CurrentTime, /* xCurrentTime */ - os2GetLastError /* xGetLastError */ + os2GetLastError, /* xGetLastError */ + os2CurrentTimeInt64, /* xCurrentTimeInt64 */ + 0, /* xSetSystemCall */ + 0, /* xGetSystemCall */ + 0 /* xNextSystemCall */ }; sqlite3_vfs_register(&os2Vfs, 1); initUconvObjects(); +/* sqlite3OSTrace = 1; */ return SQLITE_OK; } SQLITE_API int sqlite3_os_end(void){ @@ -21868,7 +24433,7 @@ SQLITE_API int sqlite3_os_end(void){ ** Styles 4, 5, and 7 are only available of SQLITE_ENABLE_LOCKING_STYLE ** is defined to 1. The SQLITE_ENABLE_LOCKING_STYLE also enables automatic ** selection of the appropriate locking style based on the filesystem -** where the database is located. +** where the database is located. */ #if !defined(SQLITE_ENABLE_LOCKING_STYLE) # if defined(__APPLE__) @@ -21879,7 +24444,7 @@ SQLITE_API int sqlite3_os_end(void){ #endif /* -** Define the OS_VXWORKS pre-processor macro to 1 if building on +** Define the OS_VXWORKS pre-processor macro to 1 if building on ** vxworks, or 0 otherwise. */ #ifndef OS_VXWORKS @@ -21923,8 +24488,12 @@ SQLITE_API int sqlite3_os_end(void){ #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> +/* #include <time.h> */ #include <sys/time.h> #include <errno.h> +#ifndef SQLITE_OMIT_WAL +#include <sys/mman.h> +#endif #if SQLITE_ENABLE_LOCKING_STYLE # include <sys/ioctl.h> @@ -21941,6 +24510,10 @@ SQLITE_API int sqlite3_os_end(void){ # include <sys/mount.h> #endif +#ifdef HAVE_UTIME +# include <utime.h> +#endif + /* ** Allowed values of unixFile.fsFlags */ @@ -21951,6 +24524,7 @@ SQLITE_API int sqlite3_os_end(void){ ** the SQLITE_UNIX_THREADS macro. */ #if SQLITE_THREADSAFE +/* # include <pthread.h> */ # define SQLITE_UNIX_THREADS 1 #endif @@ -21974,11 +24548,16 @@ SQLITE_API int sqlite3_os_end(void){ #define MAX_PATHNAME 512 /* -** Only set the lastErrno if the error code is a real error and not +** Only set the lastErrno if the error code is a real error and not ** a normal expected return code of SQLITE_BUSY or SQLITE_OK */ #define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY)) +/* Forward references */ +typedef struct unixShm unixShm; /* Connection shared memory */ +typedef struct unixShmNode unixShmNode; /* Shared memory instance */ +typedef struct unixInodeInfo unixInodeInfo; /* An i-node */ +typedef struct UnixUnusedFd UnixUnusedFd; /* An unused file descriptor */ /* ** Sometimes, after a file handle is closed by SQLite, the file descriptor @@ -21986,7 +24565,6 @@ SQLITE_API int sqlite3_os_end(void){ ** structure are used to store the file descriptor while waiting for an ** opportunity to either close or reuse it. */ -typedef struct UnixUnusedFd UnixUnusedFd; struct UnixUnusedFd { int fd; /* File descriptor to close */ int flags; /* Flags this file descriptor was opened with */ @@ -22000,27 +24578,25 @@ struct UnixUnusedFd { typedef struct unixFile unixFile; struct unixFile { sqlite3_io_methods const *pMethod; /* Always the first entry */ - struct unixOpenCnt *pOpen; /* Info about all open fd's on this inode */ - struct unixLockInfo *pLock; /* Info about locks on this inode */ - int h; /* The file descriptor */ - int dirfd; /* File descriptor for the directory */ - unsigned char locktype; /* The type of lock held on this fd */ - int lastErrno; /* The unix errno from the last I/O error */ - void *lockingContext; /* Locking style specific state */ - UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ - int fileFlags; /* Miscellanous flags */ + unixInodeInfo *pInode; /* Info about locks on this inode */ + int h; /* The file descriptor */ + unsigned char eFileLock; /* The type of lock held on this fd */ + unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ + int lastErrno; /* The unix errno from last I/O error */ + void *lockingContext; /* Locking style specific state */ + UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ + const char *zPath; /* Name of the file */ + unixShm *pShm; /* Shared memory segment information */ + int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ #if SQLITE_ENABLE_LOCKING_STYLE - int openFlags; /* The flags specified at open() */ + int openFlags; /* The flags specified at open() */ #endif #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) - unsigned fsFlags; /* cached details from statfs() */ -#endif -#if SQLITE_THREADSAFE && defined(__linux__) - pthread_t tid; /* The thread that "owns" this unixFile */ + unsigned fsFlags; /* cached details from statfs() */ #endif #if OS_VXWORKS - int isDelete; /* Delete on close if true */ - struct vxworksFileId *pId; /* Unique file ID */ + int isDelete; /* Delete on close if true */ + struct vxworksFileId *pId; /* Unique file ID */ #endif #ifndef NDEBUG /* The next group of variables are used to track whether or not the @@ -22028,14 +24604,14 @@ struct unixFile { ** whenever any part of the database changes. An assertion fault will ** occur if a file is updated without also updating the transaction ** counter. This test is made to avoid new problems similar to the - ** one described by ticket #3584. + ** one described by ticket #3584. */ unsigned char transCntrChng; /* True if the transaction counter changed */ unsigned char dbUpdate; /* True if any part of database file changed */ unsigned char inNormalWrite; /* True if in a normal write operation */ #endif #ifdef SQLITE_TEST - /* In test mode, increase the size of this structure a bit so that + /* In test mode, increase the size of this structure a bit so that ** it is larger than the struct CrashFile defined in test6.c. */ char aPadding[32]; @@ -22043,9 +24619,16 @@ struct unixFile { }; /* -** The following macros define bits in unixFile.fileFlags +** Allowed values for the unixFile.ctrlFlags bitmask: */ -#define SQLITE_WHOLE_FILE_LOCKING 0x0001 /* Use whole-file locking */ +#define UNIXFILE_EXCL 0x01 /* Connections from one process only */ +#define UNIXFILE_RDONLY 0x02 /* Connection is read only */ +#define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ +#ifndef SQLITE_DISABLE_DIRSYNC +# define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ +#else +# define UNIXFILE_DIRSYNC 0x00 +#endif /* ** Include code that is common to all os_*.c files @@ -22083,25 +24666,14 @@ struct unixFile { # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." #endif -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE int sqlite3OSTrace = 0; -#define OSTRACE1(X) if( sqlite3OSTrace ) sqlite3DebugPrintf(X) -#define OSTRACE2(X,Y) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y) -#define OSTRACE3(X,Y,Z) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z) -#define OSTRACE4(X,Y,Z,A) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A) -#define OSTRACE5(X,Y,Z,A,B) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A,B) -#define OSTRACE6(X,Y,Z,A,B,C) \ - if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C) -#define OSTRACE7(X,Y,Z,A,B,C,D) \ - if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D) +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +# ifndef SQLITE_DEBUG_OS_TRACE +# define SQLITE_DEBUG_OS_TRACE 0 +# endif + int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; +# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X #else -#define OSTRACE1(X) -#define OSTRACE2(X,Y) -#define OSTRACE3(X,Y,Z) -#define OSTRACE4(X,Y,Z,A) -#define OSTRACE5(X,Y,Z,A,B) -#define OSTRACE6(X,Y,Z,A,B,C) -#define OSTRACE7(X,Y,Z,A,B,C,D) +# define OSTRACE(X) #endif /* @@ -22110,8 +24682,8 @@ SQLITE_PRIVATE int sqlite3OSTrace = 0; */ #ifdef SQLITE_PERFORMANCE_TRACE -/* -** hwtime.h contains inline assembler code for implementing +/* +** hwtime.h contains inline assembler code for implementing ** high-performance timing routines. */ /************** Include hwtime.h in the middle of os_common.h ****************/ @@ -22169,7 +24741,7 @@ SQLITE_PRIVATE int sqlite3OSTrace = 0; __asm__ __volatile__ ("rdtsc" : "=A" (val)); return val; } - + #elif (defined(__GNUC__) && defined(__ppc__)) __inline__ sqlite_uint64 sqlite3Hwtime(void){ @@ -22289,34 +24861,234 @@ SQLITE_API int sqlite3_open_file_count = 0; #endif /* +** The threadid macro resolves to the thread-id or to 0. Used for +** testing and debugging only. +*/ +#if SQLITE_THREADSAFE +#define threadid pthread_self() +#else +#define threadid 0 +#endif + +/* +** Different Unix systems declare open() in different ways. Same use +** open(const char*,int,mode_t). Others use open(const char*,int,...). +** The difference is important when using a pointer to the function. +** +** The safest way to deal with the problem is to always use this wrapper +** which always has the same well-defined interface. +*/ +static int posixOpen(const char *zFile, int flags, int mode){ + return open(zFile, flags, mode); +} + +/* Forward reference */ +static int openDirectory(const char*, int*); + +/* +** Many system calls are accessed through pointer-to-functions so that +** they may be overridden at runtime to facilitate fault injection during +** testing and sandboxing. The following array holds the names and pointers +** to all overrideable system calls. +*/ +static struct unix_syscall { + const char *zName; /* Name of the sytem call */ + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ +} aSyscall[] = { + { "open", (sqlite3_syscall_ptr)posixOpen, 0 }, +#define osOpen ((int(*)(const char*,int,int))aSyscall[0].pCurrent) + + { "close", (sqlite3_syscall_ptr)close, 0 }, +#define osClose ((int(*)(int))aSyscall[1].pCurrent) + + { "access", (sqlite3_syscall_ptr)access, 0 }, +#define osAccess ((int(*)(const char*,int))aSyscall[2].pCurrent) + + { "getcwd", (sqlite3_syscall_ptr)getcwd, 0 }, +#define osGetcwd ((char*(*)(char*,size_t))aSyscall[3].pCurrent) + + { "stat", (sqlite3_syscall_ptr)stat, 0 }, +#define osStat ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent) + +/* ** The DJGPP compiler environment looks mostly like Unix, but it ** lacks the fcntl() system call. So redefine fcntl() to be something ** that always succeeds. This means that locking does not occur under ** DJGPP. But it is DOS - what did you expect? */ #ifdef __DJGPP__ -# define fcntl(A,B,C) 0 + { "fstat", 0, 0 }, +#define osFstat(a,b,c) 0 +#else + { "fstat", (sqlite3_syscall_ptr)fstat, 0 }, +#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent) #endif -/* -** The threadid macro resolves to the thread-id or to 0. Used for -** testing and debugging only. -*/ -#if SQLITE_THREADSAFE -#define threadid pthread_self() + { "ftruncate", (sqlite3_syscall_ptr)ftruncate, 0 }, +#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent) + + { "fcntl", (sqlite3_syscall_ptr)fcntl, 0 }, +#define osFcntl ((int(*)(int,int,...))aSyscall[7].pCurrent) + + { "read", (sqlite3_syscall_ptr)read, 0 }, +#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent) + +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE + { "pread", (sqlite3_syscall_ptr)pread, 0 }, #else -#define threadid 0 + { "pread", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent) + +#if defined(USE_PREAD64) + { "pread64", (sqlite3_syscall_ptr)pread64, 0 }, +#else + { "pread64", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPread64 ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent) + + { "write", (sqlite3_syscall_ptr)write, 0 }, +#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) + +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE + { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 }, +#else + { "pwrite", (sqlite3_syscall_ptr)0, 0 }, #endif +#define osPwrite ((ssize_t(*)(int,const void*,size_t,off_t))\ + aSyscall[12].pCurrent) +#if defined(USE_PREAD64) + { "pwrite64", (sqlite3_syscall_ptr)pwrite64, 0 }, +#else + { "pwrite64", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\ + aSyscall[13].pCurrent) + +#if SQLITE_ENABLE_LOCKING_STYLE + { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, +#else + { "fchmod", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) + +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE + { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 }, +#else + { "fallocate", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent) + + { "unlink", (sqlite3_syscall_ptr)unlink, 0 }, +#define osUnlink ((int(*)(const char*))aSyscall[16].pCurrent) + + { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 }, +#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent) + +}; /* End of the overrideable system calls */ + +/* +** This is the xSetSystemCall() method of sqlite3_vfs for all of the +** "unix" VFSes. Return SQLITE_OK opon successfully updating the +** system call pointer, or SQLITE_NOTFOUND if there is no configurable +** system call named zName. +*/ +static int unixSetSystemCall( + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + const char *zName, /* Name of system call to override */ + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ +){ + unsigned int i; + int rc = SQLITE_NOTFOUND; + + UNUSED_PARAMETER(pNotUsed); + if( zName==0 ){ + /* If no zName is given, restore all system calls to their default + ** settings and return NULL + */ + rc = SQLITE_OK; + for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){ + if( aSyscall[i].pDefault ){ + aSyscall[i].pCurrent = aSyscall[i].pDefault; + } + } + }else{ + /* If zName is specified, operate on only the one system call + ** specified. + */ + for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){ + if( strcmp(zName, aSyscall[i].zName)==0 ){ + if( aSyscall[i].pDefault==0 ){ + aSyscall[i].pDefault = aSyscall[i].pCurrent; + } + rc = SQLITE_OK; + if( pNewFunc==0 ) pNewFunc = aSyscall[i].pDefault; + aSyscall[i].pCurrent = pNewFunc; + break; + } + } + } + return rc; +} + +/* +** Return the value of a system call. Return NULL if zName is not a +** recognized system call name. NULL is also returned if the system call +** is currently undefined. +*/ +static sqlite3_syscall_ptr unixGetSystemCall( + sqlite3_vfs *pNotUsed, + const char *zName +){ + unsigned int i; + + UNUSED_PARAMETER(pNotUsed); + for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){ + if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent; + } + return 0; +} + +/* +** Return the name of the first system call after zName. If zName==NULL +** then return the name of the first system call. Return NULL if zName +** is the last system call or if zName is not the name of a valid +** system call. +*/ +static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){ + int i = -1; + + UNUSED_PARAMETER(p); + if( zName ){ + for(i=0; i<ArraySize(aSyscall)-1; i++){ + if( strcmp(zName, aSyscall[i].zName)==0 ) break; + } + } + for(i++; i<ArraySize(aSyscall); i++){ + if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; + } + return 0; +} + +/* +** Retry open() calls that fail due to EINTR +*/ +static int robust_open(const char *z, int f, int m){ + int rc; + do{ rc = osOpen(z,f,m); }while( rc<0 && errno==EINTR ); + return rc; +} /* ** Helper functions to obtain and relinquish the global mutex. The -** global mutex is used to protect the unixOpenCnt, unixLockInfo and -** vxworksFileId objects used by this file, all of which may be +** global mutex is used to protect the unixInodeInfo and +** vxworksFileId objects used by this file, all of which may be ** shared by multiple threads. ** -** Function unixMutexHeld() is used to assert() that the global mutex -** is held when required. This function is only used as part of assert() +** Function unixMutexHeld() is used to assert() that the global mutex +** is held when required. This function is only used as part of assert() ** statements. e.g. ** ** unixEnterMutex() @@ -22342,8 +25114,8 @@ static int unixMutexHeld(void) { ** binaries. This returns the string represetation of the supplied ** integer lock-type. */ -static const char *locktypeName(int locktype){ - switch( locktype ){ +static const char *azFileLock(int eFileLock){ + switch( eFileLock ){ case NO_LOCK: return "NONE"; case SHARED_LOCK: return "SHARED"; case RESERVED_LOCK: return "RESERVED"; @@ -22372,7 +25144,7 @@ static int lockTrace(int fd, int op, struct flock *p){ }else if( op==F_SETLK ){ zOpName = "SETLK"; }else{ - s = fcntl(fd, op, p); + s = osFcntl(fd, op, p); sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s); return s; } @@ -22386,7 +25158,7 @@ static int lockTrace(int fd, int op, struct flock *p){ assert( 0 ); } assert( p->l_whence==SEEK_SET ); - s = fcntl(fd, op, p); + s = osFcntl(fd, op, p); savedErrno = errno; sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n", threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len, @@ -22394,7 +25166,7 @@ static int lockTrace(int fd, int op, struct flock *p){ if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){ struct flock l2; l2 = *p; - fcntl(fd, F_GETLK, &l2); + osFcntl(fd, F_GETLK, &l2); if( l2.l_type==F_RDLCK ){ zType = "RDLCK"; }else if( l2.l_type==F_WRLCK ){ @@ -22410,58 +25182,86 @@ static int lockTrace(int fd, int op, struct flock *p){ errno = savedErrno; return s; } -#define fcntl lockTrace +#undef osFcntl +#define osFcntl lockTrace #endif /* SQLITE_LOCK_TRACE */ - +/* +** Retry ftruncate() calls that fail due to EINTR +*/ +static int robust_ftruncate(int h, sqlite3_int64 sz){ + int rc; + do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR ); + return rc; +} /* ** This routine translates a standard POSIX errno code into something ** useful to the clients of the sqlite3 functions. Specifically, it is ** intended to translate a variety of "try again" errors into SQLITE_BUSY -** and a variety of "please close the file descriptor NOW" errors into +** and a variety of "please close the file descriptor NOW" errors into ** SQLITE_IOERR -** +** ** Errors during initialization of locks, or file system support for locks, ** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately. */ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { switch (posixError) { - case 0: +#if 0 + /* At one point this code was not commented out. In theory, this branch + ** should never be hit, as this function should only be called after + ** a locking-related function (i.e. fcntl()) has returned non-zero with + ** the value of errno as the first argument. Since a system call has failed, + ** errno should be non-zero. + ** + ** Despite this, if errno really is zero, we still don't want to return + ** SQLITE_OK. The system call failed, and *some* SQLite error should be + ** propagated back to the caller. Commenting this branch out means errno==0 + ** will be handled by the "default:" case below. + */ + case 0: return SQLITE_OK; +#endif case EAGAIN: case ETIMEDOUT: case EBUSY: case EINTR: - case ENOLCK: - /* random NFS retry error, unless during file system support + case ENOLCK: + /* random NFS retry error, unless during file system support * introspection, in which it actually means what it says */ return SQLITE_BUSY; - - case EACCES: + + case EACCES: /* EACCES is like EAGAIN during locking operations, but not any other time*/ - if( (sqliteIOErr == SQLITE_IOERR_LOCK) || - (sqliteIOErr == SQLITE_IOERR_UNLOCK) || + if( (sqliteIOErr == SQLITE_IOERR_LOCK) || + (sqliteIOErr == SQLITE_IOERR_UNLOCK) || (sqliteIOErr == SQLITE_IOERR_RDLOCK) || (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){ return SQLITE_BUSY; } /* else fall through */ - case EPERM: + case EPERM: return SQLITE_PERM; - + + /* EDEADLK is only possible if a call to fcntl(F_SETLKW) is made. And + ** this module never makes such a call. And the code in SQLite itself + ** asserts that SQLITE_IOERR_BLOCKED is never returned. For these reasons + ** this case is also commented out. If the system does set errno to EDEADLK, + ** the default SQLITE_IOERR_XXX code will be returned. */ +#if 0 case EDEADLK: return SQLITE_IOERR_BLOCKED; - +#endif + #if EOPNOTSUPP!=ENOTSUP - case EOPNOTSUPP: - /* something went terribly awry, unless during file system support + case EOPNOTSUPP: + /* something went terribly awry, unless during file system support * introspection, in which it actually means what it says */ #endif #ifdef ENOTSUP - case ENOTSUP: - /* invalid fd, unless during file system support introspection, in which + case ENOTSUP: + /* invalid fd, unless during file system support introspection, in which * it actually means what it says */ #endif case EIO: @@ -22471,11 +25271,13 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { case ENODEV: case ENXIO: case ENOENT: +#ifdef ESTALE /* ESTALE is not defined on Interix systems */ case ESTALE: +#endif case ENOSYS: /* these should force the client to close the file and reconnect */ - - default: + + default: return sqliteIOErr; } } @@ -22491,7 +25293,7 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { ** ** A pointer to an instance of the following structure can be used as a ** unique file ID in VxWorks. Each instance of this structure contains -** a copy of the canonical filename. There is also a reference count. +** a copy of the canonical filename. There is also a reference count. ** The structure is reclaimed when the number of pointers to it drops to ** zero. ** @@ -22507,7 +25309,7 @@ struct vxworksFileId { }; #if OS_VXWORKS -/* +/* ** All unique filenames are held on a linked list headed by this ** variable: */ @@ -22579,7 +25381,7 @@ static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){ */ unixEnterMutex(); for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){ - if( pCandidate->nName==n + if( pCandidate->nName==n && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0 ){ sqlite3_free(pNew); @@ -22672,7 +25474,7 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){ ** cnt>0 means there are cnt shared locks on the file. ** ** Any attempt to lock or unlock a file first checks the locking -** structure. The fcntl() system call is only invoked to set a +** structure. The fcntl() system call is only invoked to set a ** POSIX lock if the internal lock structure transitions between ** a locked and an unlocked state. ** @@ -22680,13 +25482,12 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){ ** ** If you close a file descriptor that points to a file that has locks, ** all locks on that file that are owned by the current process are -** released. To work around this problem, each unixFile structure contains -** a pointer to an unixOpenCnt structure. There is one unixOpenCnt structure -** per open inode, which means that multiple unixFile can point to a single -** unixOpenCnt. When an attempt is made to close an unixFile, if there are +** released. To work around this problem, each unixInodeInfo object +** maintains a count of the number of pending locks on tha inode. +** When an attempt is made to close an unixFile, if there are ** other unixFile open on the same inode that are holding locks, the call ** to close() the file descriptor is deferred until all of the locks clear. -** The unixOpenCnt structure keeps a list of file descriptors that need to +** The unixInodeInfo structure keeps a list of file descriptors that need to ** be closed and that list is walked (and cleared) when the last lock ** clears. ** @@ -22701,46 +25502,19 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){ ** in thread B. But there is no way to know at compile-time which ** threading library is being used. So there is no way to know at ** compile-time whether or not thread A can override locks on thread B. -** We have to do a run-time check to discover the behavior of the +** One has to do a run-time check to discover the behavior of the ** current process. ** -** On systems where thread A is unable to modify locks created by -** thread B, we have to keep track of which thread created each -** lock. Hence there is an extra field in the key to the unixLockInfo -** structure to record this information. And on those systems it -** is illegal to begin a transaction in one thread and finish it -** in another. For this latter restriction, there is no work-around. -** It is a limitation of LinuxThreads. -*/ - -/* -** Set or check the unixFile.tid field. This field is set when an unixFile -** is first opened. All subsequent uses of the unixFile verify that the -** same thread is operating on the unixFile. Some operating systems do -** not allow locks to be overridden by other threads and that restriction -** means that sqlite3* database handles cannot be moved from one thread -** to another while locks are held. -** -** Version 3.3.1 (2006-01-15): unixFile can be moved from one thread to -** another as long as we are running on a system that supports threads -** overriding each others locks (which is now the most common behavior) -** or if no locks are held. But the unixFile.pLock field needs to be -** recomputed because its key includes the thread-id. See the -** transferOwnership() function below for additional information -*/ -#if SQLITE_THREADSAFE && defined(__linux__) -# define SET_THREADID(X) (X)->tid = pthread_self() -# define CHECK_THREADID(X) (threadsOverrideEachOthersLocks==0 && \ - !pthread_equal((X)->tid, pthread_self())) -#else -# define SET_THREADID(X) -# define CHECK_THREADID(X) 0 -#endif +** SQLite used to support LinuxThreads. But support for LinuxThreads +** was dropped beginning with version 3.7.0. SQLite will still work with +** LinuxThreads provided that (1) there is no more than one connection +** per database file in the same process and (2) database connections +** do not move across threads. +*/ /* ** An instance of the following structure serves as the key used -** to locate a particular unixOpenCnt structure given its inode. This -** is the same as the unixLockKey except that the thread ID is omitted. +** to locate a particular unixInodeInfo object. */ struct unixFileId { dev_t dev; /* Device number */ @@ -22752,23 +25526,6 @@ struct unixFileId { }; /* -** An instance of the following structure serves as the key used -** to locate a particular unixLockInfo structure given its inode. -** -** If threads cannot override each others locks (LinuxThreads), then we -** set the unixLockKey.tid field to the thread ID. If threads can override -** each others locks (Posix and NPTL) then tid is always set to zero. -** tid is omitted if we compile without threading support or on an OS -** other than linux. -*/ -struct unixLockKey { - struct unixFileId fid; /* Unique identifier for the file */ -#if SQLITE_THREADSAFE && defined(__linux__) - pthread_t tid; /* Thread ID of lock owner. Zero if not using LinuxThreads */ -#endif -}; - -/* ** An instance of the following structure is allocated for each open ** inode. Or, on LinuxThreads, there is one of these structures for ** each inode opened by each thread. @@ -22777,230 +25534,185 @@ struct unixLockKey { ** structure contains a pointer to an instance of this object and this ** object keeps a count of the number of unixFile pointing to it. */ -struct unixLockInfo { - struct unixLockKey lockKey; /* The lookup key */ - int cnt; /* Number of SHARED locks held */ - int locktype; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ +struct unixInodeInfo { + struct unixFileId fileId; /* The lookup key */ + int nShared; /* Number of SHARED locks held */ + unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ + unsigned char bProcessLock; /* An exclusive process lock is held */ int nRef; /* Number of pointers to this structure */ -#if defined(SQLITE_ENABLE_LOCKING_STYLE) + unixShmNode *pShmNode; /* Shared memory associated with this inode */ + int nLock; /* Number of outstanding file locks */ + UnixUnusedFd *pUnused; /* Unused file descriptors to close */ + unixInodeInfo *pNext; /* List of all unixInodeInfo objects */ + unixInodeInfo *pPrev; /* .... doubly linked */ +#if SQLITE_ENABLE_LOCKING_STYLE unsigned long long sharedByte; /* for AFP simulated shared lock */ #endif - struct unixLockInfo *pNext; /* List of all unixLockInfo objects */ - struct unixLockInfo *pPrev; /* .... doubly linked */ -}; - -/* -** An instance of the following structure is allocated for each open -** inode. This structure keeps track of the number of locks on that -** inode. If a close is attempted against an inode that is holding -** locks, the close is deferred until all locks clear by adding the -** file descriptor to be closed to the pending list. -** -** TODO: Consider changing this so that there is only a single file -** descriptor for each open file, even when it is opened multiple times. -** The close() system call would only occur when the last database -** using the file closes. -*/ -struct unixOpenCnt { - struct unixFileId fileId; /* The lookup key */ - int nRef; /* Number of pointers to this structure */ - int nLock; /* Number of outstanding locks */ - UnixUnusedFd *pUnused; /* Unused file descriptors to close */ #if OS_VXWORKS - sem_t *pSem; /* Named POSIX semaphore */ - char aSemName[MAX_PATHNAME+2]; /* Name of that semaphore */ + sem_t *pSem; /* Named POSIX semaphore */ + char aSemName[MAX_PATHNAME+2]; /* Name of that semaphore */ #endif - struct unixOpenCnt *pNext, *pPrev; /* List of all unixOpenCnt objects */ }; /* -** Lists of all unixLockInfo and unixOpenCnt objects. These used to be hash -** tables. But the number of objects is rarely more than a dozen and -** never exceeds a few thousand. And lookup is not on a critical -** path so a simple linked list will suffice. +** A lists of all unixInodeInfo objects. */ -static struct unixLockInfo *lockList = 0; -static struct unixOpenCnt *openList = 0; +static unixInodeInfo *inodeList = 0; /* -** This variable remembers whether or not threads can override each others -** locks. ** -** 0: No. Threads cannot override each others locks. (LinuxThreads) -** 1: Yes. Threads can override each others locks. (Posix & NLPT) -** -1: We don't know yet. +** This function - unixLogError_x(), is only ever called via the macro +** unixLogError(). ** -** On some systems, we know at compile-time if threads can override each -** others locks. On those systems, the SQLITE_THREAD_OVERRIDE_LOCK macro -** will be set appropriately. On other systems, we have to check at -** runtime. On these latter systems, SQLTIE_THREAD_OVERRIDE_LOCK is -** undefined. +** It is invoked after an error occurs in an OS function and errno has been +** set. It logs a message using sqlite3_log() containing the current value of +** errno and, if possible, the human-readable equivalent from strerror() or +** strerror_r(). ** -** This variable normally has file scope only. But during testing, we make -** it a global so that the test code can change its value in order to verify -** that the right stuff happens in either case. +** The first argument passed to the macro should be the error code that +** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). +** The two subsequent arguments should be the name of the OS function that +** failed (e.g. "unlink", "open") and the the associated file-system path, +** if any. */ -#if SQLITE_THREADSAFE && defined(__linux__) -# ifndef SQLITE_THREAD_OVERRIDE_LOCK -# define SQLITE_THREAD_OVERRIDE_LOCK -1 -# endif -# ifdef SQLITE_TEST -int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK; -# else -static int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK; -# endif +#define unixLogError(a,b,c) unixLogErrorAtLine(a,b,c,__LINE__) +static int unixLogErrorAtLine( + int errcode, /* SQLite error code */ + const char *zFunc, /* Name of OS function that failed */ + const char *zPath, /* File path associated with error */ + int iLine /* Source line number where error occurred */ +){ + char *zErr; /* Message from strerror() or equivalent */ + int iErrno = errno; /* Saved syscall error number */ + + /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use + ** the strerror() function to obtain the human-readable error message + ** equivalent to errno. Otherwise, use strerror_r(). + */ +#if SQLITE_THREADSAFE && defined(HAVE_STRERROR_R) + char aErr[80]; + memset(aErr, 0, sizeof(aErr)); + zErr = aErr; + + /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined, + ** assume that the system provides the the GNU version of strerror_r() that + ** returns a pointer to a buffer containing the error message. That pointer + ** may point to aErr[], or it may point to some static storage somewhere. + ** Otherwise, assume that the system provides the POSIX version of + ** strerror_r(), which always writes an error message into aErr[]. + ** + ** If the code incorrectly assumes that it is the POSIX version that is + ** available, the error message will often be an empty string. Not a + ** huge problem. Incorrectly concluding that the GNU version is available + ** could lead to a segfault though. + */ +#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU) + zErr = +# endif + strerror_r(iErrno, aErr, sizeof(aErr)-1); + +#elif SQLITE_THREADSAFE + /* This is a threadsafe build, but strerror_r() is not available. */ + zErr = ""; +#else + /* Non-threadsafe build, use strerror(). */ + zErr = strerror(iErrno); #endif -/* -** This structure holds information passed into individual test -** threads by the testThreadLockingBehavior() routine. -*/ -struct threadTestData { - int fd; /* File to be locked */ - struct flock lock; /* The locking operation */ - int result; /* Result of the locking operation */ -}; + assert( errcode!=SQLITE_OK ); + if( zPath==0 ) zPath = ""; + sqlite3_log(errcode, + "os_unix.c:%d: (%d) %s(%s) - %s", + iLine, iErrno, zFunc, zPath, zErr + ); + + return errcode; +} -#if SQLITE_THREADSAFE && defined(__linux__) /* -** This function is used as the main routine for a thread launched by -** testThreadLockingBehavior(). It tests whether the shared-lock obtained -** by the main thread in testThreadLockingBehavior() conflicts with a -** hypothetical write-lock obtained by this thread on the same file. +** Close a file descriptor. +** +** We assume that close() almost always works, since it is only in a +** very sick application or on a very sick platform that it might fail. +** If it does fail, simply leak the file descriptor, but do log the +** error. ** -** The write-lock is not actually acquired, as this is not possible if -** the file is open in read-only mode (see ticket #3472). +** Note that it is not safe to retry close() after EINTR since the +** file descriptor might have already been reused by another thread. +** So we don't even try to recover from an EINTR. Just log the error +** and move on. */ -static void *threadLockingTest(void *pArg){ - struct threadTestData *pData = (struct threadTestData*)pArg; - pData->result = fcntl(pData->fd, F_GETLK, &pData->lock); - return pArg; +static void robust_close(unixFile *pFile, int h, int lineno){ + if( osClose(h) ){ + unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close", + pFile ? pFile->zPath : 0, lineno); + } } -#endif /* SQLITE_THREADSAFE && defined(__linux__) */ - -#if SQLITE_THREADSAFE && defined(__linux__) /* -** This procedure attempts to determine whether or not threads -** can override each others locks then sets the -** threadsOverrideEachOthersLocks variable appropriately. -*/ -static void testThreadLockingBehavior(int fd_orig){ - int fd; - int rc; - struct threadTestData d; - struct flock l; - pthread_t t; - - fd = dup(fd_orig); - if( fd<0 ) return; - memset(&l, 0, sizeof(l)); - l.l_type = F_RDLCK; - l.l_len = 1; - l.l_start = 0; - l.l_whence = SEEK_SET; - rc = fcntl(fd_orig, F_SETLK, &l); - if( rc!=0 ) return; - memset(&d, 0, sizeof(d)); - d.fd = fd; - d.lock = l; - d.lock.l_type = F_WRLCK; - if( pthread_create(&t, 0, threadLockingTest, &d)==0 ){ - pthread_join(t, 0); - } - close(fd); - if( d.result!=0 ) return; - threadsOverrideEachOthersLocks = (d.lock.l_type==F_UNLCK); -} -#endif /* SQLITE_THREADSAFE && defined(__linux__) */ - -/* -** Release a unixLockInfo structure previously allocated by findLockInfo(). -** -** The mutex entered using the unixEnterMutex() function must be held -** when this function is called. -*/ -static void releaseLockInfo(struct unixLockInfo *pLock){ - assert( unixMutexHeld() ); - if( pLock ){ - pLock->nRef--; - if( pLock->nRef==0 ){ - if( pLock->pPrev ){ - assert( pLock->pPrev->pNext==pLock ); - pLock->pPrev->pNext = pLock->pNext; - }else{ - assert( lockList==pLock ); - lockList = pLock->pNext; - } - if( pLock->pNext ){ - assert( pLock->pNext->pPrev==pLock ); - pLock->pNext->pPrev = pLock->pPrev; - } - sqlite3_free(pLock); - } +** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. +*/ +static void closePendingFds(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; + UnixUnusedFd *p; + UnixUnusedFd *pNext; + for(p=pInode->pUnused; p; p=pNext){ + pNext = p->pNext; + robust_close(pFile, p->fd, __LINE__); + sqlite3_free(p); } + pInode->pUnused = 0; } /* -** Release a unixOpenCnt structure previously allocated by findLockInfo(). +** Release a unixInodeInfo structure previously allocated by findInodeInfo(). ** ** The mutex entered using the unixEnterMutex() function must be held ** when this function is called. */ -static void releaseOpenCnt(struct unixOpenCnt *pOpen){ +static void releaseInodeInfo(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; assert( unixMutexHeld() ); - if( pOpen ){ - pOpen->nRef--; - if( pOpen->nRef==0 ){ - if( pOpen->pPrev ){ - assert( pOpen->pPrev->pNext==pOpen ); - pOpen->pPrev->pNext = pOpen->pNext; + if( ALWAYS(pInode) ){ + pInode->nRef--; + if( pInode->nRef==0 ){ + assert( pInode->pShmNode==0 ); + closePendingFds(pFile); + if( pInode->pPrev ){ + assert( pInode->pPrev->pNext==pInode ); + pInode->pPrev->pNext = pInode->pNext; }else{ - assert( openList==pOpen ); - openList = pOpen->pNext; + assert( inodeList==pInode ); + inodeList = pInode->pNext; } - if( pOpen->pNext ){ - assert( pOpen->pNext->pPrev==pOpen ); - pOpen->pNext->pPrev = pOpen->pPrev; + if( pInode->pNext ){ + assert( pInode->pNext->pPrev==pInode ); + pInode->pNext->pPrev = pInode->pPrev; } -#if SQLITE_THREADSAFE && defined(__linux__) - assert( !pOpen->pUnused || threadsOverrideEachOthersLocks==0 ); -#endif - - /* If pOpen->pUnused is not null, then memory and file-descriptors - ** are leaked. - ** - ** This will only happen if, under Linuxthreads, the user has opened - ** a transaction in one thread, then attempts to close the database - ** handle from another thread (without first unlocking the db file). - ** This is a misuse. */ - sqlite3_free(pOpen); + sqlite3_free(pInode); } } } /* -** Given a file descriptor, locate unixLockInfo and unixOpenCnt structures that -** describes that file descriptor. Create new ones if necessary. The -** return values might be uninitialized if an error occurs. +** Given a file descriptor, locate the unixInodeInfo object that +** describes that file descriptor. Create a new one if necessary. The +** return value might be uninitialized if an error occurs. ** ** The mutex entered using the unixEnterMutex() function must be held ** when this function is called. ** ** Return an appropriate error code. */ -static int findLockInfo( +static int findInodeInfo( unixFile *pFile, /* Unix file with file desc used in the key */ - struct unixLockInfo **ppLock, /* Return the unixLockInfo structure here */ - struct unixOpenCnt **ppOpen /* Return the unixOpenCnt structure here */ + unixInodeInfo **ppInode /* Return the unixInodeInfo object here */ ){ int rc; /* System call return code */ int fd; /* The file descriptor for pFile */ - struct unixLockKey lockKey; /* Lookup key for the unixLockInfo structure */ - struct unixFileId fileId; /* Lookup key for the unixOpenCnt struct */ + struct unixFileId fileId; /* Lookup key for the unixInodeInfo */ struct stat statbuf; /* Low-level file information */ - struct unixLockInfo *pLock = 0;/* Candidate unixLockInfo object */ - struct unixOpenCnt *pOpen; /* Candidate unixOpenCnt object */ + unixInodeInfo *pInode = 0; /* Candidate unixInodeInfo object */ assert( unixMutexHeld() ); @@ -23008,7 +25720,7 @@ static int findLockInfo( ** create a unique name for the file. */ fd = pFile->h; - rc = fstat(fd, &statbuf); + rc = osFstat(fd, &statbuf); if( rc!=0 ){ pFile->lastErrno = errno; #ifdef EOVERFLOW @@ -23029,12 +25741,12 @@ static int findLockInfo( ** the first page of the database, no damage is done. */ if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){ - rc = write(fd, "S", 1); + do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR ); if( rc!=1 ){ pFile->lastErrno = errno; return SQLITE_IOERR; } - rc = fstat(fd, &statbuf); + rc = osFstat(fd, &statbuf); if( rc!=0 ){ pFile->lastErrno = errno; return SQLITE_IOERR; @@ -23042,122 +25754,35 @@ static int findLockInfo( } #endif - memset(&lockKey, 0, sizeof(lockKey)); - lockKey.fid.dev = statbuf.st_dev; + memset(&fileId, 0, sizeof(fileId)); + fileId.dev = statbuf.st_dev; #if OS_VXWORKS - lockKey.fid.pId = pFile->pId; + fileId.pId = pFile->pId; #else - lockKey.fid.ino = statbuf.st_ino; + fileId.ino = statbuf.st_ino; #endif -#if SQLITE_THREADSAFE && defined(__linux__) - if( threadsOverrideEachOthersLocks<0 ){ - testThreadLockingBehavior(fd); - } - lockKey.tid = threadsOverrideEachOthersLocks ? 0 : pthread_self(); -#endif - fileId = lockKey.fid; - if( ppLock!=0 ){ - pLock = lockList; - while( pLock && memcmp(&lockKey, &pLock->lockKey, sizeof(lockKey)) ){ - pLock = pLock->pNext; - } - if( pLock==0 ){ - pLock = sqlite3_malloc( sizeof(*pLock) ); - if( pLock==0 ){ - rc = SQLITE_NOMEM; - goto exit_findlockinfo; - } - memcpy(&pLock->lockKey,&lockKey,sizeof(lockKey)); - pLock->nRef = 1; - pLock->cnt = 0; - pLock->locktype = 0; -#if defined(SQLITE_ENABLE_LOCKING_STYLE) - pLock->sharedByte = 0; -#endif - pLock->pNext = lockList; - pLock->pPrev = 0; - if( lockList ) lockList->pPrev = pLock; - lockList = pLock; - }else{ - pLock->nRef++; - } - *ppLock = pLock; + pInode = inodeList; + while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ + pInode = pInode->pNext; } - if( ppOpen!=0 ){ - pOpen = openList; - while( pOpen && memcmp(&fileId, &pOpen->fileId, sizeof(fileId)) ){ - pOpen = pOpen->pNext; - } - if( pOpen==0 ){ - pOpen = sqlite3_malloc( sizeof(*pOpen) ); - if( pOpen==0 ){ - releaseLockInfo(pLock); - rc = SQLITE_NOMEM; - goto exit_findlockinfo; - } - memset(pOpen, 0, sizeof(*pOpen)); - pOpen->fileId = fileId; - pOpen->nRef = 1; - pOpen->pNext = openList; - if( openList ) openList->pPrev = pOpen; - openList = pOpen; - }else{ - pOpen->nRef++; + if( pInode==0 ){ + pInode = sqlite3_malloc( sizeof(*pInode) ); + if( pInode==0 ){ + return SQLITE_NOMEM; } - *ppOpen = pOpen; - } - -exit_findlockinfo: - return rc; -} - -/* -** If we are currently in a different thread than the thread that the -** unixFile argument belongs to, then transfer ownership of the unixFile -** over to the current thread. -** -** A unixFile is only owned by a thread on systems that use LinuxThreads. -** -** Ownership transfer is only allowed if the unixFile is currently unlocked. -** If the unixFile is locked and an ownership is wrong, then return -** SQLITE_MISUSE. SQLITE_OK is returned if everything works. -*/ -#if SQLITE_THREADSAFE && defined(__linux__) -static int transferOwnership(unixFile *pFile){ - int rc; - pthread_t hSelf; - if( threadsOverrideEachOthersLocks ){ - /* Ownership transfers not needed on this system */ - return SQLITE_OK; - } - hSelf = pthread_self(); - if( pthread_equal(pFile->tid, hSelf) ){ - /* We are still in the same thread */ - OSTRACE1("No-transfer, same thread\n"); - return SQLITE_OK; - } - if( pFile->locktype!=NO_LOCK ){ - /* We cannot change ownership while we are holding a lock! */ - return SQLITE_MISUSE_BKPT; - } - OSTRACE4("Transfer ownership of %d from %d to %d\n", - pFile->h, pFile->tid, hSelf); - pFile->tid = hSelf; - if (pFile->pLock != NULL) { - releaseLockInfo(pFile->pLock); - rc = findLockInfo(pFile, &pFile->pLock, 0); - OSTRACE5("LOCK %d is now %s(%s,%d)\n", pFile->h, - locktypeName(pFile->locktype), - locktypeName(pFile->pLock->locktype), pFile->pLock->cnt); - return rc; - } else { - return SQLITE_OK; + memset(pInode, 0, sizeof(*pInode)); + memcpy(&pInode->fileId, &fileId, sizeof(fileId)); + pInode->nRef = 1; + pInode->pNext = inodeList; + pInode->pPrev = 0; + if( inodeList ) inodeList->pPrev = pInode; + inodeList = pInode; + }else{ + pInode->nRef++; } + *ppInode = pInode; + return SQLITE_OK; } -#else /* if not SQLITE_THREADSAFE */ - /* On single-threaded builds, ownership transfer is a no-op */ -# define transferOwnership(X) SQLITE_OK -#endif /* SQLITE_THREADSAFE */ /* @@ -23174,41 +25799,87 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); assert( pFile ); - unixEnterMutex(); /* Because pFile->pLock is shared across threads */ + unixEnterMutex(); /* Because pFile->pInode is shared across threads */ /* Check if a thread in this process holds such a lock */ - if( pFile->pLock->locktype>SHARED_LOCK ){ + if( pFile->pInode->eFileLock>SHARED_LOCK ){ reserved = 1; } /* Otherwise see if some other process holds it. */ #ifndef __DJGPP__ - if( !reserved ){ + if( !reserved && !pFile->pInode->bProcessLock ){ struct flock lock; lock.l_whence = SEEK_SET; lock.l_start = RESERVED_BYTE; lock.l_len = 1; lock.l_type = F_WRLCK; - if (-1 == fcntl(pFile->h, F_GETLK, &lock)) { - int tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK); - pFile->lastErrno = tErrno; + if( osFcntl(pFile->h, F_GETLK, &lock) ){ + rc = SQLITE_IOERR_CHECKRESERVEDLOCK; + pFile->lastErrno = errno; } else if( lock.l_type!=F_UNLCK ){ reserved = 1; } } #endif - + unixLeaveMutex(); - OSTRACE4("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved); + OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); *pResOut = reserved; return rc; } /* -** Lock the file with the lock specified by parameter locktype - one +** Attempt to set a system-lock on the file pFile. The lock is +** described by pLock. +** +** If the pFile was opened read/write from unix-excl, then the only lock +** ever obtained is an exclusive lock, and it is obtained exactly once +** the first time any lock is attempted. All subsequent system locking +** operations become no-ops. Locking operations still happen internally, +** in order to coordinate access between separate database connections +** within this process, but all of that is handled in memory and the +** operating system does not participate. +** +** This function is a pass-through to fcntl(F_SETLK) if pFile is using +** any VFS other than "unix-excl" or if pFile is opened on "unix-excl" +** and is read-only. +** +** Zero is returned if the call completes successfully, or -1 if a call +** to fcntl() fails. In this case, errno is set appropriately (by fcntl()). +*/ +static int unixFileLock(unixFile *pFile, struct flock *pLock){ + int rc; + unixInodeInfo *pInode = pFile->pInode; + assert( unixMutexHeld() ); + assert( pInode!=0 ); + if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock) + && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0) + ){ + if( pInode->bProcessLock==0 ){ + struct flock lock; + assert( pInode->nLock==0 ); + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + lock.l_type = F_WRLCK; + rc = osFcntl(pFile->h, F_SETLK, &lock); + if( rc<0 ) return rc; + pInode->bProcessLock = 1; + pInode->nLock++; + }else{ + rc = 0; + } + }else{ + rc = osFcntl(pFile->h, F_SETLK, pLock); + } + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one ** of the following: ** ** (1) SHARED_LOCK @@ -23231,7 +25902,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ ** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. */ -static int unixLock(sqlite3_file *id, int locktype){ +static int unixLock(sqlite3_file *id, int eFileLock){ /* The following describes the implementation of the various locks and ** lock transitions in terms of the POSIX advisory shared and exclusive ** lock primitives (called read-locks and write-locks below, to avoid @@ -23249,7 +25920,7 @@ static int unixLock(sqlite3_file *id, int locktype){ ** ** 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'. + ** 'reserved byte'. ** ** 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 @@ -23263,7 +25934,7 @@ static int unixLock(sqlite3_file *id, int locktype){ ** 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. + ** database. ** ** The reason a single byte cannot be used instead of the 'shared byte ** range' is that some versions of windows do not support read-locks. By @@ -23272,23 +25943,22 @@ static int unixLock(sqlite3_file *id, int locktype){ */ int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; - struct unixLockInfo *pLock = pFile->pLock; + unixInodeInfo *pInode = pFile->pInode; struct flock lock; - int s = 0; int tErrno = 0; assert( pFile ); - OSTRACE7("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h, - locktypeName(locktype), locktypeName(pFile->locktype), - locktypeName(pLock->locktype), pLock->cnt , getpid()); + OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h, + azFileLock(eFileLock), azFileLock(pFile->eFileLock), + azFileLock(pInode->eFileLock), pInode->nShared , getpid())); /* If there is already a lock of this type or more restrictive on the ** unixFile, do nothing. Don't use the end_lock: exit path, as ** unixEnterMutex() hasn't been called yet. */ - if( pFile->locktype>=locktype ){ - OSTRACE3("LOCK %d %s ok (already held) (unix)\n", pFile->h, - locktypeName(locktype)); + if( pFile->eFileLock>=eFileLock ){ + OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h, + azFileLock(eFileLock))); return SQLITE_OK; } @@ -23297,28 +25967,20 @@ static int unixLock(sqlite3_file *id, int locktype){ ** (2) SQLite never explicitly requests a pendig lock. ** (3) A shared lock is always held when a reserve lock is requested. */ - assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); - assert( locktype!=PENDING_LOCK ); - assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); + assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); + assert( eFileLock!=PENDING_LOCK ); + assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); - /* This mutex is needed because pFile->pLock is shared across threads + /* This mutex is needed because pFile->pInode is shared across threads */ unixEnterMutex(); - - /* Make sure the current thread owns the pFile. - */ - rc = transferOwnership(pFile); - if( rc!=SQLITE_OK ){ - unixLeaveMutex(); - return rc; - } - pLock = pFile->pLock; + pInode = pFile->pInode; /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. */ - if( (pFile->locktype!=pLock->locktype && - (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK)) + if( (pFile->eFileLock!=pInode->eFileLock && + (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK)) ){ rc = SQLITE_BUSY; goto end_lock; @@ -23328,14 +25990,14 @@ static int unixLock(sqlite3_file *id, int locktype){ ** has a SHARED or RESERVED lock, then increment reference counts and ** return SQLITE_OK. */ - if( locktype==SHARED_LOCK && - (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){ - assert( locktype==SHARED_LOCK ); - assert( pFile->locktype==0 ); - assert( pLock->cnt>0 ); - pFile->locktype = SHARED_LOCK; - pLock->cnt++; - pFile->pOpen->nLock++; + if( eFileLock==SHARED_LOCK && + (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ + assert( eFileLock==SHARED_LOCK ); + assert( pFile->eFileLock==0 ); + assert( pInode->nShared>0 ); + pFile->eFileLock = SHARED_LOCK; + pInode->nShared++; + pInode->nLock++; goto end_lock; } @@ -23346,16 +26008,15 @@ static int unixLock(sqlite3_file *id, int locktype){ */ lock.l_len = 1L; lock.l_whence = SEEK_SET; - if( locktype==SHARED_LOCK - || (locktype==EXCLUSIVE_LOCK && pFile->locktype<PENDING_LOCK) + if( eFileLock==SHARED_LOCK + || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK) ){ - lock.l_type = (locktype==SHARED_LOCK?F_RDLCK:F_WRLCK); + lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); lock.l_start = PENDING_BYTE; - s = fcntl(pFile->h, F_SETLK, &lock); - if( s==(-1) ){ + if( unixFileLock(pFile, &lock) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); - if( IS_LOCK_ERROR(rc) ){ + if( rc!=SQLITE_BUSY ){ pFile->lastErrno = tErrno; } goto end_lock; @@ -23366,42 +26027,40 @@ static int unixLock(sqlite3_file *id, int locktype){ /* If control gets to this point, then actually go ahead and make ** operating system calls for the specified lock. */ - if( locktype==SHARED_LOCK ){ - assert( pLock->cnt==0 ); - assert( pLock->locktype==0 ); + if( eFileLock==SHARED_LOCK ){ + assert( pInode->nShared==0 ); + assert( pInode->eFileLock==0 ); + assert( rc==SQLITE_OK ); /* Now get the read-lock */ lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; - if( (s = fcntl(pFile->h, F_SETLK, &lock))==(-1) ){ + if( unixFileLock(pFile, &lock) ){ tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); } + /* Drop the temporary PENDING lock */ lock.l_start = PENDING_BYTE; lock.l_len = 1L; lock.l_type = F_UNLCK; - if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){ - if( s != -1 ){ - /* This could happen with a network mount */ - tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); - if( IS_LOCK_ERROR(rc) ){ - pFile->lastErrno = tErrno; - } - goto end_lock; - } + if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){ + /* This could happen with a network mount */ + tErrno = errno; + rc = SQLITE_IOERR_UNLOCK; } - if( s==(-1) ){ - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); - if( IS_LOCK_ERROR(rc) ){ + + if( rc ){ + if( rc!=SQLITE_BUSY ){ pFile->lastErrno = tErrno; } + goto end_lock; }else{ - pFile->locktype = SHARED_LOCK; - pFile->pOpen->nLock++; - pLock->cnt = 1; + pFile->eFileLock = SHARED_LOCK; + pInode->nLock++; + pInode->nShared = 1; } - }else if( locktype==EXCLUSIVE_LOCK && pLock->cnt>1 ){ + }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){ /* We are trying for an exclusive lock but another thread in this ** same process is still holding a shared lock. */ rc = SQLITE_BUSY; @@ -23410,29 +26069,27 @@ static int unixLock(sqlite3_file *id, int locktype){ ** assumed that there is a SHARED or greater lock on the file ** already. */ - assert( 0!=pFile->locktype ); + assert( 0!=pFile->eFileLock ); lock.l_type = F_WRLCK; - switch( locktype ){ - case RESERVED_LOCK: - lock.l_start = RESERVED_BYTE; - break; - case EXCLUSIVE_LOCK: - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; - break; - default: - assert(0); + + assert( eFileLock==RESERVED_LOCK || eFileLock==EXCLUSIVE_LOCK ); + if( eFileLock==RESERVED_LOCK ){ + lock.l_start = RESERVED_BYTE; + lock.l_len = 1L; + }else{ + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; } - s = fcntl(pFile->h, F_SETLK, &lock); - if( s==(-1) ){ + + if( unixFileLock(pFile, &lock) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); - if( IS_LOCK_ERROR(rc) ){ + if( rc!=SQLITE_BUSY ){ pFile->lastErrno = tErrno; } } } - + #ifndef NDEBUG /* Set up the transaction-counter change checking flags when @@ -23441,8 +26098,8 @@ static int unixLock(sqlite3_file *id, int locktype){ ** write operation (not a hot journal rollback). */ if( rc==SQLITE_OK - && pFile->locktype<=SHARED_LOCK - && locktype==RESERVED_LOCK + && pFile->eFileLock<=SHARED_LOCK + && eFileLock==RESERVED_LOCK ){ pFile->transCntrChng = 0; pFile->dbUpdate = 0; @@ -23452,47 +26109,17 @@ static int unixLock(sqlite3_file *id, int locktype){ if( rc==SQLITE_OK ){ - pFile->locktype = locktype; - pLock->locktype = locktype; - }else if( locktype==EXCLUSIVE_LOCK ){ - pFile->locktype = PENDING_LOCK; - pLock->locktype = PENDING_LOCK; + pFile->eFileLock = eFileLock; + pInode->eFileLock = eFileLock; + }else if( eFileLock==EXCLUSIVE_LOCK ){ + pFile->eFileLock = PENDING_LOCK; + pInode->eFileLock = PENDING_LOCK; } end_lock: unixLeaveMutex(); - OSTRACE4("LOCK %d %s %s (unix)\n", pFile->h, locktypeName(locktype), - rc==SQLITE_OK ? "ok" : "failed"); - return rc; -} - -/* -** Close all file descriptors accumuated in the unixOpenCnt->pUnused list. -** If all such file descriptors are closed without error, the list is -** cleared and SQLITE_OK returned. -** -** Otherwise, if an error occurs, then successfully closed file descriptor -** entries are removed from the list, and SQLITE_IOERR_CLOSE returned. -** not deleted and SQLITE_IOERR_CLOSE returned. -*/ -static int closePendingFds(unixFile *pFile){ - int rc = SQLITE_OK; - struct unixOpenCnt *pOpen = pFile->pOpen; - UnixUnusedFd *pError = 0; - UnixUnusedFd *p; - UnixUnusedFd *pNext; - for(p=pOpen->pUnused; p; p=pNext){ - pNext = p->pNext; - if( close(p->fd) ){ - pFile->lastErrno = errno; - rc = SQLITE_IOERR_CLOSE; - p->pNext = pError; - pError = p; - }else{ - sqlite3_free(p); - } - } - pOpen->pUnused = pError; + OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); return rc; } @@ -23501,52 +26128,49 @@ static int closePendingFds(unixFile *pFile){ ** pUnused list. */ static void setPendingFd(unixFile *pFile){ - struct unixOpenCnt *pOpen = pFile->pOpen; + unixInodeInfo *pInode = pFile->pInode; UnixUnusedFd *p = pFile->pUnused; - p->pNext = pOpen->pUnused; - pOpen->pUnused = p; + p->pNext = pInode->pUnused; + pInode->pUnused = p; pFile->h = -1; pFile->pUnused = 0; } /* -** Lower the locking level on file descriptor pFile to locktype. locktype +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. -** +** ** If handleNFSUnlock is true, then on downgrading an EXCLUSIVE_LOCK to SHARED ** the byte range is divided into 2 parts and the first part is unlocked then -** set to a read lock, then the other part is simply unlocked. This works -** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to +** set to a read lock, then the other part is simply unlocked. This works +** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to ** remove the write lock on a region when a read lock is set. */ -static int _posixUnlock(sqlite3_file *id, int locktype, int handleNFSUnlock){ +static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ unixFile *pFile = (unixFile*)id; - struct unixLockInfo *pLock; + unixInodeInfo *pInode; struct flock lock; int rc = SQLITE_OK; int h; - int tErrno; /* Error code from system call errors */ assert( pFile ); - OSTRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, locktype, - pFile->locktype, pFile->pLock->locktype, pFile->pLock->cnt, getpid()); + OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock, + pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, + getpid())); - assert( locktype<=SHARED_LOCK ); - if( pFile->locktype<=locktype ){ + assert( eFileLock<=SHARED_LOCK ); + if( pFile->eFileLock<=eFileLock ){ return SQLITE_OK; } - if( CHECK_THREADID(pFile) ){ - return SQLITE_MISUSE_BKPT; - } unixEnterMutex(); h = pFile->h; - pLock = pFile->pLock; - assert( pLock->cnt!=0 ); - if( pFile->locktype>SHARED_LOCK ){ - assert( pLock->locktype==pFile->locktype ); + pInode = pFile->pInode; + assert( pInode->nShared!=0 ); + if( pFile->eFileLock>SHARED_LOCK ){ + assert( pInode->eFileLock==pFile->eFileLock ); SimulateIOErrorBenign(1); SimulateIOError( h=(-1) ) SimulateIOErrorBenign(0); @@ -23560,32 +26184,41 @@ static int _posixUnlock(sqlite3_file *id, int locktype, int handleNFSUnlock){ ** the file has changed and hence might not know to flush their ** cache. The use of a stale cache can lead to database corruption. */ +#if 0 assert( pFile->inNormalWrite==0 || pFile->dbUpdate==0 || pFile->transCntrChng==1 ); +#endif pFile->inNormalWrite = 0; #endif /* downgrading to a shared lock on NFS involves clearing the write lock ** before establishing the readlock - to avoid a race condition we downgrade - ** the lock in 2 blocks, so that part of the range will be covered by a + ** the lock in 2 blocks, so that part of the range will be covered by a ** write lock until the rest is covered by a read lock: ** 1: [WWWWW] ** 2: [....W] ** 3: [RRRRW] ** 4: [RRRR.] */ - if( locktype==SHARED_LOCK ){ + if( eFileLock==SHARED_LOCK ){ + +#if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE + (void)handleNFSUnlock; + assert( handleNFSUnlock==0 ); +#endif +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE if( handleNFSUnlock ){ + int tErrno; /* Error code from system call errors */ off_t divSize = SHARED_SIZE - 1; - + lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = divSize; - if( fcntl(h, F_SETLK, &lock)==(-1) ){ + if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); + rc = SQLITE_IOERR_UNLOCK; if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } @@ -23595,7 +26228,7 @@ static int _posixUnlock(sqlite3_file *id, int locktype, int handleNFSUnlock){ lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = divSize; - if( fcntl(h, F_SETLK, &lock)==(-1) ){ + if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); if( IS_LOCK_ERROR(rc) ){ @@ -23607,25 +26240,30 @@ static int _posixUnlock(sqlite3_file *id, int locktype, int handleNFSUnlock){ lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST+divSize; lock.l_len = SHARED_SIZE-divSize; - if( fcntl(h, F_SETLK, &lock)==(-1) ){ + if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); + rc = SQLITE_IOERR_UNLOCK; if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } goto end_unlock; } - }else{ + }else +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ + { lock.l_type = F_RDLCK; lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; - if( fcntl(h, F_SETLK, &lock)==(-1) ){ - tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); - if( IS_LOCK_ERROR(rc) ){ - pFile->lastErrno = tErrno; - } + if( unixFileLock(pFile, &lock) ){ + /* In theory, the call to unixFileLock() cannot fail because another + ** process is holding an incompatible lock. If it does, this + ** indicates that the other process is not following the locking + ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning + ** SQLITE_BUSY would confuse the upper layer (in practice it causes + ** an assert to fail). */ + rc = SQLITE_IOERR_RDLOCK; + pFile->lastErrno = errno; goto end_unlock; } } @@ -23634,42 +26272,34 @@ static int _posixUnlock(sqlite3_file *id, int locktype, int handleNFSUnlock){ lock.l_whence = SEEK_SET; lock.l_start = PENDING_BYTE; lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); - if( fcntl(h, F_SETLK, &lock)!=(-1) ){ - pLock->locktype = SHARED_LOCK; + if( unixFileLock(pFile, &lock)==0 ){ + pInode->eFileLock = SHARED_LOCK; }else{ - tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); - if( IS_LOCK_ERROR(rc) ){ - pFile->lastErrno = tErrno; - } + rc = SQLITE_IOERR_UNLOCK; + pFile->lastErrno = errno; goto end_unlock; } } - if( locktype==NO_LOCK ){ - struct unixOpenCnt *pOpen; - + if( eFileLock==NO_LOCK ){ /* Decrement the shared lock counter. Release the lock using an ** OS call only when all threads in this same process have released ** the lock. */ - pLock->cnt--; - if( pLock->cnt==0 ){ + pInode->nShared--; + if( pInode->nShared==0 ){ lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = lock.l_len = 0L; SimulateIOErrorBenign(1); SimulateIOError( h=(-1) ) SimulateIOErrorBenign(0); - if( fcntl(h, F_SETLK, &lock)!=(-1) ){ - pLock->locktype = NO_LOCK; + if( unixFileLock(pFile, &lock)==0 ){ + pInode->eFileLock = NO_LOCK; }else{ - tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); - if( IS_LOCK_ERROR(rc) ){ - pFile->lastErrno = tErrno; - } - pLock->locktype = NO_LOCK; - pFile->locktype = NO_LOCK; + rc = SQLITE_IOERR_UNLOCK; + pFile->lastErrno = errno; + pInode->eFileLock = NO_LOCK; + pFile->eFileLock = NO_LOCK; } } @@ -23677,36 +26307,32 @@ static int _posixUnlock(sqlite3_file *id, int locktype, int handleNFSUnlock){ ** count reaches zero, close any other file descriptors whose close ** was deferred because of outstanding locks. */ - pOpen = pFile->pOpen; - pOpen->nLock--; - assert( pOpen->nLock>=0 ); - if( pOpen->nLock==0 ){ - int rc2 = closePendingFds(pFile); - if( rc==SQLITE_OK ){ - rc = rc2; - } + pInode->nLock--; + assert( pInode->nLock>=0 ); + if( pInode->nLock==0 ){ + closePendingFds(pFile); } } - + end_unlock: unixLeaveMutex(); - if( rc==SQLITE_OK ) pFile->locktype = locktype; + if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; return rc; } /* -** Lower the locking level on file descriptor pFile to locktype. locktype +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int unixUnlock(sqlite3_file *id, int locktype){ - return _posixUnlock(id, locktype, 0); +static int unixUnlock(sqlite3_file *id, int eFileLock){ + return posixUnlock(id, eFileLock, 0); } /* -** This function performs the parts of the "close file" operation +** This function performs the parts of the "close file" operation ** common to all locking schemes. It closes the directory and file ** handles, if they are valid, and sets all fields of the unixFile ** structure to 0. @@ -23717,37 +26343,23 @@ static int unixUnlock(sqlite3_file *id, int locktype){ */ static int closeUnixFile(sqlite3_file *id){ unixFile *pFile = (unixFile*)id; - if( pFile ){ - if( pFile->dirfd>=0 ){ - int err = close(pFile->dirfd); - if( err ){ - pFile->lastErrno = errno; - return SQLITE_IOERR_DIR_CLOSE; - }else{ - pFile->dirfd=-1; - } - } - if( pFile->h>=0 ){ - int err = close(pFile->h); - if( err ){ - pFile->lastErrno = errno; - return SQLITE_IOERR_CLOSE; - } - } + if( pFile->h>=0 ){ + robust_close(pFile, pFile->h, __LINE__); + pFile->h = -1; + } #if OS_VXWORKS - if( pFile->pId ){ - if( pFile->isDelete ){ - unlink(pFile->pId->zCanonicalName); - } - vxworksReleaseFileId(pFile->pId); - pFile->pId = 0; + if( pFile->pId ){ + if( pFile->isDelete ){ + osUnlink(pFile->pId->zCanonicalName); } -#endif - OSTRACE2("CLOSE %-3d\n", pFile->h); - OpenCounter(-1); - sqlite3_free(pFile->pUnused); - memset(pFile, 0, sizeof(unixFile)); + vxworksReleaseFileId(pFile->pId); + pFile->pId = 0; } +#endif + OSTRACE(("CLOSE %-3d\n", pFile->h)); + OpenCounter(-1); + sqlite3_free(pFile->pUnused); + memset(pFile, 0, sizeof(unixFile)); return SQLITE_OK; } @@ -23756,23 +26368,25 @@ static int closeUnixFile(sqlite3_file *id){ */ static int unixClose(sqlite3_file *id){ int rc = SQLITE_OK; - if( id ){ - unixFile *pFile = (unixFile *)id; - unixUnlock(id, NO_LOCK); - unixEnterMutex(); - if( pFile->pOpen && pFile->pOpen->nLock ){ - /* If there are outstanding locks, do not actually close the file just - ** yet because that would clear those locks. Instead, add the file - ** descriptor to pOpen->pUnused list. It will be automatically closed - ** when the last lock is cleared. - */ - setPendingFd(pFile); - } - releaseLockInfo(pFile->pLock); - releaseOpenCnt(pFile->pOpen); - rc = closeUnixFile(id); - unixLeaveMutex(); + unixFile *pFile = (unixFile *)id; + unixUnlock(id, NO_LOCK); + unixEnterMutex(); + + /* unixFile.pInode is always valid here. Otherwise, a different close + ** routine (e.g. nolockClose()) would be called instead. + */ + assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 ); + if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){ + /* If there are outstanding locks, do not actually close the file just + ** yet because that would clear those locks. Instead, add the file + ** descriptor to pInode->pUnused list. It will be automatically closed + ** when the last lock is cleared. + */ + setPendingFd(pFile); } + releaseInodeInfo(pFile); + rc = closeUnixFile(id); + unixLeaveMutex(); return rc; } @@ -23864,26 +26478,26 @@ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { unixFile *pFile = (unixFile*)id; SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - + assert( pFile ); /* Check if a thread in this process holds such a lock */ - if( pFile->locktype>SHARED_LOCK ){ + if( pFile->eFileLock>SHARED_LOCK ){ /* Either this connection or some other connection in the same process ** holds a lock on the file. No need to check further. */ reserved = 1; }else{ /* The lock is held if and only if the lockfile exists */ const char *zLockFile = (const char*)pFile->lockingContext; - reserved = access(zLockFile, 0)==0; + reserved = osAccess(zLockFile, 0)==0; } - OSTRACE4("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved); + OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); *pResOut = reserved; return rc; } /* -** Lock the file with the lock specified by parameter locktype - one +** Lock the file with the lock specified by parameter eFileLock - one ** of the following: ** ** (1) SHARED_LOCK @@ -23909,7 +26523,7 @@ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { ** With dotfile locking, we really only support state (4): EXCLUSIVE. ** But we track the other locking levels internally. */ -static int dotlockLock(sqlite3_file *id, int locktype) { +static int dotlockLock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; int fd; char *zLockFile = (char *)pFile->lockingContext; @@ -23919,17 +26533,19 @@ static int dotlockLock(sqlite3_file *id, int locktype) { /* If we have any lock, then the lock file already exists. All we have ** to do is adjust our internal record of the lock level. */ - if( pFile->locktype > NO_LOCK ){ - pFile->locktype = locktype; -#if !OS_VXWORKS + if( pFile->eFileLock > NO_LOCK ){ + pFile->eFileLock = eFileLock; /* Always update the timestamp on the old file */ +#ifdef HAVE_UTIME + utime(zLockFile, NULL); +#else utimes(zLockFile, NULL); #endif return SQLITE_OK; } - + /* grab an exclusive lock */ - fd = open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600); + fd = robust_open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600); if( fd<0 ){ /* failed to open/create the file, someone else may have stolen the lock */ int tErrno = errno; @@ -23942,19 +26558,16 @@ static int dotlockLock(sqlite3_file *id, int locktype) { } } return rc; - } - if( close(fd) ){ - pFile->lastErrno = errno; - rc = SQLITE_IOERR_CLOSE; - } - + } + robust_close(pFile, fd, __LINE__); + /* got it, set the type and return ok */ - pFile->locktype = locktype; + pFile->eFileLock = eFileLock; return rc; } /* -** Lower the locking level on file descriptor pFile to locktype. locktype +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below @@ -23962,42 +26575,42 @@ static int dotlockLock(sqlite3_file *id, int locktype) { ** ** When the locking level reaches NO_LOCK, delete the lock file. */ -static int dotlockUnlock(sqlite3_file *id, int locktype) { +static int dotlockUnlock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; char *zLockFile = (char *)pFile->lockingContext; assert( pFile ); - OSTRACE5("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, locktype, - pFile->locktype, getpid()); - assert( locktype<=SHARED_LOCK ); - + OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, + pFile->eFileLock, getpid())); + assert( eFileLock<=SHARED_LOCK ); + /* no-op if possible */ - if( pFile->locktype==locktype ){ + if( pFile->eFileLock==eFileLock ){ return SQLITE_OK; } /* To downgrade to shared, simply update our internal notion of the ** lock state. No need to mess with the file on disk. */ - if( locktype==SHARED_LOCK ){ - pFile->locktype = SHARED_LOCK; + if( eFileLock==SHARED_LOCK ){ + pFile->eFileLock = SHARED_LOCK; return SQLITE_OK; } - + /* To fully unlock the database, delete the lock file */ - assert( locktype==NO_LOCK ); - if( unlink(zLockFile) ){ + assert( eFileLock==NO_LOCK ); + if( osUnlink(zLockFile) ){ int rc = 0; int tErrno = errno; if( ENOENT != tErrno ){ - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); + rc = SQLITE_IOERR_UNLOCK; } if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } - return rc; + return rc; } - pFile->locktype = NO_LOCK; + pFile->eFileLock = NO_LOCK; return SQLITE_OK; } @@ -24035,6 +26648,20 @@ static int dotlockClose(sqlite3_file *id) { #if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS /* +** Retry flock() calls that fail with EINTR +*/ +#ifdef EINTR +static int robust_flock(int fd, int op){ + int rc; + do{ rc = flock(fd,op); }while( rc<0 && errno==EINTR ); + return rc; +} +#else +# define robust_flock(a,b) flock(a,b) +#endif + + +/* ** This routine checks if there is a RESERVED lock held on the specified ** file by this or any other process. If such a lock is held, set *pResOut ** to a non-zero value otherwise *pResOut is set to zero. The return value @@ -24044,27 +26671,27 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ int rc = SQLITE_OK; int reserved = 0; unixFile *pFile = (unixFile*)id; - + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - + assert( pFile ); - + /* Check if a thread in this process holds such a lock */ - if( pFile->locktype>SHARED_LOCK ){ + if( pFile->eFileLock>SHARED_LOCK ){ reserved = 1; } - + /* Otherwise see if some other process holds it. */ if( !reserved ){ /* attempt to get the lock */ - int lrc = flock(pFile->h, LOCK_EX | LOCK_NB); + int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); if( !lrc ){ /* got the lock, unlock it */ - lrc = flock(pFile->h, LOCK_UN); + lrc = robust_flock(pFile->h, LOCK_UN); if ( lrc ) { int tErrno = errno; /* unlock failed with an error */ - lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); + lrc = SQLITE_IOERR_UNLOCK; if( IS_LOCK_ERROR(lrc) ){ pFile->lastErrno = tErrno; rc = lrc; @@ -24074,14 +26701,14 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ int tErrno = errno; reserved = 1; /* someone else might have it reserved */ - lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( IS_LOCK_ERROR(lrc) ){ pFile->lastErrno = tErrno; rc = lrc; } } } - OSTRACE4("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved); + OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ @@ -24094,7 +26721,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ } /* -** Lock the file with the lock specified by parameter locktype - one +** Lock the file with the lock specified by parameter eFileLock - one ** of the following: ** ** (1) SHARED_LOCK @@ -24122,22 +26749,22 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ ** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. */ -static int flockLock(sqlite3_file *id, int locktype) { +static int flockLock(sqlite3_file *id, int eFileLock) { int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; assert( pFile ); - /* if we already have a lock, it is exclusive. + /* if we already have a lock, it is exclusive. ** Just adjust level and punt on outta here. */ - if (pFile->locktype > NO_LOCK) { - pFile->locktype = locktype; + if (pFile->eFileLock > NO_LOCK) { + pFile->eFileLock = eFileLock; return SQLITE_OK; } - + /* grab an exclusive lock */ - - if (flock(pFile->h, LOCK_EX | LOCK_NB)) { + + if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) { int tErrno = errno; /* didn't get, must be busy */ rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); @@ -24146,10 +26773,10 @@ static int flockLock(sqlite3_file *id, int locktype) { } } else { /* got it, set the type and return ok */ - pFile->locktype = locktype; + pFile->eFileLock = eFileLock; } - OSTRACE4("LOCK %d %s %s (flock)\n", pFile->h, locktypeName(locktype), - rc==SQLITE_OK ? "ok" : "failed"); + OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ rc = SQLITE_BUSY; @@ -24160,48 +26787,39 @@ static int flockLock(sqlite3_file *id, int locktype) { /* -** Lower the locking level on file descriptor pFile to locktype. locktype +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int flockUnlock(sqlite3_file *id, int locktype) { +static int flockUnlock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; - + assert( pFile ); - OSTRACE5("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, locktype, - pFile->locktype, getpid()); - assert( locktype<=SHARED_LOCK ); - + OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock, + pFile->eFileLock, getpid())); + assert( eFileLock<=SHARED_LOCK ); + /* no-op if possible */ - if( pFile->locktype==locktype ){ + if( pFile->eFileLock==eFileLock ){ return SQLITE_OK; } - + /* shared can just be set because we always have an exclusive */ - if (locktype==SHARED_LOCK) { - pFile->locktype = locktype; + if (eFileLock==SHARED_LOCK) { + pFile->eFileLock = eFileLock; return SQLITE_OK; } - + /* no, really, unlock. */ - int rc = flock(pFile->h, LOCK_UN); - if (rc) { - int r, tErrno = errno; - r = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); - if( IS_LOCK_ERROR(r) ){ - pFile->lastErrno = tErrno; - } + if( robust_flock(pFile->h, LOCK_UN) ){ #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS - if( (r & SQLITE_IOERR) == SQLITE_IOERR ){ - r = SQLITE_BUSY; - } + return SQLITE_OK; #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ - - return r; - } else { - pFile->locktype = NO_LOCK; + return SQLITE_IOERR_UNLOCK; + }else{ + pFile->eFileLock = NO_LOCK; return SQLITE_OK; } } @@ -24245,17 +26863,17 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) { unixFile *pFile = (unixFile*)id; SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - + assert( pFile ); /* Check if a thread in this process holds such a lock */ - if( pFile->locktype>SHARED_LOCK ){ + if( pFile->eFileLock>SHARED_LOCK ){ reserved = 1; } - + /* Otherwise see if some other process holds it. */ if( !reserved ){ - sem_t *pSem = pFile->pOpen->pSem; + sem_t *pSem = pFile->pInode->pSem; struct stat statBuf; if( sem_trywait(pSem)==-1 ){ @@ -24265,21 +26883,21 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) { pFile->lastErrno = tErrno; } else { /* someone else has the lock when we are in NO_LOCK */ - reserved = (pFile->locktype < SHARED_LOCK); + reserved = (pFile->eFileLock < SHARED_LOCK); } }else{ /* we could have it if we want it */ sem_post(pSem); } } - OSTRACE4("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved); + OSTRACE(("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved)); *pResOut = reserved; return rc; } /* -** Lock the file with the lock specified by parameter locktype - one +** Lock the file with the lock specified by parameter eFileLock - one ** of the following: ** ** (1) SHARED_LOCK @@ -24307,20 +26925,20 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) { ** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. */ -static int semLock(sqlite3_file *id, int locktype) { +static int semLock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; int fd; - sem_t *pSem = pFile->pOpen->pSem; + sem_t *pSem = pFile->pInode->pSem; int rc = SQLITE_OK; - /* if we already have a lock, it is exclusive. + /* if we already have a lock, it is exclusive. ** Just adjust level and punt on outta here. */ - if (pFile->locktype > NO_LOCK) { - pFile->locktype = locktype; + if (pFile->eFileLock > NO_LOCK) { + pFile->eFileLock = eFileLock; rc = SQLITE_OK; goto sem_end_lock; } - + /* lock semaphore now but bail out when already locked. */ if( sem_trywait(pSem)==-1 ){ rc = SQLITE_BUSY; @@ -24328,40 +26946,40 @@ static int semLock(sqlite3_file *id, int locktype) { } /* got it, set the type and return ok */ - pFile->locktype = locktype; + pFile->eFileLock = eFileLock; sem_end_lock: return rc; } /* -** Lower the locking level on file descriptor pFile to locktype. locktype +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int semUnlock(sqlite3_file *id, int locktype) { +static int semUnlock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; - sem_t *pSem = pFile->pOpen->pSem; + sem_t *pSem = pFile->pInode->pSem; assert( pFile ); assert( pSem ); - OSTRACE5("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, locktype, - pFile->locktype, getpid()); - assert( locktype<=SHARED_LOCK ); - + OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock, + pFile->eFileLock, getpid())); + assert( eFileLock<=SHARED_LOCK ); + /* no-op if possible */ - if( pFile->locktype==locktype ){ + if( pFile->eFileLock==eFileLock ){ return SQLITE_OK; } - + /* shared can just be set because we always have an exclusive */ - if (locktype==SHARED_LOCK) { - pFile->locktype = locktype; + if (eFileLock==SHARED_LOCK) { + pFile->eFileLock = eFileLock; return SQLITE_OK; } - + /* no, really unlock. */ if ( sem_post(pSem)==-1 ) { int rc, tErrno = errno; @@ -24369,9 +26987,9 @@ static int semUnlock(sqlite3_file *id, int locktype) { if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } - return rc; + return rc; } - pFile->locktype = NO_LOCK; + pFile->eFileLock = NO_LOCK; return SQLITE_OK; } @@ -24384,8 +27002,7 @@ static int semClose(sqlite3_file *id) { semUnlock(id, NO_LOCK); assert( pFile ); unixEnterMutex(); - releaseLockInfo(pFile->pLock); - releaseOpenCnt(pFile->pOpen); + releaseInodeInfo(pFile); unixLeaveMutex(); closeUnixFile(id); } @@ -24435,7 +27052,7 @@ struct ByteRangeLockPB2 /* ** This is a utility for setting or clearing a bit-range lock on an ** AFP filesystem. -** +** ** Return SQLITE_OK on success, SQLITE_BUSY on failure. */ static int afpSetLock( @@ -24447,22 +27064,22 @@ static int afpSetLock( ){ struct ByteRangeLockPB2 pb; int err; - + pb.unLockFlag = setLockFlag ? 0 : 1; pb.startEndFlag = 0; pb.offset = offset; - pb.length = length; + pb.length = length; pb.fd = pFile->h; - - OSTRACE6("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n", + + OSTRACE(("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n", (setLockFlag?"ON":"OFF"), pFile->h, (pb.fd==-1?"[testval-1]":""), - offset, length); + offset, length)); err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0); if ( err==-1 ) { int rc; int tErrno = errno; - OSTRACE4("AFPSETLOCK failed to fsctl() '%s' %d %s\n", - path, tErrno, strerror(tErrno)); + OSTRACE(("AFPSETLOCK failed to fsctl() '%s' %d %s\n", + path, tErrno, strerror(tErrno))); #ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS rc = SQLITE_BUSY; #else @@ -24488,27 +27105,28 @@ static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ int rc = SQLITE_OK; int reserved = 0; unixFile *pFile = (unixFile*)id; - + afpLockingContext *context; + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - + assert( pFile ); - afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; + context = (afpLockingContext *) pFile->lockingContext; if( context->reserved ){ *pResOut = 1; return SQLITE_OK; } - unixEnterMutex(); /* Because pFile->pLock is shared across threads */ - + unixEnterMutex(); /* Because pFile->pInode is shared across threads */ + /* Check if a thread in this process holds such a lock */ - if( pFile->pLock->locktype>SHARED_LOCK ){ + if( pFile->pInode->eFileLock>SHARED_LOCK ){ reserved = 1; } - + /* Otherwise see if some other process holds it. */ if( !reserved ){ /* lock the RESERVED byte */ - int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); + int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); if( SQLITE_OK==lrc ){ /* if we succeeded in taking the reserved lock, unlock it to restore ** the original state */ @@ -24521,16 +27139,16 @@ static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ rc=lrc; } } - + unixLeaveMutex(); - OSTRACE4("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved); - + OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved)); + *pResOut = reserved; return rc; } /* -** Lock the file with the lock specified by parameter locktype - one +** Lock the file with the lock specified by parameter eFileLock - one ** of the following: ** ** (1) SHARED_LOCK @@ -24553,24 +27171,24 @@ static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ ** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. */ -static int afpLock(sqlite3_file *id, int locktype){ +static int afpLock(sqlite3_file *id, int eFileLock){ int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; - struct unixLockInfo *pLock = pFile->pLock; + unixInodeInfo *pInode = pFile->pInode; afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; - + assert( pFile ); - OSTRACE7("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h, - locktypeName(locktype), locktypeName(pFile->locktype), - locktypeName(pLock->locktype), pLock->cnt , getpid()); + OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h, + azFileLock(eFileLock), azFileLock(pFile->eFileLock), + azFileLock(pInode->eFileLock), pInode->nShared , getpid())); /* If there is already a lock of this type or more restrictive on the ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as ** unixEnterMutex() hasn't been called yet. */ - if( pFile->locktype>=locktype ){ - OSTRACE3("LOCK %d %s ok (already held) (afp)\n", pFile->h, - locktypeName(locktype)); + if( pFile->eFileLock>=eFileLock ){ + OSTRACE(("LOCK %d %s ok (already held) (afp)\n", pFile->h, + azFileLock(eFileLock))); return SQLITE_OK; } @@ -24579,54 +27197,46 @@ static int afpLock(sqlite3_file *id, int locktype){ ** (2) SQLite never explicitly requests a pendig lock. ** (3) A shared lock is always held when a reserve lock is requested. */ - assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); - assert( locktype!=PENDING_LOCK ); - assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); - - /* This mutex is needed because pFile->pLock is shared across threads + assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); + assert( eFileLock!=PENDING_LOCK ); + assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); + + /* This mutex is needed because pFile->pInode is shared across threads */ unixEnterMutex(); - - /* Make sure the current thread owns the pFile. - */ - rc = transferOwnership(pFile); - if( rc!=SQLITE_OK ){ - unixLeaveMutex(); - return rc; - } - pLock = pFile->pLock; + pInode = pFile->pInode; /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. */ - if( (pFile->locktype!=pLock->locktype && - (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK)) + if( (pFile->eFileLock!=pInode->eFileLock && + (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK)) ){ rc = SQLITE_BUSY; goto afp_end_lock; } - + /* If a SHARED lock is requested, and some thread using this PID already ** has a SHARED or RESERVED lock, then increment reference counts and ** return SQLITE_OK. */ - if( locktype==SHARED_LOCK && - (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){ - assert( locktype==SHARED_LOCK ); - assert( pFile->locktype==0 ); - assert( pLock->cnt>0 ); - pFile->locktype = SHARED_LOCK; - pLock->cnt++; - pFile->pOpen->nLock++; + if( eFileLock==SHARED_LOCK && + (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ + assert( eFileLock==SHARED_LOCK ); + assert( pFile->eFileLock==0 ); + assert( pInode->nShared>0 ); + pFile->eFileLock = SHARED_LOCK; + pInode->nShared++; + pInode->nLock++; goto afp_end_lock; } - + /* A PENDING lock is needed before acquiring a SHARED lock and before ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will ** be released. */ - if( locktype==SHARED_LOCK - || (locktype==EXCLUSIVE_LOCK && pFile->locktype<PENDING_LOCK) + if( eFileLock==SHARED_LOCK + || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK) ){ int failed; failed = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 1); @@ -24635,30 +27245,30 @@ static int afpLock(sqlite3_file *id, int locktype){ goto afp_end_lock; } } - + /* If control gets to this point, then actually go ahead and make ** operating system calls for the specified lock. */ - if( locktype==SHARED_LOCK ){ - int lrc1, lrc2, lrc1Errno; + if( eFileLock==SHARED_LOCK ){ + int lrc1, lrc2, lrc1Errno = 0; long lk, mask; - - assert( pLock->cnt==0 ); - assert( pLock->locktype==0 ); - + + assert( pInode->nShared==0 ); + assert( pInode->eFileLock==0 ); + mask = (sizeof(long)==8) ? LARGEST_INT64 : 0x7fffffff; /* Now get the read-lock SHARED_LOCK */ /* note that the quality of the randomness doesn't matter that much */ - lk = random(); - pLock->sharedByte = (lk & mask)%(SHARED_SIZE - 1); - lrc1 = afpSetLock(context->dbPath, pFile, - SHARED_FIRST+pLock->sharedByte, 1, 1); + lk = random(); + pInode->sharedByte = (lk & mask)%(SHARED_SIZE - 1); + lrc1 = afpSetLock(context->dbPath, pFile, + SHARED_FIRST+pInode->sharedByte, 1, 1); if( IS_LOCK_ERROR(lrc1) ){ lrc1Errno = pFile->lastErrno; } /* Drop the temporary PENDING lock */ lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); - + if( IS_LOCK_ERROR(lrc1) ) { pFile->lastErrno = lrc1Errno; rc = lrc1; @@ -24669,11 +27279,11 @@ static int afpLock(sqlite3_file *id, int locktype){ } else if( lrc1 != SQLITE_OK ) { rc = lrc1; } else { - pFile->locktype = SHARED_LOCK; - pFile->pOpen->nLock++; - pLock->cnt = 1; + pFile->eFileLock = SHARED_LOCK; + pInode->nLock++; + pInode->nShared = 1; } - }else if( locktype==EXCLUSIVE_LOCK && pLock->cnt>1 ){ + }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){ /* We are trying for an exclusive lock but another thread in this ** same process is still holding a shared lock. */ rc = SQLITE_BUSY; @@ -24683,70 +27293,70 @@ static int afpLock(sqlite3_file *id, int locktype){ ** already. */ int failed = 0; - assert( 0!=pFile->locktype ); - if (locktype >= RESERVED_LOCK && pFile->locktype < RESERVED_LOCK) { + assert( 0!=pFile->eFileLock ); + if (eFileLock >= RESERVED_LOCK && pFile->eFileLock < RESERVED_LOCK) { /* Acquire a RESERVED lock */ failed = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); if( !failed ){ context->reserved = 1; } } - if (!failed && locktype == EXCLUSIVE_LOCK) { + if (!failed && eFileLock == EXCLUSIVE_LOCK) { /* Acquire an EXCLUSIVE lock */ - - /* Remove the shared lock before trying the range. we'll need to + + /* Remove the shared lock before trying the range. we'll need to ** reestablish the shared lock if we can't get the afpUnlock */ if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST + - pLock->sharedByte, 1, 0)) ){ + pInode->sharedByte, 1, 0)) ){ int failed2 = SQLITE_OK; /* now attemmpt to get the exclusive lock range */ - failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, + failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 1); - if( failed && (failed2 = afpSetLock(context->dbPath, pFile, - SHARED_FIRST + pLock->sharedByte, 1, 1)) ){ + if( failed && (failed2 = afpSetLock(context->dbPath, pFile, + SHARED_FIRST + pInode->sharedByte, 1, 1)) ){ /* Can't reestablish the shared lock. Sqlite can't deal, this is ** a critical I/O error */ - rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 : + rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 : SQLITE_IOERR_LOCK; goto afp_end_lock; - } + } }else{ - rc = failed; + rc = failed; } } if( failed ){ rc = failed; } } - + if( rc==SQLITE_OK ){ - pFile->locktype = locktype; - pLock->locktype = locktype; - }else if( locktype==EXCLUSIVE_LOCK ){ - pFile->locktype = PENDING_LOCK; - pLock->locktype = PENDING_LOCK; + pFile->eFileLock = eFileLock; + pInode->eFileLock = eFileLock; + }else if( eFileLock==EXCLUSIVE_LOCK ){ + pFile->eFileLock = PENDING_LOCK; + pInode->eFileLock = PENDING_LOCK; } - + afp_end_lock: unixLeaveMutex(); - OSTRACE4("LOCK %d %s %s (afp)\n", pFile->h, locktypeName(locktype), - rc==SQLITE_OK ? "ok" : "failed"); + OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); return rc; } /* -** Lower the locking level on file descriptor pFile to locktype. locktype +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int afpUnlock(sqlite3_file *id, int locktype) { +static int afpUnlock(sqlite3_file *id, int eFileLock) { int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; - struct unixLockInfo *pLock; + unixInodeInfo *pInode; afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; int skipShared = 0; #ifdef SQLITE_TEST @@ -24754,25 +27364,23 @@ static int afpUnlock(sqlite3_file *id, int locktype) { #endif assert( pFile ); - OSTRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, locktype, - pFile->locktype, pFile->pLock->locktype, pFile->pLock->cnt, getpid()); + OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock, + pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, + getpid())); - assert( locktype<=SHARED_LOCK ); - if( pFile->locktype<=locktype ){ + assert( eFileLock<=SHARED_LOCK ); + if( pFile->eFileLock<=eFileLock ){ return SQLITE_OK; } - if( CHECK_THREADID(pFile) ){ - return SQLITE_MISUSE_BKPT; - } unixEnterMutex(); - pLock = pFile->pLock; - assert( pLock->cnt!=0 ); - if( pFile->locktype>SHARED_LOCK ){ - assert( pLock->locktype==pFile->locktype ); + pInode = pFile->pInode; + assert( pInode->nShared!=0 ); + if( pFile->eFileLock>SHARED_LOCK ){ + assert( pInode->eFileLock==pFile->eFileLock ); SimulateIOErrorBenign(1); SimulateIOError( h=(-1) ) SimulateIOErrorBenign(0); - + #ifndef NDEBUG /* When reducing a lock such that other processes can start ** reading the database file again, make sure that the @@ -24787,39 +27395,39 @@ static int afpUnlock(sqlite3_file *id, int locktype) { || pFile->transCntrChng==1 ); pFile->inNormalWrite = 0; #endif - - if( pFile->locktype==EXCLUSIVE_LOCK ){ + + if( pFile->eFileLock==EXCLUSIVE_LOCK ){ rc = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0); - if( rc==SQLITE_OK && (locktype==SHARED_LOCK || pLock->cnt>1) ){ + if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1) ){ /* only re-establish the shared lock if necessary */ - int sharedLockByte = SHARED_FIRST+pLock->sharedByte; + int sharedLockByte = SHARED_FIRST+pInode->sharedByte; rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 1); } else { skipShared = 1; } } - if( rc==SQLITE_OK && pFile->locktype>=PENDING_LOCK ){ + if( rc==SQLITE_OK && pFile->eFileLock>=PENDING_LOCK ){ rc = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); - } - if( rc==SQLITE_OK && pFile->locktype>=RESERVED_LOCK && context->reserved ){ + } + if( rc==SQLITE_OK && pFile->eFileLock>=RESERVED_LOCK && context->reserved ){ rc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0); - if( !rc ){ - context->reserved = 0; + if( !rc ){ + context->reserved = 0; } } - if( rc==SQLITE_OK && (locktype==SHARED_LOCK || pLock->cnt>1)){ - pLock->locktype = SHARED_LOCK; + if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1)){ + pInode->eFileLock = SHARED_LOCK; } } - if( rc==SQLITE_OK && locktype==NO_LOCK ){ + if( rc==SQLITE_OK && eFileLock==NO_LOCK ){ /* Decrement the shared lock counter. Release the lock using an ** OS call only when all threads in this same process have released ** the lock. */ - unsigned long long sharedLockByte = SHARED_FIRST+pLock->sharedByte; - pLock->cnt--; - if( pLock->cnt==0 ){ + unsigned long long sharedLockByte = SHARED_FIRST+pInode->sharedByte; + pInode->nShared--; + if( pInode->nShared==0 ){ SimulateIOErrorBenign(1); SimulateIOError( h=(-1) ) SimulateIOErrorBenign(0); @@ -24827,28 +27435,26 @@ static int afpUnlock(sqlite3_file *id, int locktype) { rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0); } if( !rc ){ - pLock->locktype = NO_LOCK; - pFile->locktype = NO_LOCK; + pInode->eFileLock = NO_LOCK; + pFile->eFileLock = NO_LOCK; } } if( rc==SQLITE_OK ){ - struct unixOpenCnt *pOpen = pFile->pOpen; - - pOpen->nLock--; - assert( pOpen->nLock>=0 ); - if( pOpen->nLock==0 ){ - rc = closePendingFds(pFile); + pInode->nLock--; + assert( pInode->nLock>=0 ); + if( pInode->nLock==0 ){ + closePendingFds(pFile); } } } - + unixLeaveMutex(); - if( rc==SQLITE_OK ) pFile->locktype = locktype; + if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; return rc; } /* -** Close a file & cleanup AFP specific locking context +** Close a file & cleanup AFP specific locking context */ static int afpClose(sqlite3_file *id) { int rc = SQLITE_OK; @@ -24856,16 +27462,15 @@ static int afpClose(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; afpUnlock(id, NO_LOCK); unixEnterMutex(); - if( pFile->pOpen && pFile->pOpen->nLock ){ + if( pFile->pInode && pFile->pInode->nLock ){ /* If there are outstanding locks, do not actually close the file just ** yet because that would clear those locks. Instead, add the file - ** descriptor to pOpen->aPending. It will be automatically closed when + ** descriptor to pInode->aPending. It will be automatically closed when ** the last lock is cleared. */ setPendingFd(pFile); } - releaseLockInfo(pFile->pLock); - releaseOpenCnt(pFile->pOpen); + releaseInodeInfo(pFile); sqlite3_free(pFile->lockingContext); rc = closeUnixFile(id); unixLeaveMutex(); @@ -24888,21 +27493,21 @@ static int afpClose(sqlite3_file *id) { #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE /* - ** Lower the locking level on file descriptor pFile to locktype. locktype + ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int nfsUnlock(sqlite3_file *id, int locktype){ - return _posixUnlock(id, locktype, 1); +static int nfsUnlock(sqlite3_file *id, int eFileLock){ + return posixUnlock(id, eFileLock, 1); } #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ /* ** The code above is the NFS lock implementation. The code is specific ** to MacOSX and does not work on other unix platforms. No alternative -** is available. +** is available. ** ********************* End of the NFS lock implementation ********************** ******************************************************************************/ @@ -24910,7 +27515,7 @@ static int nfsUnlock(sqlite3_file *id, int locktype){ /****************************************************************************** **************** Non-locking sqlite3_file methods ***************************** ** -** The next division contains implementations for all methods of the +** The next division contains implementations for all methods of the ** sqlite3_file object other than the locking methods. The locking ** methods were defined in divisions above (one locking method per ** division). Those methods that are common to all locking modes @@ -24918,7 +27523,7 @@ static int nfsUnlock(sqlite3_file *id, int locktype){ */ /* -** Seek to the offset passed as the second argument, then read cnt +** Seek to the offset passed as the second argument, then read cnt ** bytes into pBuf. Return the number of bytes actually read. ** ** NB: If you define USE_PREAD or USE_PREAD64, then it might also @@ -24937,10 +27542,10 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ #endif TIMER_START; #if defined(USE_PREAD) - got = pread(id->h, pBuf, cnt, offset); + do{ got = osPread(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); SimulateIOError( got = -1 ); #elif defined(USE_PREAD64) - got = pread64(id->h, pBuf, cnt, offset); + do{ got = osPread64(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR); SimulateIOError( got = -1 ); #else newOffset = lseek(id->h, offset, SEEK_SET); @@ -24949,17 +27554,17 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ if( newOffset == -1 ){ ((unixFile*)id)->lastErrno = errno; }else{ - ((unixFile*)id)->lastErrno = 0; + ((unixFile*)id)->lastErrno = 0; } return -1; } - got = read(id->h, pBuf, cnt); + do{ got = osRead(id->h, pBuf, cnt); }while( got<0 && errno==EINTR ); #endif TIMER_END; if( got<0 ){ ((unixFile*)id)->lastErrno = errno; } - OSTRACE5("READ %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED); + OSTRACE(("READ %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED)); return got; } @@ -24969,8 +27574,8 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ ** wrong. */ static int unixRead( - sqlite3_file *id, - void *pBuf, + sqlite3_file *id, + void *pBuf, int amt, sqlite3_int64 offset ){ @@ -24980,10 +27585,12 @@ static int unixRead( /* If this is a database file (not a journal, master-journal or temp ** file), the bytes in the locking range should never be read or written. */ +#if 0 assert( pFile->pUnused==0 || offset>=PENDING_BYTE+512 - || offset+amt<=PENDING_BYTE + || offset+amt<=PENDING_BYTE ); +#endif got = seekAndRead(pFile, offset, pBuf, amt); if( got==amt ){ @@ -25013,27 +27620,30 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ #endif TIMER_START; #if defined(USE_PREAD) - got = pwrite(id->h, pBuf, cnt, offset); + do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); #elif defined(USE_PREAD64) - got = pwrite64(id->h, pBuf, cnt, offset); + do{ got = osPwrite64(id->h, pBuf, cnt, offset);}while( got<0 && errno==EINTR); #else - newOffset = lseek(id->h, offset, SEEK_SET); - if( newOffset!=offset ){ - if( newOffset == -1 ){ - ((unixFile*)id)->lastErrno = errno; - }else{ - ((unixFile*)id)->lastErrno = 0; + do{ + newOffset = lseek(id->h, offset, SEEK_SET); + SimulateIOError( newOffset-- ); + if( newOffset!=offset ){ + if( newOffset == -1 ){ + ((unixFile*)id)->lastErrno = errno; + }else{ + ((unixFile*)id)->lastErrno = 0; + } + return -1; } - return -1; - } - got = write(id->h, pBuf, cnt); + got = osWrite(id->h, pBuf, cnt); + }while( got<0 && errno==EINTR ); #endif TIMER_END; if( got<0 ){ ((unixFile*)id)->lastErrno = errno; } - OSTRACE5("WRITE %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED); + OSTRACE(("WRITE %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED)); return got; } @@ -25043,10 +27653,10 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ ** or some other error code on failure. */ static int unixWrite( - sqlite3_file *id, - const void *pBuf, + sqlite3_file *id, + const void *pBuf, int amt, - sqlite3_int64 offset + sqlite3_int64 offset ){ unixFile *pFile = (unixFile*)id; int wrote = 0; @@ -25055,10 +27665,12 @@ static int unixWrite( /* If this is a database file (not a journal, master-journal or temp ** file), the bytes in the locking range should never be read or written. */ +#if 0 assert( pFile->pUnused==0 || offset>=PENDING_BYTE+512 - || offset+amt<=PENDING_BYTE + || offset+amt<=PENDING_BYTE ); +#endif #ifndef NDEBUG /* If we are doing a normal write to a database file (as opposed to @@ -25089,8 +27701,9 @@ static int unixWrite( } SimulateIOError(( wrote=(-1), amt=1 )); SimulateDiskfullError(( wrote=0, amt=1 )); + if( amt>0 ){ - if( wrote<0 ){ + if( wrote<0 && pFile->lastErrno!=ENOSPC ){ /* lastErrno set by seekAndWrite */ return SQLITE_IOERR_WRITE; }else{ @@ -25098,6 +27711,7 @@ static int unixWrite( return SQLITE_FULL; } } + return SQLITE_OK; } @@ -25112,11 +27726,11 @@ SQLITE_API int sqlite3_fullsync_count = 0; /* ** We do not trust systems to provide a working fdatasync(). Some do. -** Others do no. To be safe, we will stick with the (slower) fsync(). -** If you know that your system does support fdatasync() correctly, +** Others do no. To be safe, we will stick with the (slightly slower) +** fsync(). If you know that your system does support fdatasync() correctly, ** then simply compile with -Dfdatasync=fdatasync */ -#if !defined(fdatasync) && !defined(__linux__) +#if !defined(fdatasync) # define fdatasync fsync #endif @@ -25145,8 +27759,8 @@ SQLITE_API int sqlite3_fullsync_count = 0; ** ** SQLite sets the dataOnly flag if the size of the file is unchanged. ** The idea behind dataOnly is that it should only write the file content -** to disk, not the inode. We only set dataOnly if the file size is -** unchanged since the file size is part of the inode. However, +** to disk, not the inode. We only set dataOnly if the file size is +** unchanged since the file size is part of the inode. However, ** Ted Ts'o tells us that fdatasync() will also write the inode if the ** file size has changed. The only real difference between fdatasync() ** and fsync(), Ted tells us, is that fdatasync() will not flush the @@ -25160,7 +27774,7 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ int rc; /* The following "ifdef/elif/else/" block has the same structure as - ** the one below. It is replicated here solely to avoid cluttering + ** the one below. It is replicated here solely to avoid cluttering ** up the real code with the UNUSED_PARAMETER() macros. */ #ifdef SQLITE_NO_SYNC @@ -25174,7 +27788,7 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ UNUSED_PARAMETER(dataOnly); #endif - /* Record the number of times that we do a normal fsync() and + /* Record the number of times that we do a normal fsync() and ** FULLSYNC. This is used during testing to verify that this procedure ** gets called with the correct arguments. */ @@ -25190,16 +27804,16 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ rc = SQLITE_OK; #elif HAVE_FULLFSYNC if( fullSync ){ - rc = fcntl(fd, F_FULLFSYNC, 0); + rc = osFcntl(fd, F_FULLFSYNC, 0); }else{ rc = 1; } /* If the FULLFSYNC failed, fall back to attempting an fsync(). - ** It shouldn't be possible for fullfsync to fail on the local + ** It shouldn't be possible for fullfsync to fail on the local ** file system (on OSX), so failure indicates that FULLFSYNC - ** isn't supported for this file system. So, attempt an fsync - ** and (for now) ignore the overhead of a superfluous fcntl call. - ** It'd be better to detect fullfsync support once and avoid + ** isn't supported for this file system. So, attempt an fsync + ** and (for now) ignore the overhead of a superfluous fcntl call. + ** It'd be better to detect fullfsync support once and avoid ** the fcntl call every time sync is called. */ if( rc ) rc = fsync(fd); @@ -25209,7 +27823,7 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ ** so currently we default to the macro that redefines fdatasync to fsync */ rc = fsync(fd); -#else +#else rc = fdatasync(fd); #if OS_VXWORKS if( rc==-1 && errno==ENOTSUP ){ @@ -25225,6 +27839,50 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ } /* +** Open a file descriptor to the directory containing file zFilename. +** If successful, *pFd is set to the opened file descriptor and +** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM +** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined +** value. +** +** The directory file descriptor is used for only one thing - to +** fsync() a directory to make sure file creation and deletion events +** are flushed to disk. Such fsyncs are not needed on newer +** journaling filesystems, but are required on older filesystems. +** +** This routine can be overridden using the xSetSysCall interface. +** The ability to override this routine was added in support of the +** chromium sandbox. Opening a directory is a security risk (we are +** told) so making it overrideable allows the chromium sandbox to +** replace this routine with a harmless no-op. To make this routine +** a no-op, replace it with a stub that returns SQLITE_OK but leaves +** *pFd set to a negative number. +** +** If SQLITE_OK is returned, the caller is responsible for closing +** the file descriptor *pFd using close(). +*/ +static int openDirectory(const char *zFilename, int *pFd){ + int ii; + int fd = -1; + char zDirname[MAX_PATHNAME+1]; + + sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); + for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); + if( ii>0 ){ + zDirname[ii] = '\0'; + fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); + if( fd>=0 ){ +#ifdef FD_CLOEXEC + osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); +#endif + OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); + } + } + *pFd = fd; + return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname)); +} + +/* ** Make sure all writes to a particular file are committed to disk. ** ** If dataOnly==0 then both the file itself and its metadata (file @@ -25257,40 +27915,30 @@ static int unixSync(sqlite3_file *id, int flags){ SimulateDiskfullError( return SQLITE_FULL ); assert( pFile ); - OSTRACE2("SYNC %-3d\n", pFile->h); + OSTRACE(("SYNC %-3d\n", pFile->h)); rc = full_fsync(pFile->h, isFullsync, isDataOnly); SimulateIOError( rc=1 ); if( rc ){ pFile->lastErrno = errno; - return SQLITE_IOERR_FSYNC; - } - if( pFile->dirfd>=0 ){ - int err; - OSTRACE4("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd, - HAVE_FULLFSYNC, isFullsync); -#ifndef SQLITE_DISABLE_DIRSYNC - /* The directory sync is only attempted if full_fsync is - ** turned off or unavailable. If a full_fsync occurred above, - ** then the directory sync is superfluous. - */ - if( (!HAVE_FULLFSYNC || !isFullsync) && full_fsync(pFile->dirfd,0,0) ){ - /* - ** We have received multiple reports of fsync() returning - ** errors when applied to directories on certain file systems. - ** A failed directory sync is not a big deal. So it seems - ** better to ignore the error. Ticket #1657 - */ - /* pFile->lastErrno = errno; */ - /* return SQLITE_IOERR; */ - } -#endif - err = close(pFile->dirfd); /* Only need to sync once, so close the */ - if( err==0 ){ /* directory when we are done */ - pFile->dirfd = -1; - }else{ - pFile->lastErrno = errno; - rc = SQLITE_IOERR_DIR_CLOSE; + return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath); + } + + /* Also fsync the directory containing the file if the DIRSYNC flag + ** is set. This is a one-time occurrance. Many systems (examples: AIX) + ** are unable to fsync a directory, so ignore errors on the fsync. + */ + if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){ + int dirfd; + OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath, + HAVE_FULLFSYNC, isFullsync)); + rc = osOpenDirectory(pFile->zPath, &dirfd); + if( rc==SQLITE_OK && dirfd>=0 ){ + full_fsync(dirfd, 0, 0); + robust_close(pFile, dirfd, __LINE__); + }else if( rc==SQLITE_CANTOPEN ){ + rc = SQLITE_OK; } + pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC; } return rc; } @@ -25299,13 +27947,24 @@ static int unixSync(sqlite3_file *id, int flags){ ** Truncate an open file to a specified size */ static int unixTruncate(sqlite3_file *id, i64 nByte){ + unixFile *pFile = (unixFile *)id; int rc; - assert( id ); + assert( pFile ); SimulateIOError( return SQLITE_IOERR_TRUNCATE ); - rc = ftruncate(((unixFile*)id)->h, (off_t)nByte); + + /* If the user has configured a chunk-size for this file, truncate the + ** file so that it consists of an integer number of chunks (i.e. the + ** actual file size after the operation may be larger than the requested + ** size). + */ + if( pFile->szChunk ){ + nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; + } + + rc = robust_ftruncate(pFile->h, (off_t)nByte); if( rc ){ - ((unixFile*)id)->lastErrno = errno; - return SQLITE_IOERR_TRUNCATE; + pFile->lastErrno = errno; + return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); }else{ #ifndef NDEBUG /* If we are doing a normal write to a database file (as opposed to @@ -25315,8 +27974,8 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){ ** when restoring a database using the backup API from a zero-length ** source. */ - if( ((unixFile*)id)->inNormalWrite && nByte==0 ){ - ((unixFile*)id)->transCntrChng = 1; + if( pFile->inNormalWrite && nByte==0 ){ + pFile->transCntrChng = 1; } #endif @@ -25331,7 +27990,7 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){ int rc; struct stat buf; assert( id ); - rc = fstat(((unixFile*)id)->h, &buf); + rc = osFstat(((unixFile*)id)->h, &buf); SimulateIOError( rc=1 ); if( rc!=0 ){ ((unixFile*)id)->lastErrno = errno; @@ -25339,7 +27998,7 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){ } *pSize = buf.st_size; - /* When opening a zero-size database, the findLockInfo() procedure + /* When opening a zero-size database, the findInodeInfo() procedure ** writes a single byte into that file in order to work around a bug ** in the OS-X msdos filesystem. In order to avoid problems with upper ** layers, we need to report this file size as zero even though it is @@ -25359,18 +28018,92 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){ static int proxyFileControl(sqlite3_file*,int,void*); #endif +/* +** This function is called to handle the SQLITE_FCNTL_SIZE_HINT +** file-control operation. Enlarge the database to nBytes in size +** (rounded up to the next chunk-size). If the database is already +** nBytes or larger, this routine is a no-op. +*/ +static int fcntlSizeHint(unixFile *pFile, i64 nByte){ + if( pFile->szChunk>0 ){ + i64 nSize; /* Required file size */ + struct stat buf; /* Used to hold return values of fstat() */ + + if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT; + + nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk; + if( nSize>(i64)buf.st_size ){ + +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE + /* The code below is handling the return value of osFallocate() + ** correctly. posix_fallocate() is defined to "returns zero on success, + ** or an error number on failure". See the manpage for details. */ + int err; + do{ + err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size); + }while( err==EINTR ); + if( err ) return SQLITE_IOERR_WRITE; +#else + /* If the OS does not have posix_fallocate(), fake it. First use + ** ftruncate() to set the file size, then write a single byte to + ** the last byte in each block within the extended region. This + ** is the same technique used by glibc to implement posix_fallocate() + ** on systems that do not have a real fallocate() system call. + */ + int nBlk = buf.st_blksize; /* File-system block size */ + i64 iWrite; /* Next offset to write to */ + + if( robust_ftruncate(pFile->h, nSize) ){ + pFile->lastErrno = errno; + return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); + } + iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1; + while( iWrite<nSize ){ + int nWrite = seekAndWrite(pFile, iWrite, "", 1); + if( nWrite!=1 ) return SQLITE_IOERR_WRITE; + iWrite += nBlk; + } +#endif + } + } + + return SQLITE_OK; +} /* ** Information and control of an open file handle. */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ + unixFile *pFile = (unixFile*)id; switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { - *(int*)pArg = ((unixFile*)id)->locktype; + *(int*)pArg = pFile->eFileLock; return SQLITE_OK; } case SQLITE_LAST_ERRNO: { - *(int*)pArg = ((unixFile*)id)->lastErrno; + *(int*)pArg = pFile->lastErrno; + return SQLITE_OK; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + pFile->szChunk = *(int *)pArg; + return SQLITE_OK; + } + case SQLITE_FCNTL_SIZE_HINT: { + int rc; + SimulateIOErrorBenign(1); + rc = fcntlSizeHint(pFile, *(i64 *)pArg); + SimulateIOErrorBenign(0); + return rc; + } + case SQLITE_FCNTL_PERSIST_WAL: { + int bPersist = *(int*)pArg; + if( bPersist<0 ){ + *(int*)pArg = (pFile->ctrlFlags & UNIXFILE_PERSIST_WAL)!=0; + }else if( bPersist==0 ){ + pFile->ctrlFlags &= ~UNIXFILE_PERSIST_WAL; + }else{ + pFile->ctrlFlags |= UNIXFILE_PERSIST_WAL; + } return SQLITE_OK; } #ifndef NDEBUG @@ -25390,8 +28123,11 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ return proxyFileControl(id,op,pArg); } #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ + case SQLITE_FCNTL_SYNC_OMITTED: { + return SQLITE_OK; /* A no-op */ + } } - return SQLITE_ERROR; + return SQLITE_NOTFOUND; } /* @@ -25417,6 +28153,656 @@ static int unixDeviceCharacteristics(sqlite3_file *NotUsed){ return 0; } +#ifndef SQLITE_OMIT_WAL + + +/* +** Object used to represent an shared memory buffer. +** +** When multiple threads all reference the same wal-index, each thread +** has its own unixShm object, but they all point to a single instance +** of this unixShmNode object. In other words, each wal-index is opened +** only once per process. +** +** Each unixShmNode object is connected to a single unixInodeInfo object. +** We could coalesce this object into unixInodeInfo, but that would mean +** every open file that does not use shared memory (in other words, most +** open files) would have to carry around this extra information. So +** the unixInodeInfo object contains a pointer to this unixShmNode object +** and the unixShmNode object is created only when needed. +** +** unixMutexHeld() must be true when creating or destroying +** this object or while reading or writing the following fields: +** +** nRef +** +** The following fields are read-only after the object is created: +** +** fid +** zFilename +** +** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and +** unixMutexHeld() is true when reading or writing any other field +** in this structure. +*/ +struct unixShmNode { + unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ + sqlite3_mutex *mutex; /* Mutex to access this object */ + char *zFilename; /* Name of the mmapped file */ + int h; /* Open file descriptor */ + int szRegion; /* Size of shared-memory regions */ + u16 nRegion; /* Size of array apRegion */ + u8 isReadonly; /* True if read-only */ + char **apRegion; /* Array of mapped shared-memory regions */ + int nRef; /* Number of unixShm objects pointing to this */ + unixShm *pFirst; /* All unixShm objects pointing to this */ +#ifdef SQLITE_DEBUG + u8 exclMask; /* Mask of exclusive locks held */ + u8 sharedMask; /* Mask of shared locks held */ + u8 nextShmId; /* Next available unixShm.id value */ +#endif +}; + +/* +** Structure used internally by this VFS to record the state of an +** open shared memory connection. +** +** The following fields are initialized when this object is created and +** are read-only thereafter: +** +** unixShm.pFile +** unixShm.id +** +** All other fields are read/write. The unixShm.pFile->mutex must be held +** while accessing any read/write fields. +*/ +struct unixShm { + unixShmNode *pShmNode; /* The underlying unixShmNode object */ + unixShm *pNext; /* Next unixShm with the same unixShmNode */ + u8 hasMutex; /* True if holding the unixShmNode mutex */ + u8 id; /* Id of this connection within its unixShmNode */ + u16 sharedMask; /* Mask of shared locks held */ + u16 exclMask; /* Mask of exclusive locks held */ +}; + +/* +** Constants used for locking +*/ +#define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ +#define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ + +/* +** Apply posix advisory locks for all bytes from ofst through ofst+n-1. +** +** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking +** otherwise. +*/ +static int unixShmSystemLock( + unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */ + int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */ + int ofst, /* First byte of the locking range */ + int n /* Number of bytes to lock */ +){ + struct flock f; /* The posix advisory locking structure */ + int rc = SQLITE_OK; /* Result code form fcntl() */ + + /* Access to the unixShmNode object is serialized by the caller */ + assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 ); + + /* Shared locks never span more than one byte */ + assert( n==1 || lockType!=F_RDLCK ); + + /* Locks are within range */ + assert( n>=1 && n<SQLITE_SHM_NLOCK ); + + if( pShmNode->h>=0 ){ + /* Initialize the locking parameters */ + memset(&f, 0, sizeof(f)); + f.l_type = lockType; + f.l_whence = SEEK_SET; + f.l_start = ofst; + f.l_len = n; + + rc = osFcntl(pShmNode->h, F_SETLK, &f); + rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; + } + + /* Update the global lock state and do debug tracing */ +#ifdef SQLITE_DEBUG + { u16 mask; + OSTRACE(("SHM-LOCK ")); + mask = (1<<(ofst+n)) - (1<<ofst); + if( rc==SQLITE_OK ){ + if( lockType==F_UNLCK ){ + OSTRACE(("unlock %d ok", ofst)); + pShmNode->exclMask &= ~mask; + pShmNode->sharedMask &= ~mask; + }else if( lockType==F_RDLCK ){ + OSTRACE(("read-lock %d ok", ofst)); + pShmNode->exclMask &= ~mask; + pShmNode->sharedMask |= mask; + }else{ + assert( lockType==F_WRLCK ); + OSTRACE(("write-lock %d ok", ofst)); + pShmNode->exclMask |= mask; + pShmNode->sharedMask &= ~mask; + } + }else{ + if( lockType==F_UNLCK ){ + OSTRACE(("unlock %d failed", ofst)); + }else if( lockType==F_RDLCK ){ + OSTRACE(("read-lock failed")); + }else{ + assert( lockType==F_WRLCK ); + OSTRACE(("write-lock %d failed", ofst)); + } + } + OSTRACE((" - afterwards %03x,%03x\n", + pShmNode->sharedMask, pShmNode->exclMask)); + } +#endif + + return rc; +} + + +/* +** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0. +** +** This is not a VFS shared-memory method; it is a utility function called +** by VFS shared-memory methods. +*/ +static void unixShmPurge(unixFile *pFd){ + unixShmNode *p = pFd->pInode->pShmNode; + assert( unixMutexHeld() ); + if( p && p->nRef==0 ){ + int i; + assert( p->pInode==pFd->pInode ); + sqlite3_mutex_free(p->mutex); + for(i=0; i<p->nRegion; i++){ + if( p->h>=0 ){ + munmap(p->apRegion[i], p->szRegion); + }else{ + sqlite3_free(p->apRegion[i]); + } + } + sqlite3_free(p->apRegion); + if( p->h>=0 ){ + robust_close(pFd, p->h, __LINE__); + p->h = -1; + } + p->pInode->pShmNode = 0; + sqlite3_free(p); + } +} + +/* +** Open a shared-memory area associated with open database file pDbFd. +** This particular implementation uses mmapped files. +** +** The file used to implement shared-memory is in the same directory +** as the open database file and has the same name as the open database +** file with the "-shm" suffix added. For example, if the database file +** is "/home/user1/config.db" then the file that is created and mmapped +** for shared memory will be called "/home/user1/config.db-shm". +** +** Another approach to is to use files in /dev/shm or /dev/tmp or an +** some other tmpfs mount. But if a file in a different directory +** from the database file is used, then differing access permissions +** or a chroot() might cause two different processes on the same +** database to end up using different files for shared memory - +** meaning that their memory would not really be shared - resulting +** in database corruption. Nevertheless, this tmpfs file usage +** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm" +** or the equivalent. The use of the SQLITE_SHM_DIRECTORY compile-time +** option results in an incompatible build of SQLite; builds of SQLite +** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the +** same database file at the same time, database corruption will likely +** result. The SQLITE_SHM_DIRECTORY compile-time option is considered +** "unsupported" and may go away in a future SQLite release. +** +** When opening a new shared-memory file, if no other instances of that +** file are currently open, in this process or in other processes, then +** the file must be truncated to zero length or have its header cleared. +** +** If the original database file (pDbFd) is using the "unix-excl" VFS +** that means that an exclusive lock is held on the database file and +** that no other processes are able to read or write the database. In +** that case, we do not really need shared memory. No shared memory +** file is created. The shared memory will be simulated with heap memory. +*/ +static int unixOpenSharedMemory(unixFile *pDbFd){ + struct unixShm *p = 0; /* The connection to be opened */ + struct unixShmNode *pShmNode; /* The underlying mmapped file */ + int rc; /* Result code */ + unixInodeInfo *pInode; /* The inode of fd */ + char *zShmFilename; /* Name of the file used for SHM */ + int nShmFilename; /* Size of the SHM filename in bytes */ + + /* Allocate space for the new unixShm object. */ + p = sqlite3_malloc( sizeof(*p) ); + if( p==0 ) return SQLITE_NOMEM; + memset(p, 0, sizeof(*p)); + assert( pDbFd->pShm==0 ); + + /* Check to see if a unixShmNode object already exists. Reuse an existing + ** one if present. Create a new one if necessary. + */ + unixEnterMutex(); + pInode = pDbFd->pInode; + pShmNode = pInode->pShmNode; + if( pShmNode==0 ){ + struct stat sStat; /* fstat() info for database file */ + + /* Call fstat() to figure out the permissions on the database file. If + ** a new *-shm file is created, an attempt will be made to create it + ** with the same permissions. The actual permissions the file is created + ** with are subject to the current umask setting. + */ + if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){ + rc = SQLITE_IOERR_FSTAT; + goto shm_open_err; + } + +#ifdef SQLITE_SHM_DIRECTORY + nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 30; +#else + nShmFilename = 5 + (int)strlen(pDbFd->zPath); +#endif + pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename ); + if( pShmNode==0 ){ + rc = SQLITE_NOMEM; + goto shm_open_err; + } + memset(pShmNode, 0, sizeof(*pShmNode)); + zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1]; +#ifdef SQLITE_SHM_DIRECTORY + sqlite3_snprintf(nShmFilename, zShmFilename, + SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", + (u32)sStat.st_ino, (u32)sStat.st_dev); +#else + sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath); + sqlite3FileSuffix3(pDbFd->zPath, zShmFilename); +#endif + pShmNode->h = -1; + pDbFd->pInode->pShmNode = pShmNode; + pShmNode->pInode = pDbFd->pInode; + pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->mutex==0 ){ + rc = SQLITE_NOMEM; + goto shm_open_err; + } + + if( pInode->bProcessLock==0 ){ + pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, + (sStat.st_mode & 0777)); + if( pShmNode->h<0 ){ + const char *zRO; + zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm"); + if( zRO && sqlite3GetBoolean(zRO) ){ + pShmNode->h = robust_open(zShmFilename, O_RDONLY, + (sStat.st_mode & 0777)); + pShmNode->isReadonly = 1; + } + if( pShmNode->h<0 ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); + goto shm_open_err; + } + } + + /* Check to see if another process is holding the dead-man switch. + ** If not, truncate the file to zero length. + */ + rc = SQLITE_OK; + if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ + if( robust_ftruncate(pShmNode->h, 0) ){ + rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); + } + } + if( rc==SQLITE_OK ){ + rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); + } + if( rc ) goto shm_open_err; + } + } + + /* Make the new connection a child of the unixShmNode */ + p->pShmNode = pShmNode; +#ifdef SQLITE_DEBUG + p->id = pShmNode->nextShmId++; +#endif + pShmNode->nRef++; + pDbFd->pShm = p; + unixLeaveMutex(); + + /* The reference count on pShmNode has already been incremented under + ** the cover of the unixEnterMutex() mutex and the pointer from the + ** new (struct unixShm) object to the pShmNode has been set. All that is + ** left to do is to link the new object into the linked list starting + ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex + ** mutex. + */ + sqlite3_mutex_enter(pShmNode->mutex); + p->pNext = pShmNode->pFirst; + pShmNode->pFirst = p; + sqlite3_mutex_leave(pShmNode->mutex); + return SQLITE_OK; + + /* Jump here on any error */ +shm_open_err: + unixShmPurge(pDbFd); /* This call frees pShmNode if required */ + sqlite3_free(p); + unixLeaveMutex(); + return rc; +} + +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the bExtend parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** bExtend is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int unixShmMap( + sqlite3_file *fd, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int bExtend, /* True to extend file if necessary */ + void volatile **pp /* OUT: Mapped memory */ +){ + unixFile *pDbFd = (unixFile*)fd; + unixShm *p; + unixShmNode *pShmNode; + int rc = SQLITE_OK; + + /* If the shared-memory file has not yet been opened, open it now. */ + if( pDbFd->pShm==0 ){ + rc = unixOpenSharedMemory(pDbFd); + if( rc!=SQLITE_OK ) return rc; + } + + p = pDbFd->pShm; + pShmNode = p->pShmNode; + sqlite3_mutex_enter(pShmNode->mutex); + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + assert( pShmNode->pInode==pDbFd->pInode ); + assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); + + if( pShmNode->nRegion<=iRegion ){ + char **apNew; /* New apRegion[] array */ + int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ + struct stat sStat; /* Used by fstat() */ + + pShmNode->szRegion = szRegion; + + if( pShmNode->h>=0 ){ + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). + */ + if( osFstat(pShmNode->h, &sStat) ){ + rc = SQLITE_IOERR_SHMSIZE; + goto shmpage_out; + } + + if( sStat.st_size<nByte ){ + /* The requested memory region does not exist. If bExtend is set to + ** false, exit early. *pp will be set to NULL and SQLITE_OK returned. + ** + ** Alternatively, if bExtend is true, use ftruncate() to allocate + ** the requested memory region. + */ + if( !bExtend ) goto shmpage_out; + if( robust_ftruncate(pShmNode->h, nByte) ){ + rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate", + pShmNode->zFilename); + goto shmpage_out; + } + } + } + + /* Map the requested memory region into this processes address space. */ + apNew = (char **)sqlite3_realloc( + pShmNode->apRegion, (iRegion+1)*sizeof(char *) + ); + if( !apNew ){ + rc = SQLITE_IOERR_NOMEM; + goto shmpage_out; + } + pShmNode->apRegion = apNew; + while(pShmNode->nRegion<=iRegion){ + void *pMem; + if( pShmNode->h>=0 ){ + pMem = mmap(0, szRegion, + pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, + MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion + ); + if( pMem==MAP_FAILED ){ + rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); + goto shmpage_out; + } + }else{ + pMem = sqlite3_malloc(szRegion); + if( pMem==0 ){ + rc = SQLITE_NOMEM; + goto shmpage_out; + } + memset(pMem, 0, szRegion); + } + pShmNode->apRegion[pShmNode->nRegion] = pMem; + pShmNode->nRegion++; + } + } + +shmpage_out: + if( pShmNode->nRegion>iRegion ){ + *pp = pShmNode->apRegion[iRegion]; + }else{ + *pp = 0; + } + if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; + sqlite3_mutex_leave(pShmNode->mutex); + return rc; +} + +/* +** Change the lock state for a shared-memory segment. +** +** Note that the relationship between SHAREd and EXCLUSIVE locks is a little +** different here than in posix. In xShmLock(), one can go from unlocked +** to shared and back or from unlocked to exclusive and back. But one may +** not go from shared to exclusive or from exclusive to shared. +*/ +static int unixShmLock( + sqlite3_file *fd, /* Database file holding the shared memory */ + int ofst, /* First lock to acquire or release */ + int n, /* Number of locks to acquire or release */ + int flags /* What to do with the lock */ +){ + unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */ + unixShm *p = pDbFd->pShm; /* The shared memory being locked */ + unixShm *pX; /* For looping over all siblings */ + unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */ + int rc = SQLITE_OK; /* Result code */ + u16 mask; /* Mask of locks to take or release */ + + assert( pShmNode==pDbFd->pInode->pShmNode ); + assert( pShmNode->pInode==pDbFd->pInode ); + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); + assert( n>=1 ); + assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); + assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); + + mask = (1<<(ofst+n)) - (1<<ofst); + assert( n>1 || mask==(1<<ofst) ); + sqlite3_mutex_enter(pShmNode->mutex); + if( flags & SQLITE_SHM_UNLOCK ){ + u16 allMask = 0; /* Mask of locks held by siblings */ + + /* See if any siblings hold this same lock */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( pX==p ) continue; + assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); + allMask |= pX->sharedMask; + } + + /* Unlock the system-level locks */ + if( (mask & allMask)==0 ){ + rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + + /* Undo the local locks */ + if( rc==SQLITE_OK ){ + p->exclMask &= ~mask; + p->sharedMask &= ~mask; + } + }else if( flags & SQLITE_SHM_SHARED ){ + u16 allShared = 0; /* Union of locks held by connections other than "p" */ + + /* Find out which shared locks are already held by sibling connections. + ** If any sibling already holds an exclusive lock, go ahead and return + ** SQLITE_BUSY. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + allShared |= pX->sharedMask; + } + + /* Get shared locks at the system level, if necessary */ + if( rc==SQLITE_OK ){ + if( (allShared & mask)==0 ){ + rc = unixShmSystemLock(pShmNode, F_RDLCK, ofst+UNIX_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + } + + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + } + }else{ + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + } + + /* Get the exclusive locks at the system level. Then if successful + ** also mark the local connection as being locked. + */ + if( rc==SQLITE_OK ){ + rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n); + if( rc==SQLITE_OK ){ + assert( (p->sharedMask & mask)==0 ); + p->exclMask |= mask; + } + } + } + sqlite3_mutex_leave(pShmNode->mutex); + OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", + p->id, getpid(), p->sharedMask, p->exclMask)); + return rc; +} + +/* +** Implement a memory barrier or memory fence on shared memory. +** +** All loads and stores begun before the barrier must complete before +** any load or store begun after the barrier. +*/ +static void unixShmBarrier( + sqlite3_file *fd /* Database file holding the shared memory */ +){ + UNUSED_PARAMETER(fd); + unixEnterMutex(); + unixLeaveMutex(); +} + +/* +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. +** +** If there is no shared memory associated with the connection then this +** routine is a harmless no-op. +*/ +static int unixShmUnmap( + sqlite3_file *fd, /* The underlying database file */ + int deleteFlag /* Delete shared-memory if true */ +){ + unixShm *p; /* The connection to be closed */ + unixShmNode *pShmNode; /* The underlying shared-memory file */ + unixShm **pp; /* For looping over sibling connections */ + unixFile *pDbFd; /* The underlying database file */ + + pDbFd = (unixFile*)fd; + p = pDbFd->pShm; + if( p==0 ) return SQLITE_OK; + pShmNode = p->pShmNode; + + assert( pShmNode==pDbFd->pInode->pShmNode ); + assert( pShmNode->pInode==pDbFd->pInode ); + + /* Remove connection p from the set of connections associated + ** with pShmNode */ + sqlite3_mutex_enter(pShmNode->mutex); + for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} + *pp = p->pNext; + + /* Free the connection p */ + sqlite3_free(p); + pDbFd->pShm = 0; + sqlite3_mutex_leave(pShmNode->mutex); + + /* If pShmNode->nRef has reached 0, then close the underlying + ** shared-memory file, too */ + unixEnterMutex(); + assert( pShmNode->nRef>0 ); + pShmNode->nRef--; + if( pShmNode->nRef==0 ){ + if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename); + unixShmPurge(pDbFd); + } + unixLeaveMutex(); + + return SQLITE_OK; +} + + +#else +# define unixShmMap 0 +# define unixShmLock 0 +# define unixShmBarrier 0 +# define unixShmUnmap 0 +#endif /* #ifndef SQLITE_OMIT_WAL */ + /* ** Here ends the implementation of all sqlite3_file methods. ** @@ -25457,9 +28843,9 @@ static int unixDeviceCharacteristics(sqlite3_file *NotUsed){ ** * An I/O method finder function called FINDER that returns a pointer ** to the METHOD object in the previous bullet. */ -#define IOMETHODS(FINDER, METHOD, CLOSE, LOCK, UNLOCK, CKLOCK) \ +#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK) \ static const sqlite3_io_methods METHOD = { \ - 1, /* iVersion */ \ + VERSION, /* iVersion */ \ CLOSE, /* xClose */ \ unixRead, /* xRead */ \ unixWrite, /* xWrite */ \ @@ -25471,7 +28857,11 @@ static const sqlite3_io_methods METHOD = { \ CKLOCK, /* xCheckReservedLock */ \ unixFileControl, /* xFileControl */ \ unixSectorSize, /* xSectorSize */ \ - unixDeviceCharacteristics /* xDeviceCapabilities */ \ + unixDeviceCharacteristics, /* xDeviceCapabilities */ \ + unixShmMap, /* xShmMap */ \ + unixShmLock, /* xShmLock */ \ + unixShmBarrier, /* xShmBarrier */ \ + unixShmUnmap /* xShmUnmap */ \ }; \ static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \ UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \ @@ -25488,6 +28878,7 @@ static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \ IOMETHODS( posixIoFinder, /* Finder function name */ posixIoMethods, /* sqlite3_io_methods object name */ + 2, /* shared memory is enabled */ unixClose, /* xClose method */ unixLock, /* xLock method */ unixUnlock, /* xUnlock method */ @@ -25496,6 +28887,7 @@ IOMETHODS( IOMETHODS( nolockIoFinder, /* Finder function name */ nolockIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ nolockClose, /* xClose method */ nolockLock, /* xLock method */ nolockUnlock, /* xUnlock method */ @@ -25504,6 +28896,7 @@ IOMETHODS( IOMETHODS( dotlockIoFinder, /* Finder function name */ dotlockIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ dotlockClose, /* xClose method */ dotlockLock, /* xLock method */ dotlockUnlock, /* xUnlock method */ @@ -25514,6 +28907,7 @@ IOMETHODS( IOMETHODS( flockIoFinder, /* Finder function name */ flockIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ flockClose, /* xClose method */ flockLock, /* xLock method */ flockUnlock, /* xUnlock method */ @@ -25525,6 +28919,7 @@ IOMETHODS( IOMETHODS( semIoFinder, /* Finder function name */ semIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ semClose, /* xClose method */ semLock, /* xLock method */ semUnlock, /* xUnlock method */ @@ -25536,6 +28931,7 @@ IOMETHODS( IOMETHODS( afpIoFinder, /* Finder function name */ afpIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ afpClose, /* xClose method */ afpLock, /* xLock method */ afpUnlock, /* xUnlock method */ @@ -25560,6 +28956,7 @@ static int proxyCheckReservedLock(sqlite3_file*, int*); IOMETHODS( proxyIoFinder, /* Finder function name */ proxyIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ proxyClose, /* xClose method */ proxyLock, /* xLock method */ proxyUnlock, /* xUnlock method */ @@ -25572,6 +28969,7 @@ IOMETHODS( IOMETHODS( nfsIoFinder, /* Finder function name */ nfsIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ unixClose, /* xClose method */ unixLock, /* xLock method */ nfsUnlock, /* xUnlock method */ @@ -25580,8 +28978,8 @@ IOMETHODS( #endif #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE -/* -** This "finder" function attempts to determine the best locking strategy +/* +** This "finder" function attempts to determine the best locking strategy ** for the database file "filePath". It then returns the sqlite3_io_methods ** object that implements that strategy. ** @@ -25623,14 +29021,14 @@ static const sqlite3_io_methods *autolockIoFinderImpl( } /* Default case. Handles, amongst others, "nfs". - ** Test byte-range lock using fcntl(). If the call succeeds, - ** assume that the file-system supports POSIX style locks. + ** Test byte-range lock using fcntl(). If the call succeeds, + ** assume that the file-system supports POSIX style locks. */ lockInfo.l_len = 1; lockInfo.l_start = 0; lockInfo.l_whence = SEEK_SET; lockInfo.l_type = F_RDLCK; - if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){ return &nfsIoMethods; } else { @@ -25640,14 +29038,14 @@ static const sqlite3_io_methods *autolockIoFinderImpl( return &dotlockIoMethods; } } -static const sqlite3_io_methods +static const sqlite3_io_methods *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ #if OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE -/* -** This "finder" function attempts to determine the best locking strategy +/* +** This "finder" function attempts to determine the best locking strategy ** for the database file "filePath". It then returns the sqlite3_io_methods ** object that implements that strategy. ** @@ -25672,13 +29070,13 @@ static const sqlite3_io_methods *autolockIoFinderImpl( lockInfo.l_start = 0; lockInfo.l_whence = SEEK_SET; lockInfo.l_type = F_RDLCK; - if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { return &posixIoMethods; }else{ return &semIoMethods; } } -static const sqlite3_io_methods +static const sqlite3_io_methods *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; #endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */ @@ -25702,29 +29100,49 @@ typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); static int fillInUnixFile( sqlite3_vfs *pVfs, /* Pointer to vfs object */ int h, /* Open file descriptor of file being opened */ - int dirfd, /* Directory file descriptor */ + int syncDir, /* True to sync directory on first sync */ sqlite3_file *pId, /* Write to the unixFile structure here */ const char *zFilename, /* Name of the file being opened */ int noLock, /* Omit locking if true */ - int isDelete /* Delete on close if true */ + int isDelete, /* Delete on close if true */ + int isReadOnly /* True if the file is opened read-only */ ){ const sqlite3_io_methods *pLockingStyle; unixFile *pNew = (unixFile *)pId; int rc = SQLITE_OK; - assert( pNew->pLock==NULL ); - assert( pNew->pOpen==NULL ); + assert( pNew->pInode==NULL ); - /* Parameter isDelete is only used on vxworks. Express this explicitly + /* Parameter isDelete is only used on vxworks. Express this explicitly ** here to prevent compiler warnings about unused parameters. */ UNUSED_PARAMETER(isDelete); - OSTRACE3("OPEN %-3d %s\n", h, zFilename); + /* Usually the path zFilename should not be a relative pathname. The + ** exception is when opening the proxy "conch" file in builds that + ** include the special Apple locking styles. + */ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + assert( zFilename==0 || zFilename[0]=='/' + || pVfs->pAppData==(void*)&autolockIoFinder ); +#else + assert( zFilename==0 || zFilename[0]=='/' ); +#endif + + OSTRACE(("OPEN %-3d %s\n", h, zFilename)); pNew->h = h; - pNew->dirfd = dirfd; - SET_THREADID(pNew); - pNew->fileFlags = 0; + pNew->zPath = zFilename; + if( memcmp(pVfs->zName,"unix-excl",10)==0 ){ + pNew->ctrlFlags = UNIXFILE_EXCL; + }else{ + pNew->ctrlFlags = 0; + } + if( isReadOnly ){ + pNew->ctrlFlags |= UNIXFILE_RDONLY; + } + if( syncDir ){ + pNew->ctrlFlags |= UNIXFILE_DIRSYNC; + } #if OS_VXWORKS pNew->pId = vxworksFindFileId(zFilename); @@ -25752,10 +29170,10 @@ static int fillInUnixFile( #endif ){ unixEnterMutex(); - rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen); + rc = findInodeInfo(pNew, &pNew->pInode); if( rc!=SQLITE_OK ){ - /* If an error occured in findLockInfo(), close the file descriptor - ** immediately, before releasing the mutex. findLockInfo() may fail + /* If an error occured in findInodeInfo(), close the file descriptor + ** immediately, before releasing the mutex. findInodeInfo() may fail ** in two scenarios: ** ** (a) A call to fstat() failed. @@ -25764,7 +29182,7 @@ static int fillInUnixFile( ** Scenario (b) may only occur if the process is holding no other ** file descriptors open on the same file. If there were other file ** descriptors on this file, then no malloc would be required by - ** findLockInfo(). If this is the case, it is quite safe to close + ** findInodeInfo(). If this is the case, it is quite safe to close ** handle h - as it is guaranteed that no posix locks will be released ** by doing so. ** @@ -25772,7 +29190,7 @@ static int fillInUnixFile( ** implicit assumption here is that if fstat() fails, things are in ** such bad shape that dropping a lock or two doesn't matter much. */ - close(h); + robust_close(pNew, h, __LINE__); h = -1; } unixLeaveMutex(); @@ -25795,20 +29213,20 @@ static int fillInUnixFile( pCtx->reserved = 0; srandomdev(); unixEnterMutex(); - rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen); + rc = findInodeInfo(pNew, &pNew->pInode); if( rc!=SQLITE_OK ){ sqlite3_free(pNew->lockingContext); - close(h); + robust_close(pNew, h, __LINE__); h = -1; } - unixLeaveMutex(); + unixLeaveMutex(); } } #endif else if( pLockingStyle == &dotlockIoMethods ){ /* Dotfile locking uses the file path so it needs to be included in - ** the dotlockLockingContext + ** the dotlockLockingContext */ char *zLockFile; int nFilename; @@ -25828,37 +29246,36 @@ static int fillInUnixFile( ** included in the semLockingContext */ unixEnterMutex(); - rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen); - if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){ - char *zSemName = pNew->pOpen->aSemName; + rc = findInodeInfo(pNew, &pNew->pInode); + if( (rc==SQLITE_OK) && (pNew->pInode->pSem==NULL) ){ + char *zSemName = pNew->pInode->aSemName; int n; sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem", pNew->pId->zCanonicalName); for( n=1; zSemName[n]; n++ ) if( zSemName[n]=='/' ) zSemName[n] = '_'; - pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1); - if( pNew->pOpen->pSem == SEM_FAILED ){ + pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1); + if( pNew->pInode->pSem == SEM_FAILED ){ rc = SQLITE_NOMEM; - pNew->pOpen->aSemName[0] = '\0'; + pNew->pInode->aSemName[0] = '\0'; } } unixLeaveMutex(); } #endif - + pNew->lastErrno = 0; #if OS_VXWORKS if( rc!=SQLITE_OK ){ - if( h>=0 ) close(h); + if( h>=0 ) robust_close(pNew, h, __LINE__); h = -1; - unlink(zFilename); + osUnlink(zFilename); isDelete = 0; } pNew->isDelete = isDelete; #endif if( rc!=SQLITE_OK ){ - if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */ - if( h>=0 ) close(h); + if( h>=0 ) robust_close(pNew, h, __LINE__); }else{ pNew->pMethod = pLockingStyle; OpenCounter(+1); @@ -25867,34 +29284,32 @@ static int fillInUnixFile( } /* -** Open a file descriptor to the directory containing file zFilename. -** If successful, *pFd is set to the opened file descriptor and -** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM -** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined -** value. -** -** If SQLITE_OK is returned, the caller is responsible for closing -** the file descriptor *pFd using close(). +** Return the name of a directory in which to put temporary files. +** If no suitable temporary file directory can be found, return NULL. */ -static int openDirectory(const char *zFilename, int *pFd){ - int ii; - int fd = -1; - char zDirname[MAX_PATHNAME+1]; +static const char *unixTempFileDir(void){ + static const char *azDirs[] = { + 0, + 0, + "/var/tmp", + "/usr/tmp", + "/tmp", + 0 /* List terminator */ + }; + unsigned int i; + struct stat buf; + const char *zDir = 0; - sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); - for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); - if( ii>0 ){ - zDirname[ii] = '\0'; - fd = open(zDirname, O_RDONLY|O_BINARY, 0); - if( fd>=0 ){ -#ifdef FD_CLOEXEC - fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC); -#endif - OSTRACE3("OPENDIR %-3d %s\n", fd, zDirname); - } + azDirs[0] = sqlite3_temp_directory; + if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); + for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ + if( zDir==0 ) continue; + if( osStat(zDir, &buf) ) continue; + if( !S_ISDIR(buf.st_mode) ) continue; + if( osAccess(zDir, 07) ) continue; + break; } - *pFd = fd; - return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN_BKPT); + return zDir; } /* @@ -25902,44 +29317,24 @@ static int openDirectory(const char *zFilename, int *pFd){ ** by the calling process and must be big enough to hold at least ** pVfs->mxPathname bytes. */ -static int getTempname(int nBuf, char *zBuf){ - static const char *azDirs[] = { - 0, - 0, - "/var/tmp", - "/usr/tmp", - "/tmp", - ".", - }; +static int unixGetTempname(int nBuf, char *zBuf){ static const unsigned char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; unsigned int i, j; - struct stat buf; - const char *zDir = "."; + const char *zDir; /* 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. + ** function failing. */ SimulateIOError( return SQLITE_IOERR ); - azDirs[0] = sqlite3_temp_directory; - if (NULL == azDirs[1]) { - azDirs[1] = getenv("TMPDIR"); - } + zDir = unixTempFileDir(); + if( zDir==0 ) zDir = "."; - for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){ - if( azDirs[i]==0 ) continue; - if( stat(azDirs[i], &buf) ) continue; - if( !S_ISDIR(buf.st_mode) ) continue; - if( access(azDirs[i], 07) ) continue; - zDir = azDirs[i]; - break; - } - - /* Check that the output buffer is large enough for the temporary file + /* Check that the output buffer is large enough for the temporary file ** name. If it is not, return SQLITE_ERROR. */ if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 17) >= (size_t)nBuf ){ @@ -25954,7 +29349,7 @@ static int getTempname(int nBuf, char *zBuf){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; - }while( access(zBuf,0)==0 ); + }while( osAccess(zBuf,0)==0 ); return SQLITE_OK; } @@ -25968,7 +29363,7 @@ static int proxyTransformUnixFile(unixFile*, const char*); #endif /* -** Search for an unused file descriptor that was opened on the database +** Search for an unused file descriptor that was opened on the database ** file (not a journal or master-journal file) identified by pathname ** zPath with SQLITE_OPEN_XXX flags matching those passed as the second ** argument to this function. @@ -25977,7 +29372,7 @@ static int proxyTransformUnixFile(unixFile*, const char*); ** but the associated file descriptor could not be closed because some ** other file descriptor open on the same file is holding a file-lock. ** Refer to comments in the unixClose() function and the lengthy comment -** describing "Posix Advisory Locking" at the start of this file for +** describing "Posix Advisory Locking" at the start of this file for ** further details. Also, ticket #4018. ** ** If a suitable file descriptor is found, then it is returned. If no @@ -25988,8 +29383,8 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ /* Do not search for an unused file descriptor on vxworks. Not because ** vxworks would not benefit from the change (it might, we're not sure), - ** but because no way to test it is currently available. It is better - ** not to risk breaking vxworks support for the sake of such an obscure + ** but because no way to test it is currently available. It is better + ** not to risk breaking vxworks support for the sake of such an obscure ** feature. */ #if !OS_VXWORKS struct stat sStat; /* Results of stat() call */ @@ -26002,18 +29397,18 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ ** ** Even if a subsequent open() call does succeed, the consequences of ** not searching for a resusable file descriptor are not dire. */ - if( 0==stat(zPath, &sStat) ){ - struct unixOpenCnt *pOpen; + if( 0==osStat(zPath, &sStat) ){ + unixInodeInfo *pInode; unixEnterMutex(); - pOpen = openList; - while( pOpen && (pOpen->fileId.dev!=sStat.st_dev - || pOpen->fileId.ino!=sStat.st_ino) ){ - pOpen = pOpen->pNext; + pInode = inodeList; + while( pInode && (pInode->fileId.dev!=sStat.st_dev + || pInode->fileId.ino!=sStat.st_ino) ){ + pInode = pInode->pNext; } - if( pOpen ){ + if( pInode ){ UnixUnusedFd **pp; - for(pp=&pOpen->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); + for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); pUnused = *pp; if( pUnused ){ *pp = pUnused->pNext; @@ -26026,8 +29421,72 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ } /* -** Open the file zPath. +** This function is called by unixOpen() to determine the unix permissions +** to create new files with. If no error occurs, then SQLITE_OK is returned +** and a value suitable for passing as the third argument to open(2) is +** written to *pMode. If an IO error occurs, an SQLite error code is +** returned and the value of *pMode is not modified. +** +** If the file being opened is a temporary file, it is always created with +** the octal permissions 0600 (read/writable by owner only). If the file +** is a database or master journal file, it is created with the permissions +** mask SQLITE_DEFAULT_FILE_PERMISSIONS. +** +** Finally, if the file being opened is a WAL or regular journal file, then +** this function queries the file-system for the permissions on the +** corresponding database file and sets *pMode to this value. Whenever +** possible, WAL and journal files are created using the same permissions +** as the associated database file. ** +** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the +** original filename is unavailable. But 8_3_NAMES is only used for +** FAT filesystems and permissions do not matter there, so just use +** the default permissions. +*/ +static int findCreateFileMode( + const char *zPath, /* Path of file (possibly) being created */ + int flags, /* Flags passed as 4th argument to xOpen() */ + mode_t *pMode /* OUT: Permissions to open file with */ +){ + int rc = SQLITE_OK; /* Return Code */ + *pMode = SQLITE_DEFAULT_FILE_PERMISSIONS; + if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ + char zDb[MAX_PATHNAME+1]; /* Database file path */ + int nDb; /* Number of valid bytes in zDb */ + struct stat sStat; /* Output of stat() on database file */ + + /* zPath is a path to a WAL or journal file. The following block derives + ** the path to the associated database file from zPath. This block handles + ** the following naming conventions: + ** + ** "<path to db>-journal" + ** "<path to db>-wal" + ** "<path to db>-journalNN" + ** "<path to db>-walNN" + ** + ** where NN is a 4 digit decimal number. The NN naming schemes are + ** used by the test_multiplex.c module. + */ + nDb = sqlite3Strlen30(zPath) - 1; + while( nDb>0 && zPath[nDb]!='-' ) nDb--; + if( nDb==0 ) return SQLITE_OK; + memcpy(zDb, zPath, nDb); + zDb[nDb] = '\0'; + + if( 0==osStat(zDb, &sStat) ){ + *pMode = sStat.st_mode & 0777; + }else{ + rc = SQLITE_IOERR_FSTAT; + } + }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ + *pMode = 0600; + } + return rc; +} + +/* +** Open the file zPath. +** ** Previously, the SQLite OS layer used three functions in place of this ** one: ** @@ -26038,13 +29497,13 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ ** These calls correspond to the following combinations of flags: ** ** ReadWrite() -> (READWRITE | CREATE) -** ReadOnly() -> (READONLY) +** ReadOnly() -> (READONLY) ** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE) ** ** The old OpenExclusive() accepted a boolean argument - "delFlag". If ** true, the file was configured to be automatically deleted when the -** file handle closed. To achieve the same effect using this new -** interface, add the DELETEONCLOSE flag to those specified above for +** file handle closed. To achieve the same effect using this new +** interface, add the DELETEONCLOSE flag to those specified above for ** OpenExclusive(). */ static int unixOpen( @@ -26056,7 +29515,6 @@ static int unixOpen( ){ unixFile *p = (unixFile *)pFile; int fd = -1; /* File descriptor returned by open() */ - int dirfd = -1; /* Directory file descriptor */ int openFlags = 0; /* Flags to pass to open() */ int eType = flags&0xFFFFFF00; /* Type of file to open */ int noLock; /* True to omit locking primitives */ @@ -26070,14 +29528,19 @@ static int unixOpen( #if SQLITE_ENABLE_LOCKING_STYLE int isAutoProxy = (flags & SQLITE_OPEN_AUTOPROXY); #endif +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE + struct statfs fsInfo; +#endif /* If creating a master or main-file journal, this function will open ** a file-descriptor on the directory too. The first time unixSync() ** is called the directory file descriptor will be fsync()ed and close()d. */ - int isOpenDirectory = (isCreate && - (eType==SQLITE_OPEN_MASTER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL) - ); + int syncDir = (isCreate && ( + eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_WAL + )); /* If argument zPath is a NULL pointer, this function is required to open ** a temporary file. Use this buffer to store the file name in. @@ -26085,9 +29548,9 @@ static int unixOpen( char zTmpname[MAX_PATHNAME+1]; const char *zName = zPath; - /* Check the following statements are true: + /* Check the following statements are true: ** - ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and ** (b) if CREATE is set, then READWRITE must also be set, and ** (c) if EXCLUSIVE is set, then CREATE must also be set. ** (d) if DELETEONCLOSE is set, then CREATE must also be set. @@ -26097,17 +29560,18 @@ static int unixOpen( assert(isExclusive==0 || isCreate); assert(isDelete==0 || isCreate); - /* The main DB, main journal, and master journal are never automatically - ** deleted. Nor are they ever temporary files. */ + /* The main DB, main journal, WAL file and master journal are never + ** automatically deleted. Nor are they ever temporary files. */ assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); /* Assert that the upper layer has set one of the "file-type" flags. */ - assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB - || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL - || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL - || eType==SQLITE_OPEN_TRANSIENT_DB + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL ); memset(p, 0, sizeof(unixFile)); @@ -26126,8 +29590,8 @@ static int unixOpen( p->pUnused = pUnused; }else if( !zName ){ /* If zName is NULL, the upper layer is requesting a temp file. */ - assert(isDelete && !isOpenDirectory); - rc = getTempname(MAX_PATHNAME+1, zTmpname); + assert(isDelete && !syncDir); + rc = unixGetTempname(MAX_PATHNAME+1, zTmpname); if( rc!=SQLITE_OK ){ return rc; } @@ -26136,7 +29600,7 @@ static int unixOpen( /* Determine the value of the flags parameter passed to POSIX function ** open(). These must be calculated even if open() is not called, as - ** they may be stored as part of the file handle and used by the + ** they may be stored as part of the file handle and used by the ** 'conch file' locking functions later on. */ if( isReadonly ) openFlags |= O_RDONLY; if( isReadWrite ) openFlags |= O_RDWR; @@ -26145,19 +29609,26 @@ static int unixOpen( openFlags |= (O_LARGEFILE|O_BINARY); if( fd<0 ){ - mode_t openMode = (isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS); - fd = open(zName, openFlags, openMode); - OSTRACE4("OPENX %-3d %s 0%o\n", fd, zName, openFlags); + mode_t openMode; /* Permissions to create file with */ + rc = findCreateFileMode(zName, flags, &openMode); + if( rc!=SQLITE_OK ){ + assert( !p->pUnused ); + assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); + return rc; + } + fd = robust_open(zName, openFlags, openMode); + OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){ /* Failed to open the file for read/write access. Try read-only. */ flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); openFlags &= ~(O_RDWR|O_CREAT); flags |= SQLITE_OPEN_READONLY; openFlags |= O_RDONLY; - fd = open(zName, openFlags, openMode); + isReadonly = 1; + fd = robust_open(zName, openFlags, openMode); } if( fd<0 ){ - rc = SQLITE_CANTOPEN_BKPT; + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); goto open_finished; } } @@ -26175,7 +29646,7 @@ static int unixOpen( #if OS_VXWORKS zPath = zName; #else - unlink(zName); + osUnlink(zName); #endif } #if SQLITE_ENABLE_LOCKING_STYLE @@ -26184,39 +29655,24 @@ static int unixOpen( } #endif - if( isOpenDirectory ){ - rc = openDirectory(zPath, &dirfd); - if( rc!=SQLITE_OK ){ - /* It is safe to close fd at this point, because it is guaranteed not - ** to be open on a database file. If it were open on a database file, - ** it would not be safe to close as this would release any locks held - ** on the file by this process. */ - assert( eType!=SQLITE_OPEN_MAIN_DB ); - close(fd); /* silently leak if fail, already in error */ - goto open_finished; - } - } - #ifdef FD_CLOEXEC - fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC); + osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); #endif noLock = eType!=SQLITE_OPEN_MAIN_DB; - + #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE - struct statfs fsInfo; if( fstatfs(fd, &fsInfo) == -1 ){ ((unixFile*)pFile)->lastErrno = errno; - if( dirfd>=0 ) close(dirfd); /* silently leak if fail, in error */ - close(fd); /* silently leak if fail, in error */ + robust_close(p, fd, __LINE__); return SQLITE_IOERR_ACCESS; } if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) { ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; } #endif - + #if SQLITE_ENABLE_LOCKING_STYLE #if SQLITE_PREFER_PROXY_LOCKING isAutoProxy = 1; @@ -26225,12 +29681,11 @@ static int unixOpen( char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING"); int useProxy = 0; - /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means + /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means ** never use proxy, NULL means use proxy for non-local files only. */ if( envforce!=NULL ){ useProxy = atoi(envforce)>0; }else{ - struct statfs fsInfo; if( statfs(zPath, &fsInfo) == -1 ){ /* In theory, the close(fd) call is sub-optimal. If the file opened ** with fd is a database file, and there are other connections open @@ -26240,23 +29695,21 @@ static int unixOpen( ** not while other file descriptors opened by the same process on ** the same file are working. */ p->lastErrno = errno; - if( dirfd>=0 ){ - close(dirfd); /* silently leak if fail, in error */ - } - close(fd); /* silently leak if fail, in error */ + robust_close(p, fd, __LINE__); rc = SQLITE_IOERR_ACCESS; goto open_finished; } useProxy = !(fsInfo.f_flags&MNT_LOCAL); } if( useProxy ){ - rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); + rc = fillInUnixFile(pVfs, fd, syncDir, pFile, zPath, noLock, + isDelete, isReadonly); if( rc==SQLITE_OK ){ rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); if( rc!=SQLITE_OK ){ - /* Use unixClose to clean up the resources added in fillInUnixFile - ** and clear all the structure's references. Specifically, - ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op + /* Use unixClose to clean up the resources added in fillInUnixFile + ** and clear all the structure's references. Specifically, + ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op */ unixClose(pFile); return rc; @@ -26266,8 +29719,9 @@ static int unixOpen( } } #endif - - rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); + + rc = fillInUnixFile(pVfs, fd, syncDir, pFile, zPath, noLock, + isDelete, isReadonly); open_finished: if( rc!=SQLITE_OK ){ sqlite3_free(p->pUnused); @@ -26288,11 +29742,13 @@ static int unixDelete( int rc = SQLITE_OK; UNUSED_PARAMETER(NotUsed); SimulateIOError(return SQLITE_IOERR_DELETE); - unlink(zPath); + if( osUnlink(zPath)==(-1) && errno!=ENOENT ){ + return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath); + } #ifndef SQLITE_DISABLE_DIRSYNC if( dirSync ){ int fd; - rc = openDirectory(zPath, &fd); + rc = osOpenDirectory(zPath, &fd); if( rc==SQLITE_OK ){ #if OS_VXWORKS if( fsync(fd)==-1 ) @@ -26300,11 +29756,11 @@ static int unixDelete( if( fsync(fd) ) #endif { - rc = SQLITE_IOERR_DIR_FSYNC; - } - if( close(fd)&&!rc ){ - rc = SQLITE_IOERR_DIR_CLOSE; + rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); } + robust_close(0, fd, __LINE__); + }else if( rc==SQLITE_CANTOPEN ){ + rc = SQLITE_OK; } } #endif @@ -26344,7 +29800,13 @@ static int unixAccess( default: assert(!"Invalid flags argument"); } - *pResOut = (access(zPath, amode)==0); + *pResOut = (osAccess(zPath, amode)==0); + if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){ + struct stat buf; + if( 0==osStat(zPath, &buf) && buf.st_size==0 ){ + *pResOut = 0; + } + } return SQLITE_OK; } @@ -26352,9 +29814,9 @@ static int unixAccess( /* ** Turn a relative pathname into a full pathname. The relative path ** is stored as a nul-terminated string in the buffer pointed to by -** zPath. +** zPath. ** -** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes +** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes ** (in this case, MAX_PATHNAME bytes). The full-path is written to ** this buffer before returning. */ @@ -26380,8 +29842,8 @@ static int unixFullPathname( sqlite3_snprintf(nOut, zOut, "%s", zPath); }else{ int nCwd; - if( getcwd(zOut, nOut-1)==0 ){ - return SQLITE_CANTOPEN_BKPT; + if( osGetcwd(zOut, nOut-1)==0 ){ + return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); } nCwd = (int)strlen(zOut); sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath); @@ -26409,7 +29871,7 @@ static void *unixDlOpen(sqlite3_vfs *NotUsed, const char *zFilename){ ** error message. */ static void unixDlError(sqlite3_vfs *NotUsed, int nBuf, char *zBufOut){ - char *zErr; + const char *zErr; UNUSED_PARAMETER(NotUsed); unixEnterMutex(); zErr = dlerror(); @@ -26419,7 +29881,7 @@ static void unixDlError(sqlite3_vfs *NotUsed, int nBuf, char *zBufOut){ unixLeaveMutex(); } static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){ - /* + /* ** GCC with -pedantic-errors says that C90 does not allow a void* to be ** cast into a pointer to a function. And yet the library dlsym() routine ** returns a void* which is really a pointer to a function. So how do we @@ -26429,7 +29891,7 @@ static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){ ** parameters void* and const char* and returning a pointer to a function. ** We initialize x by assigning it a pointer to the dlsym() function. ** (That assignment requires a cast.) Then we call the function that - ** x points to. + ** x points to. ** ** This work-around is unlikely to work correctly on any system where ** you really cannot cast a function pointer into void*. But then, on the @@ -26475,7 +29937,7 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ #if !defined(SQLITE_TEST) { int pid, fd; - fd = open("/dev/urandom", O_RDONLY); + fd = robust_open("/dev/urandom", O_RDONLY, 0); if( fd<0 ){ time_t t; time(&t); @@ -26485,8 +29947,8 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf ); nBuf = sizeof(t) + sizeof(pid); }else{ - nBuf = read(fd, zBuf, nBuf); - close(fd); + do{ nBuf = osRead(fd, zBuf, nBuf); }while( nBuf<0 && errno==EINTR ); + robust_close(0, fd, __LINE__); } } #endif @@ -26533,32 +29995,33 @@ SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1 #endif /* -** Find the current time (in Universal Coordinated Time). Write the -** current time and date as a Julian Day number into *prNow and -** return 0. Return 1 if the time and date cannot be found. +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return 0. Return 1 if the time and date cannot be found. */ -static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ -#if defined(SQLITE_OMIT_FLOATING_POINT) +static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){ + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; +#if defined(NO_GETTOD) time_t t; time(&t); - *prNow = (((sqlite3_int64)t)/8640 + 24405875)/10; -#elif defined(NO_GETTOD) - time_t t; - time(&t); - *prNow = t/86400.0 + 2440587.5; + *piNow = ((sqlite3_int64)t)*1000 + unixEpoch; #elif OS_VXWORKS struct timespec sNow; clock_gettime(CLOCK_REALTIME, &sNow); - *prNow = 2440587.5 + sNow.tv_sec/86400.0 + sNow.tv_nsec/86400000000000.0; + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000; #else struct timeval sNow; gettimeofday(&sNow, 0); - *prNow = 2440587.5 + sNow.tv_sec/86400.0 + sNow.tv_usec/86400000000.0; + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; #endif #ifdef SQLITE_TEST if( sqlite3_current_time ){ - *prNow = sqlite3_current_time/86400.0 + 2440587.5; + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; } #endif UNUSED_PARAMETER(NotUsed); @@ -26566,6 +30029,19 @@ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ } /* +** Find the current time (in Universal Coordinated Time). Write the +** current time and date as a Julian Day number into *prNow and +** return 0. Return 1 if the time and date cannot be found. +*/ +static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ + sqlite3_int64 i; + UNUSED_PARAMETER(NotUsed); + unixCurrentTimeInt64(0, &i); + *prNow = i/86400000.0; + return 0; +} + +/* ** We added the xGetLastError() method with the intention of providing ** better low-level error messages when operating-system problems come up ** during SQLite operation. But so far, none of that has been implemented @@ -26579,6 +30055,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ return 0; } + /* ************************ End of sqlite3_vfs methods *************************** ******************************************************************************/ @@ -26607,7 +30084,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ ** address in the shared range is taken for a SHARED lock, the entire ** shared range is taken for an EXCLUSIVE lock): ** -** PENDING_BYTE 0x40000000 +** PENDING_BYTE 0x40000000 ** RESERVED_BYTE 0x40000001 ** SHARED_RANGE 0x40000002 -> 0x40000200 ** @@ -26625,7 +30102,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ ** To address the performance and cache coherency issues, proxy file locking ** changes the way database access is controlled by limiting access to a ** single host at a time and moving file locks off of the database file -** and onto a proxy file on the local file system. +** and onto a proxy file on the local file system. ** ** ** Using proxy locks @@ -26650,19 +30127,19 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ ** actual proxy file name is generated from the name and path of the ** database file. For example: ** -** For database path "/Users/me/foo.db" +** For database path "/Users/me/foo.db" ** The lock path will be "<tmpdir>/sqliteplocks/_Users_me_foo.db:auto:") ** ** Once a lock proxy is configured for a database connection, it can not ** be removed, however it may be switched to a different proxy path via ** the above APIs (assuming the conch file is not being held by another -** connection or process). +** connection or process). ** ** ** How proxy locking works ** ----------------------- ** -** Proxy file locking relies primarily on two new supporting files: +** Proxy file locking relies primarily on two new supporting files: ** ** * conch file to limit access to the database file to a single host ** at a time @@ -26689,11 +30166,11 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ ** host (the conch ensures that they all use the same local lock file). ** ** Requesting the lock proxy does not immediately take the conch, it is -** only taken when the first request to lock database file is made. +** only taken when the first request to lock database file is made. ** This matches the semantics of the traditional locking behavior, where ** opening a connection to a database file does not take a lock on it. -** The shared lock and an open file descriptor are maintained until -** the connection to the database is closed. +** The shared lock and an open file descriptor are maintained until +** the connection to the database is closed. ** ** The proxy file and the lock file are never deleted so they only need ** to be created the first time they are used. @@ -26707,7 +30184,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ ** automatically configured for proxy locking, lock files are ** named automatically using the same logic as ** PRAGMA lock_proxy_file=":auto:" -** +** ** SQLITE_PROXY_DEBUG ** ** Enables the logging of error messages during host id file @@ -26722,8 +30199,8 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ ** ** Permissions to use when creating a directory for storing the ** lock proxy files, only used when LOCKPROXYDIR is not set. -** -** +** +** ** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING, ** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will ** force proxy locking to be used for every database file opened, and 0 @@ -26733,12 +30210,12 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ */ /* -** Proxy locking is only available on MacOSX +** Proxy locking is only available on MacOSX */ #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE /* -** The proxyLockingContext has the path and file structures for the remote +** The proxyLockingContext has the path and file structures for the remote ** and local proxy files in it */ typedef struct proxyLockingContext proxyLockingContext; @@ -26753,10 +30230,10 @@ struct proxyLockingContext { sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ }; -/* -** The proxy lock file path for the database at dbPath is written into lPath, +/* +** The proxy lock file path for the database at dbPath is written into lPath, ** which must point to valid, writable memory large enough for a maxLen length -** file path. +** file path. */ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ int len; @@ -26769,11 +30246,11 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ # ifdef _CS_DARWIN_USER_TEMP_DIR { if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){ - OSTRACE4("GETLOCKPATH failed %s errno=%d pid=%d\n", - lPath, errno, getpid()); + OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n", + lPath, errno, getpid())); return SQLITE_IOERR_LOCK; } - len = strlcat(lPath, "sqliteplocks", maxLen); + len = strlcat(lPath, "sqliteplocks", maxLen); } # else len = strlcpy(lPath, "/tmp/", maxLen); @@ -26783,27 +30260,27 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ if( lPath[len-1]!='/' ){ len = strlcat(lPath, "/", maxLen); } - + /* transform the db path to a unique cache name */ dbLen = (int)strlen(dbPath); - for( i=0; i<dbLen && (i+len+7)<maxLen; i++){ + for( i=0; i<dbLen && (i+len+7)<(int)maxLen; i++){ char c = dbPath[i]; lPath[i+len] = (c=='/')?'_':c; } lPath[i+len]='\0'; strlcat(lPath, ":auto:", maxLen); - OSTRACE3("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, getpid()); + OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, getpid())); return SQLITE_OK; } -/* +/* ** Creates the lock file and any missing directories in lockPath */ static int proxyCreateLockPath(const char *lockPath){ int i, len; char buf[MAXPATHLEN]; int start = 0; - + assert(lockPath!=NULL); /* try to create all the intermediate directories */ len = (int)strlen(lockPath); @@ -26811,15 +30288,15 @@ static int proxyCreateLockPath(const char *lockPath){ for( i=1; i<len; i++ ){ if( lockPath[i] == '/' && (i - start > 0) ){ /* only mkdir if leaf dir != "." or "/" or ".." */ - if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') + if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){ buf[i]='\0'; if( mkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){ int err=errno; if( err!=EEXIST ) { - OSTRACE5("CREATELOCKPATH FAILED creating %s, " + OSTRACE(("CREATELOCKPATH FAILED creating %s, " "'%s' proxy lock path=%s pid=%d\n", - buf, strerror(err), lockPath, getpid()); + buf, strerror(err), lockPath, getpid())); return err; } } @@ -26828,7 +30305,7 @@ static int proxyCreateLockPath(const char *lockPath){ } buf[i] = lockPath[i]; } - OSTRACE3("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, getpid()); + OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, getpid())); return 0; } @@ -26845,7 +30322,6 @@ static int proxyCreateUnixFile( int islockfile /* if non zero missing dirs will be created */ ) { int fd = -1; - int dirfd = -1; unixFile *pNew; int rc = SQLITE_OK; int openFlags = O_RDWR | O_CREAT; @@ -26869,17 +30345,17 @@ static int proxyCreateUnixFile( } } if( fd<0 ){ - fd = open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); terrno = errno; if( fd<0 && errno==ENOENT && islockfile ){ if( proxyCreateLockPath(path) == SQLITE_OK ){ - fd = open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); } } } if( fd<0 ){ openFlags = O_RDONLY; - fd = open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); terrno = errno; } if( fd<0 ){ @@ -26889,13 +30365,13 @@ static int proxyCreateUnixFile( switch (terrno) { case EACCES: return SQLITE_PERM; - case EIO: + case EIO: return SQLITE_IOERR_LOCK; /* even though it is the conch */ default: return SQLITE_CANTOPEN_BKPT; } } - + pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew)); if( pNew==NULL ){ rc = SQLITE_NOMEM; @@ -26903,18 +30379,20 @@ static int proxyCreateUnixFile( } memset(pNew, 0, sizeof(unixFile)); pNew->openFlags = openFlags; + memset(&dummyVfs, 0, sizeof(dummyVfs)); dummyVfs.pAppData = (void*)&autolockIoFinder; + dummyVfs.zName = "dummy"; pUnused->fd = fd; pUnused->flags = openFlags; pNew->pUnused = pUnused; - - rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0); + + rc = fillInUnixFile(&dummyVfs, fd, 0, (sqlite3_file*)pNew, path, 0, 0, 0); if( rc==SQLITE_OK ){ *ppFile = pNew; return SQLITE_OK; } -end_create_proxy: - close(fd); /* silently leak fd if error, we're already in error */ +end_create_proxy: + robust_close(pNew, fd, __LINE__); sqlite3_free(pNew); sqlite3_free(pUnused); return rc; @@ -26927,28 +30405,37 @@ SQLITE_API int sqlite3_hostid_num = 0; #define PROXY_HOSTIDLEN 16 /* conch file host id length */ -/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN +/* Not always defined in the headers as it ought to be */ +extern int gethostuuid(uuid_t id, const struct timespec *wait); + +/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN ** bytes of writable memory. */ static int proxyGetHostID(unsigned char *pHostID, int *pError){ - struct timespec timeout = {1, 0}; /* 1 sec timeout */ - assert(PROXY_HOSTIDLEN == sizeof(uuid_t)); memset(pHostID, 0, PROXY_HOSTIDLEN); - if( gethostuuid(pHostID, &timeout) ){ - int err = errno; - if( pError ){ - *pError = err; +#if defined(__MAX_OS_X_VERSION_MIN_REQUIRED)\ + && __MAC_OS_X_VERSION_MIN_REQUIRED<1050 + { + static const struct timespec timeout = {1, 0}; /* 1 sec timeout */ + if( gethostuuid(pHostID, &timeout) ){ + int err = errno; + if( pError ){ + *pError = err; + } + return SQLITE_IOERR; } - return SQLITE_IOERR; } +#else + UNUSED_PARAMETER(pError); +#endif #ifdef SQLITE_TEST /* simulate multiple hosts by creating unique hostid file paths */ if( sqlite3_hostid_num != 0){ pHostID[0] = (char)(pHostID[0] + (char)(sqlite3_hostid_num & 0xFF)); } #endif - + return SQLITE_OK; } @@ -26959,14 +30446,14 @@ static int proxyGetHostID(unsigned char *pHostID, int *pError){ #define PROXY_PATHINDEX (PROXY_HEADERLEN+PROXY_HOSTIDLEN) #define PROXY_MAXCONCHLEN (PROXY_HEADERLEN+PROXY_HOSTIDLEN+MAXPATHLEN) -/* -** Takes an open conch file, copies the contents to a new path and then moves +/* +** Takes an open conch file, copies the contents to a new path and then moves ** it back. The newly created file's file descriptor is assigned to the -** conch file structure and finally the original conch file descriptor is +** conch file structure and finally the original conch file descriptor is ** closed. Returns zero if successful. */ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ - proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; unixFile *conchFile = pCtx->conchFile; char tPath[MAXPATHLEN]; char buf[PROXY_MAXCONCHLEN]; @@ -26976,92 +30463,95 @@ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ char errmsg[64] = ""; int fd = -1; int rc = -1; + UNUSED_PARAMETER(myHostID); /* create a new path by replace the trailing '-conch' with '-break' */ pathLen = strlcpy(tPath, cPath, MAXPATHLEN); - if( pathLen>MAXPATHLEN || pathLen<6 || + if( pathLen>MAXPATHLEN || pathLen<6 || (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){ - sprintf(errmsg, "path error (len %d)", (int)pathLen); + sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen); goto end_breaklock; } /* read the conch content */ - readLen = pread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0); + readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0); if( readLen<PROXY_PATHINDEX ){ - sprintf(errmsg, "read error (len %d)", (int)readLen); + sqlite3_snprintf(sizeof(errmsg),errmsg,"read error (len %d)",(int)readLen); goto end_breaklock; } /* write it out to the temporary break file */ - fd = open(tPath, (O_RDWR|O_CREAT|O_EXCL), SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL), + SQLITE_DEFAULT_FILE_PERMISSIONS); if( fd<0 ){ - sprintf(errmsg, "create failed (%d)", errno); + sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno); goto end_breaklock; } - if( pwrite(fd, buf, readLen, 0) != readLen ){ - sprintf(errmsg, "write failed (%d)", errno); + if( osPwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){ + sqlite3_snprintf(sizeof(errmsg), errmsg, "write failed (%d)", errno); goto end_breaklock; } if( rename(tPath, cPath) ){ - sprintf(errmsg, "rename failed (%d)", errno); + sqlite3_snprintf(sizeof(errmsg), errmsg, "rename failed (%d)", errno); goto end_breaklock; } rc = 0; fprintf(stderr, "broke stale lock on %s\n", cPath); - close(conchFile->h); + robust_close(pFile, conchFile->h, __LINE__); conchFile->h = fd; conchFile->openFlags = O_RDWR | O_CREAT; end_breaklock: if( rc ){ if( fd>=0 ){ - unlink(tPath); - close(fd); + osUnlink(tPath); + robust_close(pFile, fd, __LINE__); } fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg); } return rc; } -/* Take the requested lock on the conch file and break a stale lock if the +/* Take the requested lock on the conch file and break a stale lock if the ** host id matches. */ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ - proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; unixFile *conchFile = pCtx->conchFile; int rc = SQLITE_OK; int nTries = 0; struct timespec conchModTime; - + + memset(&conchModTime, 0, sizeof(conchModTime)); do { rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); nTries ++; if( rc==SQLITE_BUSY ){ /* If the lock failed (busy): - * 1st try: get the mod time of the conch, wait 0.5s and try again. - * 2nd try: fail if the mod time changed or host id is different, wait + * 1st try: get the mod time of the conch, wait 0.5s and try again. + * 2nd try: fail if the mod time changed or host id is different, wait * 10 sec and try again * 3rd try: break the lock unless the mod time has changed. */ struct stat buf; - if( fstat(conchFile->h, &buf) ){ + if( osFstat(conchFile->h, &buf) ){ pFile->lastErrno = errno; return SQLITE_IOERR_LOCK; } - + if( nTries==1 ){ conchModTime = buf.st_mtimespec; usleep(500000); /* wait 0.5 sec and try the lock again*/ - continue; + continue; } assert( nTries>1 ); - if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || + if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){ return SQLITE_BUSY; } - - if( nTries==2 ){ + + if( nTries==2 ){ char tBuf[PROXY_MAXCONCHLEN]; - int len = pread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); + int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); if( len<0 ){ pFile->lastErrno = errno; return SQLITE_IOERR_LOCK; @@ -27076,14 +30566,14 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ return SQLITE_BUSY; } usleep(10000000); /* wait 10 sec and try the lock again */ - continue; + continue; } - + assert( nTries==3 ); if( 0==proxyBreakConchLock(pFile, myHostID) ){ rc = SQLITE_OK; if( lockType==EXCLUSIVE_LOCK ){ - rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK); + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK); } if( !rc ){ rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); @@ -27091,19 +30581,19 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ } } } while( rc==SQLITE_BUSY && nTries<3 ); - + return rc; } -/* Takes the conch by taking a shared lock and read the contents conch, if -** lockPath is non-NULL, the host ID and lock file path must match. A NULL -** lockPath means that the lockPath in the conch file will be used if the -** host IDs match, or a new lock path will be generated automatically +/* Takes the conch by taking a shared lock and read the contents conch, if +** lockPath is non-NULL, the host ID and lock file path must match. A NULL +** lockPath means that the lockPath in the conch file will be used if the +** host IDs match, or a new lock path will be generated automatically ** and written to the conch file. */ static int proxyTakeConch(unixFile *pFile){ - proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; - + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld!=0 ){ return SQLITE_OK; }else{ @@ -27119,9 +30609,9 @@ static int proxyTakeConch(unixFile *pFile){ int readLen = 0; int tryOldLockPath = 0; int forceNewLockPath = 0; - - OSTRACE4("TAKECONCH %d for %s pid=%d\n", conchFile->h, - (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid()); + + OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h, + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid())); rc = proxyGetHostID(myHostID, &pError); if( (rc&0xff)==SQLITE_IOERR ){ @@ -27139,21 +30629,21 @@ static int proxyTakeConch(unixFile *pFile){ pFile->lastErrno = conchFile->lastErrno; rc = SQLITE_IOERR_READ; goto end_takeconch; - }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || + }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || readBuf[0]!=(char)PROXY_CONCHVERSION ){ - /* a short read or version format mismatch means we need to create a new - ** conch file. + /* a short read or version format mismatch means we need to create a new + ** conch file. */ createConch = 1; } /* if the host id matches and the lock path already exists in the conch - ** we'll try to use the path there, if we can't open that path, we'll - ** retry with a new auto-generated path + ** we'll try to use the path there, if we can't open that path, we'll + ** retry with a new auto-generated path */ do { /* in case we need to try again for an :auto: named lock file */ if( !createConch && !forceNewLockPath ){ - hostIdMatch = !memcmp(&readBuf[PROXY_HEADERLEN], myHostID, + hostIdMatch = !memcmp(&readBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); /* if the conch has data compare the contents */ if( !pCtx->lockProxyPath ){ @@ -27162,7 +30652,7 @@ static int proxyTakeConch(unixFile *pFile){ */ if( hostIdMatch ){ size_t pathLen = (readLen - PROXY_PATHINDEX); - + if( pathLen>=MAXPATHLEN ){ pathLen=MAXPATHLEN-1; } @@ -27178,34 +30668,34 @@ static int proxyTakeConch(unixFile *pFile){ readLen-PROXY_PATHINDEX) ){ /* conch host and lock path match */ - goto end_takeconch; + goto end_takeconch; } } - + /* if the conch isn't writable and doesn't match, we can't take it */ if( (conchFile->openFlags&O_RDWR) == 0 ){ rc = SQLITE_BUSY; goto end_takeconch; } - + /* either the conch didn't match or we need to create a new one */ if( !pCtx->lockProxyPath ){ proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN); tempLockPath = lockPath; /* create a copy of the lock path _only_ if the conch is taken */ } - + /* update conch with host and path (this will fail if other process ** has a shared lock already), if the host id matches, use the big ** stick. */ futimes(conchFile->h, NULL); if( hostIdMatch && !createConch ){ - if( conchFile->pLock && conchFile->pLock->cnt>1 ){ + if( conchFile->pInode && conchFile->pInode->nShared>1 ){ /* We are trying for an exclusive lock but another thread in this ** same process is still holding a shared lock. */ rc = SQLITE_BUSY; - } else { + } else { rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); } }else{ @@ -27214,7 +30704,7 @@ static int proxyTakeConch(unixFile *pFile){ if( rc==SQLITE_OK ){ char writeBuffer[PROXY_MAXCONCHLEN]; int writeSize = 0; - + writeBuffer[0] = (char)PROXY_CONCHVERSION; memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); if( pCtx->lockProxyPath!=NULL ){ @@ -27223,23 +30713,26 @@ static int proxyTakeConch(unixFile *pFile){ strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN); } writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); - ftruncate(conchFile->h, writeSize); + robust_ftruncate(conchFile->h, writeSize); rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); fsync(conchFile->h); - /* If we created a new conch file (not just updated the contents of a - ** valid conch file), try to match the permissions of the database + /* If we created a new conch file (not just updated the contents of a + ** valid conch file), try to match the permissions of the database */ if( rc==SQLITE_OK && createConch ){ struct stat buf; - int err = fstat(pFile->h, &buf); + int err = osFstat(pFile->h, &buf); if( err==0 ){ mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | S_IROTH|S_IWOTH); /* try to match the database file R/W permissions, ignore failure */ #ifndef SQLITE_PROXY_DEBUG - fchmod(conchFile->h, cmode); + osFchmod(conchFile->h, cmode); #else - if( fchmod(conchFile->h, cmode)!=0 ){ + do{ + rc = osFchmod(conchFile->h, cmode); + }while( rc==(-1) && errno==EINTR ); + if( rc!=0 ){ int code = errno; fprintf(stderr, "fchmod %o FAILED with %d %s\n", cmode, code, strerror(code)); @@ -27248,31 +30741,25 @@ static int proxyTakeConch(unixFile *pFile){ } }else{ int code = errno; - fprintf(stderr, "STAT FAILED[%d] with %d %s\n", + fprintf(stderr, "STAT FAILED[%d] with %d %s\n", err, code, strerror(code)); #endif } } } conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK); - + end_takeconch: - OSTRACE2("TRANSPROXY: CLOSE %d\n", pFile->h); + OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h)); if( rc==SQLITE_OK && pFile->openFlags ){ + int fd; if( pFile->h>=0 ){ -#ifdef STRICT_CLOSE_ERROR - if( close(pFile->h) ){ - pFile->lastErrno = errno; - return SQLITE_IOERR_CLOSE; - } -#else - close(pFile->h); /* silently leak fd if fail */ -#endif + robust_close(pFile, pFile->h, __LINE__); } pFile->h = -1; - int fd = open(pCtx->dbPath, pFile->openFlags, + fd = robust_open(pCtx->dbPath, pFile->openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); - OSTRACE2("TRANSPROXY: OPEN %d\n", fd); + OSTRACE(("TRANSPROXY: OPEN %d\n", fd)); if( fd>=0 ){ pFile->h = fd; }else{ @@ -27285,7 +30772,7 @@ static int proxyTakeConch(unixFile *pFile){ rc = proxyCreateUnixFile(path, &pCtx->lockProxy, 1); if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && tryOldLockPath ){ /* we couldn't create the proxy lock file with the old lock file path - ** so try again via auto-naming + ** so try again via auto-naming */ forceNewLockPath = 1; tryOldLockPath = 0; @@ -27305,7 +30792,7 @@ static int proxyTakeConch(unixFile *pFile){ } if( rc==SQLITE_OK ){ pCtx->conchHeld = 1; - + if( pCtx->lockProxy->pMethod == &afpIoMethods ){ afpLockingContext *afpCtx; afpCtx = (afpLockingContext *)pCtx->lockProxy->lockingContext; @@ -27314,9 +30801,11 @@ static int proxyTakeConch(unixFile *pFile){ } else { conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); } - OSTRACE3("TAKECONCH %d %s\n", conchFile->h, rc==SQLITE_OK?"ok":"failed"); + OSTRACE(("TAKECONCH %d %s\n", conchFile->h, + rc==SQLITE_OK?"ok":"failed")); return rc; - } while (1); /* in case we need to retry the :auto: lock file - we should never get here except via the 'continue' call. */ + } while (1); /* in case we need to retry the :auto: lock file - + ** we should never get here except via the 'continue' call. */ } } @@ -27324,21 +30813,21 @@ static int proxyTakeConch(unixFile *pFile){ ** If pFile holds a lock on a conch file, then release that lock. */ static int proxyReleaseConch(unixFile *pFile){ - int rc; /* Subroutine return code */ + int rc = SQLITE_OK; /* Subroutine return code */ proxyLockingContext *pCtx; /* The locking context for the proxy lock */ unixFile *conchFile; /* Name of the conch file */ pCtx = (proxyLockingContext *)pFile->lockingContext; conchFile = pCtx->conchFile; - OSTRACE4("RELEASECONCH %d for %s pid=%d\n", conchFile->h, - (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), - getpid()); + OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h, + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), + getpid())); if( pCtx->conchHeld>0 ){ rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); } pCtx->conchHeld = 0; - OSTRACE3("RELEASECONCH %d %s\n", conchFile->h, - (rc==SQLITE_OK ? "ok" : "failed")); + OSTRACE(("RELEASECONCH %d %s\n", conchFile->h, + (rc==SQLITE_OK ? "ok" : "failed"))); return rc; } @@ -27359,13 +30848,13 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){ char *conchPath; /* buffer in which to construct conch name */ /* Allocate space for the conch filename and initialize the name to - ** the name of the original database file. */ + ** the name of the original database file. */ *pConchPath = conchPath = (char *)sqlite3_malloc(len + 8); if( conchPath==0 ){ return SQLITE_NOMEM; } memcpy(conchPath, dbPath, len+1); - + /* now insert a "." before the last / character */ for( i=(len-1); i>=0; i-- ){ if( conchPath[i]=='/' ){ @@ -27388,16 +30877,16 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){ /* Takes a fully configured proxy locking-style unix file and switches -** the local lock file path +** the local lock file path */ static int switchLockProxyPath(unixFile *pFile, const char *path) { proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; char *oldPath = pCtx->lockProxyPath; int rc = SQLITE_OK; - if( pFile->locktype!=NO_LOCK ){ + if( pFile->eFileLock!=NO_LOCK ){ return SQLITE_BUSY; - } + } /* nothing to do if the path is NULL, :auto: or matches the existing path */ if( !path || path[0]=='\0' || !strcmp(path, ":auto:") || @@ -27415,7 +30904,7 @@ static int switchLockProxyPath(unixFile *pFile, const char *path) { sqlite3_free(oldPath); pCtx->lockProxyPath = sqlite3DbStrDup(0, path); } - + return rc; } @@ -27429,7 +30918,7 @@ static int switchLockProxyPath(unixFile *pFile, const char *path) { static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){ #if defined(__APPLE__) if( pFile->pMethod == &afpIoMethods ){ - /* afp style keeps a reference to the db path in the filePath field + /* afp style keeps a reference to the db path in the filePath field ** of the struct */ assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, MAXPATHLEN); @@ -27449,9 +30938,9 @@ static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){ } /* -** Takes an already filled in unix file and alters it so all file locking +** Takes an already filled in unix file and alters it so all file locking ** will be performed on the local proxy lock file. The following fields -** are preserved in the locking context so that they can be restored and +** are preserved in the locking context so that they can be restored and ** the unix structure properly cleaned up at close time: ** ->lockingContext ** ->pMethod @@ -27461,8 +30950,8 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { char dbPath[MAXPATHLEN+1]; /* Name of the database file */ char *lockPath=NULL; int rc = SQLITE_OK; - - if( pFile->locktype!=NO_LOCK ){ + + if( pFile->eFileLock!=NO_LOCK ){ return SQLITE_BUSY; } proxyGetDbPathForUnixFile(pFile, dbPath); @@ -27471,9 +30960,9 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { }else{ lockPath=(char *)path; } - - OSTRACE4("TRANSPROXY %d for %s pid=%d\n", pFile->h, - (lockPath ? lockPath : ":auto:"), getpid()); + + OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h, + (lockPath ? lockPath : ":auto:"), getpid())); pCtx = sqlite3_malloc( sizeof(*pCtx) ); if( pCtx==0 ){ @@ -27494,7 +30983,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { struct stat conchInfo; int goLockless = 0; - if( stat(pCtx->conchFilePath, &conchInfo) == -1 ) { + if( osStat(pCtx->conchFilePath, &conchInfo) == -1 ) { int err = errno; if( (err==ENOENT) && (statfs(dbPath, &fsInfo) != -1) ){ goLockless = (fsInfo.f_flags&MNT_RDONLY) == MNT_RDONLY; @@ -27505,7 +30994,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { rc = SQLITE_OK; } } - } + } if( rc==SQLITE_OK && lockPath ){ pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath); } @@ -27517,7 +31006,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { } } if( rc==SQLITE_OK ){ - /* all memory is allocated, proxys are created and assigned, + /* all memory is allocated, proxys are created and assigned, ** switch the locking context and pMethod then return. */ pCtx->oldLockingContext = pFile->lockingContext; @@ -27525,16 +31014,16 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { pCtx->pOldMethod = pFile->pMethod; pFile->pMethod = &proxyIoMethods; }else{ - if( pCtx->conchFile ){ + if( pCtx->conchFile ){ pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile); sqlite3_free(pCtx->conchFile); } - sqlite3_free(pCtx->lockProxyPath); - sqlite3_free(pCtx->conchFilePath); + sqlite3DbFree(0, pCtx->lockProxyPath); + sqlite3_free(pCtx->conchFilePath); sqlite3_free(pCtx); } - OSTRACE3("TRANSPROXY %d %s\n", pFile->h, - (rc==SQLITE_OK ? "ok" : "failed")); + OSTRACE(("TRANSPROXY %d %s\n", pFile->h, + (rc==SQLITE_OK ? "ok" : "failed"))); return rc; } @@ -27575,9 +31064,9 @@ static int proxyFileControl(sqlite3_file *id, int op, void *pArg){ }else{ const char *proxyPath = (const char *)pArg; if( isProxyStyle ){ - proxyLockingContext *pCtx = + proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; - if( !strcmp(pArg, ":auto:") + if( !strcmp(pArg, ":auto:") || (pCtx->lockProxyPath && !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN)) ){ @@ -27629,7 +31118,7 @@ static int proxyCheckReservedLock(sqlite3_file *id, int *pResOut) { } /* -** Lock the file with the lock specified by parameter locktype - one +** Lock the file with the lock specified by parameter eFileLock - one ** of the following: ** ** (1) SHARED_LOCK @@ -27652,15 +31141,15 @@ static int proxyCheckReservedLock(sqlite3_file *id, int *pResOut) { ** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. */ -static int proxyLock(sqlite3_file *id, int locktype) { +static int proxyLock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; int rc = proxyTakeConch(pFile); if( rc==SQLITE_OK ){ proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; if( pCtx->conchHeld>0 ){ unixFile *proxy = pCtx->lockProxy; - rc = proxy->pMethod->xLock((sqlite3_file*)proxy, locktype); - pFile->locktype = proxy->locktype; + rc = proxy->pMethod->xLock((sqlite3_file*)proxy, eFileLock); + pFile->eFileLock = proxy->eFileLock; }else{ /* conchHeld < 0 is lockless */ } @@ -27670,21 +31159,21 @@ static int proxyLock(sqlite3_file *id, int locktype) { /* -** Lower the locking level on file descriptor pFile to locktype. locktype +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int proxyUnlock(sqlite3_file *id, int locktype) { +static int proxyUnlock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; int rc = proxyTakeConch(pFile); if( rc==SQLITE_OK ){ proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; if( pCtx->conchHeld>0 ){ unixFile *proxy = pCtx->lockProxy; - rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, locktype); - pFile->locktype = proxy->locktype; + rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, eFileLock); + pFile->eFileLock = proxy->eFileLock; }else{ /* conchHeld < 0 is lockless */ } @@ -27702,7 +31191,7 @@ static int proxyClose(sqlite3_file *id) { unixFile *lockProxy = pCtx->lockProxy; unixFile *conchFile = pCtx->conchFile; int rc = SQLITE_OK; - + if( lockProxy ){ rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK); if( rc ) return rc; @@ -27720,9 +31209,9 @@ static int proxyClose(sqlite3_file *id) { if( rc ) return rc; sqlite3_free(conchFile); } - sqlite3_free(pCtx->lockProxyPath); + sqlite3DbFree(0, pCtx->lockProxyPath); sqlite3_free(pCtx->conchFilePath); - sqlite3_free(pCtx->dbPath); + sqlite3DbFree(0, pCtx->dbPath); /* restore the original locking context and pMethod then close it */ pFile->lockingContext = pCtx->oldLockingContext; pFile->pMethod = pCtx->pOldMethod; @@ -27739,7 +31228,7 @@ static int proxyClose(sqlite3_file *id) { ** The proxy locking style is intended for use with AFP filesystems. ** And since AFP is only supported on MacOSX, the proxy locking is also ** restricted to MacOSX. -** +** ** ******************* End of the proxy lock implementation ********************** ******************************************************************************/ @@ -27757,8 +31246,8 @@ static int proxyClose(sqlite3_file *id) { ** necessarily been initialized when this routine is called, and so they ** should not be used. */ -SQLITE_API int sqlite3_os_init(void){ - /* +SQLITE_API int sqlite3_os_init(void){ + /* ** The following macro defines an initializer for an sqlite3_vfs object. ** The name of the VFS is NAME. The pAppData is a pointer to a pointer ** to the "finder" function. (pAppData is a pointer to a pointer because @@ -27774,12 +31263,12 @@ SQLITE_API int sqlite3_os_init(void){ ** ** Most finders simply return a pointer to a fixed sqlite3_io_methods ** object. But the "autolockIoFinder" available on MacOSX does a little - ** more than that; it looks at the filesystem type that hosts the + ** more than that; it looks at the filesystem type that hosts the ** database file and tries to choose an locking method appropriate for ** that filesystem time. */ #define UNIXVFS(VFSNAME, FINDER) { \ - 1, /* iVersion */ \ + 3, /* iVersion */ \ sizeof(unixFile), /* szOsFile */ \ MAX_PATHNAME, /* mxPathname */ \ 0, /* pNext */ \ @@ -27796,7 +31285,11 @@ SQLITE_API int sqlite3_os_init(void){ unixRandomness, /* xRandomness */ \ unixSleep, /* xSleep */ \ unixCurrentTime, /* xCurrentTime */ \ - unixGetLastError /* xGetLastError */ \ + unixGetLastError, /* xGetLastError */ \ + unixCurrentTimeInt64, /* xCurrentTimeInt64 */ \ + unixSetSystemCall, /* xSetSystemCall */ \ + unixGetSystemCall, /* xGetSystemCall */ \ + unixNextSystemCall, /* xNextSystemCall */ \ } /* @@ -27814,6 +31307,7 @@ SQLITE_API int sqlite3_os_init(void){ #endif UNIXVFS("unix-none", nolockIoFinder ), UNIXVFS("unix-dotfile", dotlockIoFinder ), + UNIXVFS("unix-excl", posixIoFinder ), #if OS_VXWORKS UNIXVFS("unix-namedsem", semIoFinder ), #endif @@ -27831,11 +31325,15 @@ SQLITE_API int sqlite3_os_init(void){ }; unsigned int i; /* Loop counter */ + /* Double-check that the aSyscall[] array has been constructed + ** correctly. See ticket [bb3a86e890c8e96ab] */ + assert( ArraySize(aSyscall)==18 ); + /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ sqlite3_vfs_register(&aVfs[i], i==0); } - return SQLITE_OK; + return SQLITE_OK; } /* @@ -27845,10 +31343,10 @@ SQLITE_API int sqlite3_os_init(void){ ** to release dynamically allocated objects. But not on unix. ** This routine is a no-op for unix. */ -SQLITE_API int sqlite3_os_end(void){ - return SQLITE_OK; +SQLITE_API int sqlite3_os_end(void){ + return SQLITE_OK; } - + #endif /* SQLITE_OS_UNIX */ /************** End of os_unix.c *********************************************/ @@ -27945,25 +31443,14 @@ SQLITE_API int sqlite3_os_end(void){ # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." #endif -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE int sqlite3OSTrace = 0; -#define OSTRACE1(X) if( sqlite3OSTrace ) sqlite3DebugPrintf(X) -#define OSTRACE2(X,Y) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y) -#define OSTRACE3(X,Y,Z) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z) -#define OSTRACE4(X,Y,Z,A) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A) -#define OSTRACE5(X,Y,Z,A,B) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A,B) -#define OSTRACE6(X,Y,Z,A,B,C) \ - if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C) -#define OSTRACE7(X,Y,Z,A,B,C,D) \ - if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D) +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +# ifndef SQLITE_DEBUG_OS_TRACE +# define SQLITE_DEBUG_OS_TRACE 0 +# endif + int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; +# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X #else -#define OSTRACE1(X) -#define OSTRACE2(X,Y) -#define OSTRACE3(X,Y,Z) -#define OSTRACE4(X,Y,Z,A) -#define OSTRACE5(X,Y,Z,A,B) -#define OSTRACE6(X,Y,Z,A,B,C) -#define OSTRACE7(X,Y,Z,A,B,C,D) +# define OSTRACE(X) #endif /* @@ -27972,8 +31459,8 @@ SQLITE_PRIVATE int sqlite3OSTrace = 0; */ #ifdef SQLITE_PERFORMANCE_TRACE -/* -** hwtime.h contains inline assembler code for implementing +/* +** hwtime.h contains inline assembler code for implementing ** high-performance timing routines. */ /************** Include hwtime.h in the middle of os_common.h ****************/ @@ -28031,7 +31518,7 @@ SQLITE_PRIVATE int sqlite3OSTrace = 0; __asm__ __volatile__ ("rdtsc" : "=A" (val)); return val; } - + #elif (defined(__GNUC__) && defined(__ppc__)) __inline__ sqlite_uint64 sqlite3Hwtime(void){ @@ -28137,7 +31624,7 @@ SQLITE_API int sqlite3_open_file_count = 0; ** Some microsoft compilers lack this definition. */ #ifndef INVALID_FILE_ATTRIBUTES -# define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +# define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif /* @@ -28149,6 +31636,10 @@ SQLITE_API int sqlite3_open_file_count = 0; # define FormatMessageW(a,b,c,d,e,f,g) 0 #endif +/* Forward references */ +typedef struct winShm winShm; /* A connection to shared-memory */ +typedef struct winShmNode winShmNode; /* A region of shared-memory */ + /* ** WinCE lacks native support for file locking so we have to fake it ** with some code of our own. @@ -28168,15 +31659,20 @@ typedef struct winceLock { */ typedef struct winFile winFile; struct winFile { - const sqlite3_io_methods *pMethod;/* Must be first */ + const sqlite3_io_methods *pMethod; /*** Must be first ***/ + sqlite3_vfs *pVfs; /* The VFS used to open this file */ HANDLE h; /* Handle for accessing the file */ - unsigned char locktype; /* Type of lock currently held on this file */ + u8 locktype; /* Type of lock currently held on this file */ short sharedLockByte; /* Randomly chosen byte used as a shared lock */ + u8 bPersistWal; /* True to persist WAL files */ DWORD lastErrno; /* The Windows errno from the last I/O error */ DWORD sectorSize; /* Sector size of the device file is on */ + winShm *pShm; /* Instance of shared memory on this file */ + const char *zPath; /* Full pathname of this file */ + int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ #if SQLITE_OS_WINCE WCHAR *zDeleteOnClose; /* Name of file to delete when closing */ - HANDLE hMutex; /* Mutex used to control access to shared lock */ + HANDLE hMutex; /* Mutex used to control access to shared lock */ HANDLE hShared; /* Shared memory segment used for locking */ winceLock local; /* Locks obtained by this instance of winFile */ winceLock *shared; /* Global shared lock memory for the file */ @@ -28184,6 +31680,77 @@ struct winFile { }; /* + * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the + * various Win32 API heap functions instead of our own. + */ +#ifdef SQLITE_WIN32_MALLOC +/* + * The initial size of the Win32-specific heap. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_INIT_SIZE +# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \ + (SQLITE_DEFAULT_PAGE_SIZE) + 4194304) +#endif + +/* + * The maximum size of the Win32-specific heap. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_MAX_SIZE +# define SQLITE_WIN32_HEAP_MAX_SIZE (0) +#endif + +/* + * The extra flags to use in calls to the Win32 heap APIs. This value may be + * zero for the default behavior. + */ +#ifndef SQLITE_WIN32_HEAP_FLAGS +# define SQLITE_WIN32_HEAP_FLAGS (0) +#endif + +/* +** The winMemData structure stores information required by the Win32-specific +** sqlite3_mem_methods implementation. +*/ +typedef struct winMemData winMemData; +struct winMemData { +#ifndef NDEBUG + u32 magic; /* Magic number to detect structure corruption. */ +#endif + HANDLE hHeap; /* The handle to our heap. */ + BOOL bOwned; /* Do we own the heap (i.e. destroy it on shutdown)? */ +}; + +#ifndef NDEBUG +#define WINMEM_MAGIC 0x42b2830b +#endif + +static struct winMemData win_mem_data = { +#ifndef NDEBUG + WINMEM_MAGIC, +#endif + NULL, FALSE +}; + +#ifndef NDEBUG +#define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC ) +#else +#define winMemAssertMagic() +#endif + +#define winMemGetHeap() win_mem_data.hHeap + +static void *winMemMalloc(int nBytes); +static void winMemFree(void *pPrior); +static void *winMemRealloc(void *pPrior, int nBytes); +static int winMemSize(void *p); +static int winMemRoundup(int n); +static int winMemInit(void *pAppData); +static void winMemShutdown(void *pAppData); + +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void); +#endif /* SQLITE_WIN32_MALLOC */ + +/* ** Forward prototypes. */ static int getSectorSize( @@ -28234,8 +31801,190 @@ static int sqlite3_os_type = 0; } #endif /* SQLITE_OS_WINCE */ +#ifdef SQLITE_WIN32_MALLOC +/* +** Allocate nBytes of memory. +*/ +static void *winMemMalloc(int nBytes){ + HANDLE hHeap; + void *p; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + assert( nBytes>=0 ); + p = HeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + if( !p ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p", + nBytes, GetLastError(), (void*)hHeap); + } + return p; +} + +/* +** Free memory. +*/ +static void winMemFree(void *pPrior){ + HANDLE hHeap; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); +#endif + if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */ + if( !HeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p", + pPrior, GetLastError(), (void*)hHeap); + } +} + +/* +** Change the size of an existing memory allocation +*/ +static void *winMemRealloc(void *pPrior, int nBytes){ + HANDLE hHeap; + void *p; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); +#endif + assert( nBytes>=0 ); + if( !pPrior ){ + p = HeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + }else{ + p = HeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes); + } + if( !p ){ + sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%d), heap=%p", + pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, GetLastError(), + (void*)hHeap); + } + return p; +} + +/* +** Return the size of an outstanding allocation, in bytes. +*/ +static int winMemSize(void *p){ + HANDLE hHeap; + SIZE_T n; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + if( !p ) return 0; + n = HeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p); + if( n==(SIZE_T)-1 ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p", + p, GetLastError(), (void*)hHeap); + return 0; + } + return (int)n; +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int winMemRoundup(int n){ + return n; +} + +/* +** Initialize this module. +*/ +static int winMemInit(void *pAppData){ + winMemData *pWinMemData = (winMemData *)pAppData; + + if( !pWinMemData ) return SQLITE_ERROR; + assert( pWinMemData->magic==WINMEM_MAGIC ); + if( !pWinMemData->hHeap ){ + pWinMemData->hHeap = HeapCreate(SQLITE_WIN32_HEAP_FLAGS, + SQLITE_WIN32_HEAP_INIT_SIZE, + SQLITE_WIN32_HEAP_MAX_SIZE); + if( !pWinMemData->hHeap ){ + sqlite3_log(SQLITE_NOMEM, + "failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u", + GetLastError(), SQLITE_WIN32_HEAP_FLAGS, SQLITE_WIN32_HEAP_INIT_SIZE, + SQLITE_WIN32_HEAP_MAX_SIZE); + return SQLITE_NOMEM; + } + pWinMemData->bOwned = TRUE; + } + assert( pWinMemData->hHeap!=0 ); + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert( HeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + return SQLITE_OK; +} + /* -** Convert a UTF-8 string to microsoft unicode (UTF-16?). +** Deinitialize this module. +*/ +static void winMemShutdown(void *pAppData){ + winMemData *pWinMemData = (winMemData *)pAppData; + + if( !pWinMemData ) return; + if( pWinMemData->hHeap ){ + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert( HeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + if( pWinMemData->bOwned ){ + if( !HeapDestroy(pWinMemData->hHeap) ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p", + GetLastError(), (void*)pWinMemData->hHeap); + } + pWinMemData->bOwned = FALSE; + } + pWinMemData->hHeap = NULL; + } +} + +/* +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. The +** arguments specify the block of memory to manage. +** +** This routine is only called by sqlite3_config(), and therefore +** is not required to be threadsafe (it is not). +*/ +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void){ + static const sqlite3_mem_methods winMemMethods = { + winMemMalloc, + winMemFree, + winMemRealloc, + winMemSize, + winMemRoundup, + winMemInit, + winMemShutdown, + &win_mem_data + }; + return &winMemMethods; +} + +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32()); +} +#endif /* SQLITE_WIN32_MALLOC */ + +/* +** Convert a UTF-8 string to microsoft unicode (UTF-16?). ** ** Space to hold the returned string is obtained from malloc. */ @@ -28281,7 +32030,7 @@ static char *unicodeToUtf8(const WCHAR *zWideFilename){ /* ** Convert an ansi string to microsoft unicode, based on the ** current codepage settings for file apis. -** +** ** Space to hold the returned string is obtained ** from malloc. */ @@ -28347,10 +32096,10 @@ SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ } /* -** Convert UTF-8 to multibyte character string. Space to hold the +** Convert UTF-8 to multibyte character string. Space to hold the ** returned string is obtained from malloc(). */ -static char *utf8ToMbcs(const char *zFilename){ +SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ char *zFilenameMbcs; WCHAR *zTmpWide; @@ -28363,6 +32112,157 @@ static char *utf8ToMbcs(const char *zFilename){ return zFilenameMbcs; } + +/* +** The return value of getLastErrorMsg +** is zero if the error message fits in the buffer, or non-zero +** otherwise (if the message was truncated). +*/ +static int getLastErrorMsg(int nBuf, char *zBuf){ + /* FormatMessage returns 0 on failure. Otherwise it + ** returns the number of TCHARs written to the output + ** buffer, excluding the terminating null char. + */ + DWORD error = GetLastError(); + DWORD dwLen = 0; + char *zOut = 0; + + if( isNT() ){ + WCHAR *zTempWide = NULL; + dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + error, + 0, + (LPWSTR) &zTempWide, + 0, + 0); + if( dwLen > 0 ){ + /* allocate a buffer and convert to UTF8 */ + zOut = unicodeToUtf8(zTempWide); + /* free the system buffer allocated by FormatMessage */ + LocalFree(zTempWide); + } +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +** Since the ASCII version of these Windows API do not exist for WINCE, +** it's important to not reference them for WINCE builds. +*/ +#if SQLITE_OS_WINCE==0 + }else{ + char *zTemp = NULL; + dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + error, + 0, + (LPSTR) &zTemp, + 0, + 0); + if( dwLen > 0 ){ + /* allocate a buffer and convert to UTF8 */ + zOut = sqlite3_win32_mbcs_to_utf8(zTemp); + /* free the system buffer allocated by FormatMessage */ + LocalFree(zTemp); + } +#endif + } + if( 0 == dwLen ){ + sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error); + }else{ + /* copy a maximum of nBuf chars to output buffer */ + sqlite3_snprintf(nBuf, zBuf, "%s", zOut); + /* free the UTF8 buffer */ + free(zOut); + } + return 0; +} + +/* +** +** This function - winLogErrorAtLine() - is only ever called via the macro +** winLogError(). +** +** This routine is invoked after an error occurs in an OS function. +** It logs a message using sqlite3_log() containing the current value of +** error code and, if possible, the human-readable equivalent from +** FormatMessage. +** +** The first argument passed to the macro should be the error code that +** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). +** The two subsequent arguments should be the name of the OS function that +** failed and the the associated file-system path, if any. +*/ +#define winLogError(a,b,c) winLogErrorAtLine(a,b,c,__LINE__) +static int winLogErrorAtLine( + int errcode, /* SQLite error code */ + const char *zFunc, /* Name of OS function that failed */ + const char *zPath, /* File path associated with error */ + int iLine /* Source line number where error occurred */ +){ + char zMsg[500]; /* Human readable error text */ + int i; /* Loop counter */ + DWORD iErrno = GetLastError(); /* Error code */ + + zMsg[0] = 0; + getLastErrorMsg(sizeof(zMsg), zMsg); + assert( errcode!=SQLITE_OK ); + if( zPath==0 ) zPath = ""; + for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} + zMsg[i] = 0; + sqlite3_log(errcode, + "os_win.c:%d: (%d) %s(%s) - %s", + iLine, iErrno, zFunc, zPath, zMsg + ); + + return errcode; +} + +/* +** The number of times that a ReadFile(), WriteFile(), and DeleteFile() +** will be retried following a locking error - probably caused by +** antivirus software. Also the initial delay before the first retry. +** The delay increases linearly with each retry. +*/ +#ifndef SQLITE_WIN32_IOERR_RETRY +# define SQLITE_WIN32_IOERR_RETRY 10 +#endif +#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY +# define SQLITE_WIN32_IOERR_RETRY_DELAY 25 +#endif +static int win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY; +static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; + +/* +** If a ReadFile() or WriteFile() error occurs, invoke this routine +** to see if it should be retried. Return TRUE to retry. Return FALSE +** to give up with an error. +*/ +static int retryIoerr(int *pnRetry){ + DWORD e; + if( *pnRetry>=win32IoerrRetry ){ + return 0; + } + e = GetLastError(); + if( e==ERROR_ACCESS_DENIED || + e==ERROR_LOCK_VIOLATION || + e==ERROR_SHARING_VIOLATION ){ + Sleep(win32IoerrRetryDelay*(1+*pnRetry)); + ++*pnRetry; + return 1; + } + return 0; +} + +/* +** Log a I/O error retry episode. +*/ +static void logIoerr(int nRetry){ + if( nRetry ){ + sqlite3_log(SQLITE_IOERR, + "delayed %dms for lock/sharing conflict", + win32IoerrRetryDelay*nRetry*(nRetry+1)/2 + ); + } +} + #if SQLITE_OS_WINCE /************************************************************************* ** This section contains code for WinCE only. @@ -28371,6 +32271,7 @@ static char *utf8ToMbcs(const char *zFilename){ ** WindowsCE does not have a localtime() function. So create a ** substitute. */ +/* #include <time.h> */ struct tm *__cdecl localtime(const time_t *t) { static struct tm y; @@ -28439,23 +32340,24 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ pFile->hMutex = CreateMutexW(NULL, FALSE, zName); if (!pFile->hMutex){ pFile->lastErrno = GetLastError(); + winLogError(SQLITE_ERROR, "winceCreateLock1", zFilename); free(zName); return FALSE; } /* Acquire the mutex before continuing */ winceMutexAcquire(pFile->hMutex); - - /* Since the names of named mutexes, semaphores, file mappings etc are + + /* Since the names of named mutexes, semaphores, file mappings etc are ** case-sensitive, take advantage of that by uppercasing the mutex name ** and using that as the shared filemapping name. */ CharUpperW(zName); pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(winceLock), - zName); + zName); - /* Set a flag that indicates we're the first to create the memory so it + /* Set a flag that indicates we're the first to create the memory so it ** must be zero-initialized */ if (GetLastError() == ERROR_ALREADY_EXISTS){ bInit = FALSE; @@ -28465,11 +32367,12 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ /* If we succeeded in making the shared memory handle, map it. */ if (pFile->hShared){ - pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, + pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); /* If mapping failed, close the shared memory handle and erase it */ if (!pFile->shared){ pFile->lastErrno = GetLastError(); + winLogError(SQLITE_ERROR, "winceCreateLock2", zFilename); CloseHandle(pFile->hShared); pFile->hShared = NULL; } @@ -28482,7 +32385,7 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ pFile->hMutex = NULL; return FALSE; } - + /* Initialize the shared memory if we're supposed to */ if (bInit) { ZeroMemory(pFile->shared, sizeof(winceLock)); @@ -28520,13 +32423,13 @@ static void winceDestroyLock(winFile *pFile){ CloseHandle(pFile->hShared); /* Done with the mutex */ - winceMutexRelease(pFile->hMutex); + winceMutexRelease(pFile->hMutex); CloseHandle(pFile->hMutex); pFile->hMutex = NULL; } } -/* +/* ** An implementation of the LockFile() API of windows for wince */ static BOOL winceLockFile( @@ -28686,6 +32589,43 @@ static BOOL winceLockFileEx( ******************************************************************************/ /* +** Some microsoft compilers lack this definition. +*/ +#ifndef INVALID_SET_FILE_POINTER +# define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif + +/* +** Move the current position of the file handle passed as the first +** argument to offset iOffset within the file. If successful, return 0. +** Otherwise, set pFile->lastErrno and return non-zero. +*/ +static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ + LONG upperBits; /* Most sig. 32 bits of new offset */ + LONG lowerBits; /* Least sig. 32 bits of new offset */ + DWORD dwRet; /* Value returned by SetFilePointer() */ + + upperBits = (LONG)((iOffset>>32) & 0x7fffffff); + lowerBits = (LONG)(iOffset & 0xffffffff); + + /* API oddity: If successful, SetFilePointer() returns a dword + ** containing the lower 32-bits of the new file-offset. Or, if it fails, + ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, + ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine + ** whether an error has actually occured, it is also necessary to call + ** GetLastError(). + */ + dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); + if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){ + pFile->lastErrno = GetLastError(); + winLogError(SQLITE_IOERR_SEEK, "seekWinFile", pFile->zPath); + return 1; + } + + return 0; +} + +/* ** Close a file. ** ** It is reported that an attempt to close a handle might sometimes @@ -28701,9 +32641,11 @@ static int winClose(sqlite3_file *id){ winFile *pFile = (winFile*)id; assert( id!=0 ); - OSTRACE2("CLOSE %d\n", pFile->h); + assert( pFile->pShm==0 ); + OSTRACE(("CLOSE %d\n", pFile->h)); do{ rc = CloseHandle(pFile->h); + /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); #if SQLITE_OS_WINCE #define WINCE_DELETION_ATTEMPTS 3 @@ -28712,7 +32654,7 @@ static int winClose(sqlite3_file *id){ int cnt = 0; while( DeleteFileW(pFile->zDeleteOnClose)==0 - && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff + && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff && cnt++ < WINCE_DELETION_ATTEMPTS ){ Sleep(100); /* Wait a little before trying again */ @@ -28720,18 +32662,13 @@ static int winClose(sqlite3_file *id){ free(pFile->zDeleteOnClose); } #endif + OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed")); OpenCounter(-1); - return rc ? SQLITE_OK : SQLITE_IOERR; + return rc ? SQLITE_OK + : winLogError(SQLITE_IOERR_CLOSE, "winClose", pFile->zPath); } /* -** Some microsoft compilers lack this definition. -*/ -#ifndef INVALID_SET_FILE_POINTER -# define INVALID_SET_FILE_POINTER ((DWORD)-1) -#endif - -/* ** Read data from a file into a buffer. Return SQLITE_OK if all ** bytes were read successfully and SQLITE_IOERR if anything goes ** wrong. @@ -28742,32 +32679,30 @@ static int winRead( int amt, /* Number of bytes to read */ sqlite3_int64 offset /* Begin reading at this offset */ ){ - LONG upperBits = (LONG)((offset>>32) & 0x7fffffff); - LONG lowerBits = (LONG)(offset & 0xffffffff); - DWORD rc; - winFile *pFile = (winFile*)id; - DWORD error; - DWORD got; + winFile *pFile = (winFile*)id; /* file handle */ + DWORD nRead; /* Number of bytes actually read from file */ + int nRetry = 0; /* Number of retrys */ assert( id!=0 ); SimulateIOError(return SQLITE_IOERR_READ); - OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype); - rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); - if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){ - pFile->lastErrno = error; + OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype)); + + if( seekWinFile(pFile, offset) ){ return SQLITE_FULL; } - if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){ + while( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ + if( retryIoerr(&nRetry) ) continue; pFile->lastErrno = GetLastError(); - return SQLITE_IOERR_READ; + return winLogError(SQLITE_IOERR_READ, "winRead", pFile->zPath); } - if( got==(DWORD)amt ){ - return SQLITE_OK; - }else{ + logIoerr(nRetry); + if( nRead<(DWORD)amt ){ /* Unread parts of the buffer must be zero-filled */ - memset(&((char*)pBuf)[got], 0, amt-got); + memset(&((char*)pBuf)[nRead], 0, amt-nRead); return SQLITE_IOERR_SHORT_READ; } + + return SQLITE_OK; } /* @@ -28775,39 +32710,51 @@ static int winRead( ** or some other error code on failure. */ static int winWrite( - sqlite3_file *id, /* File to write into */ - const void *pBuf, /* The bytes to be written */ - int amt, /* Number of bytes to write */ - sqlite3_int64 offset /* Offset into the file to begin writing at */ -){ - LONG upperBits = (LONG)((offset>>32) & 0x7fffffff); - LONG lowerBits = (LONG)(offset & 0xffffffff); - DWORD rc; - winFile *pFile = (winFile*)id; - DWORD error; - DWORD wrote = 0; + sqlite3_file *id, /* File to write into */ + const void *pBuf, /* The bytes to be written */ + int amt, /* Number of bytes to write */ + sqlite3_int64 offset /* Offset into the file to begin writing at */ +){ + int rc; /* True if error has occured, else false */ + winFile *pFile = (winFile*)id; /* File handle */ + int nRetry = 0; /* Number of retries */ - assert( id!=0 ); + assert( amt>0 ); + assert( pFile ); SimulateIOError(return SQLITE_IOERR_WRITE); SimulateDiskfullError(return SQLITE_FULL); - OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype); - rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); - if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){ - pFile->lastErrno = error; - return SQLITE_FULL; - } - assert( amt>0 ); - while( - amt>0 - && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0 - && wrote>0 - ){ - amt -= wrote; - pBuf = &((char*)pBuf)[wrote]; + + OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype)); + + rc = seekWinFile(pFile, offset); + if( rc==0 ){ + u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ + int nRem = amt; /* Number of bytes yet to be written */ + DWORD nWrite; /* Bytes written by each WriteFile() call */ + + while( nRem>0 ){ + if( !WriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ + if( retryIoerr(&nRetry) ) continue; + break; + } + if( nWrite<=0 ) break; + aRem += nWrite; + nRem -= nWrite; + } + if( nRem>0 ){ + pFile->lastErrno = GetLastError(); + rc = 1; + } } - if( !rc || amt>(int)wrote ){ - pFile->lastErrno = GetLastError(); - return SQLITE_FULL; + + if( rc ){ + if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) + || ( pFile->lastErrno==ERROR_DISK_FULL )){ + return SQLITE_FULL; + } + return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath); + }else{ + logIoerr(nRetry); } return SQLITE_OK; } @@ -28816,26 +32763,33 @@ static int winWrite( ** Truncate an open file to a specified size */ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ - LONG upperBits = (LONG)((nByte>>32) & 0x7fffffff); - LONG lowerBits = (LONG)(nByte & 0xffffffff); - DWORD rc; - winFile *pFile = (winFile*)id; - DWORD error; + winFile *pFile = (winFile*)id; /* File handle object */ + int rc = SQLITE_OK; /* Return code for this function */ - assert( id!=0 ); - OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte); + assert( pFile ); + + OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte)); SimulateIOError(return SQLITE_IOERR_TRUNCATE); - rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); - if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){ - pFile->lastErrno = error; - return SQLITE_IOERR_TRUNCATE; + + /* If the user has configured a chunk-size for this file, truncate the + ** file so that it consists of an integer number of chunks (i.e. the + ** actual file size after the operation may be larger than the requested + ** size). + */ + if( pFile->szChunk>0 ){ + nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; } - /* SetEndOfFile will fail if nByte is negative */ - if( !SetEndOfFile(pFile->h) ){ + + /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ + if( seekWinFile(pFile, nByte) ){ + rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate1", pFile->zPath); + }else if( 0==SetEndOfFile(pFile->h) ){ pFile->lastErrno = GetLastError(); - return SQLITE_IOERR_TRUNCATE; + rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate2", pFile->zPath); } - return SQLITE_OK; + + OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok")); + return rc; } #ifdef SQLITE_TEST @@ -28852,32 +32806,57 @@ SQLITE_API int sqlite3_fullsync_count = 0; */ static int winSync(sqlite3_file *id, int flags){ #ifndef SQLITE_NO_SYNC + /* + ** Used only when SQLITE_NO_SYNC is not defined. + */ + BOOL rc; +#endif +#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \ + (defined(SQLITE_TEST) && defined(SQLITE_DEBUG)) + /* + ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or + ** OSTRACE() macros. + */ winFile *pFile = (winFile*)id; - - assert( id!=0 ); - OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype); #else UNUSED_PARAMETER(id); #endif + + assert( pFile ); + /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ + assert((flags&0x0F)==SQLITE_SYNC_NORMAL + || (flags&0x0F)==SQLITE_SYNC_FULL + ); + + OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype)); + + /* Unix cannot, but some systems may return SQLITE_FULL from here. This + ** line is to test that doing so does not cause any problems. + */ + SimulateDiskfullError( return SQLITE_FULL ); + #ifndef SQLITE_TEST UNUSED_PARAMETER(flags); #else - if( flags & SQLITE_SYNC_FULL ){ + if( (flags&0x0F)==SQLITE_SYNC_FULL ){ sqlite3_fullsync_count++; } sqlite3_sync_count++; #endif + /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a ** no-op */ #ifdef SQLITE_NO_SYNC - return SQLITE_OK; + return SQLITE_OK; #else - if( FlushFileBuffers(pFile->h) ){ + rc = FlushFileBuffers(pFile->h); + SimulateIOError( rc=FALSE ); + if( rc ){ return SQLITE_OK; }else{ pFile->lastErrno = GetLastError(); - return SQLITE_IOERR; + return winLogError(SQLITE_IOERR_FSYNC, "winSync", pFile->zPath); } #endif } @@ -28898,7 +32877,7 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ && ((error = GetLastError()) != NO_ERROR) ) { pFile->lastErrno = error; - return SQLITE_IOERR_FSTAT; + return winLogError(SQLITE_IOERR_FSTAT, "winFileSize", pFile->zPath); } *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; return SQLITE_OK; @@ -28925,7 +32904,7 @@ static int getReadLock(winFile *pFile){ ovlp.hEvent = 0; res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE, 0, &ovlp); -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. */ #if SQLITE_OS_WINCE==0 }else{ @@ -28937,6 +32916,7 @@ static int getReadLock(winFile *pFile){ } if( res == 0 ){ pFile->lastErrno = GetLastError(); + /* No need to log a failure to lock */ } return res; } @@ -28948,15 +32928,16 @@ static int unlockReadLock(winFile *pFile){ int res; if( isNT() ){ res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. */ #if SQLITE_OS_WINCE==0 }else{ res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); #endif } - if( res == 0 ){ + if( res==0 && GetLastError()!=ERROR_NOT_LOCKED ){ pFile->lastErrno = GetLastError(); + winLogError(SQLITE_IOERR_UNLOCK, "unlockReadLock", pFile->zPath); } return res; } @@ -28996,8 +32977,8 @@ static int winLock(sqlite3_file *id, int locktype){ DWORD error = NO_ERROR; assert( id!=0 ); - OSTRACE5("LOCK %d %d was %d(%d)\n", - pFile->h, locktype, pFile->locktype, pFile->sharedLockByte); + OSTRACE(("LOCK %d %d was %d(%d)\n", + pFile->h, locktype, pFile->locktype, pFile->sharedLockByte)); /* If there is already a lock of this type or more restrictive on the ** OsFile, do nothing. Don't use the end_lock: exit path, as @@ -29027,7 +33008,7 @@ static int winLock(sqlite3_file *id, int locktype){ /* Try 3 times to get the pending lock. The pending lock might be ** held by another reader process who will release it momentarily. */ - OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt); + OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt)); Sleep(1); } gotPendingLock = res; @@ -29072,13 +33053,13 @@ static int winLock(sqlite3_file *id, int locktype){ if( locktype==EXCLUSIVE_LOCK && res ){ assert( pFile->locktype>=SHARED_LOCK ); res = unlockReadLock(pFile); - OSTRACE2("unreadlock = %d\n", res); + OSTRACE(("unreadlock = %d\n", res)); res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); if( res ){ newLocktype = EXCLUSIVE_LOCK; }else{ error = GetLastError(); - OSTRACE2("error-code = %d\n", error); + OSTRACE(("error-code = %d\n", error)); getReadLock(pFile); } } @@ -29096,8 +33077,8 @@ static int winLock(sqlite3_file *id, int locktype){ if( res ){ rc = SQLITE_OK; }else{ - OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h, - locktype, newLocktype); + OSTRACE(("LOCK FAILED %d trying for %d but got %d\n", pFile->h, + locktype, newLocktype)); pFile->lastErrno = error; rc = SQLITE_BUSY; } @@ -29114,17 +33095,19 @@ static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ int rc; winFile *pFile = (winFile*)id; + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + assert( id!=0 ); if( pFile->locktype>=RESERVED_LOCK ){ rc = 1; - OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc); + OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc)); }else{ rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); if( rc ){ UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); } rc = !rc; - OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc); + OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc)); } *pResOut = rc; return SQLITE_OK; @@ -29147,15 +33130,15 @@ static int winUnlock(sqlite3_file *id, int locktype){ int rc = SQLITE_OK; assert( pFile!=0 ); assert( locktype<=SHARED_LOCK ); - OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype, - pFile->locktype, pFile->sharedLockByte); + OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype, + pFile->locktype, pFile->sharedLockByte)); type = pFile->locktype; if( type>=EXCLUSIVE_LOCK ){ UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ /* This should never happen. We should always be able to ** reacquire the read lock */ - rc = SQLITE_IOERR_UNLOCK; + rc = winLogError(SQLITE_IOERR_UNLOCK, "winUnlock", pFile->zPath); } } if( type>=RESERVED_LOCK ){ @@ -29175,17 +33158,64 @@ static int winUnlock(sqlite3_file *id, int locktype){ ** Control and query of the open file handle. */ static int winFileControl(sqlite3_file *id, int op, void *pArg){ + winFile *pFile = (winFile*)id; switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { - *(int*)pArg = ((winFile*)id)->locktype; + *(int*)pArg = pFile->locktype; return SQLITE_OK; } case SQLITE_LAST_ERRNO: { - *(int*)pArg = (int)((winFile*)id)->lastErrno; + *(int*)pArg = (int)pFile->lastErrno; + return SQLITE_OK; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + pFile->szChunk = *(int *)pArg; + return SQLITE_OK; + } + case SQLITE_FCNTL_SIZE_HINT: { + if( pFile->szChunk>0 ){ + sqlite3_int64 oldSz; + int rc = winFileSize(id, &oldSz); + if( rc==SQLITE_OK ){ + sqlite3_int64 newSz = *(sqlite3_int64*)pArg; + if( newSz>oldSz ){ + SimulateIOErrorBenign(1); + rc = winTruncate(id, newSz); + SimulateIOErrorBenign(0); + } + } + return rc; + } + return SQLITE_OK; + } + case SQLITE_FCNTL_PERSIST_WAL: { + int bPersist = *(int*)pArg; + if( bPersist<0 ){ + *(int*)pArg = pFile->bPersistWal; + }else{ + pFile->bPersistWal = bPersist!=0; + } + return SQLITE_OK; + } + case SQLITE_FCNTL_SYNC_OMITTED: { + return SQLITE_OK; + } + case SQLITE_FCNTL_WIN32_AV_RETRY: { + int *a = (int*)pArg; + if( a[0]>0 ){ + win32IoerrRetry = a[0]; + }else{ + a[0] = win32IoerrRetry; + } + if( a[1]>0 ){ + win32IoerrRetryDelay = a[1]; + }else{ + a[1] = win32IoerrRetryDelay; + } return SQLITE_OK; } } - return SQLITE_ERROR; + return SQLITE_NOTFOUND; } /* @@ -29208,34 +33238,674 @@ static int winSectorSize(sqlite3_file *id){ */ static int winDeviceCharacteristics(sqlite3_file *id){ UNUSED_PARAMETER(id); - return 0; + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN; } +#ifndef SQLITE_OMIT_WAL + +/* +** Windows will only let you create file view mappings +** on allocation size granularity boundaries. +** During sqlite3_os_init() we do a GetSystemInfo() +** to get the granularity size. +*/ +SYSTEM_INFO winSysInfo; + +/* +** Helper functions to obtain and relinquish the global mutex. The +** global mutex is used to protect the winLockInfo objects used by +** this file, all of which may be shared by multiple threads. +** +** Function winShmMutexHeld() is used to assert() that the global mutex +** is held when required. This function is only used as part of assert() +** statements. e.g. +** +** winShmEnterMutex() +** assert( winShmMutexHeld() ); +** winShmLeaveMutex() +*/ +static void winShmEnterMutex(void){ + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +static void winShmLeaveMutex(void){ + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +#ifdef SQLITE_DEBUG +static int winShmMutexHeld(void) { + return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +#endif + +/* +** Object used to represent a single file opened and mmapped to provide +** shared memory. When multiple threads all reference the same +** log-summary, each thread has its own winFile object, but they all +** point to a single instance of this object. In other words, each +** log-summary is opened only once per process. +** +** winShmMutexHeld() must be true when creating or destroying +** this object or while reading or writing the following fields: +** +** nRef +** pNext +** +** The following fields are read-only after the object is created: +** +** fid +** zFilename +** +** Either winShmNode.mutex must be held or winShmNode.nRef==0 and +** winShmMutexHeld() is true when reading or writing any other field +** in this structure. +** +*/ +struct winShmNode { + sqlite3_mutex *mutex; /* Mutex to access this object */ + char *zFilename; /* Name of the file */ + winFile hFile; /* File handle from winOpen */ + + int szRegion; /* Size of shared-memory regions */ + int nRegion; /* Size of array apRegion */ + struct ShmRegion { + HANDLE hMap; /* File handle from CreateFileMapping */ + void *pMap; + } *aRegion; + DWORD lastErrno; /* The Windows errno from the last I/O error */ + + int nRef; /* Number of winShm objects pointing to this */ + winShm *pFirst; /* All winShm objects pointing to this */ + winShmNode *pNext; /* Next in list of all winShmNode objects */ +#ifdef SQLITE_DEBUG + u8 nextShmId; /* Next available winShm.id value */ +#endif +}; + +/* +** A global array of all winShmNode objects. +** +** The winShmMutexHeld() must be true while reading or writing this list. +*/ +static winShmNode *winShmNodeList = 0; + +/* +** Structure used internally by this VFS to record the state of an +** open shared memory connection. +** +** The following fields are initialized when this object is created and +** are read-only thereafter: +** +** winShm.pShmNode +** winShm.id +** +** All other fields are read/write. The winShm.pShmNode->mutex must be held +** while accessing any read/write fields. +*/ +struct winShm { + winShmNode *pShmNode; /* The underlying winShmNode object */ + winShm *pNext; /* Next winShm with the same winShmNode */ + u8 hasMutex; /* True if holding the winShmNode mutex */ + u16 sharedMask; /* Mask of shared locks held */ + u16 exclMask; /* Mask of exclusive locks held */ +#ifdef SQLITE_DEBUG + u8 id; /* Id of this connection with its winShmNode */ +#endif +}; + +/* +** Constants used for locking +*/ +#define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ +#define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ + +/* +** Apply advisory locks for all n bytes beginning at ofst. +*/ +#define _SHM_UNLCK 1 +#define _SHM_RDLCK 2 +#define _SHM_WRLCK 3 +static int winShmSystemLock( + winShmNode *pFile, /* Apply locks to this open shared-memory segment */ + int lockType, /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */ + int ofst, /* Offset to first byte to be locked/unlocked */ + int nByte /* Number of bytes to lock or unlock */ +){ + OVERLAPPED ovlp; + DWORD dwFlags; + int rc = 0; /* Result code form Lock/UnlockFileEx() */ + + /* Access to the winShmNode object is serialized by the caller */ + assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 ); + + /* Initialize the locking parameters */ + dwFlags = LOCKFILE_FAIL_IMMEDIATELY; + if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; + + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = ofst; + + /* Release/Acquire the system-level lock */ + if( lockType==_SHM_UNLCK ){ + rc = UnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp); + }else{ + rc = LockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp); + } + + if( rc!= 0 ){ + rc = SQLITE_OK; + }else{ + pFile->lastErrno = GetLastError(); + rc = SQLITE_BUSY; + } + + OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", + pFile->hFile.h, + rc==SQLITE_OK ? "ok" : "failed", + lockType==_SHM_UNLCK ? "UnlockFileEx" : "LockFileEx", + pFile->lastErrno)); + + return rc; +} + +/* Forward references to VFS methods */ +static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); +static int winDelete(sqlite3_vfs *,const char*,int); + +/* +** Purge the winShmNodeList list of all entries with winShmNode.nRef==0. +** +** This is not a VFS shared-memory method; it is a utility function called +** by VFS shared-memory methods. +*/ +static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ + winShmNode **pp; + winShmNode *p; + BOOL bRc; + assert( winShmMutexHeld() ); + pp = &winShmNodeList; + while( (p = *pp)!=0 ){ + if( p->nRef==0 ){ + int i; + if( p->mutex ) sqlite3_mutex_free(p->mutex); + for(i=0; i<p->nRegion; i++){ + bRc = UnmapViewOfFile(p->aRegion[i].pMap); + OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n", + (int)GetCurrentProcessId(), i, + bRc ? "ok" : "failed")); + bRc = CloseHandle(p->aRegion[i].hMap); + OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n", + (int)GetCurrentProcessId(), i, + bRc ? "ok" : "failed")); + } + if( p->hFile.h != INVALID_HANDLE_VALUE ){ + SimulateIOErrorBenign(1); + winClose((sqlite3_file *)&p->hFile); + SimulateIOErrorBenign(0); + } + if( deleteFlag ){ + SimulateIOErrorBenign(1); + winDelete(pVfs, p->zFilename, 0); + SimulateIOErrorBenign(0); + } + *pp = p->pNext; + sqlite3_free(p->aRegion); + sqlite3_free(p); + }else{ + pp = &p->pNext; + } + } +} + +/* +** Open the shared-memory area associated with database file pDbFd. +** +** When opening a new shared-memory file, if no other instances of that +** file are currently open, in this process or in other processes, then +** the file must be truncated to zero length or have its header cleared. +*/ +static int winOpenSharedMemory(winFile *pDbFd){ + struct winShm *p; /* The connection to be opened */ + struct winShmNode *pShmNode = 0; /* The underlying mmapped file */ + int rc; /* Result code */ + struct winShmNode *pNew; /* Newly allocated winShmNode */ + int nName; /* Size of zName in bytes */ + + assert( pDbFd->pShm==0 ); /* Not previously opened */ + + /* Allocate space for the new sqlite3_shm object. Also speculatively + ** allocate space for a new winShmNode and filename. + */ + p = sqlite3_malloc( sizeof(*p) ); + if( p==0 ) return SQLITE_NOMEM; + memset(p, 0, sizeof(*p)); + nName = sqlite3Strlen30(pDbFd->zPath); + pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 15 ); + if( pNew==0 ){ + sqlite3_free(p); + return SQLITE_NOMEM; + } + memset(pNew, 0, sizeof(*pNew)); + pNew->zFilename = (char*)&pNew[1]; + sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); + sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); + + /* Look to see if there is an existing winShmNode that can be used. + ** If no matching winShmNode currently exists, create a new one. + */ + winShmEnterMutex(); + for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){ + /* TBD need to come up with better match here. Perhaps + ** use FILE_ID_BOTH_DIR_INFO Structure. + */ + if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; + } + if( pShmNode ){ + sqlite3_free(pNew); + }else{ + pShmNode = pNew; + pNew = 0; + ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; + pShmNode->pNext = winShmNodeList; + winShmNodeList = pShmNode; + + pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->mutex==0 ){ + rc = SQLITE_NOMEM; + goto shm_open_err; + } + + rc = winOpen(pDbFd->pVfs, + pShmNode->zFilename, /* Name of the file (UTF-8) */ + (sqlite3_file*)&pShmNode->hFile, /* File handle here */ + SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */ + 0); + if( SQLITE_OK!=rc ){ + rc = SQLITE_CANTOPEN_BKPT; + goto shm_open_err; + } + + /* Check to see if another process is holding the dead-man switch. + ** If not, truncate the file to zero length. + */ + if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ + rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); + if( rc!=SQLITE_OK ){ + rc = winLogError(SQLITE_IOERR_SHMOPEN, "winOpenShm", pDbFd->zPath); + } + } + if( rc==SQLITE_OK ){ + winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); + rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1); + } + if( rc ) goto shm_open_err; + } + + /* Make the new connection a child of the winShmNode */ + p->pShmNode = pShmNode; +#ifdef SQLITE_DEBUG + p->id = pShmNode->nextShmId++; +#endif + pShmNode->nRef++; + pDbFd->pShm = p; + winShmLeaveMutex(); + + /* The reference count on pShmNode has already been incremented under + ** the cover of the winShmEnterMutex() mutex and the pointer from the + ** new (struct winShm) object to the pShmNode has been set. All that is + ** left to do is to link the new object into the linked list starting + ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex + ** mutex. + */ + sqlite3_mutex_enter(pShmNode->mutex); + p->pNext = pShmNode->pFirst; + pShmNode->pFirst = p; + sqlite3_mutex_leave(pShmNode->mutex); + return SQLITE_OK; + + /* Jump here on any error */ +shm_open_err: + winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); + winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ + sqlite3_free(p); + sqlite3_free(pNew); + winShmLeaveMutex(); + return rc; +} + +/* +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. +*/ +static int winShmUnmap( + sqlite3_file *fd, /* Database holding shared memory */ + int deleteFlag /* Delete after closing if true */ +){ + winFile *pDbFd; /* Database holding shared-memory */ + winShm *p; /* The connection to be closed */ + winShmNode *pShmNode; /* The underlying shared-memory file */ + winShm **pp; /* For looping over sibling connections */ + + pDbFd = (winFile*)fd; + p = pDbFd->pShm; + if( p==0 ) return SQLITE_OK; + pShmNode = p->pShmNode; + + /* Remove connection p from the set of connections associated + ** with pShmNode */ + sqlite3_mutex_enter(pShmNode->mutex); + for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} + *pp = p->pNext; + + /* Free the connection p */ + sqlite3_free(p); + pDbFd->pShm = 0; + sqlite3_mutex_leave(pShmNode->mutex); + + /* If pShmNode->nRef has reached 0, then close the underlying + ** shared-memory file, too */ + winShmEnterMutex(); + assert( pShmNode->nRef>0 ); + pShmNode->nRef--; + if( pShmNode->nRef==0 ){ + winShmPurge(pDbFd->pVfs, deleteFlag); + } + winShmLeaveMutex(); + + return SQLITE_OK; +} + +/* +** Change the lock state for a shared-memory segment. +*/ +static int winShmLock( + sqlite3_file *fd, /* Database file holding the shared memory */ + int ofst, /* First lock to acquire or release */ + int n, /* Number of locks to acquire or release */ + int flags /* What to do with the lock */ +){ + winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ + winShm *p = pDbFd->pShm; /* The shared memory being locked */ + winShm *pX; /* For looping over all siblings */ + winShmNode *pShmNode = p->pShmNode; + int rc = SQLITE_OK; /* Result code */ + u16 mask; /* Mask of locks to take or release */ + + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); + assert( n>=1 ); + assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); + assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + + mask = (u16)((1U<<(ofst+n)) - (1U<<ofst)); + assert( n>1 || mask==(1<<ofst) ); + sqlite3_mutex_enter(pShmNode->mutex); + if( flags & SQLITE_SHM_UNLOCK ){ + u16 allMask = 0; /* Mask of locks held by siblings */ + + /* See if any siblings hold this same lock */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( pX==p ) continue; + assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); + allMask |= pX->sharedMask; + } + + /* Unlock the system-level locks */ + if( (mask & allMask)==0 ){ + rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + + /* Undo the local locks */ + if( rc==SQLITE_OK ){ + p->exclMask &= ~mask; + p->sharedMask &= ~mask; + } + }else if( flags & SQLITE_SHM_SHARED ){ + u16 allShared = 0; /* Union of locks held by connections other than "p" */ + + /* Find out which shared locks are already held by sibling connections. + ** If any sibling already holds an exclusive lock, go ahead and return + ** SQLITE_BUSY. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + allShared |= pX->sharedMask; + } + + /* Get shared locks at the system level, if necessary */ + if( rc==SQLITE_OK ){ + if( (allShared & mask)==0 ){ + rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + } + + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + } + }else{ + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + } + + /* Get the exclusive locks at the system level. Then if successful + ** also mark the local connection as being locked. + */ + if( rc==SQLITE_OK ){ + rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n); + if( rc==SQLITE_OK ){ + assert( (p->sharedMask & mask)==0 ); + p->exclMask |= mask; + } + } + } + sqlite3_mutex_leave(pShmNode->mutex); + OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n", + p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask, + rc ? "failed" : "ok")); + return rc; +} + +/* +** Implement a memory barrier or memory fence on shared memory. +** +** All loads and stores begun before the barrier must complete before +** any load or store begun after the barrier. +*/ +static void winShmBarrier( + sqlite3_file *fd /* Database holding the shared memory */ +){ + UNUSED_PARAMETER(fd); + /* MemoryBarrier(); // does not work -- do not know why not */ + winShmEnterMutex(); + winShmLeaveMutex(); +} + +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the isWrite parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** isWrite is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int winShmMap( + sqlite3_file *fd, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int isWrite, /* True to extend file if necessary */ + void volatile **pp /* OUT: Mapped memory */ +){ + winFile *pDbFd = (winFile*)fd; + winShm *p = pDbFd->pShm; + winShmNode *pShmNode; + int rc = SQLITE_OK; + + if( !p ){ + rc = winOpenSharedMemory(pDbFd); + if( rc!=SQLITE_OK ) return rc; + p = pDbFd->pShm; + } + pShmNode = p->pShmNode; + + sqlite3_mutex_enter(pShmNode->mutex); + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + + if( pShmNode->nRegion<=iRegion ){ + struct ShmRegion *apNew; /* New aRegion[] array */ + int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ + sqlite3_int64 sz; /* Current size of wal-index file */ + + pShmNode->szRegion = szRegion; + + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). + */ + rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); + if( rc!=SQLITE_OK ){ + rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap1", pDbFd->zPath); + goto shmpage_out; + } + + if( sz<nByte ){ + /* The requested memory region does not exist. If isWrite is set to + ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned. + ** + ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate + ** the requested memory region. + */ + if( !isWrite ) goto shmpage_out; + rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); + if( rc!=SQLITE_OK ){ + rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap2", pDbFd->zPath); + goto shmpage_out; + } + } + + /* Map the requested memory region into this processes address space. */ + apNew = (struct ShmRegion *)sqlite3_realloc( + pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) + ); + if( !apNew ){ + rc = SQLITE_IOERR_NOMEM; + goto shmpage_out; + } + pShmNode->aRegion = apNew; + + while( pShmNode->nRegion<=iRegion ){ + HANDLE hMap; /* file-mapping handle */ + void *pMap = 0; /* Mapped memory region */ + + hMap = CreateFileMapping(pShmNode->hFile.h, + NULL, PAGE_READWRITE, 0, nByte, NULL + ); + OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n", + (int)GetCurrentProcessId(), pShmNode->nRegion, nByte, + hMap ? "ok" : "failed")); + if( hMap ){ + int iOffset = pShmNode->nRegion*szRegion; + int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; + pMap = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, + 0, iOffset - iOffsetShift, szRegion + iOffsetShift + ); + OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n", + (int)GetCurrentProcessId(), pShmNode->nRegion, iOffset, szRegion, + pMap ? "ok" : "failed")); + } + if( !pMap ){ + pShmNode->lastErrno = GetLastError(); + rc = winLogError(SQLITE_IOERR_SHMMAP, "winShmMap3", pDbFd->zPath); + if( hMap ) CloseHandle(hMap); + goto shmpage_out; + } + + pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; + pShmNode->aRegion[pShmNode->nRegion].hMap = hMap; + pShmNode->nRegion++; + } + } + +shmpage_out: + if( pShmNode->nRegion>iRegion ){ + int iOffset = iRegion*szRegion; + int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; + char *p = (char *)pShmNode->aRegion[iRegion].pMap; + *pp = (void *)&p[iOffsetShift]; + }else{ + *pp = 0; + } + sqlite3_mutex_leave(pShmNode->mutex); + return rc; +} + +#else +# define winShmMap 0 +# define winShmLock 0 +# define winShmBarrier 0 +# define winShmUnmap 0 +#endif /* #ifndef SQLITE_OMIT_WAL */ + +/* +** Here ends the implementation of all sqlite3_file methods. +** +********************** End sqlite3_file Methods ******************************* +******************************************************************************/ + /* ** This vector defines all the methods that can operate on an ** sqlite3_file for win32. */ static const sqlite3_io_methods winIoMethod = { - 1, /* iVersion */ - winClose, - winRead, - winWrite, - winTruncate, - winSync, - winFileSize, - winLock, - winUnlock, - winCheckReservedLock, - winFileControl, - winSectorSize, - winDeviceCharacteristics + 2, /* iVersion */ + winClose, /* xClose */ + winRead, /* xRead */ + winWrite, /* xWrite */ + winTruncate, /* xTruncate */ + winSync, /* xSync */ + winFileSize, /* xFileSize */ + winLock, /* xLock */ + winUnlock, /* xUnlock */ + winCheckReservedLock, /* xCheckReservedLock */ + winFileControl, /* xFileControl */ + winSectorSize, /* xSectorSize */ + winDeviceCharacteristics, /* xDeviceCharacteristics */ + winShmMap, /* xShmMap */ + winShmLock, /* xShmLock */ + winShmBarrier, /* xShmBarrier */ + winShmUnmap /* xShmUnmap */ }; -/*************************************************************************** -** Here ends the I/O methods that form the sqlite3_io_methods object. +/**************************************************************************** +**************************** sqlite3_vfs methods **************************** ** -** The next block of code implements the VFS methods. -****************************************************************************/ +** This division contains the implementation of methods on the +** sqlite3_vfs object. +*/ /* ** Convert a UTF-8 filename into whatever form the underlying @@ -29247,11 +33917,11 @@ static void *convertUtf8Filename(const char *zFilename){ void *zConverted = 0; if( isNT() ){ zConverted = utf8ToUnicode(zFilename); -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. */ #if SQLITE_OS_WINCE==0 }else{ - zConverted = utf8ToMbcs(zFilename); + zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); #endif } /* caller will handle out of memory */ @@ -29269,6 +33939,13 @@ static int getTempname(int nBuf, char *zBuf){ "0123456789"; size_t i, j; char zTempPath[MAX_PATH+1]; + + /* 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. + */ + SimulateIOError( return SQLITE_IOERR ); + if( sqlite3_temp_directory ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); }else if( isNT() ){ @@ -29282,7 +33959,7 @@ static int getTempname(int nBuf, char *zBuf){ }else{ return SQLITE_NOMEM; } -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ @@ -29300,80 +33977,28 @@ static int getTempname(int nBuf, char *zBuf){ } #endif } + + /* Check that the output buffer is large enough for the temporary file + ** name. If it is not, return SQLITE_ERROR. + */ + if( (sqlite3Strlen30(zTempPath) + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 17) >= nBuf ){ + return SQLITE_ERROR; + } + for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} zTempPath[i] = 0; - sqlite3_snprintf(nBuf-30, zBuf, + + sqlite3_snprintf(nBuf-17, zBuf, "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); j = sqlite3Strlen30(zBuf); - sqlite3_randomness(20, &zBuf[j]); - for(i=0; i<20; i++, j++){ + sqlite3_randomness(15, &zBuf[j]); + for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; - OSTRACE2("TEMP FILENAME: %s\n", zBuf); - return SQLITE_OK; -} - -/* -** The return value of getLastErrorMsg -** is zero if the error message fits in the buffer, or non-zero -** otherwise (if the message was truncated). -*/ -static int getLastErrorMsg(int nBuf, char *zBuf){ - /* FormatMessage returns 0 on failure. Otherwise it - ** returns the number of TCHARs written to the output - ** buffer, excluding the terminating null char. - */ - DWORD error = GetLastError(); - DWORD dwLen = 0; - char *zOut = 0; - if( isNT() ){ - WCHAR *zTempWide = NULL; - dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - error, - 0, - (LPWSTR) &zTempWide, - 0, - 0); - if( dwLen > 0 ){ - /* allocate a buffer and convert to UTF8 */ - zOut = unicodeToUtf8(zTempWide); - /* free the system buffer allocated by FormatMessage */ - LocalFree(zTempWide); - } -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, -** it's important to not reference them for WINCE builds. -*/ -#if SQLITE_OS_WINCE==0 - }else{ - char *zTemp = NULL; - dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - error, - 0, - (LPSTR) &zTemp, - 0, - 0); - if( dwLen > 0 ){ - /* allocate a buffer and convert to UTF8 */ - zOut = sqlite3_win32_mbcs_to_utf8(zTemp); - /* free the system buffer allocated by FormatMessage */ - LocalFree(zTemp); - } -#endif - } - if( 0 == dwLen ){ - sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error); - }else{ - /* copy a maximum of nBuf chars to output buffer */ - sqlite3_snprintf(nBuf, zBuf, "%s", zOut); - /* free the UTF8 buffer */ - free(zOut); - } - return 0; + OSTRACE(("TEMP FILENAME: %s\n", zBuf)); + return SQLITE_OK; } /* @@ -29395,18 +34020,73 @@ static int winOpen( int isTemp = 0; #endif winFile *pFile = (winFile*)id; - void *zConverted; /* Filename in OS encoding */ - const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ - char zTmpname[MAX_PATH+1]; /* Buffer used to create temp filename */ + void *zConverted; /* Filename in OS encoding */ + const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ + int cnt = 0; + + /* If argument zPath is a NULL pointer, this function is required to open + ** a temporary file. Use this buffer to store the file name in. + */ + char zTmpname[MAX_PATH+1]; /* Buffer used to create temp filename */ + + int rc = SQLITE_OK; /* Function Return Code */ +#if !defined(NDEBUG) || SQLITE_OS_WINCE + int eType = flags&0xFFFFFF00; /* Type of file to open */ +#endif + + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); + int isCreate = (flags & SQLITE_OPEN_CREATE); +#ifndef NDEBUG + int isReadonly = (flags & SQLITE_OPEN_READONLY); +#endif + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); + +#ifndef NDEBUG + int isOpenJournal = (isCreate && ( + eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_WAL + )); +#endif + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. + */ + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); + assert(isCreate==0 || isReadWrite); + assert(isExclusive==0 || isCreate); + assert(isDelete==0 || isCreate); + + /* The main DB, main journal, WAL file and master journal are never + ** automatically deleted. Nor are they ever temporary files. */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); + + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL + ); assert( id!=0 ); UNUSED_PARAMETER(pVfs); - /* If the second argument to this function is NULL, generate a - ** temporary file name to use + pFile->h = INVALID_HANDLE_VALUE; + + /* If the second argument to this function is NULL, generate a + ** temporary file name to use */ if( !zUtf8Name ){ - int rc = getTempname(MAX_PATH+1, zTmpname); + assert(isDelete && !isOpenJournal); + rc = getTempname(MAX_PATH+1, zTmpname); if( rc!=SQLITE_OK ){ return rc; } @@ -29419,29 +34099,31 @@ static int winOpen( return SQLITE_NOMEM; } - if( flags & SQLITE_OPEN_READWRITE ){ + if( isReadWrite ){ dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; }else{ dwDesiredAccess = GENERIC_READ; } - /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is - ** created. SQLite doesn't use it to indicate "exclusive access" + + /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is + ** created. SQLite doesn't use it to indicate "exclusive access" ** as it is usually understood. */ - assert(!(flags & SQLITE_OPEN_EXCLUSIVE) || (flags & SQLITE_OPEN_CREATE)); - if( flags & SQLITE_OPEN_EXCLUSIVE ){ + if( isExclusive ){ /* Creates a new file, only if it does not already exist. */ /* If the file exists, it fails. */ dwCreationDisposition = CREATE_NEW; - }else if( flags & SQLITE_OPEN_CREATE ){ + }else if( isCreate ){ /* Open existing file, or create if it doesn't exist */ dwCreationDisposition = OPEN_ALWAYS; }else{ /* Opens a file, only if it exists. */ dwCreationDisposition = OPEN_EXISTING; } + dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; - if( flags & SQLITE_OPEN_DELETEONCLOSE ){ + + if( isDelete ){ #if SQLITE_OS_WINCE dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN; isTemp = 1; @@ -29458,55 +34140,68 @@ static int winOpen( #if SQLITE_OS_WINCE dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; #endif + if( isNT() ){ - h = CreateFileW((WCHAR*)zConverted, - dwDesiredAccess, - dwShareMode, - NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL - ); -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. + while( (h = CreateFileW((WCHAR*)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL))==INVALID_HANDLE_VALUE && + retryIoerr(&cnt) ){} +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ - h = CreateFileA((char*)zConverted, - dwDesiredAccess, - dwShareMode, - NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL - ); + while( (h = CreateFileA((char*)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL))==INVALID_HANDLE_VALUE && + retryIoerr(&cnt) ){} #endif } + + logIoerr(cnt); + + OSTRACE(("OPEN %d %s 0x%lx %s\n", + h, zName, dwDesiredAccess, + h==INVALID_HANDLE_VALUE ? "failed" : "ok")); + if( h==INVALID_HANDLE_VALUE ){ + pFile->lastErrno = GetLastError(); + winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name); free(zConverted); - if( flags & SQLITE_OPEN_READWRITE ){ - return winOpen(pVfs, zName, id, - ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags); + if( isReadWrite ){ + return winOpen(pVfs, zName, id, + ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags); }else{ return SQLITE_CANTOPEN_BKPT; } } + if( pOutFlags ){ - if( flags & SQLITE_OPEN_READWRITE ){ + if( isReadWrite ){ *pOutFlags = SQLITE_OPEN_READWRITE; }else{ *pOutFlags = SQLITE_OPEN_READONLY; } } + memset(pFile, 0, sizeof(*pFile)); pFile->pMethod = &winIoMethod; pFile->h = h; pFile->lastErrno = NO_ERROR; + pFile->pVfs = pVfs; + pFile->pShm = 0; + pFile->zPath = zName; pFile->sectorSize = getSectorSize(pVfs, zUtf8Name); + #if SQLITE_OS_WINCE - if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) == - (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB) + if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB && !winceCreateLock(zName, pFile) ){ CloseHandle(h); @@ -29520,8 +34215,9 @@ static int winOpen( { free(zConverted); } + OpenCounter(+1); - return SQLITE_OK; + return rc; } /* @@ -29536,47 +34232,47 @@ static int winOpen( ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving ** up and returning an error. */ -#define MX_DELETION_ATTEMPTS 5 static int winDelete( sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to delete */ int syncDir /* Not used on win32 */ ){ int cnt = 0; - DWORD rc; - DWORD error = 0; - void *zConverted = convertUtf8Filename(zFilename); + int rc; + void *zConverted; UNUSED_PARAMETER(pVfs); UNUSED_PARAMETER(syncDir); + + SimulateIOError(return SQLITE_IOERR_DELETE); + zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return SQLITE_NOMEM; } - SimulateIOError(return SQLITE_IOERR_DELETE); if( isNT() ){ - do{ - DeleteFileW(zConverted); - }while( ( ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES) - || ((error = GetLastError()) == ERROR_ACCESS_DENIED)) - && (++cnt < MX_DELETION_ATTEMPTS) - && (Sleep(100), 1) ); -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. + rc = 1; + while( GetFileAttributesW(zConverted)!=INVALID_FILE_ATTRIBUTES && + (rc = DeleteFileW(zConverted))==0 && retryIoerr(&cnt) ){} + rc = rc ? SQLITE_OK : SQLITE_ERROR; +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ - do{ - DeleteFileA(zConverted); - }while( ( ((rc = GetFileAttributesA(zConverted)) != INVALID_FILE_ATTRIBUTES) - || ((error = GetLastError()) == ERROR_ACCESS_DENIED)) - && (++cnt < MX_DELETION_ATTEMPTS) - && (Sleep(100), 1) ); + rc = 1; + while( GetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES && + (rc = DeleteFileA(zConverted))==0 && retryIoerr(&cnt) ){} + rc = rc ? SQLITE_OK : SQLITE_ERROR; #endif } + if( rc ){ + rc = winLogError(SQLITE_IOERR_DELETE, "winDelete", zFilename); + }else{ + logIoerr(cnt); + } free(zConverted); - OSTRACE2("DELETE \"%s\"\n", zFilename); - return ( (rc == INVALID_FILE_ATTRIBUTES) - && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : SQLITE_IOERR_DELETE; + OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" ))); + return rc; } /* @@ -29590,14 +34286,43 @@ static int winAccess( ){ DWORD attr; int rc = 0; - void *zConverted = convertUtf8Filename(zFilename); + void *zConverted; UNUSED_PARAMETER(pVfs); + + SimulateIOError( return SQLITE_IOERR_ACCESS; ); + zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return SQLITE_NOMEM; } if( isNT() ){ - attr = GetFileAttributesW((WCHAR*)zConverted); -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. + int cnt = 0; + WIN32_FILE_ATTRIBUTE_DATA sAttrData; + memset(&sAttrData, 0, sizeof(sAttrData)); + while( !(rc = GetFileAttributesExW((WCHAR*)zConverted, + GetFileExInfoStandard, + &sAttrData)) && retryIoerr(&cnt) ){} + if( rc ){ + /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file + ** as if it does not exist. + */ + if( flags==SQLITE_ACCESS_EXISTS + && sAttrData.nFileSizeHigh==0 + && sAttrData.nFileSizeLow==0 ){ + attr = INVALID_FILE_ATTRIBUTES; + }else{ + attr = sAttrData.dwFileAttributes; + } + }else{ + logIoerr(cnt); + if( GetLastError()!=ERROR_FILE_NOT_FOUND ){ + winLogError(SQLITE_IOERR_ACCESS, "winAccess", zFilename); + free(zConverted); + return SQLITE_IOERR_ACCESS; + }else{ + attr = INVALID_FILE_ATTRIBUTES; + } + } +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ @@ -29613,7 +34338,8 @@ static int winAccess( rc = attr!=INVALID_FILE_ATTRIBUTES; break; case SQLITE_ACCESS_READWRITE: - rc = (attr & FILE_ATTRIBUTE_READONLY)==0; + rc = attr!=INVALID_FILE_ATTRIBUTES && + (attr & FILE_ATTRIBUTE_READONLY)==0; break; default: assert(!"Invalid flags argument"); @@ -29634,14 +34360,16 @@ static int winFullPathname( int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ - + #if defined(__CYGWIN__) + SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); cygwin_conv_to_full_win32_path(zRelative, zFull); return SQLITE_OK; #endif #if SQLITE_OS_WINCE + SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); /* WinCE has no concept of a relative pathname, or so I am told. */ sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative); @@ -29652,6 +34380,20 @@ static int winFullPathname( int nByte; void *zConverted; char *zOut; + + /* If this path name begins with "/X:", where "X" is any alphabetic + ** character, discard the initial "/" from the pathname. + */ + if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){ + zRelative++; + } + + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. This function could fail if, for example, the + ** current working directory has been unlinked. + */ + SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); zConverted = convertUtf8Filename(zRelative); if( isNT() ){ @@ -29666,7 +34408,7 @@ static int winFullPathname( free(zConverted); zOut = unicodeToUtf8(zTemp); free(zTemp); -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ @@ -29719,7 +34461,9 @@ static int getSectorSize( ** to get the drive letter to look up the sector ** size. */ + SimulateIOErrorBenign(1); rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath); + SimulateIOErrorBenign(0); if( rc == SQLITE_OK ) { void *zConverted = convertUtf8Filename(zFullpath); @@ -29760,7 +34504,7 @@ static int getSectorSize( } } #endif - return (int) bytesPerSector; + return (int) bytesPerSector; } #ifndef SQLITE_OMIT_LOAD_EXTENSION @@ -29781,7 +34525,7 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ } if( isNT() ){ h = LoadLibraryW((WCHAR*)zConverted); -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ @@ -29867,36 +34611,34 @@ static int winSleep(sqlite3_vfs *pVfs, int microsec){ } /* -** The following variable, if set to a non-zero value, becomes the result -** returned from sqlite3OsCurrentTime(). This is used for testing. +** The following variable, if set to a non-zero value, is interpreted as +** the number of seconds since 1970 and is used to set the result of +** sqlite3OsCurrentTime() during testing. */ #ifdef SQLITE_TEST -SQLITE_API int sqlite3_current_time = 0; +SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ #endif /* -** Find the current time (in Universal Coordinated Time). Write the -** current time and date as a Julian Day number into *prNow and -** return 0. Return 1 if the time and date cannot be found. +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return 0. Return 1 if the time and date cannot be found. */ -int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ - FILETIME ft; - /* FILETIME structure is a 64-bit value representing the number of - 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). +static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ + /* FILETIME structure is a 64-bit value representing the number of + 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). */ - sqlite3_int64 timeW; /* Whole days */ - sqlite3_int64 timeF; /* Fractional Days */ - - /* Number of 100-nanosecond intervals in a single day */ - static const sqlite3_int64 ntuPerDay = - 10000000*(sqlite3_int64)86400; - - /* Number of 100-nanosecond intervals in half of a day */ - static const sqlite3_int64 ntuPerHalfDay = - 10000000*(sqlite3_int64)43200; - + FILETIME ft; + static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000; +#ifdef SQLITE_TEST + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; +#endif /* 2^32 - to avoid use of LL and warnings in gcc */ - static const sqlite3_int64 max32BitValue = + static const sqlite3_int64 max32BitValue = (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296; #if SQLITE_OS_WINCE @@ -29909,24 +34651,36 @@ int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ #else GetSystemTimeAsFileTime( &ft ); #endif - UNUSED_PARAMETER(pVfs); - timeW = (((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + (sqlite3_int64)ft.dwLowDateTime; - timeF = timeW % ntuPerDay; /* fractional days (100-nanoseconds) */ - timeW = timeW / ntuPerDay; /* whole days */ - timeW = timeW + 2305813; /* add whole days (from 2305813.5) */ - timeF = timeF + ntuPerHalfDay; /* add half a day (from 2305813.5) */ - timeW = timeW + (timeF/ntuPerDay); /* add whole day if half day made one */ - timeF = timeF % ntuPerDay; /* compute new fractional days */ - *prNow = (double)timeW + ((double)timeF / (double)ntuPerDay); + + *piNow = winFiletimeEpoch + + ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + + (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000; + #ifdef SQLITE_TEST if( sqlite3_current_time ){ - *prNow = ((double)sqlite3_current_time + (double)43200) / (double)86400 + (double)2440587; + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; } #endif + UNUSED_PARAMETER(pVfs); return 0; } /* +** Find the current time (in Universal Coordinated Time). Write the +** current time and date as a Julian Day number into *prNow and +** return 0. Return 1 if the time and date cannot be found. +*/ +int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ + int rc; + sqlite3_int64 i; + rc = winCurrentTimeInt64(pVfs, &i); + if( !rc ){ + *prNow = i/86400000.0; + } + return rc; +} + +/* ** The idea is that this function works like a combination of ** GetLastError() and FormatMessage() on windows (or errno and ** strerror_r() on unix). After an error is returned by an OS @@ -29961,36 +34715,48 @@ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ return getLastErrorMsg(nBuf, zBuf); } + + /* ** Initialize and deinitialize the operating system interface. */ SQLITE_API int sqlite3_os_init(void){ static sqlite3_vfs winVfs = { - 1, /* iVersion */ - sizeof(winFile), /* szOsFile */ - MAX_PATH, /* mxPathname */ - 0, /* pNext */ - "win32", /* zName */ - 0, /* pAppData */ - - winOpen, /* xOpen */ - winDelete, /* xDelete */ - winAccess, /* xAccess */ - winFullPathname, /* xFullPathname */ - winDlOpen, /* xDlOpen */ - winDlError, /* xDlError */ - winDlSym, /* xDlSym */ - winDlClose, /* xDlClose */ - winRandomness, /* xRandomness */ - winSleep, /* xSleep */ - winCurrentTime, /* xCurrentTime */ - winGetLastError /* xGetLastError */ + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + MAX_PATH, /* mxPathname */ + 0, /* pNext */ + "win32", /* zName */ + 0, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + 0, /* xSetSystemCall */ + 0, /* xGetSystemCall */ + 0, /* xNextSystemCall */ }; +#ifndef SQLITE_OMIT_WAL + /* get memory map allocation granularity */ + memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); + GetSystemInfo(&winSysInfo); + assert(winSysInfo.dwAllocationGranularity > 0); +#endif + sqlite3_vfs_register(&winVfs, 1); - return SQLITE_OK; + return SQLITE_OK; } -SQLITE_API int sqlite3_os_end(void){ +SQLITE_API int sqlite3_os_end(void){ return SQLITE_OK; } @@ -30017,8 +34783,8 @@ SQLITE_API int sqlite3_os_end(void){ ** property. Usually only a few pages are meet either condition. ** So the bitmap is usually sparse and has low cardinality. ** But sometimes (for example when during a DROP of a large table) most -** or all of the pages in a database can get journalled. In those cases, -** the bitmap becomes dense with high cardinality. The algorithm needs +** or all of the pages in a database can get journalled. In those cases, +** the bitmap becomes dense with high cardinality. The algorithm needs ** to handle both cases well. ** ** The size of the bitmap is fixed when the object is created. @@ -30036,14 +34802,14 @@ SQLITE_API int sqlite3_os_end(void){ */ /* Size of the Bitvec structure in bytes. */ -#define BITVEC_SZ (sizeof(void*)*128) /* 512 on 32bit. 1024 on 64bit */ +#define BITVEC_SZ 512 -/* Round the union size down to the nearest pointer boundary, since that's how +/* Round the union size down to the nearest pointer boundary, since that's how ** it will be aligned within the Bitvec struct. */ #define BITVEC_USIZE (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*)) -/* Type of the array "element" for the bitmap representation. -** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. +/* Type of the array "element" for the bitmap representation. +** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. ** Setting this to the "natural word" size of your CPU may improve ** performance. */ #define BITVEC_TELEM u8 @@ -30056,12 +34822,12 @@ SQLITE_API int sqlite3_os_end(void){ /* Number of u32 values in hash table. */ #define BITVEC_NINT (BITVEC_USIZE/sizeof(u32)) -/* Maximum number of entries in hash table before +/* Maximum number of entries in hash table before ** sub-dividing and re-hashing. */ #define BITVEC_MXHASH (BITVEC_NINT/2) /* Hashing function for the aHash representation. -** Empirical testing showed that the *37 multiplier -** (an arbitrary prime)in the hash function provided +** Empirical testing showed that the *37 multiplier +** (an arbitrary prime)in the hash function provided ** no fewer collisions than the no-op *1. */ #define BITVEC_HASH(X) (((X)*1)%BITVEC_NINT) @@ -30107,7 +34873,7 @@ struct Bitvec { /* ** Create a new bitmap object able to handle bits between 0 and iSize, -** inclusive. Return a pointer to the new object. Return NULL if +** inclusive. Return a pointer to the new object. Return NULL if ** malloc fails. */ SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){ @@ -30361,7 +35127,7 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ break; } case 3: - case 4: + case 4: default: { nx = 2; sqlite3_randomness(sizeof(i), &i); @@ -30546,17 +35312,21 @@ static void pcacheUnpin(PgHdr *p){ /*************************************************** General Interfaces ****** ** -** Initialize and shutdown the page cache subsystem. Neither of these +** Initialize and shutdown the page cache subsystem. Neither of these ** functions are threadsafe. */ SQLITE_PRIVATE int sqlite3PcacheInitialize(void){ if( sqlite3GlobalConfig.pcache.xInit==0 ){ + /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the + ** built-in default page cache is used instead of the application defined + ** page cache. */ sqlite3PCacheSetDefault(); } return sqlite3GlobalConfig.pcache.xInit(sqlite3GlobalConfig.pcache.pArg); } SQLITE_PRIVATE void sqlite3PcacheShutdown(void){ if( sqlite3GlobalConfig.pcache.xShutdown ){ + /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */ sqlite3GlobalConfig.pcache.xShutdown(sqlite3GlobalConfig.pcache.pArg); } } @@ -30568,8 +35338,8 @@ SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); } /* ** Create a new PCache object. Storage space to hold the object -** has already been allocated and is passed in as the p pointer. -** The caller discovers how much space needs to be allocated by +** has already been allocated and is passed in as the p pointer. +** The caller discovers how much space needs to be allocated by ** calling sqlite3PcacheSize(). */ SQLITE_PRIVATE void sqlite3PcacheOpen( @@ -30642,14 +35412,14 @@ SQLITE_PRIVATE int sqlite3PcacheFetch( if( !pPage && eCreate==1 ){ PgHdr *pPg; - /* Find a dirty page to write-out and recycle. First try to find a + /* Find a dirty page to write-out and recycle. First try to find a ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC - ** cleared), but if that is not possible settle for any other + ** cleared), but if that is not possible settle for any other ** unreferenced dirty page. */ expensive_assert( pcacheCheckSynced(pCache) ); - for(pPg=pCache->pSynced; - pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); + for(pPg=pCache->pSynced; + pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); pPg=pPg->pDirtyPrev ); pCache->pSynced = pPg; @@ -30658,6 +35428,13 @@ SQLITE_PRIVATE int sqlite3PcacheFetch( } if( pPg ){ int rc; +#ifdef SQLITE_LOG_CACHE_SPILL + sqlite3_log(SQLITE_FULL, + "spill page %d making room for %d - cache used: %d/%d", + pPg->pgno, pgno, + sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), + pCache->nMax); +#endif rc = pCache->xStress(pCache->pStress, pPg); if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ return rc; @@ -30669,15 +35446,17 @@ SQLITE_PRIVATE int sqlite3PcacheFetch( if( pPage ){ if( !pPage->pData ){ - memset(pPage, 0, sizeof(PgHdr) + pCache->szExtra); - pPage->pExtra = (void*)&pPage[1]; - pPage->pData = (void *)&((char *)pPage)[sizeof(PgHdr) + pCache->szExtra]; + memset(pPage, 0, sizeof(PgHdr)); + pPage->pData = (void *)&pPage[1]; + pPage->pExtra = (void*)&((char *)pPage->pData)[pCache->szPage]; + memset(pPage->pExtra, 0, pCache->szExtra); pPage->pCache = pCache; pPage->pgno = pgno; } assert( pPage->pCache==pCache ); assert( pPage->pgno==pgno ); - assert( pPage->pExtra==(void *)&pPage[1] ); + assert( pPage->pData==(void *)&pPage[1] ); + assert( pPage->pExtra==(void *)&((char *)&pPage[1])[pCache->szPage] ); if( 0==pPage->nRef ){ pCache->nRef++; @@ -30787,7 +35566,7 @@ SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){ } /* -** Change the page number of page p to newPgno. +** Change the page number of page p to newPgno. */ SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ PCache *pCache = p->pCache; @@ -30816,7 +35595,12 @@ SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ PgHdr *pNext; for(p=pCache->pDirty; p; p=pNext){ pNext = p->pDirtyNext; - if( p->pgno>pgno ){ + /* This routine never gets call with a positive pgno except right + ** after sqlite3PcacheCleanAll(). So if there are dirty pages, + ** it must be that pgno==0. + */ + assert( p->pgno>0 ); + if( ALWAYS(p->pgno>pgno) ){ assert( p->flags&PGHDR_DIRTY ); sqlite3PcacheMakeClean(p); } @@ -30838,7 +35622,7 @@ SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){ } } -/* +/* ** Discard the contents of the cache. */ SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){ @@ -30926,7 +35710,7 @@ SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){ return pcacheSortDirtyList(pCache->pDirty); } -/* +/* ** Return the total number of referenced pages held by the cache. */ SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){ @@ -30940,7 +35724,7 @@ SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){ return p->nRef; } -/* +/* ** Return the total number of pages in the cache. */ SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){ @@ -31009,24 +35793,123 @@ SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHd typedef struct PCache1 PCache1; typedef struct PgHdr1 PgHdr1; typedef struct PgFreeslot PgFreeslot; +typedef struct PGroup PGroup; + +typedef struct PGroupBlock PGroupBlock; +typedef struct PGroupBlockList PGroupBlockList; + +/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set +** of one or more PCaches that are able to recycle each others unpinned +** pages when they are under memory pressure. A PGroup is an instance of +** the following object. +** +** This page cache implementation works in one of two modes: +** +** (1) Every PCache is the sole member of its own PGroup. There is +** one PGroup per PCache. +** +** (2) There is a single global PGroup that all PCaches are a member +** of. +** +** Mode 1 uses more memory (since PCache instances are not able to rob +** unused pages from other PCaches) but it also operates without a mutex, +** and is therefore often faster. Mode 2 requires a mutex in order to be +** threadsafe, but is able recycle pages more efficient. +** +** For mode (1), PGroup.mutex is NULL. For mode (2) there is only a single +** PGroup which is the pcache1.grp global variable and its mutex is +** SQLITE_MUTEX_STATIC_LRU. +*/ +struct PGroup { + sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */ + int nMaxPage; /* Sum of nMax for purgeable caches */ + int nMinPage; /* Sum of nMin for purgeable caches */ + int mxPinned; /* nMaxpage + 10 - nMinPage */ + int nCurrentPage; /* Number of purgeable pages allocated */ + PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */ +#ifdef SQLITE_PAGECACHE_BLOCKALLOC + int isBusy; /* Do not run ReleaseMemory() if true */ + PGroupBlockList *pBlockList; /* List of block-lists for this group */ +#endif +}; -/* Pointers to structures of this type are cast and returned as -** opaque sqlite3_pcache* handles +/* +** If SQLITE_PAGECACHE_BLOCKALLOC is defined when the library is built, +** each PGroup structure has a linked list of the the following starting +** at PGroup.pBlockList. There is one entry for each distinct page-size +** currently used by members of the PGroup (i.e. 1024 bytes, 4096 bytes +** etc.). Variable PGroupBlockList.nByte is set to the actual allocation +** size requested by each pcache, which is the database page-size plus +** the various header structures used by the pcache, pager and btree layers. +** Usually around (pgsz+200) bytes. +** +** This size (pgsz+200) bytes is not allocated efficiently by some +** implementations of malloc. In particular, some implementations are only +** able to allocate blocks of memory chunks of 2^N bytes, where N is some +** integer value. Since the page-size is a power of 2, this means we +** end up wasting (pgsz-200) bytes in each allocation. +** +** If SQLITE_PAGECACHE_BLOCKALLOC is defined, the (pgsz+200) byte blocks +** are not allocated directly. Instead, blocks of roughly M*(pgsz+200) bytes +** are requested from malloc allocator. After a block is returned, +** sqlite3MallocSize() is used to determine how many (pgsz+200) byte +** allocations can fit in the space returned by malloc(). This value may +** be more than M. +** +** The blocks are stored in a doubly-linked list. Variable PGroupBlock.nEntry +** contains the number of allocations that will fit in the aData[] space. +** nEntry is limited to the number of bits in bitmask mUsed. If a slot +** within aData is in use, the corresponding bit in mUsed is set. Thus +** when (mUsed+1==(1 << nEntry)) the block is completely full. +** +** Each time a slot within a block is freed, the block is moved to the start +** of the linked-list. And if a block becomes completely full, then it is +** moved to the end of the list. As a result, when searching for a free +** slot, only the first block in the list need be examined. If it is full, +** then it is guaranteed that all blocks are full. +*/ +struct PGroupBlockList { + int nByte; /* Size of each allocation in bytes */ + PGroupBlock *pFirst; /* First PGroupBlock in list */ + PGroupBlock *pLast; /* Last PGroupBlock in list */ + PGroupBlockList *pNext; /* Next block-list attached to group */ +}; + +struct PGroupBlock { + Bitmask mUsed; /* Mask of used slots */ + int nEntry; /* Maximum number of allocations in aData[] */ + u8 *aData; /* Pointer to data block */ + PGroupBlock *pNext; /* Next PGroupBlock in list */ + PGroupBlock *pPrev; /* Previous PGroupBlock in list */ + PGroupBlockList *pList; /* Owner list */ +}; + +/* Minimum value for PGroupBlock.nEntry */ +#define PAGECACHE_BLOCKALLOC_MINENTRY 15 + +/* Each page cache is an instance of the following object. Every +** open database file (including each in-memory database and each +** temporary or transient database) has a single page cache which +** is an instance of this object. +** +** Pointers to structures of this type are cast and returned as +** opaque sqlite3_pcache* handles. */ struct PCache1 { /* Cache configuration parameters. Page size (szPage) and the purgeable - ** flag (bPurgeable) are set when the cache is created. nMax may be + ** flag (bPurgeable) are set when the cache is created. nMax may be ** modified at any time by a call to the pcache1CacheSize() method. - ** The global mutex must be held when accessing nMax. + ** The PGroup mutex must be held when accessing nMax. */ + PGroup *pGroup; /* PGroup this cache belongs to */ int szPage; /* Size of allocated pages in bytes */ int bPurgeable; /* True if cache is purgeable */ unsigned int nMin; /* Minimum number of pages reserved */ unsigned int nMax; /* Configured "cache_size" value */ + unsigned int n90pct; /* nMax*9/10 */ /* Hash table of all pages. The following variables may only be accessed - ** when the accessor is holding the global mutex (see pcache1EnterMutex() - ** and pcache1LeaveMutex()). + ** when the accessor is holding the PGroup mutex. */ unsigned int nRecyclable; /* Number of pages in the LRU list */ unsigned int nPage; /* Total number of pages in apHash */ @@ -31037,9 +35920,9 @@ struct PCache1 { }; /* -** 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 in memory (see the PGHDR1_TO_PAGE() +** 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 in memory (see the PGHDR1_TO_PAGE() ** macro below). */ struct PgHdr1 { @@ -31062,18 +35945,27 @@ struct PgFreeslot { ** Global data used by this cache. */ static SQLITE_WSD struct PCacheGlobal { - sqlite3_mutex *mutex; /* static mutex MUTEX_STATIC_LRU */ - - int nMaxPage; /* Sum of nMaxPage for purgeable caches */ - int nMinPage; /* Sum of nMinPage for purgeable caches */ - int nCurrentPage; /* Number of purgeable pages allocated */ - PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */ - - /* Variables related to SQLITE_CONFIG_PAGECACHE settings. */ - int szSlot; /* Size of each free slot */ - void *pStart, *pEnd; /* Bounds of pagecache malloc range */ - PgFreeslot *pFree; /* Free page blocks */ - int isInit; /* True if initialized */ + PGroup grp; /* The global PGroup for mode (2) */ + + /* Variables related to SQLITE_CONFIG_PAGECACHE settings. The + ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all + ** fixed at sqlite3_initialize() time and do not require mutex protection. + ** The nFreeSlot and pFree values do require mutex protection. + */ + int isInit; /* True if initialized */ + int szSlot; /* Size of each free slot */ + int nSlot; /* The number of pcache slots */ + int nReserve; /* Try to keep nFreeSlot above this */ + void *pStart, *pEnd; /* Bounds of pagecache malloc range */ + /* Above requires no mutex. Use mutex below for variable that follow. */ + sqlite3_mutex *mutex; /* Mutex for accessing the following: */ + int nFreeSlot; /* Number of unused pcache slots */ + PgFreeslot *pFree; /* Free page blocks */ + /* The following value requires a mutex to change. We skip the mutex on + ** reading because (1) most platforms read a 32-bit integer atomically and + ** (2) even if an incorrect value is read, no great harm is done since this + ** is really just an optimization. */ + int bUnderPressure; /* True if low on PAGECACHE memory */ } pcache1_g; /* @@ -31099,27 +35991,44 @@ static SQLITE_WSD struct PCacheGlobal { #define PAGE_TO_PGHDR1(c, p) (PgHdr1*)(((char*)p) + c->szPage) /* -** Macros to enter and leave the global LRU mutex. +** Blocks used by the SQLITE_PAGECACHE_BLOCKALLOC blocks to store/retrieve +** a PGroupBlock pointer based on a pointer to a page buffer. */ -#define pcache1EnterMutex() sqlite3_mutex_enter(pcache1.mutex) -#define pcache1LeaveMutex() sqlite3_mutex_leave(pcache1.mutex) +#define PAGE_SET_BLOCKPTR(pCache, pPg, pBlock) \ + ( *(PGroupBlock **)&(((u8*)pPg)[sizeof(PgHdr1) + pCache->szPage]) = pBlock ) + +#define PAGE_GET_BLOCKPTR(pCache, pPg) \ + ( *(PGroupBlock **)&(((u8*)pPg)[sizeof(PgHdr1) + pCache->szPage]) ) + + +/* +** Macros to enter and leave the PCache LRU mutex. +*/ +#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex) +#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex) /******************************************************************************/ /******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/ /* -** This function is called during initialization if a static buffer is +** This function is called during initialization if a static buffer is ** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE ** verb to sqlite3_config(). Parameter pBuf points to an allocation large ** enough to contain 'n' buffers of 'sz' bytes each. +** +** This routine is called from sqlite3_initialize() and so it is guaranteed +** to be serialized already. There is no need for further mutexing. */ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ if( pcache1.isInit ){ PgFreeslot *p; sz = ROUNDDOWN8(sz); pcache1.szSlot = sz; + pcache1.nSlot = pcache1.nFreeSlot = n; + pcache1.nReserve = n>90 ? 10 : (n/10 + 1); pcache1.pStart = pBuf; pcache1.pFree = 0; + pcache1.bUnderPressure = 0; while( n-- ){ p = (PgFreeslot*)pBuf; p->pNext = pcache1.pFree; @@ -31132,34 +36041,41 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ /* ** Malloc function used within this file to allocate space from the buffer -** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no -** such buffer exists or there is no space left in it, this function falls +** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no +** such buffer exists or there is no space left in it, this function falls ** back to sqlite3Malloc(). +** +** Multiple threads can run this routine at the same time. Global variables +** in pcache1 need to be protected via mutex. */ static void *pcache1Alloc(int nByte){ - void *p; - assert( sqlite3_mutex_held(pcache1.mutex) ); - if( nByte<=pcache1.szSlot && pcache1.pFree ){ - assert( pcache1.isInit ); + void *p = 0; + assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); + sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte); + if( nByte<=pcache1.szSlot ){ + sqlite3_mutex_enter(pcache1.mutex); p = (PgHdr1 *)pcache1.pFree; - pcache1.pFree = pcache1.pFree->pNext; - sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte); - sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1); - }else{ - - /* Allocate a new buffer using sqlite3Malloc. Before doing so, exit the - ** global pcache mutex and unlock the pager-cache object pCache. This is - ** so that if the attempt to allocate a new buffer causes the the - ** configured soft-heap-limit to be breached, it will be possible to - ** reclaim memory from this pager-cache. + if( p ){ + pcache1.pFree = pcache1.pFree->pNext; + pcache1.nFreeSlot--; + pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve; + assert( pcache1.nFreeSlot>=0 ); + sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1); + } + sqlite3_mutex_leave(pcache1.mutex); + } + if( p==0 ){ + /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get + ** it from sqlite3Malloc instead. */ - pcache1LeaveMutex(); p = sqlite3Malloc(nByte); - pcache1EnterMutex(); if( p ){ int sz = sqlite3MallocSize(p); + sqlite3_mutex_enter(pcache1.mutex); sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); + sqlite3_mutex_leave(pcache1.mutex); } + sqlite3MemdebugSetType(p, MEMTYPE_PCACHE); } return p; } @@ -31168,36 +36084,197 @@ static void *pcache1Alloc(int nByte){ ** Free an allocated buffer obtained from pcache1Alloc(). */ static void pcache1Free(void *p){ - assert( sqlite3_mutex_held(pcache1.mutex) ); if( p==0 ) return; if( p>=pcache1.pStart && p<pcache1.pEnd ){ PgFreeslot *pSlot; + sqlite3_mutex_enter(pcache1.mutex); sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1); pSlot = (PgFreeslot*)p; pSlot->pNext = pcache1.pFree; pcache1.pFree = pSlot; + pcache1.nFreeSlot++; + pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve; + assert( pcache1.nFreeSlot<=pcache1.nSlot ); + sqlite3_mutex_leave(pcache1.mutex); }else{ - int iSize = sqlite3MallocSize(p); + int iSize; + assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + iSize = sqlite3MallocSize(p); + sqlite3_mutex_enter(pcache1.mutex); sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize); + sqlite3_mutex_leave(pcache1.mutex); sqlite3_free(p); } } +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT +/* +** Return the size of a pcache allocation +*/ +static int pcache1MemSize(void *p){ + if( p>=pcache1.pStart && p<pcache1.pEnd ){ + return pcache1.szSlot; + }else{ + int iSize; + assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + iSize = sqlite3MallocSize(p); + sqlite3MemdebugSetType(p, MEMTYPE_PCACHE); + return iSize; + } +} +#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */ + +#ifdef SQLITE_PAGECACHE_BLOCKALLOC +/* +** The block pBlock belongs to list pList but is not currently linked in. +** Insert it into the start of the list. +*/ +static void addBlockToList(PGroupBlockList *pList, PGroupBlock *pBlock){ + pBlock->pPrev = 0; + pBlock->pNext = pList->pFirst; + pList->pFirst = pBlock; + if( pBlock->pNext ){ + pBlock->pNext->pPrev = pBlock; + }else{ + assert( pList->pLast==0 ); + pList->pLast = pBlock; + } +} + +/* +** If there are no blocks in the list headed by pList, remove pList +** from the pGroup->pBlockList list and free it with sqlite3_free(). +*/ +static void freeListIfEmpty(PGroup *pGroup, PGroupBlockList *pList){ + assert( sqlite3_mutex_held(pGroup->mutex) ); + if( pList->pFirst==0 ){ + PGroupBlockList **pp; + for(pp=&pGroup->pBlockList; *pp!=pList; pp=&(*pp)->pNext); + *pp = (*pp)->pNext; + sqlite3_free(pList); + } +} +#endif /* SQLITE_PAGECACHE_BLOCKALLOC */ + /* ** Allocate a new page object initially associated with cache pCache. */ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){ int nByte = sizeof(PgHdr1) + pCache->szPage; - void *pPg = pcache1Alloc(nByte); + void *pPg = 0; PgHdr1 *p; + +#ifdef SQLITE_PAGECACHE_BLOCKALLOC + PGroup *pGroup = pCache->pGroup; + PGroupBlockList *pList; + PGroupBlock *pBlock; + int i; + + nByte += sizeof(PGroupBlockList *); + nByte = ROUND8(nByte); + + for(pList=pGroup->pBlockList; pList; pList=pList->pNext){ + if( pList->nByte==nByte ) break; + } + if( pList==0 ){ + PGroupBlockList *pNew; + assert( pGroup->isBusy==0 ); + assert( sqlite3_mutex_held(pGroup->mutex) ); + pGroup->isBusy = 1; /* Disable sqlite3PcacheReleaseMemory() */ + pNew = (PGroupBlockList *)sqlite3MallocZero(sizeof(PGroupBlockList)); + pGroup->isBusy = 0; /* Reenable sqlite3PcacheReleaseMemory() */ + if( pNew==0 ){ + /* malloc() failure. Return early. */ + return 0; + } +#ifdef SQLITE_DEBUG + for(pList=pGroup->pBlockList; pList; pList=pList->pNext){ + assert( pList->nByte!=nByte ); + } +#endif + pNew->nByte = nByte; + pNew->pNext = pGroup->pBlockList; + pGroup->pBlockList = pNew; + pList = pNew; + } + + pBlock = pList->pFirst; + if( pBlock==0 || pBlock->mUsed==(((Bitmask)1<<pBlock->nEntry)-1) ){ + int sz; + + /* Allocate a new block. Try to allocate enough space for the PGroupBlock + ** structure and MINENTRY allocations of nByte bytes each. If the + ** allocator returns more memory than requested, then more than MINENTRY + ** allocations may fit in it. */ + assert( sqlite3_mutex_held(pGroup->mutex) ); + pcache1LeaveMutex(pCache->pGroup); + sz = sizeof(PGroupBlock) + PAGECACHE_BLOCKALLOC_MINENTRY * nByte; + pBlock = (PGroupBlock *)sqlite3Malloc(sz); + pcache1EnterMutex(pCache->pGroup); + + if( !pBlock ){ + freeListIfEmpty(pGroup, pList); + return 0; + } + pBlock->nEntry = (sqlite3MallocSize(pBlock) - sizeof(PGroupBlock)) / nByte; + if( pBlock->nEntry>=BMS ){ + pBlock->nEntry = BMS-1; + } + pBlock->pList = pList; + pBlock->mUsed = 0; + pBlock->aData = (u8 *)&pBlock[1]; + addBlockToList(pList, pBlock); + + sz = sqlite3MallocSize(pBlock); + sqlite3_mutex_enter(pcache1.mutex); + sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); + sqlite3_mutex_leave(pcache1.mutex); + } + + for(i=0; pPg==0 && ALWAYS(i<pBlock->nEntry); i++){ + if( 0==(pBlock->mUsed & ((Bitmask)1<<i)) ){ + pBlock->mUsed |= ((Bitmask)1<<i); + pPg = (void *)&pBlock->aData[pList->nByte * i]; + } + } + assert( pPg ); + PAGE_SET_BLOCKPTR(pCache, pPg, pBlock); + + /* If the block is now full, shift it to the end of the list */ + if( pBlock->mUsed==(((Bitmask)1<<pBlock->nEntry)-1) && pList->pLast!=pBlock ){ + assert( pList->pFirst==pBlock ); + assert( pBlock->pPrev==0 ); + assert( pList->pLast->pNext==0 ); + pList->pFirst = pBlock->pNext; + pList->pFirst->pPrev = 0; + pBlock->pPrev = pList->pLast; + pBlock->pNext = 0; + pList->pLast->pNext = pBlock; + pList->pLast = pBlock; + } + p = PAGE_TO_PGHDR1(pCache, pPg); + if( pCache->bPurgeable ){ + pCache->pGroup->nCurrentPage++; + } +#else + /* The group mutex must be released before pcache1Alloc() is called. This + ** is because it may call sqlite3_release_memory(), which assumes that + ** this mutex is not held. */ + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); + pcache1LeaveMutex(pCache->pGroup); + pPg = pcache1Alloc(nByte); + pcache1EnterMutex(pCache->pGroup); if( pPg ){ p = PAGE_TO_PGHDR1(pCache, pPg); if( pCache->bPurgeable ){ - pcache1.nCurrentPage++; + pCache->pGroup->nCurrentPage++; } }else{ p = 0; } +#endif return p; } @@ -31210,10 +36287,53 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){ */ static void pcache1FreePage(PgHdr1 *p){ if( ALWAYS(p) ){ - if( p->pCache->bPurgeable ){ - pcache1.nCurrentPage--; + PCache1 *pCache = p->pCache; + void *pPg = PGHDR1_TO_PAGE(p); + +#ifdef SQLITE_PAGECACHE_BLOCKALLOC + PGroupBlock *pBlock = PAGE_GET_BLOCKPTR(pCache, pPg); + PGroupBlockList *pList = pBlock->pList; + int i = ((u8 *)pPg - pBlock->aData) / pList->nByte; + + assert( pPg==(void *)&pBlock->aData[i*pList->nByte] ); + assert( pBlock->mUsed & ((Bitmask)1<<i) ); + pBlock->mUsed &= ~((Bitmask)1<<i); + + /* Remove the block from the list. If it is completely empty, free it. + ** Or if it is not completely empty, re-insert it at the start of the + ** list. */ + if( pList->pFirst==pBlock ){ + pList->pFirst = pBlock->pNext; + if( pList->pFirst ) pList->pFirst->pPrev = 0; + }else{ + pBlock->pPrev->pNext = pBlock->pNext; + } + if( pList->pLast==pBlock ){ + pList->pLast = pBlock->pPrev; + if( pList->pLast ) pList->pLast->pNext = 0; + }else{ + pBlock->pNext->pPrev = pBlock->pPrev; + } + + if( pBlock->mUsed==0 ){ + PGroup *pGroup = p->pCache->pGroup; + + int sz = sqlite3MallocSize(pBlock); + sqlite3_mutex_enter(pcache1.mutex); + sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -sz); + sqlite3_mutex_leave(pcache1.mutex); + freeListIfEmpty(pGroup, pList); + sqlite3_free(pBlock); + }else{ + addBlockToList(pList, pBlock); + } +#else + assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) ); + pcache1Free(pPg); +#endif + if( pCache->bPurgeable ){ + pCache->pGroup->nCurrentPage--; } - pcache1Free(PGHDR1_TO_PAGE(p)); } } @@ -31223,20 +36343,39 @@ static void pcache1FreePage(PgHdr1 *p){ ** exists, this function falls back to sqlite3Malloc(). */ SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){ - void *p; - pcache1EnterMutex(); - p = pcache1Alloc(sz); - pcache1LeaveMutex(); - return p; + return pcache1Alloc(sz); } /* ** Free an allocated buffer obtained from sqlite3PageMalloc(). */ SQLITE_PRIVATE void sqlite3PageFree(void *p){ - pcache1EnterMutex(); pcache1Free(p); - pcache1LeaveMutex(); +} + + +/* +** Return true if it desirable to avoid allocating a new page cache +** entry. +** +** If memory was allocated specifically to the page cache using +** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then +** it is desirable to avoid allocating a new page cache entry because +** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient +** for all page cache needs and we should not need to spill the +** allocation onto the heap. +** +** Or, the heap is used for all page cache memory put the heap is +** under memory pressure, then again it is desirable to avoid +** allocating a new page cache entry in order to avoid stressing +** the heap even further. +*/ +static int pcache1UnderMemoryPressure(PCache1 *pCache){ + if( pcache1.nSlot && pCache->szPage<=pcache1.szSlot ){ + return pcache1.bUnderPressure; + }else{ + return sqlite3HeapNearlyFull(); + } } /******************************************************************************/ @@ -31246,25 +36385,25 @@ SQLITE_PRIVATE void sqlite3PageFree(void *p){ ** This function is used to resize the hash table used by the cache passed ** as the first argument. ** -** The global mutex must be held when this function is called. +** The PCache mutex must be held when this function is called. */ static int pcache1ResizeHash(PCache1 *p){ PgHdr1 **apNew; unsigned int nNew; unsigned int i; - assert( sqlite3_mutex_held(pcache1.mutex) ); + assert( sqlite3_mutex_held(p->pGroup->mutex) ); nNew = p->nHash*2; if( nNew<256 ){ nNew = 256; } - pcache1LeaveMutex(); + pcache1LeaveMutex(p->pGroup); if( p->nHash ){ sqlite3BeginBenignMalloc(); } apNew = (PgHdr1 **)sqlite3_malloc(sizeof(PgHdr1 *)*nNew); if( p->nHash ){ sqlite3EndBenignMalloc(); } - pcache1EnterMutex(); + pcache1EnterMutex(p->pGroup); if( apNew ){ memset(apNew, 0, sizeof(PgHdr1 *)*nNew); for(i=0; i<p->nHash; i++){ @@ -31286,26 +36425,34 @@ static int pcache1ResizeHash(PCache1 *p){ } /* -** This function is used internally to remove the page pPage from the -** global LRU list, if is part of it. If pPage is not part of the global +** This function is used internally to remove the page pPage from the +** PGroup LRU list, if is part of it. If pPage is not part of the PGroup ** LRU list, then this function is a no-op. ** -** The global mutex must be held when this function is called. +** The PGroup mutex must be held when this function is called. +** +** If pPage is NULL then this routine is a no-op. */ static void pcache1PinPage(PgHdr1 *pPage){ - assert( sqlite3_mutex_held(pcache1.mutex) ); - if( pPage && (pPage->pLruNext || pPage==pcache1.pLruTail) ){ + PCache1 *pCache; + PGroup *pGroup; + + if( pPage==0 ) return; + pCache = pPage->pCache; + pGroup = pCache->pGroup; + assert( sqlite3_mutex_held(pGroup->mutex) ); + if( pPage->pLruNext || pPage==pGroup->pLruTail ){ if( pPage->pLruPrev ){ pPage->pLruPrev->pLruNext = pPage->pLruNext; } if( pPage->pLruNext ){ pPage->pLruNext->pLruPrev = pPage->pLruPrev; } - if( pcache1.pLruHead==pPage ){ - pcache1.pLruHead = pPage->pLruNext; + if( pGroup->pLruHead==pPage ){ + pGroup->pLruHead = pPage->pLruNext; } - if( pcache1.pLruTail==pPage ){ - pcache1.pLruTail = pPage->pLruPrev; + if( pGroup->pLruTail==pPage ){ + pGroup->pLruTail = pPage->pLruPrev; } pPage->pLruNext = 0; pPage->pLruPrev = 0; @@ -31315,16 +36462,17 @@ static void pcache1PinPage(PgHdr1 *pPage){ /* -** Remove the page supplied as an argument from the hash table +** Remove the page supplied as an argument from the hash table ** (PCache1.apHash structure) that it is currently stored in. ** -** The global mutex must be held when this function is called. +** The PGroup mutex must be held when this function is called. */ static void pcache1RemoveFromHash(PgHdr1 *pPage){ unsigned int h; PCache1 *pCache = pPage->pCache; PgHdr1 **pp; + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); h = pPage->iKey % pCache->nHash; for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext); *pp = (*pp)->pNext; @@ -31333,13 +36481,14 @@ static void pcache1RemoveFromHash(PgHdr1 *pPage){ } /* -** If there are currently more than pcache.nMaxPage pages allocated, try -** to recycle pages to reduce the number allocated to pcache.nMaxPage. +** If there are currently more than nMaxPage pages allocated, try +** to recycle pages to reduce the number allocated to nMaxPage. */ -static void pcache1EnforceMaxPage(void){ - assert( sqlite3_mutex_held(pcache1.mutex) ); - while( pcache1.nCurrentPage>pcache1.nMaxPage && pcache1.pLruTail ){ - PgHdr1 *p = pcache1.pLruTail; +static void pcache1EnforceMaxPage(PGroup *pGroup){ + assert( sqlite3_mutex_held(pGroup->mutex) ); + while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){ + PgHdr1 *p = pGroup->pLruTail; + assert( p->pCache->pGroup==pGroup ); pcache1PinPage(p); pcache1RemoveFromHash(p); pcache1FreePage(p); @@ -31347,21 +36496,21 @@ static void pcache1EnforceMaxPage(void){ } /* -** Discard all pages from cache pCache with a page number (key value) -** greater than or equal to iLimit. Any pinned pages that meet this +** Discard all pages from cache pCache with a page number (key value) +** greater than or equal to iLimit. Any pinned pages that meet this ** criteria are unpinned before they are discarded. ** -** The global mutex must be held when this function is called. +** The PCache mutex must be held when this function is called. */ static void pcache1TruncateUnsafe( - PCache1 *pCache, - unsigned int iLimit + PCache1 *pCache, /* The cache to truncate */ + unsigned int iLimit /* Drop pages with this pgno or larger */ ){ - TESTONLY( unsigned int nPage = 0; ) /* Used to assert pCache->nPage is correct */ + TESTONLY( unsigned int nPage = 0; ) /* To assert pCache->nPage is correct */ unsigned int h; - assert( sqlite3_mutex_held(pcache1.mutex) ); + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); for(h=0; h<pCache->nHash; h++){ - PgHdr1 **pp = &pCache->apHash[h]; + PgHdr1 **pp = &pCache->apHash[h]; PgHdr1 *pPage; while( (pPage = *pp)!=0 ){ if( pPage->iKey>=iLimit ){ @@ -31389,15 +36538,17 @@ static int pcache1Init(void *NotUsed){ assert( pcache1.isInit==0 ); memset(&pcache1, 0, sizeof(pcache1)); if( sqlite3GlobalConfig.bCoreMutex ){ - pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU); + pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU); + pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM); } + pcache1.grp.mxPinned = 10; pcache1.isInit = 1; return SQLITE_OK; } /* ** Implementation of the sqlite3_pcache.xShutdown method. -** Note that the static mutex allocated in xInit does +** Note that the static mutex allocated in xInit does ** not need to be freed. */ static void pcache1Shutdown(void *NotUsed){ @@ -31412,58 +36563,91 @@ static void pcache1Shutdown(void *NotUsed){ ** Allocate a new cache. */ static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){ - PCache1 *pCache; + PCache1 *pCache; /* The newly created page cache */ + PGroup *pGroup; /* The group the new page cache will belong to */ + int sz; /* Bytes of memory required to allocate the new cache */ - pCache = (PCache1 *)sqlite3_malloc(sizeof(PCache1)); + /* + ** The seperateCache variable is true if each PCache has its own private + ** PGroup. In other words, separateCache is true for mode (1) where no + ** mutexing is required. + ** + ** * Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT + ** + ** * Always use a unified cache in single-threaded applications + ** + ** * Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off) + ** use separate caches (mode-1) + */ +#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0 + const int separateCache = 0; +#else + int separateCache = sqlite3GlobalConfig.bCoreMutex>0; +#endif + + sz = sizeof(PCache1) + sizeof(PGroup)*separateCache; + pCache = (PCache1 *)sqlite3_malloc(sz); if( pCache ){ - memset(pCache, 0, sizeof(PCache1)); + memset(pCache, 0, sz); + if( separateCache ){ + pGroup = (PGroup*)&pCache[1]; + pGroup->mxPinned = 10; + }else{ + pGroup = &pcache1.grp; + } + pCache->pGroup = pGroup; pCache->szPage = szPage; pCache->bPurgeable = (bPurgeable ? 1 : 0); if( bPurgeable ){ pCache->nMin = 10; - pcache1EnterMutex(); - pcache1.nMinPage += pCache->nMin; - pcache1LeaveMutex(); + pcache1EnterMutex(pGroup); + pGroup->nMinPage += pCache->nMin; + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pcache1LeaveMutex(pGroup); } } return (sqlite3_pcache *)pCache; } /* -** Implementation of the sqlite3_pcache.xCachesize method. +** Implementation of the sqlite3_pcache.xCachesize method. ** ** Configure the cache_size limit for a cache. */ static void pcache1Cachesize(sqlite3_pcache *p, int nMax){ PCache1 *pCache = (PCache1 *)p; if( pCache->bPurgeable ){ - pcache1EnterMutex(); - pcache1.nMaxPage += (nMax - pCache->nMax); + PGroup *pGroup = pCache->pGroup; + pcache1EnterMutex(pGroup); + pGroup->nMaxPage += (nMax - pCache->nMax); + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; pCache->nMax = nMax; - pcache1EnforceMaxPage(); - pcache1LeaveMutex(); + pCache->n90pct = pCache->nMax*9/10; + pcache1EnforceMaxPage(pGroup); + pcache1LeaveMutex(pGroup); } } /* -** Implementation of the sqlite3_pcache.xPagecount method. +** Implementation of the sqlite3_pcache.xPagecount method. */ static int pcache1Pagecount(sqlite3_pcache *p){ int n; - pcache1EnterMutex(); - n = ((PCache1 *)p)->nPage; - pcache1LeaveMutex(); + PCache1 *pCache = (PCache1*)p; + pcache1EnterMutex(pCache->pGroup); + n = pCache->nPage; + pcache1LeaveMutex(pCache->pGroup); return n; } /* -** Implementation of the sqlite3_pcache.xFetch method. +** Implementation of the sqlite3_pcache.xFetch method. ** ** Fetch a page by key value. ** ** Whether or not a new page may be allocated by this function depends on ** the value of the createFlag argument. 0 means do not allocate a new -** page. 1 means allocate a new page if space is easily available. 2 +** page. 1 means allocate a new page if space is easily available. 2 ** means to try really hard to allocate a new page. ** ** For a non-purgeable cache (a cache used as the storage for an in-memory @@ -31474,62 +36658,87 @@ static int pcache1Pagecount(sqlite3_pcache *p){ ** There are three different approaches to obtaining space for a page, ** depending on the value of parameter createFlag (which may be 0, 1 or 2). ** -** 1. Regardless of the value of createFlag, the cache is searched for a +** 1. Regardless of the value of createFlag, the cache is searched for a ** copy of the requested page. If one is found, it is returned. ** ** 2. If createFlag==0 and the page is not already in the cache, NULL is ** returned. ** -** 3. If createFlag is 1, and the page is not already in the cache, -** and if either of the following are true, return NULL: +** 3. If createFlag is 1, and the page is not already in the cache, then +** return NULL (do not allocate a new page) if any of the following +** conditions are true: ** ** (a) the number of pages pinned by the cache is greater than ** PCache1.nMax, or +** ** (b) the number of pages pinned by the cache is greater than -** the sum of nMax for all purgeable caches, less the sum of -** nMin for all other purgeable caches. +** the sum of nMax for all purgeable caches, less the sum of +** nMin for all other purgeable caches, or ** ** 4. If none of the first three conditions apply and the cache is marked ** as purgeable, and if one of the following is true: ** -** (a) The number of pages allocated for the cache is already +** (a) The number of pages allocated for the cache is already ** PCache1.nMax, or ** ** (b) The number of pages allocated for all purgeable caches is ** already equal to or greater than the sum of nMax for all ** purgeable caches, ** +** (c) The system is under memory pressure and wants to avoid +** unnecessary pages cache entry allocations +** ** then attempt to recycle a page from the LRU list. If it is the right ** size, return the recycled buffer. Otherwise, free the buffer and -** proceed to step 5. +** proceed to step 5. ** ** 5. Otherwise, allocate and return a new page buffer. */ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ - unsigned int nPinned; + int nPinned; PCache1 *pCache = (PCache1 *)p; + PGroup *pGroup; PgHdr1 *pPage = 0; assert( pCache->bPurgeable || createFlag!=1 ); - pcache1EnterMutex(); - if( createFlag==1 ) sqlite3BeginBenignMalloc(); + assert( pCache->bPurgeable || pCache->nMin==0 ); + assert( pCache->bPurgeable==0 || pCache->nMin==10 ); + assert( pCache->nMin==0 || pCache->bPurgeable ); + pcache1EnterMutex(pGroup = pCache->pGroup); - /* Search the hash table for an existing entry. */ + /* Step 1: Search the hash table for an existing entry. */ if( pCache->nHash>0 ){ unsigned int h = iKey % pCache->nHash; for(pPage=pCache->apHash[h]; pPage&&pPage->iKey!=iKey; pPage=pPage->pNext); } + /* Step 2: Abort if no existing page is found and createFlag is 0 */ if( pPage || createFlag==0 ){ pcache1PinPage(pPage); goto fetch_out; } - /* Step 3 of header comment. */ + /* The pGroup local variable will normally be initialized by the + ** pcache1EnterMutex() macro above. But if SQLITE_MUTEX_OMIT is defined, + ** then pcache1EnterMutex() is a no-op, so we have to initialize the + ** local variable here. Delaying the initialization of pGroup is an + ** optimization: The common case is to exit the module before reaching + ** this point. + */ +#ifdef SQLITE_MUTEX_OMIT + pGroup = pCache->pGroup; +#endif + + + /* Step 3: Abort if createFlag is 1 but the cache is nearly full */ nPinned = pCache->nPage - pCache->nRecyclable; + assert( nPinned>=0 ); + assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); + assert( pCache->n90pct == pCache->nMax*9/10 ); if( createFlag==1 && ( - nPinned>=(pcache1.nMaxPage+pCache->nMin-pcache1.nMinPage) - || nPinned>=(pCache->nMax * 9 / 10) + nPinned>=pGroup->mxPinned + || nPinned>=(int)pCache->n90pct + || pcache1UnderMemoryPressure(pCache) )){ goto fetch_out; } @@ -31538,26 +36747,32 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ goto fetch_out; } - /* Step 4. Try to recycle a page buffer if appropriate. */ - if( pCache->bPurgeable && pcache1.pLruTail && ( - (pCache->nPage+1>=pCache->nMax) || pcache1.nCurrentPage>=pcache1.nMaxPage + /* Step 4. Try to recycle a page. */ + if( pCache->bPurgeable && pGroup->pLruTail && ( + (pCache->nPage+1>=pCache->nMax) + || pGroup->nCurrentPage>=pGroup->nMaxPage + || pcache1UnderMemoryPressure(pCache) )){ - pPage = pcache1.pLruTail; + PCache1 *pOtherCache; + pPage = pGroup->pLruTail; pcache1RemoveFromHash(pPage); pcache1PinPage(pPage); - if( pPage->pCache->szPage!=pCache->szPage ){ + if( (pOtherCache = pPage->pCache)->szPage!=pCache->szPage ){ pcache1FreePage(pPage); pPage = 0; }else{ - pcache1.nCurrentPage -= (pPage->pCache->bPurgeable - pCache->bPurgeable); + pGroup->nCurrentPage -= + (pOtherCache->bPurgeable - pCache->bPurgeable); } } - /* Step 5. If a usable page buffer has still not been found, - ** attempt to allocate a new one. + /* Step 5. If a usable page buffer has still not been found, + ** attempt to allocate a new one. */ if( !pPage ){ + if( createFlag==1 ) sqlite3BeginBenignMalloc(); pPage = pcache1AllocPage(pCache); + if( createFlag==1 ) sqlite3EndBenignMalloc(); } if( pPage ){ @@ -31576,8 +36791,7 @@ fetch_out: if( pPage && iKey>pCache->iMaxKey ){ pCache->iMaxKey = iKey; } - if( createFlag==1 ) sqlite3EndBenignMalloc(); - pcache1LeaveMutex(); + pcache1LeaveMutex(pGroup); return (pPage ? PGHDR1_TO_PAGE(pPage) : 0); } @@ -31590,41 +36804,38 @@ fetch_out: static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){ PCache1 *pCache = (PCache1 *)p; PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg); - + PGroup *pGroup = pCache->pGroup; + assert( pPage->pCache==pCache ); - pcache1EnterMutex(); + pcache1EnterMutex(pGroup); - /* It is an error to call this function if the page is already - ** part of the global LRU list. + /* It is an error to call this function if the page is already + ** part of the PGroup LRU list. */ assert( pPage->pLruPrev==0 && pPage->pLruNext==0 ); - assert( pcache1.pLruHead!=pPage && pcache1.pLruTail!=pPage ); + assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage ); - if( reuseUnlikely || pcache1.nCurrentPage>pcache1.nMaxPage ){ + if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){ pcache1RemoveFromHash(pPage); pcache1FreePage(pPage); }else{ - /* Add the page to the global LRU list. Normally, the page is added to - ** the head of the list (last page to be recycled). However, if the - ** reuseUnlikely flag passed to this function is true, the page is added - ** to the tail of the list (first page to be recycled). - */ - if( pcache1.pLruHead ){ - pcache1.pLruHead->pLruPrev = pPage; - pPage->pLruNext = pcache1.pLruHead; - pcache1.pLruHead = pPage; + /* Add the page to the PGroup LRU list. */ + if( pGroup->pLruHead ){ + pGroup->pLruHead->pLruPrev = pPage; + pPage->pLruNext = pGroup->pLruHead; + pGroup->pLruHead = pPage; }else{ - pcache1.pLruTail = pPage; - pcache1.pLruHead = pPage; + pGroup->pLruTail = pPage; + pGroup->pLruHead = pPage; } pCache->nRecyclable++; } - pcache1LeaveMutex(); + pcache1LeaveMutex(pCache->pGroup); } /* -** Implementation of the sqlite3_pcache.xRekey method. +** Implementation of the sqlite3_pcache.xRekey method. */ static void pcache1Rekey( sqlite3_pcache *p, @@ -31635,11 +36846,11 @@ static void pcache1Rekey( PCache1 *pCache = (PCache1 *)p; PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg); PgHdr1 **pp; - unsigned int h; + unsigned int h; assert( pPage->iKey==iOld ); assert( pPage->pCache==pCache ); - pcache1EnterMutex(); + pcache1EnterMutex(pCache->pGroup); h = iOld%pCache->nHash; pp = &pCache->apHash[h]; @@ -31656,11 +36867,11 @@ static void pcache1Rekey( pCache->iMaxKey = iNew; } - pcache1LeaveMutex(); + pcache1LeaveMutex(pCache->pGroup); } /* -** Implementation of the sqlite3_pcache.xTruncate method. +** Implementation of the sqlite3_pcache.xTruncate method. ** ** Discard all unpinned pages in the cache with a page number equal to ** or greater than parameter iLimit. Any pinned pages with a page number @@ -31668,27 +36879,30 @@ static void pcache1Rekey( */ static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){ PCache1 *pCache = (PCache1 *)p; - pcache1EnterMutex(); + pcache1EnterMutex(pCache->pGroup); if( iLimit<=pCache->iMaxKey ){ pcache1TruncateUnsafe(pCache, iLimit); pCache->iMaxKey = iLimit-1; } - pcache1LeaveMutex(); + pcache1LeaveMutex(pCache->pGroup); } /* -** Implementation of the sqlite3_pcache.xDestroy method. +** Implementation of the sqlite3_pcache.xDestroy method. ** ** Destroy a cache allocated using pcache1Create(). */ static void pcache1Destroy(sqlite3_pcache *p){ PCache1 *pCache = (PCache1 *)p; - pcache1EnterMutex(); + PGroup *pGroup = pCache->pGroup; + assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) ); + pcache1EnterMutex(pGroup); pcache1TruncateUnsafe(pCache, 0); - pcache1.nMaxPage -= pCache->nMax; - pcache1.nMinPage -= pCache->nMin; - pcache1EnforceMaxPage(); - pcache1LeaveMutex(); + pGroup->nMaxPage -= pCache->nMax; + pGroup->nMinPage -= pCache->nMin; + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pcache1EnforceMaxPage(pGroup); + pcache1LeaveMutex(pGroup); sqlite3_free(pCache->apHash); sqlite3_free(pCache); } @@ -31699,7 +36913,7 @@ static void pcache1Destroy(sqlite3_pcache *p){ ** already provided an alternative. */ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){ - static sqlite3_pcache_methods defaultMethods = { + static const sqlite3_pcache_methods defaultMethods = { 0, /* pArg */ pcache1Init, /* xInit */ pcache1Shutdown, /* xShutdown */ @@ -31722,21 +36936,26 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){ ** by the current thread may be sqlite3_free()ed. ** ** nReq is the number of bytes of memory required. Once this much has -** been released, the function returns. The return value is the total number +** been released, the function returns. The return value is the total number ** of bytes of memory released. */ SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){ int nFree = 0; +#ifdef SQLITE_PAGECACHE_BLOCKALLOC + if( pcache1.grp.isBusy ) return 0; +#endif + assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); + assert( sqlite3_mutex_notheld(pcache1.mutex) ); if( pcache1.pStart==0 ){ PgHdr1 *p; - pcache1EnterMutex(); - while( (nReq<0 || nFree<nReq) && (p=pcache1.pLruTail) ){ - nFree += sqlite3MallocSize(PGHDR1_TO_PAGE(p)); + pcache1EnterMutex(&pcache1.grp); + while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){ + nFree += pcache1MemSize(PGHDR1_TO_PAGE(p)); pcache1PinPage(p); pcache1RemoveFromHash(p); pcache1FreePage(p); } - pcache1LeaveMutex(); + pcache1LeaveMutex(&pcache1.grp); } return nFree; } @@ -31755,12 +36974,12 @@ SQLITE_PRIVATE void sqlite3PcacheStats( ){ PgHdr1 *p; int nRecyclable = 0; - for(p=pcache1.pLruHead; p; p=p->pLruNext){ + for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){ nRecyclable++; } - *pnCurrent = pcache1.nCurrentPage; - *pnMax = pcache1.nMaxPage; - *pnMin = pcache1.nMinPage; + *pnCurrent = pcache1.grp.nCurrentPage; + *pnMax = pcache1.grp.nMaxPage; + *pnMin = pcache1.grp.nMinPage; *pnRecyclable = nRecyclable; } #endif @@ -31804,7 +37023,7 @@ SQLITE_PRIVATE void sqlite3PcacheStats( ** extracts the least value from the RowSet. ** ** The INSERT primitive might allocate additional memory. Memory is -** allocated in chunks so most INSERTs do no allocation. There is an +** allocated in chunks so most INSERTs do no allocation. There is an ** upper bound on the size of allocated memory. No memory is freed ** until DESTROY. ** @@ -31845,7 +37064,7 @@ SQLITE_PRIVATE void sqlite3PcacheStats( /* ** Each entry in a RowSet is an instance of the following object. */ -struct RowSetEntry { +struct RowSetEntry { i64 v; /* ROWID value for this entry */ struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */ struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */ @@ -31887,7 +37106,7 @@ struct RowSet { ** ** It must be the case that N is sufficient to make a Rowset. If not ** an assertion fault occurs. -** +** ** If N is larger than the minimum, use the surplus as an initial ** allocation of entries available to be filled. */ @@ -31967,7 +37186,7 @@ SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){ /* ** Merge two lists of RowSetEntry objects. Remove duplicates. ** -** The input lists are connected via pRight pointers and are +** The input lists are connected via pRight pointers and are ** assumed to each already be in sorted order. */ static struct RowSetEntry *rowSetMerge( @@ -32005,7 +37224,7 @@ static struct RowSetEntry *rowSetMerge( /* ** Sort all elements on the pEntry list of the RowSet into ascending order. -*/ +*/ static void rowSetSort(RowSet *p){ unsigned int i; struct RowSetEntry *pEntry; @@ -32145,7 +37364,7 @@ static void rowSetToList(RowSet *p){ ** 0 if the RowSet is already empty. ** ** After this routine has been called, the sqlite3RowSetInsert() -** routine may not be called again. +** routine may not be called again. */ SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ rowSetToList(p); @@ -32203,7 +37422,7 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 i ** ************************************************************************* ** This is the implementation of the page cache subsystem or "pager". -** +** ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file @@ -32212,6 +37431,219 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 i ** another is writing. */ #ifndef SQLITE_OMIT_DISKIO +/************** Include wal.h in the middle of pager.c ***********************/ +/************** Begin file wal.h *********************************************/ +/* +** 2010 February 1 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface to the write-ahead logging +** system. Refer to the comments below and the header comment attached to +** the implementation of each function in log.c for further details. +*/ + +#ifndef _WAL_H_ +#define _WAL_H_ + + +#ifdef SQLITE_OMIT_WAL +# define sqlite3WalOpen(x,y,z) 0 +# define sqlite3WalLimit(x,y) +# define sqlite3WalClose(w,x,y,z) 0 +# define sqlite3WalBeginReadTransaction(y,z) 0 +# define sqlite3WalEndReadTransaction(z) +# define sqlite3WalRead(v,w,x,y,z) 0 +# define sqlite3WalDbsize(y) 0 +# define sqlite3WalBeginWriteTransaction(y) 0 +# define sqlite3WalEndWriteTransaction(x) 0 +# define sqlite3WalUndo(x,y,z) 0 +# define sqlite3WalSavepoint(y,z) +# define sqlite3WalSavepointUndo(y,z) 0 +# define sqlite3WalFrames(u,v,w,x,y,z) 0 +# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0 +# define sqlite3WalCallback(z) 0 +# define sqlite3WalExclusiveMode(y,z) 0 +# define sqlite3WalHeapMemory(z) 0 +#else + +#define WAL_SAVEPOINT_NDATA 4 + +/* Connection to a write-ahead log (WAL) file. +** There is one object of this type for each pager. +*/ +typedef struct Wal Wal; + +/* Open and close a connection to a write-ahead log. */ +SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**); +SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *); + +/* Set the limiting size of a WAL file. */ +SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64); + +/* Used by readers to open (lock) and close (unlock) a snapshot. A +** snapshot is like a read-transaction. It is the state of the database +** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and +** preserves the current state even if the other threads or processes +** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the +** transaction and releases the lock. +*/ +SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *); +SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal); + +/* Read a page from the write-ahead log, if it is present. */ +SQLITE_PRIVATE int sqlite3WalRead(Wal *pWal, Pgno pgno, int *pInWal, int nOut, u8 *pOut); + +/* If the WAL is not empty, return the size of the database. */ +SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal); + +/* Obtain or release the WRITER lock. */ +SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal); + +/* Undo any frames written (but not committed) to the log */ +SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx); + +/* Return an integer that records the current (uncommitted) write +** position in the WAL */ +SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData); + +/* Move the write position of the WAL back to iFrame. Called in +** response to a ROLLBACK TO command. */ +SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData); + +/* Write a frame or frames to the log. */ +SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int); + +/* Copy pages from the log to the database file */ +SQLITE_PRIVATE int sqlite3WalCheckpoint( + Wal *pWal, /* Write-ahead log connection */ + int eMode, /* One of PASSIVE, FULL and RESTART */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags to sync db file with (or 0) */ + int nBuf, /* Size of buffer nBuf */ + u8 *zBuf, /* Temporary buffer to use */ + int *pnLog, /* OUT: Number of frames in WAL */ + int *pnCkpt /* OUT: Number of backfilled frames in WAL */ +); + +/* Return the value to pass to a sqlite3_wal_hook callback, the +** number of frames in the WAL at the point of the last commit since +** sqlite3WalCallback() was called. If no commits have occurred since +** the last call, then return 0. +*/ +SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal); + +/* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released) +** by the pager layer on the database file. +*/ +SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op); + +/* Return true if the argument is non-NULL and the WAL module is using +** heap-memory for the wal-index. Otherwise, if the argument is NULL or the +** WAL module is using shared-memory, return false. +*/ +SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal); + +#endif /* ifndef SQLITE_OMIT_WAL */ +#endif /* _WAL_H_ */ + +/************** End of wal.h *************************************************/ +/************** Continuing where we left off in pager.c **********************/ + + +/******************* NOTES ON THE DESIGN OF THE PAGER ************************ +** +** This comment block describes invariants that hold when using a rollback +** journal. These invariants do not apply for journal_mode=WAL, +** journal_mode=MEMORY, or journal_mode=OFF. +** +** Within this comment block, a page is deemed to have been synced +** automatically as soon as it is written when PRAGMA synchronous=OFF. +** Otherwise, the page is not synced until the xSync method of the VFS +** is called successfully on the file containing the page. +** +** Definition: A page of the database file is said to be "overwriteable" if +** one or more of the following are true about the page: +** +** (a) The original content of the page as it was at the beginning of +** the transaction has been written into the rollback journal and +** synced. +** +** (b) The page was a freelist leaf page at the start of the transaction. +** +** (c) The page number is greater than the largest page that existed in +** the database file at the start of the transaction. +** +** (1) A page of the database file is never overwritten unless one of the +** following are true: +** +** (a) The page and all other pages on the same sector are overwriteable. +** +** (b) The atomic page write optimization is enabled, and the entire +** transaction other than the update of the transaction sequence +** number consists of a single page change. +** +** (2) The content of a page written into the rollback journal exactly matches +** both the content in the database when the rollback journal was written +** and the content in the database at the beginning of the current +** transaction. +** +** (3) Writes to the database file are an integer multiple of the page size +** in length and are aligned on a page boundary. +** +** (4) Reads from the database file are either aligned on a page boundary and +** an integer multiple of the page size in length or are taken from the +** first 100 bytes of the database file. +** +** (5) All writes to the database file are synced prior to the rollback journal +** being deleted, truncated, or zeroed. +** +** (6) If a master journal file is used, then all writes to the database file +** are synced prior to the master journal being deleted. +** +** Definition: Two databases (or the same database at two points it time) +** are said to be "logically equivalent" if they give the same answer to +** all queries. Note in particular the the content of freelist leaf +** pages can be changed arbitarily without effecting the logical equivalence +** of the database. +** +** (7) At any time, if any subset, including the empty set and the total set, +** of the unsynced changes to a rollback journal are removed and the +** journal is rolled back, the resulting database file will be logical +** equivalent to the database file at the beginning of the transaction. +** +** (8) When a transaction is rolled back, the xTruncate method of the VFS +** is called to restore the database file to the same size it was at +** the beginning of the transaction. (In some VFSes, the xTruncate +** method is a no-op, but that does not change the fact the SQLite will +** invoke it.) +** +** (9) Whenever the database file is modified, at least one bit in the range +** of bytes from 24 through 39 inclusive will be changed prior to releasing +** the EXCLUSIVE lock, thus signaling other connections on the same +** database to flush their caches. +** +** (10) The pattern of bits in bytes 24 through 39 shall not repeat in less +** than one billion transactions. +** +** (11) A database file is well-formed at the beginning and at the conclusion +** of every transaction. +** +** (12) An EXCLUSIVE lock is held on the database file when writing to +** the database file. +** +** (13) A SHARED lock is held on the database file while reading any +** content out of the database file. +** +******************************************************************************/ /* ** Macros for troubleshooting. Normally turned off @@ -32226,7 +37658,7 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ /* ** The following two macros are used within the PAGERTRACE() macros above -** to print out file-descriptors. +** to print out file-descriptors. ** ** PAGERID() takes a pointer to a Pager struct as its argument. The ** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file @@ -32236,58 +37668,279 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ #define FILEHANDLEID(fd) ((int)fd) /* -** The page cache as a whole is always in one of the following -** states: -** -** PAGER_UNLOCK The page cache is not currently reading or -** writing the database file. There is no -** data held in memory. This is the initial -** state. -** -** PAGER_SHARED The page cache is reading the database. -** Writing is not permitted. There can be -** multiple readers accessing the same database -** file at the same time. -** -** PAGER_RESERVED This process has reserved the database for writing -** but has not yet made any changes. Only one process -** at a time can reserve the database. The original -** database file has not been modified so other -** processes may still be reading the on-disk -** database file. -** -** PAGER_EXCLUSIVE The page cache is writing the database. -** Access is exclusive. No other processes or -** threads can be reading or writing while one -** process is writing. -** -** PAGER_SYNCED The pager moves to this state from PAGER_EXCLUSIVE -** after all dirty pages have been written to the -** database file and the file has been synced to -** disk. All that remains to do is to remove or -** truncate the journal file and the transaction -** will be committed. -** -** The page cache comes up in PAGER_UNLOCK. The first time a -** sqlite3PagerGet() occurs, the state transitions to PAGER_SHARED. -** After all pages have been released using sqlite_page_unref(), -** the state transitions back to PAGER_UNLOCK. The first time -** that sqlite3PagerWrite() is called, the state transitions to -** PAGER_RESERVED. (Note that sqlite3PagerWrite() can only be -** called on an outstanding page which means that the pager must -** be in PAGER_SHARED before it transitions to PAGER_RESERVED.) -** PAGER_RESERVED means that there is an open rollback journal. -** The transition to PAGER_EXCLUSIVE occurs before any changes -** are made to the database file, though writes to the rollback -** journal occurs with just PAGER_RESERVED. After an sqlite3PagerRollback() -** or sqlite3PagerCommitPhaseTwo(), the state can go back to PAGER_SHARED, -** or it can stay at PAGER_EXCLUSIVE if we are in exclusive access mode. -*/ -#define PAGER_UNLOCK 0 -#define PAGER_SHARED 1 /* same as SHARED_LOCK */ -#define PAGER_RESERVED 2 /* same as RESERVED_LOCK */ -#define PAGER_EXCLUSIVE 4 /* same as EXCLUSIVE_LOCK */ -#define PAGER_SYNCED 5 +** The Pager.eState variable stores the current 'state' of a pager. A +** pager may be in any one of the seven states shown in the following +** state diagram. +** +** OPEN <------+------+ +** | | | +** V | | +** +---------> READER-------+ | +** | | | +** | V | +** |<-------WRITER_LOCKED------> ERROR +** | | ^ +** | V | +** |<------WRITER_CACHEMOD-------->| +** | | | +** | V | +** |<-------WRITER_DBMOD---------->| +** | | | +** | V | +** +<------WRITER_FINISHED-------->+ +** +** +** List of state transitions and the C [function] that performs each: +** +** OPEN -> READER [sqlite3PagerSharedLock] +** READER -> OPEN [pager_unlock] +** +** READER -> WRITER_LOCKED [sqlite3PagerBegin] +** WRITER_LOCKED -> WRITER_CACHEMOD [pager_open_journal] +** WRITER_CACHEMOD -> WRITER_DBMOD [syncJournal] +** WRITER_DBMOD -> WRITER_FINISHED [sqlite3PagerCommitPhaseOne] +** WRITER_*** -> READER [pager_end_transaction] +** +** WRITER_*** -> ERROR [pager_error] +** ERROR -> OPEN [pager_unlock] +** +** +** OPEN: +** +** The pager starts up in this state. Nothing is guaranteed in this +** state - the file may or may not be locked and the database size is +** unknown. The database may not be read or written. +** +** * No read or write transaction is active. +** * Any lock, or no lock at all, may be held on the database file. +** * The dbSize, dbOrigSize and dbFileSize variables may not be trusted. +** +** READER: +** +** In this state all the requirements for reading the database in +** rollback (non-WAL) mode are met. Unless the pager is (or recently +** was) in exclusive-locking mode, a user-level read transaction is +** open. The database size is known in this state. +** +** A connection running with locking_mode=normal enters this state when +** it opens a read-transaction on the database and returns to state +** OPEN after the read-transaction is completed. However a connection +** running in locking_mode=exclusive (including temp databases) remains in +** this state even after the read-transaction is closed. The only way +** a locking_mode=exclusive connection can transition from READER to OPEN +** is via the ERROR state (see below). +** +** * A read transaction may be active (but a write-transaction cannot). +** * A SHARED or greater lock is held on the database file. +** * The dbSize variable may be trusted (even if a user-level read +** transaction is not active). The dbOrigSize and dbFileSize variables +** may not be trusted at this point. +** * If the database is a WAL database, then the WAL connection is open. +** * Even if a read-transaction is not open, it is guaranteed that +** there is no hot-journal in the file-system. +** +** WRITER_LOCKED: +** +** The pager moves to this state from READER when a write-transaction +** is first opened on the database. In WRITER_LOCKED state, all locks +** required to start a write-transaction are held, but no actual +** modifications to the cache or database have taken place. +** +** In rollback mode, a RESERVED or (if the transaction was opened with +** BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when +** moving to this state, but the journal file is not written to or opened +** to in this state. If the transaction is committed or rolled back while +** in WRITER_LOCKED state, all that is required is to unlock the database +** file. +** +** IN WAL mode, WalBeginWriteTransaction() is called to lock the log file. +** If the connection is running with locking_mode=exclusive, an attempt +** is made to obtain an EXCLUSIVE lock on the database file. +** +** * A write transaction is active. +** * If the connection is open in rollback-mode, a RESERVED or greater +** lock is held on the database file. +** * If the connection is open in WAL-mode, a WAL write transaction +** is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully +** called). +** * The dbSize, dbOrigSize and dbFileSize variables are all valid. +** * The contents of the pager cache have not been modified. +** * The journal file may or may not be open. +** * Nothing (not even the first header) has been written to the journal. +** +** WRITER_CACHEMOD: +** +** A pager moves from WRITER_LOCKED state to this state when a page is +** first modified by the upper layer. In rollback mode the journal file +** is opened (if it is not already open) and a header written to the +** start of it. The database file on disk has not been modified. +** +** * A write transaction is active. +** * A RESERVED or greater lock is held on the database file. +** * The journal file is open and the first header has been written +** to it, but the header has not been synced to disk. +** * The contents of the page cache have been modified. +** +** WRITER_DBMOD: +** +** The pager transitions from WRITER_CACHEMOD into WRITER_DBMOD state +** when it modifies the contents of the database file. WAL connections +** never enter this state (since they do not modify the database file, +** just the log file). +** +** * A write transaction is active. +** * An EXCLUSIVE or greater lock is held on the database file. +** * The journal file is open and the first header has been written +** and synced to disk. +** * The contents of the page cache have been modified (and possibly +** written to disk). +** +** WRITER_FINISHED: +** +** It is not possible for a WAL connection to enter this state. +** +** A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD +** state after the entire transaction has been successfully written into the +** database file. In this state the transaction may be committed simply +** by finalizing the journal file. Once in WRITER_FINISHED state, it is +** not possible to modify the database further. At this point, the upper +** layer must either commit or rollback the transaction. +** +** * A write transaction is active. +** * An EXCLUSIVE or greater lock is held on the database file. +** * All writing and syncing of journal and database data has finished. +** If no error occured, all that remains is to finalize the journal to +** commit the transaction. If an error did occur, the caller will need +** to rollback the transaction. +** +** ERROR: +** +** The ERROR state is entered when an IO or disk-full error (including +** SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it +** difficult to be sure that the in-memory pager state (cache contents, +** db size etc.) are consistent with the contents of the file-system. +** +** Temporary pager files may enter the ERROR state, but in-memory pagers +** cannot. +** +** For example, if an IO error occurs while performing a rollback, +** the contents of the page-cache may be left in an inconsistent state. +** At this point it would be dangerous to change back to READER state +** (as usually happens after a rollback). Any subsequent readers might +** report database corruption (due to the inconsistent cache), and if +** they upgrade to writers, they may inadvertently corrupt the database +** file. To avoid this hazard, the pager switches into the ERROR state +** instead of READER following such an error. +** +** Once it has entered the ERROR state, any attempt to use the pager +** to read or write data returns an error. Eventually, once all +** outstanding transactions have been abandoned, the pager is able to +** transition back to OPEN state, discarding the contents of the +** page-cache and any other in-memory state at the same time. Everything +** is reloaded from disk (and, if necessary, hot-journal rollback peformed) +** when a read-transaction is next opened on the pager (transitioning +** the pager into READER state). At that point the system has recovered +** from the error. +** +** Specifically, the pager jumps into the ERROR state if: +** +** 1. An error occurs while attempting a rollback. This happens in +** function sqlite3PagerRollback(). +** +** 2. An error occurs while attempting to finalize a journal file +** following a commit in function sqlite3PagerCommitPhaseTwo(). +** +** 3. An error occurs while attempting to write to the journal or +** database file in function pagerStress() in order to free up +** memory. +** +** In other cases, the error is returned to the b-tree layer. The b-tree +** layer then attempts a rollback operation. If the error condition +** persists, the pager enters the ERROR state via condition (1) above. +** +** Condition (3) is necessary because it can be triggered by a read-only +** statement executed within a transaction. In this case, if the error +** code were simply returned to the user, the b-tree layer would not +** automatically attempt a rollback, as it assumes that an error in a +** read-only statement cannot leave the pager in an internally inconsistent +** state. +** +** * The Pager.errCode variable is set to something other than SQLITE_OK. +** * There are one or more outstanding references to pages (after the +** last reference is dropped the pager should move back to OPEN state). +** * The pager is not an in-memory pager. +** +** +** Notes: +** +** * A pager is never in WRITER_DBMOD or WRITER_FINISHED state if the +** connection is open in WAL mode. A WAL connection is always in one +** of the first four states. +** +** * Normally, a connection open in exclusive mode is never in PAGER_OPEN +** state. There are two exceptions: immediately after exclusive-mode has +** been turned on (and before any read or write transactions are +** executed), and when the pager is leaving the "error state". +** +** * See also: assert_pager_state(). +*/ +#define PAGER_OPEN 0 +#define PAGER_READER 1 +#define PAGER_WRITER_LOCKED 2 +#define PAGER_WRITER_CACHEMOD 3 +#define PAGER_WRITER_DBMOD 4 +#define PAGER_WRITER_FINISHED 5 +#define PAGER_ERROR 6 + +/* +** The Pager.eLock variable is almost always set to one of the +** following locking-states, according to the lock currently held on +** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. +** This variable is kept up to date as locks are taken and released by +** the pagerLockDb() and pagerUnlockDb() wrappers. +** +** If the VFS xLock() or xUnlock() returns an error other than SQLITE_BUSY +** (i.e. one of the SQLITE_IOERR subtypes), it is not clear whether or not +** the operation was successful. In these circumstances pagerLockDb() and +** pagerUnlockDb() take a conservative approach - eLock is always updated +** when unlocking the file, and only updated when locking the file if the +** VFS call is successful. This way, the Pager.eLock variable may be set +** to a less exclusive (lower) value than the lock that is actually held +** at the system level, but it is never set to a more exclusive value. +** +** This is usually safe. If an xUnlock fails or appears to fail, there may +** be a few redundant xLock() calls or a lock may be held for longer than +** required, but nothing really goes wrong. +** +** The exception is when the database file is unlocked as the pager moves +** from ERROR to OPEN state. At this point there may be a hot-journal file +** in the file-system that needs to be rolled back (as part of a OPEN->SHARED +** transition, by the same pager or any other). If the call to xUnlock() +** fails at this point and the pager is left holding an EXCLUSIVE lock, this +** can confuse the call to xCheckReservedLock() call made later as part +** of hot-journal detection. +** +** xCheckReservedLock() is defined as returning true "if there is a RESERVED +** lock held by this process or any others". So xCheckReservedLock may +** return true because the caller itself is holding an EXCLUSIVE lock (but +** doesn't know it because of a previous error in xUnlock). If this happens +** a hot-journal may be mistaken for a journal being created by an active +** transaction in another process, causing SQLite to read from the database +** without rolling it back. +** +** To work around this, if a call to xUnlock() fails when unlocking the +** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It +** is only changed back to a real locking state after a successful call +** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition +** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK +** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE +** lock on the database file before attempting to roll it back. See function +** PagerSharedLock() for more detail. +** +** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in +** PAGER_OPEN state. +*/ +#define UNKNOWN_LOCK (EXCLUSIVE_LOCK+1) /* ** A macro used for invoking the codec if there is one @@ -32304,7 +37957,7 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ #endif /* -** The maximum allowed sector size. 64KiB. If the xSectorsize() method +** The maximum allowed sector size. 64KiB. If the xSectorsize() method ** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. ** This could conceivably cause corruption following a power failure on ** such a system. This is currently an undocumented limit. @@ -32319,7 +37972,7 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ ** ** When a savepoint is created, the PagerSavepoint.iHdrOffset field is ** set to 0. If a journal-header is written into the main journal while -** the savepoint is active, then iHdrOffset is set to the byte offset +** the savepoint is active, then iHdrOffset is set to the byte offset ** immediately following the last journal record written into the main ** journal before the journal-header. This is required during savepoint ** rollback (see pagerPlaybackSavepoint()). @@ -32331,140 +37984,199 @@ struct PagerSavepoint { Bitvec *pInSavepoint; /* Set of pages in this savepoint */ Pgno nOrig; /* Original number of pages in file */ Pgno iSubRec; /* Index of first record in sub-journal */ +#ifndef SQLITE_OMIT_WAL + u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ +#endif }; /* -** A open page cache is an instance of the following structure. +** A open page cache is an instance of struct Pager. A description of +** some of the more important member variables follows: ** -** errCode +** eState ** -** Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, or -** or SQLITE_FULL. Once one of the first three errors occurs, it persists -** and is returned as the result of every major pager API call. The -** SQLITE_FULL return code is slightly different. It persists only until the -** next successful rollback is performed on the pager cache. Also, -** SQLITE_FULL does not affect the sqlite3PagerGet() and sqlite3PagerLookup() -** APIs, they may still be used successfully. -** -** dbSizeValid, dbSize, dbOrigSize, dbFileSize -** -** Managing the size of the database file in pages is a little complicated. -** The variable Pager.dbSize contains the number of pages that the database -** image currently contains. As the database image grows or shrinks this -** variable is updated. The variable Pager.dbFileSize contains the number -** of pages in the database file. This may be different from Pager.dbSize -** if some pages have been appended to the database image but not yet written -** out from the cache to the actual file on disk. Or if the image has been -** truncated by an incremental-vacuum operation. The Pager.dbOrigSize variable -** contains the number of pages in the database image when the current -** transaction was opened. The contents of all three of these variables is -** only guaranteed to be correct if the boolean Pager.dbSizeValid is true. -** -** TODO: Under what conditions is dbSizeValid set? Cleared? +** The current 'state' of the pager object. See the comment and state +** diagram above for a description of the pager state. +** +** eLock +** +** For a real on-disk database, the current lock held on the database file - +** NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. +** +** For a temporary or in-memory database (neither of which require any +** locks), this variable is always set to EXCLUSIVE_LOCK. Since such +** databases always have Pager.exclusiveMode==1, this tricks the pager +** logic into thinking that it already has all the locks it will ever +** need (and no reason to release them). +** +** In some (obscure) circumstances, this variable may also be set to +** UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for +** details. ** ** changeCountDone ** -** This boolean variable is used to make sure that the change-counter -** (the 4-byte header field at byte offset 24 of the database file) is -** not updated more often than necessary. +** This boolean variable is used to make sure that the change-counter +** (the 4-byte header field at byte offset 24 of the database file) is +** not updated more often than necessary. ** -** It is set to true when the change-counter field is updated, which +** It is set to true when the change-counter field is updated, which ** can only happen if an exclusive lock is held on the database file. -** It is cleared (set to false) whenever an exclusive lock is +** It is cleared (set to false) whenever an exclusive lock is ** relinquished on the database file. Each time a transaction is committed, ** The changeCountDone flag is inspected. If it is true, the work of ** updating the change-counter is omitted for the current transaction. ** -** This mechanism means that when running in exclusive mode, a connection +** This mechanism means that when running in exclusive mode, a connection ** need only update the change-counter once, for the first transaction ** committed. ** -** dbModified -** -** The dbModified flag is set whenever a database page is dirtied. -** It is cleared at the end of each transaction. -** -** It is used when committing or otherwise ending a transaction. If -** the dbModified flag is clear then less work has to be done. -** -** journalStarted -** -** This flag is set whenever the the main journal is synced. -** -** The point of this flag is that it must be set after the -** first journal header in a journal file has been synced to disk. -** After this has happened, new pages appended to the database -** do not need the PGHDR_NEED_SYNC flag set, as they do not need -** to wait for a journal sync before they can be written out to -** the database file (see function pager_write()). -** ** setMaster ** -** This variable is used to ensure that the master journal file name -** (if any) is only written into the journal file once. -** -** When committing a transaction, the master journal file name (if any) -** may be written into the journal file while the pager is still in -** PAGER_RESERVED state (see CommitPhaseOne() for the action). It -** then attempts to upgrade to an exclusive lock. If this attempt -** fails, then SQLITE_BUSY may be returned to the user and the user -** may attempt to commit the transaction again later (calling -** CommitPhaseOne() again). This flag is used to ensure that the -** master journal name is only written to the journal file the first -** time CommitPhaseOne() is called. -** -** doNotSync -** -** This variable is set and cleared by sqlite3PagerWrite(). -** -** needSync -** -** TODO: It might be easier to set this variable in writeJournalHdr() -** and writeMasterJournal() only. Change its meaning to "unsynced data -** has been written to the journal". +** When PagerCommitPhaseOne() is called to commit a transaction, it may +** (or may not) specify a master-journal name to be written into the +** journal file before it is synced to disk. +** +** Whether or not a journal file contains a master-journal pointer affects +** the way in which the journal file is finalized after the transaction is +** committed or rolled back when running in "journal_mode=PERSIST" mode. +** If a journal file does not contain a master-journal pointer, it is +** finalized by overwriting the first journal header with zeroes. If +** it does contain a master-journal pointer the journal file is finalized +** by truncating it to zero bytes, just as if the connection were +** running in "journal_mode=truncate" mode. +** +** Journal files that contain master journal pointers cannot be finalized +** simply by overwriting the first journal-header with zeroes, as the +** master journal pointer could interfere with hot-journal rollback of any +** subsequently interrupted transaction that reuses the journal file. +** +** The flag is cleared as soon as the journal file is finalized (either +** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the +** journal file from being successfully finalized, the setMaster flag +** is cleared anyway (and the pager will move to ERROR state). +** +** doNotSpill, doNotSyncSpill +** +** These two boolean variables control the behaviour of cache-spills +** (calls made by the pcache module to the pagerStress() routine to +** write cached data to the file-system in order to free up memory). +** +** When doNotSpill is non-zero, writing to the database from pagerStress() +** is disabled altogether. This is done in a very obscure case that +** comes up during savepoint rollback that requires the pcache module +** to allocate a new page to prevent the journal file from being written +** while it is being traversed by code in pager_playback(). +** +** If doNotSyncSpill is non-zero, writing to the database from pagerStress() +** is permitted, but syncing the journal file is not. This flag is set +** by sqlite3PagerWrite() when the file-system sector-size is larger than +** the database page-size in order to prevent a journal sync from happening +** in between the journalling of two pages on the same sector. ** ** subjInMemory ** ** This is a boolean variable. If true, then any required sub-journal ** is opened as an in-memory journal file. If false, then in-memory ** sub-journals are only used for in-memory pager files. +** +** This variable is updated by the upper layer each time a new +** write-transaction is opened. +** +** dbSize, dbOrigSize, dbFileSize +** +** Variable dbSize is set to the number of pages in the database file. +** It is valid in PAGER_READER and higher states (all states except for +** OPEN and ERROR). +** +** dbSize is set based on the size of the database file, which may be +** larger than the size of the database (the value stored at offset +** 28 of the database header by the btree). If the size of the file +** is not an integer multiple of the page-size, the value stored in +** dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2). +** Except, any file that is greater than 0 bytes in size is considered +** to have at least one page. (i.e. a 1KB file with 2K page-size leads +** to dbSize==1). +** +** During a write-transaction, if pages with page-numbers greater than +** dbSize are modified in the cache, dbSize is updated accordingly. +** Similarly, if the database is truncated using PagerTruncateImage(), +** dbSize is updated. +** +** Variables dbOrigSize and dbFileSize are valid in states +** PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize +** variable at the start of the transaction. It is used during rollback, +** and to determine whether or not pages need to be journalled before +** being modified. +** +** Throughout a write-transaction, dbFileSize contains the size of +** the file on disk in pages. It is set to a copy of dbSize when the +** write-transaction is first opened, and updated when VFS calls are made +** to write or truncate the database file on disk. +** +** The only reason the dbFileSize variable is required is to suppress +** unnecessary calls to xTruncate() after committing a transaction. If, +** when a transaction is committed, the dbFileSize variable indicates +** that the database file is larger than the database image (Pager.dbSize), +** pager_truncate() is called. The pager_truncate() call uses xFilesize() +** to measure the database file on disk, and then truncates it if required. +** dbFileSize is not used when rolling back a transaction. In this case +** pager_truncate() is called unconditionally (which means there may be +** a call to xFilesize() that is not strictly required). In either case, +** pager_truncate() may cause the file to become smaller or larger. +** +** dbHintSize +** +** The dbHintSize variable is used to limit the number of calls made to +** the VFS xFileControl(FCNTL_SIZE_HINT) method. +** +** dbHintSize is set to a copy of the dbSize variable when a +** write-transaction is opened (at the same time as dbFileSize and +** dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called, +** dbHintSize is increased to the number of pages that correspond to the +** size-hint passed to the method call. See pager_write_pagelist() for +** details. +** +** errCode +** +** The Pager.errCode variable is only ever used in PAGER_ERROR state. It +** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode +** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX +** sub-codes. */ struct Pager { sqlite3_vfs *pVfs; /* OS functions to use for IO */ u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ - u8 journalMode; /* On of the PAGER_JOURNALMODE_* values */ + u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ u8 useJournal; /* Use a rollback journal on this file */ u8 noReadlock; /* Do not bother to obtain readlocks */ u8 noSync; /* Do not sync the journal if true */ u8 fullSync; /* Do extra syncs of the journal for robustness */ - u8 sync_flags; /* One of SYNC_NORMAL or SYNC_FULL */ + u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ + u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ u8 tempFile; /* zFilename is a temporary file */ u8 readOnly; /* True for a read-only database */ u8 memDb; /* True to inhibit all file I/O */ - /* The following block contains those class members that are dynamically - ** modified during normal operations. The other variables in this structure - ** are either constant throughout the lifetime of the pager, or else - ** used to store configuration parameters that affect the way the pager - ** operates. - ** - ** The 'state' variable is described in more detail along with the - ** descriptions of the values it may take - PAGER_UNLOCK etc. Many of the - ** other variables in this block are described in the comment directly - ** above this class definition. - */ - u8 state; /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */ - u8 dbModified; /* True if there are any changes to the Db */ - u8 needSync; /* True if an fsync() is needed on the journal */ - u8 journalStarted; /* True if header of journal is synced */ + /************************************************************************** + ** The following block contains those class members that change during + ** routine opertion. Class members not in this block are either fixed + ** when the pager is first created or else only change when there is a + ** significant mode change (such as changing the page_size, locking_mode, + ** or the journal_mode). From another view, these class members describe + ** the "state" of the pager, while other class members describe the + ** "configuration" of the pager. + */ + u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ + u8 eLock; /* Current lock held on database file */ u8 changeCountDone; /* Set after incrementing the change-counter */ u8 setMaster; /* True if a m-j name has been written to jrnl */ - u8 doNotSync; /* Boolean. While true, do not spill the cache */ - u8 dbSizeValid; /* Set when dbSize is correct */ + u8 doNotSpill; /* Do not spill the cache when non-zero */ + u8 doNotSyncSpill; /* Do not do a spill that requires jrnl sync */ u8 subjInMemory; /* True to use in-memory sub-journals */ Pgno dbSize; /* Number of pages in the database */ Pgno dbOrigSize; /* dbSize before the current transaction */ Pgno dbFileSize; /* Number of pages in the database file */ + Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */ int errCode; /* One of several kinds of errors */ int nRec; /* Pages journalled since last j-header written */ u32 cksumInit; /* Quasi-random value added to every checksum */ @@ -32475,16 +38187,21 @@ struct Pager { sqlite3_file *sjfd; /* File descriptor for sub-journal */ i64 journalOff; /* Current write offset in the journal file */ i64 journalHdr; /* Byte offset to previous journal header */ + sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ PagerSavepoint *aSavepoint; /* Array of active savepoints */ int nSavepoint; /* Number of elements in aSavepoint[] */ char dbFileVers[16]; /* Changes whenever database file changes */ - u32 sectorSize; /* Assumed sector size during rollback */ + /* + ** End of the routinely-changing class members + ***************************************************************************/ u16 nExtra; /* Add this many bytes to each in-memory page */ i16 nReserve; /* Number of unused bytes at end of each page */ u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ + u32 sectorSize; /* Assumed sector size during rollback */ int pageSize; /* Number of bytes in a page */ Pgno mxPgno; /* Maximum allowed size of the database */ + i64 journalSizeLimit; /* Size limit for persistent journal files */ char *zFilename; /* Name of the database file */ char *zJournal; /* Name of the journal file */ int (*xBusyHandler)(void*); /* Function to call when busy */ @@ -32501,9 +38218,11 @@ struct Pager { void *pCodec; /* First argument to xCodec... methods */ #endif char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ - i64 journalSizeLimit; /* Size limit for persistent journal files */ PCache *pPCache; /* Pointer to page cache object */ - sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ +#ifndef SQLITE_OMIT_WAL + Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ + char *zWal; /* File name for write-ahead log */ +#endif }; /* @@ -32556,7 +38275,7 @@ static const unsigned char aJournalMagic[] = { #define JOURNAL_PG_SZ(pPager) ((pPager->pageSize) + 8) /* -** The journal header size for this pager. This is usually the same +** The journal header size for this pager. This is usually the same ** size as a single disk sector. See also setSectorSize(). */ #define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize) @@ -32578,22 +38297,223 @@ static const unsigned char aJournalMagic[] = { */ #define PAGER_MAX_PGNO 2147483647 -#ifndef NDEBUG +/* +** The argument to this macro is a file descriptor (type sqlite3_file*). +** Return 0 if it is not open, or non-zero (but not 1) if it is. +** +** This is so that expressions can be written as: +** +** if( isOpen(pPager->jfd) ){ ... +** +** instead of +** +** if( pPager->jfd->pMethods ){ ... +*/ +#define isOpen(pFd) ((pFd)->pMethods) + +/* +** Return true if this pager uses a write-ahead log instead of the usual +** rollback journal. Otherwise false. +*/ +#ifndef SQLITE_OMIT_WAL +static int pagerUseWal(Pager *pPager){ + return (pPager->pWal!=0); +} +#else +# define pagerUseWal(x) 0 +# define pagerRollbackWal(x) 0 +# define pagerWalFrames(v,w,x,y,z) 0 +# define pagerOpenWalIfPresent(z) SQLITE_OK +# define pagerBeginReadTransaction(z) SQLITE_OK +#endif + +#ifndef NDEBUG /* ** Usage: ** ** assert( assert_pager_state(pPager) ); +** +** This function runs many asserts to try to find inconsistencies in +** the internal state of the Pager object. */ -static int assert_pager_state(Pager *pPager){ +static int assert_pager_state(Pager *p){ + Pager *pPager = p; - /* A temp-file is always in PAGER_EXCLUSIVE or PAGER_SYNCED state. */ - assert( pPager->tempFile==0 || pPager->state>=PAGER_EXCLUSIVE ); + /* State must be valid. */ + assert( p->eState==PAGER_OPEN + || p->eState==PAGER_READER + || p->eState==PAGER_WRITER_LOCKED + || p->eState==PAGER_WRITER_CACHEMOD + || p->eState==PAGER_WRITER_DBMOD + || p->eState==PAGER_WRITER_FINISHED + || p->eState==PAGER_ERROR + ); + + /* Regardless of the current state, a temp-file connection always behaves + ** as if it has an exclusive lock on the database file. It never updates + ** the change-counter field, so the changeCountDone flag is always set. + */ + assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK ); + assert( p->tempFile==0 || pPager->changeCountDone ); + + /* If the useJournal flag is clear, the journal-mode must be "OFF". + ** And if the journal-mode is "OFF", the journal file must not be open. + */ + assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal ); + assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) ); + + /* Check that MEMDB implies noSync. And an in-memory journal. Since + ** this means an in-memory pager performs no IO at all, it cannot encounter + ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing + ** a journal file. (although the in-memory journal implementation may + ** return SQLITE_IOERR_NOMEM while the journal file is being written). It + ** is therefore not possible for an in-memory pager to enter the ERROR + ** state. + */ + if( MEMDB ){ + assert( p->noSync ); + assert( p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_MEMORY + ); + assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); + assert( pagerUseWal(p)==0 ); + } - /* The changeCountDone flag is always set for temp-files */ - assert( pPager->tempFile==0 || pPager->changeCountDone ); + /* If changeCountDone is set, a RESERVED lock or greater must be held + ** on the file. + */ + assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK ); + assert( p->eLock!=PENDING_LOCK ); + + switch( p->eState ){ + case PAGER_OPEN: + assert( !MEMDB ); + assert( pPager->errCode==SQLITE_OK ); + assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile ); + break; + + case PAGER_READER: + assert( pPager->errCode==SQLITE_OK ); + assert( p->eLock!=UNKNOWN_LOCK ); + assert( p->eLock>=SHARED_LOCK || p->noReadlock ); + break; + + case PAGER_WRITER_LOCKED: + assert( p->eLock!=UNKNOWN_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + if( !pagerUseWal(pPager) ){ + assert( p->eLock>=RESERVED_LOCK ); + } + assert( pPager->dbSize==pPager->dbOrigSize ); + assert( pPager->dbOrigSize==pPager->dbFileSize ); + assert( pPager->dbOrigSize==pPager->dbHintSize ); + assert( pPager->setMaster==0 ); + break; + + case PAGER_WRITER_CACHEMOD: + assert( p->eLock!=UNKNOWN_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + if( !pagerUseWal(pPager) ){ + /* It is possible that if journal_mode=wal here that neither the + ** journal file nor the WAL file are open. This happens during + ** a rollback transaction that switches from journal_mode=off + ** to journal_mode=wal. + */ + assert( p->eLock>=RESERVED_LOCK ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + ); + } + assert( pPager->dbOrigSize==pPager->dbFileSize ); + assert( pPager->dbOrigSize==pPager->dbHintSize ); + break; + + case PAGER_WRITER_DBMOD: + assert( p->eLock==EXCLUSIVE_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + assert( !pagerUseWal(pPager) ); + assert( p->eLock>=EXCLUSIVE_LOCK ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + ); + assert( pPager->dbOrigSize<=pPager->dbHintSize ); + break; + + case PAGER_WRITER_FINISHED: + assert( p->eLock==EXCLUSIVE_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + assert( !pagerUseWal(pPager) ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + ); + break; + + case PAGER_ERROR: + /* There must be at least one outstanding reference to the pager if + ** in ERROR state. Otherwise the pager should have already dropped + ** back to OPEN state. + */ + assert( pPager->errCode!=SQLITE_OK ); + assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); + break; + } return 1; } +#endif /* ifndef NDEBUG */ + +#ifdef SQLITE_DEBUG +/* +** Return a pointer to a human readable string in a static buffer +** containing the state of the Pager object passed as an argument. This +** is intended to be used within debuggers. For example, as an alternative +** to "print *pPager" in gdb: +** +** (gdb) printf "%s", print_pager_state(pPager) +*/ +static char *print_pager_state(Pager *p){ + static char zRet[1024]; + + sqlite3_snprintf(1024, zRet, + "Filename: %s\n" + "State: %s errCode=%d\n" + "Lock: %s\n" + "Locking mode: locking_mode=%s\n" + "Journal mode: journal_mode=%s\n" + "Backing store: tempFile=%d memDb=%d useJournal=%d\n" + "Journal: journalOff=%lld journalHdr=%lld\n" + "Size: dbsize=%d dbOrigSize=%d dbFileSize=%d\n" + , p->zFilename + , p->eState==PAGER_OPEN ? "OPEN" : + p->eState==PAGER_READER ? "READER" : + p->eState==PAGER_WRITER_LOCKED ? "WRITER_LOCKED" : + p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" : + p->eState==PAGER_WRITER_DBMOD ? "WRITER_DBMOD" : + p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" : + p->eState==PAGER_ERROR ? "ERROR" : "?error?" + , (int)p->errCode + , p->eLock==NO_LOCK ? "NO_LOCK" : + p->eLock==RESERVED_LOCK ? "RESERVED" : + p->eLock==EXCLUSIVE_LOCK ? "EXCLUSIVE" : + p->eLock==SHARED_LOCK ? "SHARED" : + p->eLock==UNKNOWN_LOCK ? "UNKNOWN" : "?error?" + , p->exclusiveMode ? "exclusive" : "normal" + , p->journalMode==PAGER_JOURNALMODE_MEMORY ? "memory" : + p->journalMode==PAGER_JOURNALMODE_OFF ? "off" : + p->journalMode==PAGER_JOURNALMODE_DELETE ? "delete" : + p->journalMode==PAGER_JOURNALMODE_PERSIST ? "persist" : + p->journalMode==PAGER_JOURNALMODE_TRUNCATE ? "truncate" : + p->journalMode==PAGER_JOURNALMODE_WAL ? "wal" : "?error?" + , (int)p->tempFile, (int)p->memDb, (int)p->useJournal + , p->journalOff, p->journalHdr + , (int)p->dbSize, (int)p->dbOrigSize, (int)p->dbFileSize + ); + + return zRet; +} #endif /* @@ -32646,6 +38566,7 @@ static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){ */ #define put32bits(A,B) sqlite3Put4byte((u8*)A,B) + /* ** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK ** on success or an error code is something goes wrong. @@ -32657,27 +38578,53 @@ static int write32bits(sqlite3_file *fd, i64 offset, u32 val){ } /* -** The argument to this macro is a file descriptor (type sqlite3_file*). -** Return 0 if it is not open, or non-zero (but not 1) if it is. -** -** This is so that expressions can be written as: -** -** if( isOpen(pPager->jfd) ){ ... +** Unlock the database file to level eLock, which must be either NO_LOCK +** or SHARED_LOCK. Regardless of whether or not the call to xUnlock() +** succeeds, set the Pager.eLock variable to match the (attempted) new lock. ** -** instead of -** -** if( pPager->jfd->pMethods ){ ... +** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is +** called, do not modify it. See the comment above the #define of +** UNKNOWN_LOCK for an explanation of this. */ -#define isOpen(pFd) ((pFd)->pMethods) +static int pagerUnlockDb(Pager *pPager, int eLock){ + int rc = SQLITE_OK; + + assert( !pPager->exclusiveMode || pPager->eLock==eLock ); + assert( eLock==NO_LOCK || eLock==SHARED_LOCK ); + assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 ); + if( isOpen(pPager->fd) ){ + assert( pPager->eLock>=eLock ); + rc = sqlite3OsUnlock(pPager->fd, eLock); + if( pPager->eLock!=UNKNOWN_LOCK ){ + pPager->eLock = (u8)eLock; + } + IOTRACE(("UNLOCK %p %d\n", pPager, eLock)) + } + return rc; +} /* -** If file pFd is open, call sqlite3OsUnlock() on it. +** Lock the database file to level eLock, which must be either SHARED_LOCK, +** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the +** Pager.eLock variable to the new locking state. +** +** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is +** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. +** See the comment above the #define of UNKNOWN_LOCK for an explanation +** of this. */ -static int osUnlock(sqlite3_file *pFd, int eLock){ - if( !isOpen(pFd) ){ - return SQLITE_OK; +static int pagerLockDb(Pager *pPager, int eLock){ + int rc = SQLITE_OK; + + assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK ); + if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){ + rc = sqlite3OsLock(pPager->fd, eLock); + if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){ + pPager->eLock = (u8)eLock; + IOTRACE(("LOCK %p %d\n", pPager, eLock)) + } } - return sqlite3OsUnlock(pFd, eLock); + return rc; } /* @@ -32753,20 +38700,21 @@ static void pager_set_pagehash(PgHdr *pPage){ #define CHECK_PAGE(x) checkPage(x) static void checkPage(PgHdr *pPg){ Pager *pPager = pPg->pPager; - assert( !pPg->pageHash || pPager->errCode - || (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) ); + assert( pPager->eState!=PAGER_ERROR ); + assert( (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) ); } #else #define pager_datahash(X,Y) 0 #define pager_pagehash(X) 0 +#define pager_set_pagehash(X) #define CHECK_PAGE(x) #endif /* SQLITE_CHECK_PAGES */ /* ** When this is called the journal file for pager pPager must be open. -** This function attempts to read a master journal file name from the -** end of the file and, if successful, copies it into memory supplied +** This function attempts to read a master journal file name from the +** end of the file and, if successful, copies it into memory supplied ** by the caller. See comments above writeMasterJournal() for the format ** used to store a master journal file name at the end of a journal file. ** @@ -32782,7 +38730,7 @@ static void checkPage(PgHdr *pPg){ ** nul-terminator byte is appended to the buffer following the master ** journal file name. ** -** If it is determined that no master journal file name is present +** If it is determined that no master journal file name is present ** zMaster[0] is set to 0 and SQLITE_OK returned. ** ** If an error occurs while reading from the journal file, an SQLite @@ -32800,7 +38748,7 @@ static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){ if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ)) || szJ<16 || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) - || len>=nMaster + || len>=nMaster || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) || memcmp(aMagic, aJournalMagic, 8) @@ -32822,13 +38770,13 @@ static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){ len = 0; } zMaster[len] = '\0'; - + return SQLITE_OK; } /* -** Return the offset of the sector boundary at or immediately -** following the value in pPager->journalOff, assuming a sector +** Return the offset of the sector boundary at or immediately +** following the value in pPager->journalOff, assuming a sector ** size of pPager->sectorSize bytes. ** ** i.e for a sector size of 512: @@ -32839,7 +38787,7 @@ static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){ ** 512 512 ** 100 512 ** 2000 2048 -** +** */ static i64 journalHdrOffset(Pager *pPager){ i64 offset = 0; @@ -32861,12 +38809,12 @@ static i64 journalHdrOffset(Pager *pPager){ ** ** If doTruncate is non-zero or the Pager.journalSizeLimit variable is ** set to 0, then truncate the journal file to zero bytes in size. Otherwise, -** zero the 28-byte header at the start of the journal file. In either case, -** if the pager is not in no-sync mode, sync the journal file immediately +** zero the 28-byte header at the start of the journal file. In either case, +** if the pager is not in no-sync mode, sync the journal file immediately ** after writing or truncating it. ** ** If Pager.journalSizeLimit is set to a positive, non-zero value, and -** following the truncation or zeroing described above the size of the +** following the truncation or zeroing described above the size of the ** journal file in bytes is larger than this value, then truncate the ** journal file to Pager.journalSizeLimit bytes. The journal file does ** not need to be synced following this operation. @@ -32888,11 +38836,11 @@ static int zeroJournalHdr(Pager *pPager, int doTruncate){ rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0); } if( rc==SQLITE_OK && !pPager->noSync ){ - rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->sync_flags); + rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags); } - /* At this point the transaction is committed but the write lock - ** is still held on the file. If there is a size limit configured for + /* At this point the transaction is committed but the write lock + ** is still held on the file. If there is a size limit configured for ** the persistent journal and the journal file currently consumes more ** space than that limit allows for, truncate it now. There is no need ** to sync the file following this operation. @@ -32920,13 +38868,13 @@ static int zeroJournalHdr(Pager *pPager, int doTruncate){ ** - 4 bytes: Initial database page count. ** - 4 bytes: Sector size used by the process that wrote this journal. ** - 4 bytes: Database page size. -** +** ** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space. */ static int writeJournalHdr(Pager *pPager){ int rc = SQLITE_OK; /* Return code */ char *zHeader = pPager->pTmpSpace; /* Temporary space used to build header */ - u32 nHeader = pPager->pageSize; /* Size of buffer pointed to by zHeader */ + u32 nHeader = (u32)pPager->pageSize;/* Size of buffer pointed to by zHeader */ u32 nWrite; /* Bytes of header sector written */ int ii; /* Loop counter */ @@ -32936,8 +38884,8 @@ static int writeJournalHdr(Pager *pPager){ nHeader = JOURNAL_HDR_SZ(pPager); } - /* If there are active savepoints and any of them were created - ** since the most recent journal header was written, update the + /* If there are active savepoints and any of them were created + ** since the most recent journal header was written, update the ** PagerSavepoint.iHdrOffset fields now. */ for(ii=0; ii<pPager->nSavepoint; ii++){ @@ -32948,10 +38896,10 @@ static int writeJournalHdr(Pager *pPager){ pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager); - /* + /* ** Write the nRec Field - the number of page records that follow this ** journal header. Normally, zero is written to this value at this time. - ** After the records are added to the journal (and the journal synced, + ** After the records are added to the journal (and the journal synced, ** if in full-sync mode), the zero is overwritten with the true number ** of records (see syncJournal()). ** @@ -32969,8 +38917,8 @@ static int writeJournalHdr(Pager *pPager){ ** that garbage data is never appended to the journal file. */ assert( isOpen(pPager->fd) || pPager->noSync ); - if( (pPager->noSync) || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY) - || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) + if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY) + || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) ){ memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff); @@ -32978,7 +38926,7 @@ static int writeJournalHdr(Pager *pPager){ memset(zHeader, 0, sizeof(aJournalMagic)+4); } - /* The random check-hash initialiser */ + /* The random check-hash initialiser */ sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); /* The initial database size */ @@ -32997,26 +38945,27 @@ static int writeJournalHdr(Pager *pPager){ memset(&zHeader[sizeof(aJournalMagic)+20], 0, nHeader-(sizeof(aJournalMagic)+20)); - /* In theory, it is only necessary to write the 28 bytes that the - ** journal header consumes to the journal file here. Then increment the - ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next + /* In theory, it is only necessary to write the 28 bytes that the + ** journal header consumes to the journal file here. Then increment the + ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next ** record is written to the following sector (leaving a gap in the file ** that will be implicitly filled in by the OS). ** - ** However it has been discovered that on some systems this pattern can + ** However it has been discovered that on some systems this pattern can ** be significantly slower than contiguously writing data to the file, - ** even if that means explicitly writing data to the block of + ** even if that means explicitly writing data to the block of ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what - ** is done. + ** is done. ** - ** The loop is required here in case the sector-size is larger than the + ** The loop is required here in case the sector-size is larger than the ** database page size. Since the zHeader buffer is only Pager.pageSize ** bytes in size, more than one call to sqlite3OsWrite() may be required ** to populate the entire journal header sector. - */ + */ for(nWrite=0; rc==SQLITE_OK&&nWrite<JOURNAL_HDR_SZ(pPager); nWrite+=nHeader){ IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, nHeader)) rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff); + assert( pPager->journalHdr <= pPager->journalOff ); pPager->journalOff += nHeader; } @@ -33092,7 +39041,6 @@ static int readJournalHdr( if( pPager->journalOff==0 ){ u32 iPageSize; /* Page-size field of journal header */ u32 iSectorSize; /* Sector-size field of journal header */ - u16 iPageSize16; /* Copy of iPageSize in 16-bit variable */ /* Read the page-size and sector-size journal header fields. */ if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize)) @@ -33101,33 +39049,39 @@ static int readJournalHdr( return rc; } + /* Versions of SQLite prior to 3.5.8 set the page-size field of the + ** journal header to zero. In this case, assume that the Pager.pageSize + ** variable is already set to the correct page size. + */ + if( iPageSize==0 ){ + iPageSize = pPager->pageSize; + } + /* Check that the values read from the page-size and sector-size fields ** are within range. To be 'in range', both values need to be a power - ** of two greater than or equal to 512 or 32, and not greater than their + ** of two greater than or equal to 512 or 32, and not greater than their ** respective compile time maximum limits. */ if( iPageSize<512 || iSectorSize<32 || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE - || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0 + || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0 ){ - /* If the either the page-size or sector-size in the journal-header is - ** invalid, then the process that wrote the journal-header must have - ** crashed before the header was synced. In this case stop reading + /* If the either the page-size or sector-size in the journal-header is + ** invalid, then the process that wrote the journal-header must have + ** crashed before the header was synced. In this case stop reading ** the journal file here. */ return SQLITE_DONE; } - /* Update the page-size to match the value read from the journal. - ** Use a testcase() macro to make sure that malloc failure within + /* Update the page-size to match the value read from the journal. + ** Use a testcase() macro to make sure that malloc failure within ** PagerSetPagesize() is tested. */ - iPageSize16 = (u16)iPageSize; - rc = sqlite3PagerSetPagesize(pPager, &iPageSize16, -1); + rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1); testcase( rc!=SQLITE_OK ); - assert( rc!=SQLITE_OK || iPageSize16==(u16)iPageSize ); - /* Update the assumed sector-size to match the value used by + /* Update the assumed sector-size to match the value used by ** the process that created this journal. If this journal was ** created by a process other than this one, then this routine ** is being called from within pager_playback(). The local value @@ -33157,7 +39111,7 @@ static int readJournalHdr( ** The master journal page checksum is the sum of the bytes in the master ** journal name, where each byte is interpreted as a signed 8-bit integer. ** -** If zMaster is a NULL pointer (occurs for a single database transaction), +** If zMaster is a NULL pointer (occurs for a single database transaction), ** this call is a no-op. */ static int writeMasterJournal(Pager *pPager, const char *zMaster){ @@ -33167,14 +39121,18 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){ i64 jrnlSize; /* Size of journal file on disk */ u32 cksum = 0; /* Checksum of string zMaster */ - if( !zMaster || pPager->setMaster - || pPager->journalMode==PAGER_JOURNALMODE_MEMORY - || pPager->journalMode==PAGER_JOURNALMODE_OFF + assert( pPager->setMaster==0 ); + assert( !pagerUseWal(pPager) ); + + if( !zMaster + || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + || pPager->journalMode==PAGER_JOURNALMODE_OFF ){ return SQLITE_OK; } pPager->setMaster = 1; assert( isOpen(pPager->jfd) ); + assert( pPager->journalHdr <= pPager->journalOff ); /* Calculate the length in bytes and the checksum of zMaster */ for(nMaster=0; zMaster[nMaster]; nMaster++){ @@ -33202,18 +39160,17 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){ return rc; } pPager->journalOff += (nMaster+20); - pPager->needSync = !pPager->noSync; - /* If the pager is in peristent-journal mode, then the physical + /* If the pager is in peristent-journal mode, then the physical ** journal-file may extend past the end of the master-journal name - ** and 8 bytes of magic data just written to the file. This is + ** and 8 bytes of magic data just written to the file. This is ** dangerous because the code to rollback a hot-journal file - ** will not be able to find the master-journal name to determine - ** whether or not the journal is hot. + ** will not be able to find the master-journal name to determine + ** whether or not the journal is hot. ** - ** Easiest thing to do in this scenario is to truncate the journal + ** Easiest thing to do in this scenario is to truncate the journal ** file to the required size. - */ + */ if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize)) && jrnlSize>pPager->journalOff ){ @@ -33224,7 +39181,7 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){ /* ** Find a page in the hash table given its page number. Return -** a pointer to the page or NULL if the requested page is not +** a pointer to the page or NULL if the requested page is not ** already in memory. */ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){ @@ -33238,17 +39195,11 @@ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){ } /* -** Unless the pager is in error-state, discard all in-memory pages. If -** the pager is in error-state, then this call is a no-op. -** -** TODO: Why can we not reset the pager while in error state? +** Discard the entire contents of the in-memory page-cache. */ static void pager_reset(Pager *pPager){ - if( SQLITE_OK==pPager->errCode ){ - sqlite3BackupRestart(pPager->pBackup); - sqlite3PcacheClear(pPager->pPCache); - pPager->dbSizeValid = 0; - } + sqlite3BackupRestart(pPager->pBackup); + sqlite3PcacheClear(pPager->pPCache); } /* @@ -33271,7 +39222,7 @@ static void releaseAllSavepoints(Pager *pPager){ } /* -** Set the bit number pgno in the PagerSavepoint.pInSavepoint +** Set the bit number pgno in the PagerSavepoint.pInSavepoint ** bitvecs of all open savepoints. Return SQLITE_OK if successful ** or SQLITE_NOMEM if a malloc failure occurs. */ @@ -33291,72 +39242,109 @@ static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){ } /* -** Unlock the database file. This function is a no-op if the pager -** is in exclusive mode. +** This function is a no-op if the pager is in exclusive mode and not +** in the ERROR state. Otherwise, it switches the pager to PAGER_OPEN +** state. +** +** If the pager is not in exclusive-access mode, the database file is +** completely unlocked. If the file is unlocked and the file-system does +** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is +** closed (if it is open). ** -** If the pager is currently in error state, discard the contents of -** the cache and reset the Pager structure internal state. If there is -** an open journal-file, then the next time a shared-lock is obtained -** on the pager file (by this or any other process), it will be -** treated as a hot-journal and rolled back. +** If the pager is in ERROR state when this function is called, the +** contents of the pager cache are discarded before switching back to +** the OPEN state. Regardless of whether the pager is in exclusive-mode +** or not, any journal file left in the file-system will be treated +** as a hot-journal and rolled back the next time a read-transaction +** is opened (by this or by any other connection). */ static void pager_unlock(Pager *pPager){ - if( !pPager->exclusiveMode ){ - int rc; /* Return code */ - /* Always close the journal file when dropping the database lock. - ** Otherwise, another connection with journal_mode=delete might - ** delete the file out from under us. - */ - sqlite3OsClose(pPager->jfd); - sqlite3BitvecDestroy(pPager->pInJournal); - pPager->pInJournal = 0; - releaseAllSavepoints(pPager); + assert( pPager->eState==PAGER_READER + || pPager->eState==PAGER_OPEN + || pPager->eState==PAGER_ERROR + ); - /* If the file is unlocked, somebody else might change it. The - ** values stored in Pager.dbSize etc. might become invalid if - ** this happens. TODO: Really, this doesn't need to be cleared - ** until the change-counter check fails in PagerSharedLock(). - */ - pPager->dbSizeValid = 0; + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + releaseAllSavepoints(pPager); - rc = osUnlock(pPager->fd, NO_LOCK); - if( rc ){ - pPager->errCode = rc; + if( pagerUseWal(pPager) ){ + assert( !isOpen(pPager->jfd) ); + sqlite3WalEndReadTransaction(pPager->pWal); + pPager->eState = PAGER_OPEN; + }else if( !pPager->exclusiveMode ){ + int rc; /* Error code returned by pagerUnlockDb() */ + int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0; + + /* If the operating system support deletion of open files, then + ** close the journal file when dropping the database lock. Otherwise + ** another connection with journal_mode=delete might delete the file + ** out from under us. + */ + assert( (PAGER_JOURNALMODE_MEMORY & 5)!=1 ); + assert( (PAGER_JOURNALMODE_OFF & 5)!=1 ); + assert( (PAGER_JOURNALMODE_WAL & 5)!=1 ); + assert( (PAGER_JOURNALMODE_DELETE & 5)!=1 ); + assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); + assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); + if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN) + || 1!=(pPager->journalMode & 5) + ){ + sqlite3OsClose(pPager->jfd); } - IOTRACE(("UNLOCK %p\n", pPager)) - /* If Pager.errCode is set, the contents of the pager cache cannot be - ** trusted. Now that the pager file is unlocked, the contents of the - ** cache can be discarded and the error code safely cleared. + /* If the pager is in the ERROR state and the call to unlock the database + ** file fails, set the current lock to UNKNOWN_LOCK. See the comment + ** above the #define for UNKNOWN_LOCK for an explanation of why this + ** is necessary. */ - if( pPager->errCode ){ - if( rc==SQLITE_OK ){ - pPager->errCode = SQLITE_OK; - } - pager_reset(pPager); + rc = pagerUnlockDb(pPager, NO_LOCK); + if( rc!=SQLITE_OK && pPager->eState==PAGER_ERROR ){ + pPager->eLock = UNKNOWN_LOCK; } + /* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here + ** without clearing the error code. This is intentional - the error + ** code is cleared and the cache reset in the block below. + */ + assert( pPager->errCode || pPager->eState!=PAGER_ERROR ); pPager->changeCountDone = 0; - pPager->state = PAGER_UNLOCK; - pPager->dbModified = 0; + pPager->eState = PAGER_OPEN; } + + /* If Pager.errCode is set, the contents of the pager cache cannot be + ** trusted. Now that there are no outstanding references to the pager, + ** it can safely move back to PAGER_OPEN state. This happens in both + ** normal and exclusive-locking mode. + */ + if( pPager->errCode ){ + assert( !MEMDB ); + pager_reset(pPager); + pPager->changeCountDone = pPager->tempFile; + pPager->eState = PAGER_OPEN; + pPager->errCode = SQLITE_OK; + } + + pPager->journalOff = 0; + pPager->journalHdr = 0; + pPager->setMaster = 0; } /* -** This function should be called when an IOERR, CORRUPT or FULL error -** may have occurred. The first argument is a pointer to the pager -** structure, the second the error-code about to be returned by a pager -** API function. The value returned is a copy of the second argument -** to this function. +** This function is called whenever an IOERR or FULL error that requires +** the pager to transition into the ERROR state may ahve occurred. +** The first argument is a pointer to the pager structure, the second +** the error-code about to be returned by a pager API function. The +** value returned is a copy of the second argument to this function. ** -** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_FULL -** the error becomes persistent. Until the persisten error is cleared, -** subsequent API calls on this Pager will immediately return the same -** error code. +** If the second argument is SQLITE_FULL, SQLITE_IOERR or one of the +** IOERR sub-codes, the pager enters the ERROR state and the error code +** is stored in Pager.errCode. While the pager remains in the ERROR state, +** all major API calls on the Pager will immediately return Pager.errCode. ** -** A persistent error indicates that the contents of the pager-cache -** cannot be trusted. This state can be cleared by completely discarding +** The ERROR state indicates that the contents of the pager-cache +** cannot be trusted. This state can be cleared by completely discarding ** the contents of the pager-cache. If a transaction was active when ** the persistent error occurred, then the rollback journal may need ** to be replayed to restore the contents of the database file (as if @@ -33372,57 +39360,33 @@ static int pager_error(Pager *pPager, int rc){ ); if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){ pPager->errCode = rc; + pPager->eState = PAGER_ERROR; } return rc; } /* -** Execute a rollback if a transaction is active and unlock the -** database file. -** -** If the pager has already entered the error state, do not attempt -** the rollback at this time. Instead, pager_unlock() is called. The -** call to pager_unlock() will discard all in-memory pages, unlock -** the database file and clear the error state. If this means that -** there is a hot-journal left in the file-system, the next connection -** to obtain a shared lock on the pager (which may be this one) will -** roll it back. -** -** If the pager has not already entered the error state, but an IO or -** malloc error occurs during a rollback, then this will itself cause -** the pager to enter the error state. Which will be cleared by the -** call to pager_unlock(), as described above. -*/ -static void pagerUnlockAndRollback(Pager *pPager){ - if( pPager->errCode==SQLITE_OK && pPager->state>=PAGER_RESERVED ){ - sqlite3BeginBenignMalloc(); - sqlite3PagerRollback(pPager); - sqlite3EndBenignMalloc(); - } - pager_unlock(pPager); -} - -/* -** This routine ends a transaction. A transaction is usually ended by -** either a COMMIT or a ROLLBACK operation. This routine may be called +** This routine ends a transaction. A transaction is usually ended by +** either a COMMIT or a ROLLBACK operation. This routine may be called ** after rollback of a hot-journal, or if an error occurs while opening ** the journal file or writing the very first journal-header of a ** database transaction. -** -** If the pager is in PAGER_SHARED or PAGER_UNLOCK state when this -** routine is called, it is a no-op (returns SQLITE_OK). +** +** This routine is never called in PAGER_ERROR state. If it is called +** in PAGER_NONE or PAGER_SHARED state and the lock held is less +** exclusive than a RESERVED lock, it is a no-op. ** ** Otherwise, any active savepoints are released. ** -** If the journal file is open, then it is "finalized". Once a journal -** file has been finalized it is not possible to use it to roll back a +** If the journal file is open, then it is "finalized". Once a journal +** file has been finalized it is not possible to use it to roll back a ** transaction. Nor will it be considered to be a hot-journal by this ** or any other database connection. Exactly how a journal is finalized ** depends on whether or not the pager is running in exclusive mode and ** the current journal-mode (Pager.journalMode value), as follows: ** ** journalMode==MEMORY -** Journal file descriptor is simply closed. This destroys an +** Journal file descriptor is simply closed. This destroys an ** in-memory journal. ** ** journalMode==TRUNCATE @@ -33441,17 +39405,13 @@ static void pagerUnlockAndRollback(Pager *pPager){ ** DELETE and the pager is in exclusive mode, the method described under ** journalMode==PERSIST is used instead. ** -** After the journal is finalized, if running in non-exclusive mode, the -** pager moves to PAGER_SHARED state (and downgrades the lock on the -** database file accordingly). -** -** If the pager is running in exclusive mode and is in PAGER_SYNCED state, -** it moves to PAGER_EXCLUSIVE. No locks are downgraded when running in -** exclusive mode. +** After the journal is finalized, the pager moves to PAGER_READER state. +** If running in non-exclusive rollback mode, the lock on the file is +** downgraded to a SHARED_LOCK. ** ** SQLITE_OK is returned if no error occurs. If an error occurs during ** any of the IO operations to finalize the journal file or unlock the -** database then the IO error code is returned to the user. If the +** database then the IO error code is returned to the user. If the ** operation to finalize the journal file fails, then the code still ** tries to unlock the database file if not in exclusive mode. If the ** unlock operation fails as well, then the first error code related @@ -33462,13 +39422,29 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){ int rc = SQLITE_OK; /* Error code from journal finalization operation */ int rc2 = SQLITE_OK; /* Error code from db file unlock operation */ - if( pPager->state<PAGER_RESERVED ){ + /* Do nothing if the pager does not have an open write transaction + ** or at least a RESERVED lock. This function may be called when there + ** is no write-transaction active but a RESERVED or greater lock is + ** held under two circumstances: + ** + ** 1. After a successful hot-journal rollback, it is called with + ** eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK. + ** + ** 2. If a connection with locking_mode=exclusive holding an EXCLUSIVE + ** lock switches back to locking_mode=normal and then executes a + ** read-transaction, this function is called with eState==PAGER_READER + ** and eLock==EXCLUSIVE_LOCK when the read-transaction is closed. + */ + assert( assert_pager_state(pPager) ); + assert( pPager->eState!=PAGER_ERROR ); + if( pPager->eState<PAGER_WRITER_LOCKED && pPager->eLock<RESERVED_LOCK ){ return SQLITE_OK; } - releaseAllSavepoints(pPager); + releaseAllSavepoints(pPager); assert( isOpen(pPager->jfd) || pPager->pInJournal==0 ); if( isOpen(pPager->jfd) ){ + assert( !pagerUseWal(pPager) ); /* Finalize the journal file. */ if( sqlite3IsMemJournal(pPager->jfd) ){ @@ -33481,66 +39457,103 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){ rc = sqlite3OsTruncate(pPager->jfd, 0); } pPager->journalOff = 0; - pPager->journalStarted = 0; - }else if( pPager->exclusiveMode - || pPager->journalMode==PAGER_JOURNALMODE_PERSIST + }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST + || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) ){ rc = zeroJournalHdr(pPager, hasMaster); - pager_error(pPager, rc); pPager->journalOff = 0; - pPager->journalStarted = 0; }else{ /* This branch may be executed with Pager.journalMode==MEMORY if ** a hot-journal was just rolled back. In this case the journal ** file should be closed and deleted. If this connection writes to - ** the database file, it will do so using an in-memory journal. */ - assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE - || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + ** the database file, it will do so using an in-memory journal. + */ + assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE + || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + || pPager->journalMode==PAGER_JOURNALMODE_WAL ); sqlite3OsClose(pPager->jfd); if( !pPager->tempFile ){ rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); } } + } #ifdef SQLITE_CHECK_PAGES - sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); + sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); + if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){ + PgHdr *p = pager_lookup(pPager, 1); + if( p ){ + p->pageHash = 0; + sqlite3PagerUnref(p); + } + } #endif - sqlite3PcacheCleanAll(pPager->pPCache); - sqlite3BitvecDestroy(pPager->pInJournal); - pPager->pInJournal = 0; - pPager->nRec = 0; - } + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + pPager->nRec = 0; + sqlite3PcacheCleanAll(pPager->pPCache); + sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); - if( !pPager->exclusiveMode ){ - rc2 = osUnlock(pPager->fd, SHARED_LOCK); - pPager->state = PAGER_SHARED; + if( pagerUseWal(pPager) ){ + /* Drop the WAL write-lock, if any. Also, if the connection was in + ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE + ** lock held on the database file. + */ + rc2 = sqlite3WalEndWriteTransaction(pPager->pWal); + assert( rc2==SQLITE_OK ); + } + if( !pPager->exclusiveMode + && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) + ){ + rc2 = pagerUnlockDb(pPager, SHARED_LOCK); pPager->changeCountDone = 0; - }else if( pPager->state==PAGER_SYNCED ){ - pPager->state = PAGER_EXCLUSIVE; } + pPager->eState = PAGER_READER; pPager->setMaster = 0; - pPager->needSync = 0; - pPager->dbModified = 0; - - /* TODO: Is this optimal? Why is the db size invalidated here - ** when the database file is not unlocked? */ - pPager->dbOrigSize = 0; - sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); - if( !MEMDB ){ - pPager->dbSizeValid = 0; - } return (rc==SQLITE_OK?rc2:rc); } /* +** Execute a rollback if a transaction is active and unlock the +** database file. +** +** If the pager has already entered the ERROR state, do not attempt +** the rollback at this time. Instead, pager_unlock() is called. The +** call to pager_unlock() will discard all in-memory pages, unlock +** the database file and move the pager back to OPEN state. If this +** means that there is a hot-journal left in the file-system, the next +** connection to obtain a shared lock on the pager (which may be this one) +** will roll it back. +** +** If the pager has not already entered the ERROR state, but an IO or +** malloc error occurs during a rollback, then this will itself cause +** the pager to enter the ERROR state. Which will be cleared by the +** call to pager_unlock(), as described above. +*/ +static void pagerUnlockAndRollback(Pager *pPager){ + if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){ + assert( assert_pager_state(pPager) ); + if( pPager->eState>=PAGER_WRITER_LOCKED ){ + sqlite3BeginBenignMalloc(); + sqlite3PagerRollback(pPager); + sqlite3EndBenignMalloc(); + }else if( !pPager->exclusiveMode ){ + assert( pPager->eState==PAGER_READER ); + pager_end_transaction(pPager, 0); + } + } + pager_unlock(pPager); +} + +/* ** Parameter aData must point to a buffer of pPager->pageSize bytes -** of data. Compute and return a checksum based ont the contents of the +** of data. Compute and return a checksum based ont the contents of the ** page of data and the current value of pPager->cksumInit. ** -** This is not a real checksum. It is really just the sum of the +** This is not a real checksum. It is really just the sum of the ** random initial value (pPager->cksumInit) and every 200th byte ** of the page data, starting with byte offset (pPager->pageSize%200). ** Each byte is interpreted as an 8-bit unsigned integer. @@ -33548,8 +39561,8 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){ ** Changing the formula used to compute this checksum results in an ** incompatible journal file format. ** -** If journal corruption occurs due to a power failure, the most likely -** scenario is that one end or the other of the record will be changed. +** If journal corruption occurs due to a power failure, the most likely +** scenario is that one end or the other of the record will be changed. ** It is much less likely that the two ends of the journal record will be ** correct and the middle be corrupt. Thus, this "checksum" scheme, ** though fast and simple, catches the mostly likely kind of corruption. @@ -33565,14 +39578,28 @@ static u32 pager_cksum(Pager *pPager, const u8 *aData){ } /* +** Report the current page size and number of reserved bytes back +** to the codec. +*/ +#ifdef SQLITE_HAS_CODEC +static void pagerReportSize(Pager *pPager){ + if( pPager->xCodecSizeChng ){ + pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, + (int)pPager->nReserve); + } +} +#else +# define pagerReportSize(X) /* No-op if we do not support a codec */ +#endif + +/* ** Read a single page from either the journal file (if isMainJrnl==1) or ** from the sub-journal (if isMainJrnl==0) and playback that page. ** The page begins at offset *pOffset into the file. The *pOffset ** value is increased to the start of the next page in the journal. ** -** The isMainJrnl flag is true if this is the main rollback journal and -** false for the statement journal. The main rollback journal uses -** checksums - the statement journal does not. +** The main rollback journal uses checksums - the statement journal does +** not. ** ** If the page number of the page record read from the (sub-)journal file ** is greater than the current value of Pager.dbSize, then playback is @@ -33591,7 +39618,7 @@ static u32 pager_cksum(Pager *pPager, const u8 *aData){ ** is successfully read from the (sub-)journal file but appears to be ** corrupted, SQLITE_DONE is returned. Data is considered corrupted in ** two circumstances: -** +** ** * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or ** * If the record is being rolled back from the main journal file ** and the checksum field does not match the record content. @@ -33604,11 +39631,10 @@ static u32 pager_cksum(Pager *pPager, const u8 *aData){ */ static int pager_playback_one_page( Pager *pPager, /* The pager being played back */ - int isMainJrnl, /* 1 -> main journal. 0 -> sub-journal. */ - int isUnsync, /* True if reading from unsynced main journal */ i64 *pOffset, /* Offset of record to playback */ - int isSavepnt, /* True for a savepoint rollback */ - Bitvec *pDone /* Bitvec of pages already played back */ + Bitvec *pDone, /* Bitvec of pages already played back */ + int isMainJrnl, /* 1 -> main journal. 0 -> sub-journal. */ + int isSavepnt /* True for a savepoint rollback */ ){ int rc; PgHdr *pPg; /* An existing page in the cache */ @@ -33616,6 +39642,7 @@ static int pager_playback_one_page( u32 cksum; /* Checksum used for sanity checking */ char *aData; /* Temporary storage for the page */ sqlite3_file *jfd; /* The file descriptor for the journal file */ + int isSynced; /* True if journal page is synced */ assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */ assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */ @@ -33624,6 +39651,18 @@ static int pager_playback_one_page( aData = pPager->pTmpSpace; assert( aData ); /* Temp storage must have already been allocated */ + assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) ); + + /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction + ** or savepoint rollback done at the request of the caller) or this is + ** a hot-journal rollback. If it is a hot-journal rollback, the pager + ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback + ** only reads from the main journal, not the sub-journal. + */ + assert( pPager->eState>=PAGER_WRITER_CACHEMOD + || (pPager->eState==PAGER_OPEN && pPager->eLock==EXCLUSIVE_LOCK) + ); + assert( pPager->eState>=PAGER_WRITER_CACHEMOD || isMainJrnl ); /* Read the page number and page data from the journal or sub-journal ** file. Return an error code to the caller if an IO error occurs. @@ -33655,13 +39694,21 @@ static int pager_playback_one_page( } } + /* If this page has already been played by before during the current + ** rollback, then don't bother to play it back again. + */ if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ return rc; } - assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE ); + /* When playing back page 1, restore the nReserve setting + */ + if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){ + pPager->nReserve = ((u8*)aData)[20]; + pagerReportSize(pPager); + } - /* If the pager is in RESERVED state, then there must be a copy of this + /* If the pager is in CACHEMOD state, then there must be a copy of this ** page in the pager cache. In this case just update the pager cache, ** not the database file. The page is left marked dirty in this case. ** @@ -33672,8 +39719,11 @@ static int pager_playback_one_page( ** either. So the condition described in the above paragraph is not ** assert()able. ** - ** If in EXCLUSIVE state, then we update the pager cache if it exists - ** and the main file. The page is then marked not dirty. + ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the + ** pager cache if it exists and the main file. The page is then marked + ** not dirty. Since this code is only executed in PAGER_OPEN state for + ** a hot-journal rollback, it is guaranteed that the page-cache is empty + ** if the pager is in OPEN state. ** ** Ticket #1171: The statement journal might contain page content that is ** different from the page content at the start of the transaction. @@ -33693,18 +39743,29 @@ static int pager_playback_one_page( ** is possible to fail a statement on a database that does not yet exist. ** Do not attempt to write if database file has never been opened. */ - pPg = pager_lookup(pPager, pgno); + if( pagerUseWal(pPager) ){ + pPg = 0; + }else{ + pPg = pager_lookup(pPager, pgno); + } assert( pPg || !MEMDB ); + assert( pPager->eState!=PAGER_OPEN || pPg==0 ); PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n", PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData), (isMainJrnl?"main-journal":"sub-journal") )); - if( (pPager->state>=PAGER_EXCLUSIVE) - && (pPg==0 || 0==(pPg->flags&PGHDR_NEED_SYNC)) - && isOpen(pPager->fd) - && !isUnsync + if( isMainJrnl ){ + isSynced = pPager->noSync || (*pOffset <= pPager->journalHdr); + }else{ + isSynced = (pPg==0 || 0==(pPg->flags & PGHDR_NEED_SYNC)); + } + if( isOpen(pPager->fd) + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + && isSynced ){ i64 ofst = (pgno-1)*(i64)pPager->pageSize; + testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 ); + assert( !pagerUseWal(pPager) ); rc = sqlite3OsWrite(pPager->fd, (u8*)aData, pPager->pageSize, ofst); if( pgno>pPager->dbFileSize ){ pPager->dbFileSize = pgno; @@ -33717,24 +39778,27 @@ static int pager_playback_one_page( }else if( !isMainJrnl && pPg==0 ){ /* If this is a rollback of a savepoint and data was not written to ** the database and the page is not in-memory, there is a potential - ** problem. When the page is next fetched by the b-tree layer, it - ** will be read from the database file, which may or may not be - ** current. + ** problem. When the page is next fetched by the b-tree layer, it + ** will be read from the database file, which may or may not be + ** current. ** ** There are a couple of different ways this can happen. All are quite - ** obscure. When running in synchronous mode, this can only happen + ** obscure. When running in synchronous mode, this can only happen ** if the page is on the free-list at the start of the transaction, then ** populated, then moved using sqlite3PagerMovepage(). ** ** The solution is to add an in-memory page to the cache containing - ** the data just read from the sub-journal. Mark the page as dirty - ** and if the pager requires a journal-sync, then mark the page as + ** the data just read from the sub-journal. Mark the page as dirty + ** and if the pager requires a journal-sync, then mark the page as ** requiring a journal-sync before it is written. */ assert( isSavepnt ); - if( (rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1))!=SQLITE_OK ){ - return rc; - } + assert( pPager->doNotSpill==0 ); + pPager->doNotSpill++; + rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1); + assert( pPager->doNotSpill==1 ); + pPager->doNotSpill--; + if( rc!=SQLITE_OK ) return rc; pPg->flags &= ~PGHDR_NEED_READ; sqlite3PcacheMakeDirty(pPg); } @@ -33750,13 +39814,14 @@ static int pager_playback_one_page( memcpy(pData, (u8*)aData, pPager->pageSize); pPager->xReiniter(pPg); if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){ - /* If the contents of this page were just restored from the main - ** journal file, then its content must be as they were when the + /* If the contents of this page were just restored from the main + ** journal file, then its content must be as they were when the ** transaction was first opened. In this case we can mark the page - ** as clean, since there will be no need to write it out to the. + ** as clean, since there will be no need to write it out to the + ** database. ** ** There is one exception to this rule. If the page is being rolled - ** back as part of a savepoint (or statement) rollback from an + ** back as part of a savepoint (or statement) rollback from an ** unsynced portion of the main journal file, then it is not safe ** to mark the page as clean. This is because marking the page as ** clean will clear the PGHDR_NEED_SYNC flag. Since the page is @@ -33768,11 +39833,11 @@ static int pager_playback_one_page( ** segment is synced. If a crash occurs during or following this, ** database corruption may ensue. */ + assert( !pagerUseWal(pPager) ); sqlite3PcacheMakeClean(pPg); } -#ifdef SQLITE_CHECK_PAGES - pPg->pageHash = pager_pagehash(pPg); -#endif + pager_set_pagehash(pPg); + /* If this was page 1, then restore the value of Pager.dbFileVers. ** Do this before any decoding. */ if( pgno==1 ){ @@ -33792,26 +39857,26 @@ static int pager_playback_one_page( ** This routine checks if it is possible to delete the master journal file, ** and does so if it is. ** -** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not +** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not ** available for use within this function. ** -** When a master journal file is created, it is populated with the names -** of all of its child journals, one after another, formatted as utf-8 -** encoded text. The end of each child journal file is marked with a +** When a master journal file is created, it is populated with the names +** of all of its child journals, one after another, formatted as utf-8 +** encoded text. The end of each child journal file is marked with a ** nul-terminator byte (0x00). i.e. the entire contents of a master journal ** file for a transaction involving two databases might be: ** ** "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00" ** -** A master journal file may only be deleted once all of its child +** A master journal file may only be deleted once all of its child ** journals have been rolled back. ** -** This function reads the contents of the master-journal file into +** This function reads the contents of the master-journal file into ** memory and loops through each of the child journal names. For ** each child journal, it checks if: ** ** * if the child journal exists, and if so -** * if the child journal contains a reference to master journal +** * if the child journal contains a reference to master journal ** file zMaster ** ** If a child journal can be found that matches both of the criteria @@ -33821,12 +39886,12 @@ static int pager_playback_one_page( ** ** If an IO error within this function, an error code is returned. This ** function allocates memory by calling sqlite3Malloc(). If an allocation -** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors +** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors ** occur, SQLITE_OK is returned. ** ** TODO: This function allocates a single block of memory to load ** the entire contents of the master journal file. This could be -** a couple of kilobytes or so - potentially larger than the page +** a couple of kilobytes or so - potentially larger than the page ** size. */ static int pager_delmaster(Pager *pPager, const char *zMaster){ @@ -33836,6 +39901,9 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */ char *zMasterJournal = 0; /* Contents of master journal file */ i64 nMasterJournal; /* Size of master journal file */ + char *zJournal; /* Pointer to one journal within MJ file */ + char *zMasterPtr; /* Space to hold MJ filename from a journal file */ + int nMasterPtr; /* Amount of space allocated to zMasterPtr[] */ /* Allocate space for both the pJournal and pMaster file descriptors. ** If successful, open the master journal file for reading. @@ -33850,92 +39918,87 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ } if( rc!=SQLITE_OK ) goto delmaster_out; + /* Load the entire master journal file into space obtained from + ** sqlite3_malloc() and pointed to by zMasterJournal. Also obtain + ** sufficient space (in zMasterPtr) to hold the names of master + ** journal files extracted from regular rollback-journals. + */ rc = sqlite3OsFileSize(pMaster, &nMasterJournal); if( rc!=SQLITE_OK ) goto delmaster_out; + nMasterPtr = pVfs->mxPathname+1; + zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 1); + if( !zMasterJournal ){ + rc = SQLITE_NOMEM; + goto delmaster_out; + } + zMasterPtr = &zMasterJournal[nMasterJournal+1]; + rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0); + if( rc!=SQLITE_OK ) goto delmaster_out; + zMasterJournal[nMasterJournal] = 0; - if( nMasterJournal>0 ){ - char *zJournal; - char *zMasterPtr = 0; - int nMasterPtr = pVfs->mxPathname+1; - - /* Load the entire master journal file into space obtained from - ** sqlite3_malloc() and pointed to by zMasterJournal. - */ - zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 1); - if( !zMasterJournal ){ - rc = SQLITE_NOMEM; + zJournal = zMasterJournal; + while( (zJournal-zMasterJournal)<nMasterJournal ){ + int exists; + rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists); + if( rc!=SQLITE_OK ){ goto delmaster_out; } - zMasterPtr = &zMasterJournal[nMasterJournal+1]; - rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0); - if( rc!=SQLITE_OK ) goto delmaster_out; - zMasterJournal[nMasterJournal] = 0; - - zJournal = zMasterJournal; - while( (zJournal-zMasterJournal)<nMasterJournal ){ - int exists; - rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists); + if( exists ){ + /* One of the journals pointed to by the master journal exists. + ** Open it and check if it points at the master journal. If + ** so, return without deleting the master journal file. + */ + int c; + int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL); + rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0); if( rc!=SQLITE_OK ){ goto delmaster_out; } - if( exists ){ - /* One of the journals pointed to by the master journal exists. - ** Open it and check if it points at the master journal. If - ** so, return without deleting the master journal file. - */ - int c; - int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL); - rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0); - if( rc!=SQLITE_OK ){ - goto delmaster_out; - } - rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr); - sqlite3OsClose(pJournal); - if( rc!=SQLITE_OK ){ - goto delmaster_out; - } + rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr); + sqlite3OsClose(pJournal); + if( rc!=SQLITE_OK ){ + goto delmaster_out; + } - c = zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0; - if( c ){ - /* We have a match. Do not delete the master journal file. */ - goto delmaster_out; - } + c = zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0; + if( c ){ + /* We have a match. Do not delete the master journal file. */ + goto delmaster_out; } - zJournal += (sqlite3Strlen30(zJournal)+1); } + zJournal += (sqlite3Strlen30(zJournal)+1); } - + + sqlite3OsClose(pMaster); rc = sqlite3OsDelete(pVfs, zMaster, 0); delmaster_out: - if( zMasterJournal ){ - sqlite3_free(zMasterJournal); - } + sqlite3_free(zMasterJournal); if( pMaster ){ sqlite3OsClose(pMaster); assert( !isOpen(pJournal) ); + sqlite3_free(pMaster); } - sqlite3_free(pMaster); return rc; } /* -** This function is used to change the actual size of the database +** This function is used to change the actual size of the database ** file in the file-system. This only happens when committing a transaction, ** or rolling back a transaction (including rolling back a hot-journal). ** -** If the main database file is not open, or an exclusive lock is not -** held, this function is a no-op. Otherwise, the size of the file is -** changed to nPage pages (nPage*pPager->pageSize bytes). If the file -** on disk is currently larger than nPage pages, then use the VFS +** If the main database file is not open, or the pager is not in either +** DBMOD or OPEN state, this function is a no-op. Otherwise, the size +** of the file is changed to nPage pages (nPage*pPager->pageSize bytes). +** If the file on disk is currently larger than nPage pages, then use the VFS ** xTruncate() method to truncate it. ** -** Or, it might might be the case that the file on disk is smaller than -** nPage pages. Some operating system implementations can get confused if -** you try to truncate a file to some size that is larger than it -** currently is, so detect this case and write a single zero byte to +** Or, it might might be the case that the file on disk is smaller than +** nPage pages. Some operating system implementations can get confused if +** you try to truncate a file to some size that is larger than it +** currently is, so detect this case and write a single zero byte to ** the end of the new file instead. ** ** If successful, return SQLITE_OK. If an IO error occurs while modifying @@ -33943,16 +40006,28 @@ delmaster_out: */ static int pager_truncate(Pager *pPager, Pgno nPage){ int rc = SQLITE_OK; - if( pPager->state>=PAGER_EXCLUSIVE && isOpen(pPager->fd) ){ + assert( pPager->eState!=PAGER_ERROR ); + assert( pPager->eState!=PAGER_READER ); + + if( isOpen(pPager->fd) + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + ){ i64 currentSize, newSize; + int szPage = pPager->pageSize; + assert( pPager->eLock==EXCLUSIVE_LOCK ); /* TODO: Is it safe to use Pager.dbFileSize here? */ rc = sqlite3OsFileSize(pPager->fd, ¤tSize); - newSize = pPager->pageSize*(i64)nPage; + newSize = szPage*(i64)nPage; if( rc==SQLITE_OK && currentSize!=newSize ){ if( currentSize>newSize ){ rc = sqlite3OsTruncate(pPager->fd, newSize); }else{ - rc = sqlite3OsWrite(pPager->fd, "", 1, newSize-1); + char *pTmp = pPager->pTmpSpace; + memset(pTmp, 0, szPage); + testcase( (newSize-szPage) < currentSize ); + testcase( (newSize-szPage) == currentSize ); + testcase( (newSize-szPage) > currentSize ); + rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage); } if( rc==SQLITE_OK ){ pPager->dbFileSize = nPage; @@ -33965,8 +40040,8 @@ static int pager_truncate(Pager *pPager, Pgno nPage){ /* ** Set the value of the Pager.sectorSize variable for the given ** pager based on the value returned by the xSectorSize method -** of the open database file. The sector size will be used used -** to determine the size and alignment of journal header and +** of the open database file. The sector size will be used used +** to determine the size and alignment of journal header and ** master journal pointers within created journal files. ** ** For temporary files the effective sector size is always 512 bytes. @@ -33997,15 +40072,15 @@ static void setSectorSize(Pager *pPager){ /* ** Playback the journal and thus restore the database file to -** the state it was in before we started making changes. +** the state it was in before we started making changes. ** -** The journal file format is as follows: +** The journal file format is as follows: ** ** (1) 8 byte prefix. A copy of aJournalMagic[]. ** (2) 4 byte big-endian integer which is the number of valid page records ** in the journal. If this value is 0xffffffff, then compute the ** number of page records from the journal size. -** (3) 4 byte big-endian integer which is the initial value for the +** (3) 4 byte big-endian integer which is the initial value for the ** sanity checksum. ** (4) 4 byte integer which is the number of pages to truncate the ** database to during a rollback. @@ -34034,7 +40109,7 @@ static void setSectorSize(Pager *pPager){ ** from the file size. This value is used when the user selects the ** no-sync option for the journal. A power failure could lead to corruption ** in this case. But for things like temporary table (which will be -** deleted when the power is restored) we don't care. +** deleted when the power is restored) we don't care. ** ** If the file opened as the journal file is not a well-formed ** journal file then all pages up to the first corrupted page are rolled @@ -34046,7 +40121,7 @@ static void setSectorSize(Pager *pPager){ ** and an error code is returned. ** ** The isHot parameter indicates that we are trying to rollback a journal -** that might be a hot journal. Or, it could be that the journal is +** that might be a hot journal. Or, it could be that the journal is ** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE. ** If the journal really is hot, reset the pager cache prior rolling ** back any content. If the journal is merely persistent, no reset is @@ -34068,7 +40143,7 @@ static int pager_playback(Pager *pPager, int isHot){ */ assert( isOpen(pPager->jfd) ); rc = sqlite3OsFileSize(pPager->jfd, &szJ); - if( rc!=SQLITE_OK || szJ==0 ){ + if( rc!=SQLITE_OK ){ goto end_playback; } @@ -34095,20 +40170,18 @@ static int pager_playback(Pager *pPager, int isHot){ pPager->journalOff = 0; needPagerReset = isHot; - /* This loop terminates either when a readJournalHdr() or - ** pager_playback_one_page() call returns SQLITE_DONE or an IO error - ** occurs. + /* This loop terminates either when a readJournalHdr() or + ** pager_playback_one_page() call returns SQLITE_DONE or an IO error + ** occurs. */ while( 1 ){ - int isUnsync = 0; - /* Read the next journal header from the journal file. If there are ** not enough bytes left in the journal file for a complete header, or - ** it is corrupted, then a process must of failed while writing it. + ** it is corrupted, then a process must have failed while writing it. ** This indicates nothing more needs to be rolled back. */ rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg); - if( rc!=SQLITE_OK ){ + if( rc!=SQLITE_OK ){ if( rc==SQLITE_DONE ){ rc = SQLITE_OK; } @@ -34136,13 +40209,12 @@ static int pager_playback(Pager *pPager, int isHot){ ** chunk of the journal contains zero pages to be rolled back. But ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in ** the journal, it means that the journal might contain additional - ** pages that need to be rolled back and that the number of pages + ** pages that need to be rolled back and that the number of pages ** should be computed based on the journal file size. */ if( nRec==0 && !isHot && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){ nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager)); - isUnsync = 1; } /* If this is the first header read from the journal, truncate the @@ -34156,7 +40228,7 @@ static int pager_playback(Pager *pPager, int isHot){ pPager->dbSize = mxPg; } - /* Copy original pages out of the journal and back into the + /* Copy original pages out of the journal and back into the ** database file and/or page cache. */ for(u=0; u<nRec; u++){ @@ -34164,12 +40236,20 @@ static int pager_playback(Pager *pPager, int isHot){ pager_reset(pPager); needPagerReset = 0; } - rc = pager_playback_one_page(pPager,1,isUnsync,&pPager->journalOff,0,0); + rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0); if( rc!=SQLITE_OK ){ if( rc==SQLITE_DONE ){ rc = SQLITE_OK; pPager->journalOff = szJ; break; + }else if( rc==SQLITE_IOERR_SHORT_READ ){ + /* If the journal has been truncated, simply stop reading and + ** processing the journal. This might happen if the journal was + ** not completely written and synced prior to a crash. In that + ** case, the database should have never been written in the + ** first place so it is OK to simply abandon the rollback. */ + rc = SQLITE_OK; + goto end_playback; }else{ /* If we are unable to rollback, quit and return the error ** code. This will cause the pager to enter the error state @@ -34195,10 +40275,10 @@ end_playback: sqlite3OsFileControl(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0)>=SQLITE_OK ); - /* If this playback is happening automatically as a result of an IO or - ** malloc error that occurred after the change-counter was updated but - ** before the transaction was committed, then the change-counter - ** modification may just have been reverted. If this happens in exclusive + /* If this playback is happening automatically as a result of an IO or + ** malloc error that occurred after the change-counter was updated but + ** before the transaction was committed, then the change-counter + ** modification may just have been reverted. If this happens in exclusive ** mode, then subsequent transactions performed by the connection will not ** update the change-counter at all. This may lead to cache inconsistency ** problems for other processes at some point in the future. So, just @@ -34211,8 +40291,10 @@ end_playback: rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); testcase( rc!=SQLITE_OK ); } - if( rc==SQLITE_OK && pPager->noSync==0 && pPager->state>=PAGER_EXCLUSIVE ){ - rc = sqlite3OsSync(pPager->fd, pPager->sync_flags); + if( rc==SQLITE_OK + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + ){ + rc = sqlite3PagerSync(pPager); } if( rc==SQLITE_OK ){ rc = pager_end_transaction(pPager, zMaster[0]!='\0'); @@ -34234,23 +40316,386 @@ end_playback: return rc; } + +/* +** Read the content for page pPg out of the database file and into +** pPg->pData. A shared lock or greater must be held on the database +** file before this function is called. +** +** If page 1 is read, then the value of Pager.dbFileVers[] is set to +** the value read from the database file. +** +** If an IO error occurs, then the IO error is returned to the caller. +** Otherwise, SQLITE_OK is returned. +*/ +static int readDbPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ + Pgno pgno = pPg->pgno; /* Page number to read */ + int rc = SQLITE_OK; /* Return code */ + int isInWal = 0; /* True if page is in log file */ + int pgsz = pPager->pageSize; /* Number of bytes to read */ + + assert( pPager->eState>=PAGER_READER && !MEMDB ); + assert( isOpen(pPager->fd) ); + + if( NEVER(!isOpen(pPager->fd)) ){ + assert( pPager->tempFile ); + memset(pPg->pData, 0, pPager->pageSize); + return SQLITE_OK; + } + + if( pagerUseWal(pPager) ){ + /* Try to pull the page from the write-ahead log. */ + rc = sqlite3WalRead(pPager->pWal, pgno, &isInWal, pgsz, pPg->pData); + } + if( rc==SQLITE_OK && !isInWal ){ + i64 iOffset = (pgno-1)*(i64)pPager->pageSize; + rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } + } + + if( pgno==1 ){ + if( rc ){ + /* If the read is unsuccessful, set the dbFileVers[] to something + ** that will never be a valid file version. dbFileVers[] is a copy + ** of bytes 24..39 of the database. Bytes 28..31 should always be + ** zero or the size of the database in page. Bytes 32..35 and 35..39 + ** should be page numbers which are never 0xffffffff. So filling + ** pPager->dbFileVers[] with all 0xff bytes should suffice. + ** + ** For an encrypted database, the situation is more complex: bytes + ** 24..39 of the database are white noise. But the probability of + ** white noising equaling 16 bytes of 0xff is vanishingly small so + ** we should still be ok. + */ + memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers)); + }else{ + u8 *dbFileVers = &((u8*)pPg->pData)[24]; + memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); + } + } + CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM); + + PAGER_INCR(sqlite3_pager_readdb_count); + PAGER_INCR(pPager->nRead); + IOTRACE(("PGIN %p %d\n", pPager, pgno)); + PAGERTRACE(("FETCH %d page %d hash(%08x)\n", + PAGERID(pPager), pgno, pager_pagehash(pPg))); + + return rc; +} + +/* +** Update the value of the change-counter at offsets 24 and 92 in +** the header and the sqlite version number at offset 96. +** +** This is an unconditional update. See also the pager_incr_changecounter() +** routine which only updates the change-counter if the update is actually +** needed, as determined by the pPager->changeCountDone state variable. +*/ +static void pager_write_changecounter(PgHdr *pPg){ + u32 change_counter; + + /* Increment the value just read and write it back to byte 24. */ + change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1; + put32bits(((char*)pPg->pData)+24, change_counter); + + /* Also store the SQLite version number in bytes 96..99 and in + ** bytes 92..95 store the change counter for which the version number + ** is valid. */ + put32bits(((char*)pPg->pData)+92, change_counter); + put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER); +} + +#ifndef SQLITE_OMIT_WAL +/* +** This function is invoked once for each page that has already been +** written into the log file when a WAL transaction is rolled back. +** Parameter iPg is the page number of said page. The pCtx argument +** is actually a pointer to the Pager structure. +** +** If page iPg is present in the cache, and has no outstanding references, +** it is discarded. Otherwise, if there are one or more outstanding +** references, the page content is reloaded from the database. If the +** attempt to reload content from the database is required and fails, +** return an SQLite error code. Otherwise, SQLITE_OK. +*/ +static int pagerUndoCallback(void *pCtx, Pgno iPg){ + int rc = SQLITE_OK; + Pager *pPager = (Pager *)pCtx; + PgHdr *pPg; + + pPg = sqlite3PagerLookup(pPager, iPg); + if( pPg ){ + if( sqlite3PcachePageRefcount(pPg)==1 ){ + sqlite3PcacheDrop(pPg); + }else{ + rc = readDbPage(pPg); + if( rc==SQLITE_OK ){ + pPager->xReiniter(pPg); + } + sqlite3PagerUnref(pPg); + } + } + + /* Normally, if a transaction is rolled back, any backup processes are + ** updated as data is copied out of the rollback journal and into the + ** database. This is not generally possible with a WAL database, as + ** rollback involves simply truncating the log file. Therefore, if one + ** or more frames have already been written to the log (and therefore + ** also copied into the backup databases) as part of this transaction, + ** the backups must be restarted. + */ + sqlite3BackupRestart(pPager->pBackup); + + return rc; +} + +/* +** This function is called to rollback a transaction on a WAL database. +*/ +static int pagerRollbackWal(Pager *pPager){ + int rc; /* Return Code */ + PgHdr *pList; /* List of dirty pages to revert */ + + /* For all pages in the cache that are currently dirty or have already + ** been written (but not committed) to the log file, do one of the + ** following: + ** + ** + Discard the cached page (if refcount==0), or + ** + Reload page content from the database (if refcount>0). + */ + pPager->dbSize = pPager->dbOrigSize; + rc = sqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager); + pList = sqlite3PcacheDirtyList(pPager->pPCache); + while( pList && rc==SQLITE_OK ){ + PgHdr *pNext = pList->pDirty; + rc = pagerUndoCallback((void *)pPager, pList->pgno); + pList = pNext; + } + + return rc; +} + +/* +** This function is a wrapper around sqlite3WalFrames(). As well as logging +** the contents of the list of pages headed by pList (connected by pDirty), +** this function notifies any active backup processes that the pages have +** changed. +** +** The list of pages passed into this routine is always sorted by page number. +** Hence, if page 1 appears anywhere on the list, it will be the first page. +*/ +static int pagerWalFrames( + Pager *pPager, /* Pager object */ + PgHdr *pList, /* List of frames to log */ + Pgno nTruncate, /* Database size after this commit */ + int isCommit, /* True if this is a commit */ + int syncFlags /* Flags to pass to OsSync() (or 0) */ +){ + int rc; /* Return code */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES) + PgHdr *p; /* For looping over pages */ +#endif + + assert( pPager->pWal ); +#ifdef SQLITE_DEBUG + /* Verify that the page list is in accending order */ + for(p=pList; p && p->pDirty; p=p->pDirty){ + assert( p->pgno < p->pDirty->pgno ); + } +#endif + + if( isCommit ){ + /* If a WAL transaction is being committed, there is no point in writing + ** any pages with page numbers greater than nTruncate into the WAL file. + ** They will never be read by any client. So remove them from the pDirty + ** list here. */ + PgHdr *p; + PgHdr **ppNext = &pList; + for(p=pList; (*ppNext = p); p=p->pDirty){ + if( p->pgno<=nTruncate ) ppNext = &p->pDirty; + } + assert( pList ); + } + + if( pList->pgno==1 ) pager_write_changecounter(pList); + rc = sqlite3WalFrames(pPager->pWal, + pPager->pageSize, pList, nTruncate, isCommit, syncFlags + ); + if( rc==SQLITE_OK && pPager->pBackup ){ + PgHdr *p; + for(p=pList; p; p=p->pDirty){ + sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); + } + } + +#ifdef SQLITE_CHECK_PAGES + pList = sqlite3PcacheDirtyList(pPager->pPCache); + for(p=pList; p; p=p->pDirty){ + pager_set_pagehash(p); + } +#endif + + return rc; +} + +/* +** Begin a read transaction on the WAL. +** +** This routine used to be called "pagerOpenSnapshot()" because it essentially +** makes a snapshot of the database at the current point in time and preserves +** that snapshot for use by the reader in spite of concurrently changes by +** other writers or checkpointers. +*/ +static int pagerBeginReadTransaction(Pager *pPager){ + int rc; /* Return code */ + int changed = 0; /* True if cache must be reset */ + + assert( pagerUseWal(pPager) ); + assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); + + /* sqlite3WalEndReadTransaction() was not called for the previous + ** transaction in locking_mode=EXCLUSIVE. So call it now. If we + ** are in locking_mode=NORMAL and EndRead() was previously called, + ** the duplicate call is harmless. + */ + sqlite3WalEndReadTransaction(pPager->pWal); + + rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); + if( rc!=SQLITE_OK || changed ){ + pager_reset(pPager); + } + + return rc; +} +#endif + +/* +** This function is called as part of the transition from PAGER_OPEN +** to PAGER_READER state to determine the size of the database file +** in pages (assuming the page size currently stored in Pager.pageSize). +** +** If no error occurs, SQLITE_OK is returned and the size of the database +** in pages is stored in *pnPage. Otherwise, an error code (perhaps +** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified. +*/ +static int pagerPagecount(Pager *pPager, Pgno *pnPage){ + Pgno nPage; /* Value to return via *pnPage */ + + /* Query the WAL sub-system for the database size. The WalDbsize() + ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or + ** if the database size is not available. The database size is not + ** available from the WAL sub-system if the log file is empty or + ** contains no valid committed transactions. + */ + assert( pPager->eState==PAGER_OPEN ); + assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock ); + nPage = sqlite3WalDbsize(pPager->pWal); + + /* If the database size was not available from the WAL sub-system, + ** determine it based on the size of the database file. If the size + ** of the database file is not an integer multiple of the page-size, + ** round down to the nearest page. Except, any file larger than 0 + ** bytes in size is considered to contain at least one page. + */ + if( nPage==0 ){ + i64 n = 0; /* Size of db file in bytes */ + assert( isOpen(pPager->fd) || pPager->tempFile ); + if( isOpen(pPager->fd) ){ + int rc = sqlite3OsFileSize(pPager->fd, &n); + if( rc!=SQLITE_OK ){ + return rc; + } + } + nPage = (Pgno)(n / pPager->pageSize); + if( nPage==0 && n>0 ){ + nPage = 1; + } + } + + /* If the current number of pages in the file is greater than the + ** configured maximum pager number, increase the allowed limit so + ** that the file can be read. + */ + if( nPage>pPager->mxPgno ){ + pPager->mxPgno = (Pgno)nPage; + } + + *pnPage = nPage; + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_WAL +/* +** Check if the *-wal file that corresponds to the database opened by pPager +** exists if the database is not empy, or verify that the *-wal file does +** not exist (by deleting it) if the database file is empty. +** +** If the database is not empty and the *-wal file exists, open the pager +** in WAL mode. If the database is empty or if no *-wal file exists and +** if no error occurs, make sure Pager.journalMode is not set to +** PAGER_JOURNALMODE_WAL. +** +** Return SQLITE_OK or an error code. +** +** The caller must hold a SHARED lock on the database file to call this +** function. Because an EXCLUSIVE lock on the db file is required to delete +** a WAL on a none-empty database, this ensures there is no race condition +** between the xAccess() below and an xDelete() being executed by some +** other connection. +*/ +static int pagerOpenWalIfPresent(Pager *pPager){ + int rc = SQLITE_OK; + assert( pPager->eState==PAGER_OPEN ); + assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock ); + + if( !pPager->tempFile ){ + int isWal; /* True if WAL file exists */ + Pgno nPage; /* Size of the database file */ + + rc = pagerPagecount(pPager, &nPage); + if( rc ) return rc; + if( nPage==0 ){ + rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); + isWal = 0; + }else{ + rc = sqlite3OsAccess( + pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal + ); + } + if( rc==SQLITE_OK ){ + if( isWal ){ + testcase( sqlite3PcachePagecount(pPager->pPCache)==0 ); + rc = sqlite3PagerOpenWal(pPager, 0); + }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){ + pPager->journalMode = PAGER_JOURNALMODE_DELETE; + } + } + } + return rc; +} +#endif + /* ** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback -** the entire master journal file. The case pSavepoint==NULL occurs when -** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction +** the entire master journal file. The case pSavepoint==NULL occurs when +** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction ** savepoint. ** -** When pSavepoint is not NULL (meaning a non-transaction savepoint is +** When pSavepoint is not NULL (meaning a non-transaction savepoint is ** being rolled back), then the rollback consists of up to three stages, ** performed in the order specified: ** ** * Pages are played back from the main journal starting at byte -** offset PagerSavepoint.iOffset and continuing to +** offset PagerSavepoint.iOffset and continuing to ** PagerSavepoint.iHdrOffset, or to the end of the main journal ** file if PagerSavepoint.iHdrOffset is zero. ** ** * If PagerSavepoint.iHdrOffset is not zero, then pages are played -** back starting from the journal header immediately following +** back starting from the journal header immediately following ** PagerSavepoint.iHdrOffset to the end of the main journal file. ** ** * Pages are then played back from the sub-journal file, starting @@ -34266,7 +40711,7 @@ end_playback: ** journal file. There is no need for a bitvec in this case. ** ** In either case, before playback commences the Pager.dbSize variable -** is reset to the value that it held at the start of the savepoint +** is reset to the value that it held at the start of the savepoint ** (or transaction). No page with a page-number greater than this value ** is played back. If one is encountered it is simply skipped. */ @@ -34276,7 +40721,8 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ int rc = SQLITE_OK; /* Return code */ Bitvec *pDone = 0; /* Bitvec to ensure pages played back only once */ - assert( pPager->state>=PAGER_SHARED ); + assert( pPager->eState!=PAGER_ERROR ); + assert( pPager->eState>=PAGER_WRITER_LOCKED ); /* Allocate a bitvec to use to store the set of pages rolled back */ if( pSavepoint ){ @@ -34286,10 +40732,15 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ } } - /* Set the database size back to the value it was before the savepoint + /* Set the database size back to the value it was before the savepoint ** being reverted was opened. */ pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize; + pPager->changeCountDone = pPager->tempFile; + + if( !pSavepoint && pagerUseWal(pPager) ){ + return pagerRollbackWal(pPager); + } /* Use pPager->journalOff as the effective size of the main rollback ** journal. The actual file might be larger than this in @@ -34297,6 +40748,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ ** past pPager->journalOff is off-limits to us. */ szJ = pPager->journalOff; + assert( pagerUseWal(pPager)==0 || szJ==0 ); /* Begin by rolling back records from the main journal starting at ** PagerSavepoint.iOffset and continuing to the next journal header. @@ -34305,11 +40757,11 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ ** will be skipped automatically. Pages are added to pDone as they ** are played back. */ - if( pSavepoint ){ + if( pSavepoint && !pagerUseWal(pPager) ){ iHdrOff = pSavepoint->iHdrOffset ? pSavepoint->iHdrOffset : szJ; pPager->journalOff = pSavepoint->iOffset; while( rc==SQLITE_OK && pPager->journalOff<iHdrOff ){ - rc = pager_playback_one_page(pPager, 1, 0, &pPager->journalOff, 1, pDone); + rc = pager_playback_one_page(pPager, &pPager->journalOff, pDone, 1, 1); } assert( rc!=SQLITE_DONE ); }else{ @@ -34333,17 +40785,17 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ ** test is related to ticket #2565. See the discussion in the ** pager_playback() function for additional information. */ - if( nJRec==0 + if( nJRec==0 && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){ nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager)); } for(ii=0; rc==SQLITE_OK && ii<nJRec && pPager->journalOff<szJ; ii++){ - rc = pager_playback_one_page(pPager, 1, 0, &pPager->journalOff, 1, pDone); + rc = pager_playback_one_page(pPager, &pPager->journalOff, pDone, 1, 1); } assert( rc!=SQLITE_DONE ); } - assert( rc!=SQLITE_OK || pPager->journalOff==szJ ); + assert( rc!=SQLITE_OK || pPager->journalOff>=szJ ); /* Finally, rollback pages from the sub-journal. Page that were ** previously rolled back out of the main journal (and are hence in pDone) @@ -34352,9 +40804,13 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ if( pSavepoint ){ u32 ii; /* Loop counter */ i64 offset = pSavepoint->iSubRec*(4+pPager->pageSize); + + if( pagerUseWal(pPager) ){ + rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData); + } for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && ii<pPager->nSubRec; ii++){ assert( offset==ii*(4+pPager->pageSize) ); - rc = pager_playback_one_page(pPager, 0, 0, &offset, 1, pDone); + rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1); } assert( rc!=SQLITE_DONE ); } @@ -34363,6 +40819,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ if( rc==SQLITE_OK ){ pPager->journalOff = szJ; } + return rc; } @@ -34396,22 +40853,56 @@ SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){ ** assurance that the journal will not be corrupted to the ** point of causing damage to the database during rollback. ** +** The above is for a rollback-journal mode. For WAL mode, OFF continues +** to mean that no syncs ever occur. NORMAL means that the WAL is synced +** prior to the start of checkpoint and that the database file is synced +** at the conclusion of the checkpoint if the entire content of the WAL +** was written back into the database. But no sync operations occur for +** an ordinary commit in NORMAL mode with WAL. FULL means that the WAL +** file is synced following each commit operation, in addition to the +** syncs associated with NORMAL. +** +** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL. The +** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync +** using fcntl(F_FULLFSYNC). SQLITE_SYNC_NORMAL means to do an +** ordinary fsync() call. There is no difference between SQLITE_SYNC_FULL +** and SQLITE_SYNC_NORMAL on platforms other than MacOSX. But the +** synchronous=FULL versus synchronous=NORMAL setting determines when +** the xSync primitive is called and is relevant to all platforms. +** ** Numeric values associated with these states are OFF==1, NORMAL=2, ** and FULL=3. */ #ifndef SQLITE_OMIT_PAGER_PRAGMAS -SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager *pPager, int level, int bFullFsync){ +SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel( + Pager *pPager, /* The pager to set safety level for */ + int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */ + int bFullFsync, /* PRAGMA fullfsync */ + int bCkptFullFsync /* PRAGMA checkpoint_fullfsync */ +){ + assert( level>=1 && level<=3 ); pPager->noSync = (level==1 || pPager->tempFile) ?1:0; pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0; - pPager->sync_flags = (bFullFsync?SQLITE_SYNC_FULL:SQLITE_SYNC_NORMAL); - if( pPager->noSync ) pPager->needSync = 0; + if( pPager->noSync ){ + pPager->syncFlags = 0; + pPager->ckptSyncFlags = 0; + }else if( bFullFsync ){ + pPager->syncFlags = SQLITE_SYNC_FULL; + pPager->ckptSyncFlags = SQLITE_SYNC_FULL; + }else if( bCkptFullFsync ){ + pPager->syncFlags = SQLITE_SYNC_NORMAL; + pPager->ckptSyncFlags = SQLITE_SYNC_FULL; + }else{ + pPager->syncFlags = SQLITE_SYNC_NORMAL; + pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; + } } #endif /* ** The following global variable is incremented whenever the library ** attempts to open a temporary file. This information is used for -** testing and analysis only. +** testing and analysis only. */ #ifdef SQLITE_TEST SQLITE_API int sqlite3_opentemp_count = 0; @@ -34420,8 +40911,8 @@ SQLITE_API int sqlite3_opentemp_count = 0; /* ** Open a temporary file. ** -** Write the file descriptor into *pFile. Return SQLITE_OK on success -** or some other error code if we fail. The OS will automatically +** Write the file descriptor into *pFile. Return SQLITE_OK on success +** or some other error code if we fail. The OS will automatically ** delete the temporary file when it is closed. ** ** The flags passed to the VFS layer xOpen() call are those specified @@ -34453,9 +40944,9 @@ static int pagerOpentemp( /* ** Set the busy handler function. ** -** The pager invokes the busy-handler if sqlite3OsLock() returns +** The pager invokes the busy-handler if sqlite3OsLock() returns ** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock, -** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE +** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE ** lock. It does *not* invoke the busy handler when upgrading from ** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE ** (which occurs during hot-journal rollback). Summary: @@ -34467,7 +40958,7 @@ static int pagerOpentemp( ** SHARED_LOCK -> EXCLUSIVE_LOCK | No ** RESERVED_LOCK -> EXCLUSIVE_LOCK | Yes ** -** If the busy-handler callback returns non-zero, the lock is +** If the busy-handler callback returns non-zero, the lock is ** retried. If it returns zero, then the SQLITE_BUSY error is ** returned to the caller of the pager API function. */ @@ -34475,37 +40966,22 @@ SQLITE_PRIVATE void sqlite3PagerSetBusyhandler( Pager *pPager, /* Pager object */ int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ -){ +){ pPager->xBusyHandler = xBusyHandler; pPager->pBusyHandlerArg = pBusyHandlerArg; } /* -** Report the current page size and number of reserved bytes back -** to the codec. -*/ -#ifdef SQLITE_HAS_CODEC -static void pagerReportSize(Pager *pPager){ - if( pPager->xCodecSizeChng ){ - pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, - (int)pPager->nReserve); - } -} -#else -# define pagerReportSize(X) /* No-op if we do not support a codec */ -#endif - -/* -** Change the page size used by the Pager object. The new page size +** Change the page size used by the Pager object. The new page size ** is passed in *pPageSize. ** ** If the pager is in the error state when this function is called, it -** is a no-op. The value returned is the error state error code (i.e. -** one of SQLITE_IOERR, SQLITE_CORRUPT or SQLITE_FULL). +** is a no-op. The value returned is the error state error code (i.e. +** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL). ** ** Otherwise, if all of the following are true: ** -** * the new page size (value of *pPageSize) is valid (a power +** * the new page size (value of *pPageSize) is valid (a power ** of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and ** ** * there are no outstanding page references, and @@ -34515,38 +40991,58 @@ static void pagerReportSize(Pager *pPager){ ** ** then the pager object page size is set to *pPageSize. ** -** If the page size is changed, then this function uses sqlite3PagerMalloc() -** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt -** fails, SQLITE_NOMEM is returned and the page size remains unchanged. +** If the page size is changed, then this function uses sqlite3PagerMalloc() +** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt +** fails, SQLITE_NOMEM is returned and the page size remains unchanged. ** In all other cases, SQLITE_OK is returned. ** ** If the page size is not changed, either because one of the enumerated ** conditions above is not true, the pager was in error state when this -** function was called, or because the memory allocation attempt failed, +** function was called, or because the memory allocation attempt failed, ** then *pPageSize is set to the old, retained page size before returning. */ -SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize, int nReserve){ - int rc = pPager->errCode; +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ + int rc = SQLITE_OK; - if( rc==SQLITE_OK ){ - u16 pageSize = *pPageSize; - assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); - if( (pPager->memDb==0 || pPager->dbSize==0) - && sqlite3PcacheRefCount(pPager->pPCache)==0 - && pageSize && pageSize!=pPager->pageSize - ){ - char *pNew = (char *)sqlite3PageMalloc(pageSize); - if( !pNew ){ - rc = SQLITE_NOMEM; - }else{ - pager_reset(pPager); - pPager->pageSize = pageSize; - sqlite3PageFree(pPager->pTmpSpace); - pPager->pTmpSpace = pNew; - sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); - } + /* It is not possible to do a full assert_pager_state() here, as this + ** function may be called from within PagerOpen(), before the state + ** of the Pager object is internally consistent. + ** + ** At one point this function returned an error if the pager was in + ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that + ** there is at least one outstanding page reference, this function + ** is a no-op for that case anyhow. + */ + + u32 pageSize = *pPageSize; + assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); + if( (pPager->memDb==0 || pPager->dbSize==0) + && sqlite3PcacheRefCount(pPager->pPCache)==0 + && pageSize && pageSize!=(u32)pPager->pageSize + ){ + char *pNew = NULL; /* New temp space */ + i64 nByte = 0; + + if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){ + rc = sqlite3OsFileSize(pPager->fd, &nByte); + } + if( rc==SQLITE_OK ){ + pNew = (char *)sqlite3PageMalloc(pageSize); + if( !pNew ) rc = SQLITE_NOMEM; + } + + if( rc==SQLITE_OK ){ + pager_reset(pPager); + pPager->dbSize = (Pgno)(nByte/pageSize); + pPager->pageSize = pageSize; + sqlite3PageFree(pPager->pTmpSpace); + pPager->pTmpSpace = pNew; + sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); } - *pPageSize = (u16)pPager->pageSize; + } + + *pPageSize = pPager->pageSize; + if( rc==SQLITE_OK ){ if( nReserve<0 ) nReserve = pPager->nReserve; assert( nReserve>=0 && nReserve<1000 ); pPager->nReserve = (i16)nReserve; @@ -34568,7 +41064,7 @@ SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager *pPager){ } /* -** Attempt to set the maximum database page count if mxPage is positive. +** Attempt to set the maximum database page count if mxPage is positive. ** Make no changes if mxPage is zero or negative. And never reduce the ** maximum page count below the current size of the database. ** @@ -34578,7 +41074,8 @@ SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){ if( mxPage>0 ){ pPager->mxPgno = mxPage; } - sqlite3PagerPagecount(pPager, 0); + assert( pPager->eState!=PAGER_OPEN ); /* Called only by OP_MaxPgcnt */ + assert( pPager->mxPgno>=pPager->dbSize ); /* OP_MaxPgcnt enforces this */ return pPager->mxPgno; } @@ -34608,11 +41105,11 @@ void enable_simulated_io_errors(void){ /* ** Read the first N bytes from the beginning of the file into memory -** that pDest points to. +** that pDest points to. ** ** If the pager was opened on a transient file (zFilename==""), or ** opened on a file less than N bytes in size, the output buffer is -** zeroed and SQLITE_OK returned. The rationale for this is that this +** zeroed and SQLITE_OK returned. The rationale for this is that this ** function is used to read database headers, and a new transient or ** zero sized database has a header than consists entirely of zeroes. ** @@ -34624,6 +41121,13 @@ SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned cha int rc = SQLITE_OK; memset(pDest, 0, N); assert( isOpen(pPager->fd) || pPager->tempFile ); + + /* This routine is only called by btree immediately after creating + ** the Pager object. There has not been an opportunity to transition + ** to WAL mode yet. + */ + assert( !pagerUseWal(pPager) ); + if( isOpen(pPager->fd) ){ IOTRACE(("DBHDR %p 0 %d\n", pPager, N)) rc = sqlite3OsRead(pPager->fd, pDest, N, 0); @@ -34635,65 +41139,16 @@ SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned cha } /* -** Return the total number of pages in the database file associated -** with pPager. Normally, this is calculated as (<db file size>/<page-size>). -** However, if the file is between 1 and <page-size> bytes in size, then -** this is considered a 1 page file. +** This function may only be called when a read-transaction is open on +** the pager. It returns the total number of pages in the database. ** -** If the pager is in error state when this function is called, then the -** error state error code is returned and *pnPage left unchanged. Or, -** if the file system has to be queried for the size of the file and -** the query attempt returns an IO error, the IO error code is returned -** and *pnPage is left unchanged. -** -** Otherwise, if everything is successful, then SQLITE_OK is returned -** and *pnPage is set to the number of pages in the database. +** However, if the file is between 1 and <page-size> bytes in size, then +** this is considered a 1 page file. */ -SQLITE_PRIVATE int sqlite3PagerPagecount(Pager *pPager, int *pnPage){ - Pgno nPage; /* Value to return via *pnPage */ - - /* If the pager is already in the error state, return the error code. */ - if( pPager->errCode ){ - return pPager->errCode; - } - - /* Determine the number of pages in the file. Store this in nPage. */ - if( pPager->dbSizeValid ){ - nPage = pPager->dbSize; - }else{ - int rc; /* Error returned by OsFileSize() */ - i64 n = 0; /* File size in bytes returned by OsFileSize() */ - - assert( isOpen(pPager->fd) || pPager->tempFile ); - if( isOpen(pPager->fd) && (0 != (rc = sqlite3OsFileSize(pPager->fd, &n))) ){ - pager_error(pPager, rc); - return rc; - } - if( n>0 && n<pPager->pageSize ){ - nPage = 1; - }else{ - nPage = (Pgno)(n / pPager->pageSize); - } - if( pPager->state!=PAGER_UNLOCK ){ - pPager->dbSize = nPage; - pPager->dbFileSize = nPage; - pPager->dbSizeValid = 1; - } - } - - /* If the current number of pages in the file is greater than the - ** configured maximum pager number, increase the allowed limit so - ** that the file can be read. - */ - if( nPage>pPager->mxPgno ){ - pPager->mxPgno = (Pgno)nPage; - } - - /* Set the output variable and return SQLITE_OK */ - if( pnPage ){ - *pnPage = nPage; - } - return SQLITE_OK; +SQLITE_PRIVATE void sqlite3PagerPagecount(Pager *pPager, int *pnPage){ + assert( pPager->eState>=PAGER_READER ); + assert( pPager->eState!=PAGER_WRITER_FINISHED ); + *pnPage = (int)pPager->dbSize; } @@ -34702,58 +41157,39 @@ SQLITE_PRIVATE int sqlite3PagerPagecount(Pager *pPager, int *pnPage){ ** a similar or greater lock is already held, this function is a no-op ** (returning SQLITE_OK immediately). ** -** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke -** the busy callback if the lock is currently not available. Repeat -** until the busy callback returns false or until the attempt to +** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke +** the busy callback if the lock is currently not available. Repeat +** until the busy callback returns false or until the attempt to ** obtain the lock succeeds. ** ** Return SQLITE_OK on success and an error code if we cannot obtain -** the lock. If the lock is obtained successfully, set the Pager.state +** the lock. If the lock is obtained successfully, set the Pager.state ** variable to locktype before returning. */ static int pager_wait_on_lock(Pager *pPager, int locktype){ int rc; /* Return code */ - /* The OS lock values must be the same as the Pager lock values */ - assert( PAGER_SHARED==SHARED_LOCK ); - assert( PAGER_RESERVED==RESERVED_LOCK ); - assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK ); - - /* If the file is currently unlocked then the size must be unknown. It - ** must not have been modified at this point. - */ - assert( pPager->state>=PAGER_SHARED || pPager->dbSizeValid==0 ); - assert( pPager->state>=PAGER_SHARED || pPager->dbModified==0 ); - - /* Check that this is either a no-op (because the requested lock is + /* Check that this is either a no-op (because the requested lock is ** already held, or one of the transistions that the busy-handler ** may be invoked during, according to the comment above ** sqlite3PagerSetBusyhandler(). */ - assert( (pPager->state>=locktype) - || (pPager->state==PAGER_UNLOCK && locktype==PAGER_SHARED) - || (pPager->state==PAGER_RESERVED && locktype==PAGER_EXCLUSIVE) + assert( (pPager->eLock>=locktype) + || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK) + || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK) ); - if( pPager->state>=locktype ){ - rc = SQLITE_OK; - }else{ - do { - rc = sqlite3OsLock(pPager->fd, locktype); - }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) ); - if( rc==SQLITE_OK ){ - pPager->state = (u8)locktype; - IOTRACE(("LOCK %p %d\n", pPager, locktype)) - } - } + do { + rc = pagerLockDb(pPager, locktype); + }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) ); return rc; } /* -** Function assertTruncateConstraint(pPager) checks that one of the +** Function assertTruncateConstraint(pPager) checks that one of the ** following is true for all dirty pages currently in the page-cache: ** -** a) The page number is less than or equal to the size of the +** a) The page number is less than or equal to the size of the ** current database image, in pages, OR ** ** b) if the page content were written at this time, it would not @@ -34766,9 +41202,9 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ ** the database file. If a savepoint transaction were rolled back after ** this happened, the correct behaviour would be to restore the current ** content of the page. However, since this content is not present in either -** the database file or the portion of the rollback journal and +** the database file or the portion of the rollback journal and ** sub-journal rolled back the content could not be restored and the -** database image would become corrupt. It is therefore fortunate that +** database image would become corrupt. It is therefore fortunate that ** this circumstance cannot arise. */ #if defined(SQLITE_DEBUG) @@ -34784,19 +41220,44 @@ static void assertTruncateConstraint(Pager *pPager){ #endif /* -** Truncate the in-memory database file image to nPage pages. This -** function does not actually modify the database file on disk. It -** just sets the internal state of the pager object so that the +** Truncate the in-memory database file image to nPage pages. This +** function does not actually modify the database file on disk. It +** just sets the internal state of the pager object so that the ** truncation will be done when the current transaction is committed. */ SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ - assert( pPager->dbSizeValid ); assert( pPager->dbSize>=nPage ); - assert( pPager->state>=PAGER_RESERVED ); + assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); pPager->dbSize = nPage; assertTruncateConstraint(pPager); } + +/* +** This function is called before attempting a hot-journal rollback. It +** syncs the journal file to disk, then sets pPager->journalHdr to the +** size of the journal file so that the pager_playback() routine knows +** that the entire journal file has been synced. +** +** Syncing a hot-journal to disk before attempting to roll it back ensures +** that if a power-failure occurs during the rollback, the process that +** attempts rollback following system recovery sees the same journal +** content as this process. +** +** If everything goes as planned, SQLITE_OK is returned. Otherwise, +** an SQLite error code. +*/ +static int pagerSyncHotJournal(Pager *pPager){ + int rc = SQLITE_OK; + if( !pPager->noSync ){ + rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL); + } + if( rc==SQLITE_OK ){ + rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr); + } + return rc; +} + /* ** Shutdown the page cache. Free all memory and close all files. ** @@ -34807,34 +41268,49 @@ SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ ** result in a coredump. ** ** This function always succeeds. If a transaction is active an attempt -** is made to roll it back. If an error occurs during the rollback +** is made to roll it back. If an error occurs during the rollback ** a hot journal may be left in the filesystem but no error is returned ** to the caller. */ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){ + u8 *pTmp = (u8 *)pPager->pTmpSpace; + + assert( assert_pager_state(pPager) ); disable_simulated_io_errors(); sqlite3BeginBenignMalloc(); - pPager->errCode = 0; + /* pPager->errCode = 0; */ pPager->exclusiveMode = 0; +#ifndef SQLITE_OMIT_WAL + sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp); + pPager->pWal = 0; +#endif pager_reset(pPager); if( MEMDB ){ pager_unlock(pPager); }else{ - /* Set Pager.journalHdr to -1 for the benefit of the pager_playback() - ** call which may be made from within pagerUnlockAndRollback(). If it - ** is not -1, then the unsynced portion of an open journal file may - ** be played back into the database. If a power failure occurs while - ** this is happening, the database may become corrupt. + /* If it is open, sync the journal file before calling UnlockAndRollback. + ** If this is not done, then an unsynced portion of the open journal + ** file may be played back into the database. If a power failure occurs + ** while this is happening, the database could become corrupt. + ** + ** If an error occurs while trying to sync the journal, shift the pager + ** into the ERROR state. This causes UnlockAndRollback to unlock the + ** database and close the journal file without attempting to roll it + ** back or finalize it. The next database user will have to do hot-journal + ** rollback before accessing the database file. */ - pPager->journalHdr = -1; + if( isOpen(pPager->jfd) ){ + pager_error(pPager, pagerSyncHotJournal(pPager)); + } pagerUnlockAndRollback(pPager); } sqlite3EndBenignMalloc(); enable_simulated_io_errors(); PAGERTRACE(("CLOSE %d\n", PAGERID(pPager))); IOTRACE(("CLOSE %p\n", pPager)) + sqlite3OsClose(pPager->jfd); sqlite3OsClose(pPager->fd); - sqlite3PageFree(pPager->pTmpSpace); + sqlite3PageFree(pTmp); sqlite3PcacheClose(pPager->pPCache); #ifdef SQLITE_HAS_CODEC @@ -34869,9 +41345,9 @@ SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){ ** been written to the journal have actually reached the surface of the ** disk and can be restored in the event of a hot-journal rollback. ** -** If the Pager.needSync flag is not set, then this function is a -** no-op. Otherwise, the actions required depend on the journal-mode -** and the device characteristics of the the file-system, as follows: +** If the Pager.noSync flag is set, then this function is a no-op. +** Otherwise, the actions required depend on the journal-mode and the +** device characteristics of the the file-system, as follows: ** ** * If the journal file is an in-memory journal file, no action need ** be taken. @@ -34882,7 +41358,7 @@ SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){ ** been written following it. If the pager is operating in full-sync ** mode, then the journal file is synced before this field is updated. ** -** * If the device does not support the SEQUENTIAL property, then +** * If the device does not support the SEQUENTIAL property, then ** journal file is synced. ** ** Or, in pseudo-code: @@ -34891,22 +41367,29 @@ SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){ ** if( NOT SAFE_APPEND ){ ** if( <full-sync mode> ) xSync(<journal file>); ** <update nRec field> -** } +** } ** if( NOT SEQUENTIAL ) xSync(<journal file>); ** } ** -** The Pager.needSync flag is never be set for temporary files, or any -** file operating in no-sync mode (Pager.noSync set to non-zero). -** -** If successful, this routine clears the PGHDR_NEED_SYNC flag of every +** If successful, this routine clears the PGHDR_NEED_SYNC flag of every ** page currently held in memory before returning SQLITE_OK. If an IO ** error is encountered, then the IO error code is returned to the caller. */ -static int syncJournal(Pager *pPager){ - if( pPager->needSync ){ +static int syncJournal(Pager *pPager, int newHdr){ + int rc; /* Return code */ + + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + assert( !pagerUseWal(pPager) ); + + rc = sqlite3PagerExclusiveLock(pPager); + if( rc!=SQLITE_OK ) return rc; + + if( !pPager->noSync ){ assert( !pPager->tempFile ); - if( pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ - int rc; /* Return code */ + if( isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); assert( isOpen(pPager->jfd) ); @@ -34916,10 +41399,10 @@ static int syncJournal(Pager *pPager){ ** mode, then the journal file may at this point actually be larger ** than Pager.journalOff bytes. If the next thing in the journal ** file happens to be a journal-header (written as part of the - ** previous connections transaction), and a crash or power-failure - ** occurs after nRec is updated but before this connection writes - ** anything else to the journal file (or commits/rolls back its - ** transaction), then SQLite may become confused when doing the + ** previous connection's transaction), and a crash or power-failure + ** occurs after nRec is updated but before this connection writes + ** anything else to the journal file (or commits/rolls back its + ** transaction), then SQLite may become confused when doing the ** hot-journal rollback following recovery. It may roll back all ** of this connections data, then proceed to rolling back the old, ** out-of-date data that follows it. Database corruption. @@ -34929,16 +41412,16 @@ static int syncJournal(Pager *pPager){ ** byte to the start of it to prevent it from being recognized. ** ** Variable iNextHdrOffset is set to the offset at which this - ** problematic header will occur, if it exists. aMagic is used + ** problematic header will occur, if it exists. aMagic is used ** as a temporary buffer to inspect the first couple of bytes of ** the potential journal header. */ i64 iNextHdrOffset; u8 aMagic[8]; - u8 zHeader[sizeof(aJournalMagic)+4]; + u8 zHeader[sizeof(aJournalMagic)+4]; - memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); - put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec); + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); + put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec); iNextHdrOffset = journalHdrOffset(pPager); rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset); @@ -34956,7 +41439,7 @@ static int syncJournal(Pager *pPager){ ** it as a candidate for rollback. ** ** This is not required if the persistent media supports the - ** SAFE_APPEND property. Because in this case it is not possible + ** SAFE_APPEND property. Because in this case it is not possible ** for garbage data to be appended to the file, the nRec field ** is populated with 0xFFFFFFFF when the journal header is written ** and never needs to be updated. @@ -34964,33 +41447,42 @@ static int syncJournal(Pager *pPager){ if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); IOTRACE(("JSYNC %p\n", pPager)) - rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags); + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); if( rc!=SQLITE_OK ) return rc; } IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr)); rc = sqlite3OsWrite( pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr - ); + ); if( rc!=SQLITE_OK ) return rc; } if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); IOTRACE(("JSYNC %p\n", pPager)) - rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags| - (pPager->sync_flags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0) + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| + (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0) ); if( rc!=SQLITE_OK ) return rc; } - } - /* The journal file was just successfully synced. Set Pager.needSync - ** to zero and clear the PGHDR_NEED_SYNC flag on all pagess. - */ - pPager->needSync = 0; - pPager->journalStarted = 1; - sqlite3PcacheClearSyncFlags(pPager->pPCache); + pPager->journalHdr = pPager->journalOff; + if( newHdr && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ + pPager->nRec = 0; + rc = writeJournalHdr(pPager); + if( rc!=SQLITE_OK ) return rc; + } + }else{ + pPager->journalHdr = pPager->journalOff; + } } + /* Unless the pager is in noSync mode, the journal file was just + ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on + ** all pages. + */ + sqlite3PcacheClearSyncFlags(pPager->pPCache); + pPager->eState = PAGER_WRITER_DBMOD; + assert( assert_pager_state(pPager) ); return SQLITE_OK; } @@ -35005,9 +41497,9 @@ static int syncJournal(Pager *pPager){ ** is called. Before writing anything to the database file, this lock ** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained, ** SQLITE_BUSY is returned and no data is written to the database file. -** +** ** If the pager is a temp-file pager and the actual file-system file -** is not yet open, it is created and opened before any data is +** is not yet open, it is created and opened before any data is ** written out. ** ** Once the lock has been upgraded and, if necessary, the file opened, @@ -35022,35 +41514,17 @@ static int syncJournal(Pager *pPager){ ** in Pager.dbFileVers[] is updated to match the new value stored in ** the database file. ** -** If everything is successful, SQLITE_OK is returned. If an IO error +** If everything is successful, SQLITE_OK is returned. If an IO error ** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot ** be obtained, SQLITE_BUSY is returned. */ -static int pager_write_pagelist(PgHdr *pList){ - Pager *pPager; /* Pager object */ - int rc; /* Return code */ +static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ + int rc = SQLITE_OK; /* Return code */ - if( NEVER(pList==0) ) return SQLITE_OK; - pPager = pList->pPager; - - /* At this point there may be either a RESERVED or EXCLUSIVE lock on the - ** database file. If there is already an EXCLUSIVE lock, the following - ** call is a no-op. - ** - ** Moving the lock from RESERVED to EXCLUSIVE actually involves going - ** through an intermediate state PENDING. A PENDING lock prevents new - ** readers from attaching to the database but is unsufficient for us to - ** write. The idea of a PENDING lock is to prevent new readers from - ** coming in while we wait for existing readers to clear. - ** - ** While the pager is in the RESERVED state, the original database file - ** is unchanged and we can rollback without having to playback the - ** journal into the original database file. Once we transition to - ** EXCLUSIVE, it means the database file has been changed and any rollback - ** will require a journal playback. - */ - assert( pPager->state>=PAGER_RESERVED ); - rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + /* This function is only called for rollback pagers in WRITER_DBMOD state. */ + assert( !pagerUseWal(pPager) ); + assert( pPager->eState==PAGER_WRITER_DBMOD ); + assert( pPager->eLock==EXCLUSIVE_LOCK ); /* If the file is a temp-file has not yet been opened, open it now. It ** is not possible for rc to be other than SQLITE_OK if this branch @@ -35061,6 +41535,16 @@ static int pager_write_pagelist(PgHdr *pList){ rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags); } + /* Before the first write, give the VFS a hint of what the final + ** file size will be. + */ + assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); + if( rc==SQLITE_OK && pPager->dbSize>pPager->dbHintSize ){ + sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; + sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); + pPager->dbHintSize = pPager->dbSize; + } + while( rc==SQLITE_OK && pList ){ Pgno pgno = pList->pgno; @@ -35074,7 +41558,10 @@ static int pager_write_pagelist(PgHdr *pList){ */ if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){ i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */ - char *pData; /* Data to write */ + char *pData; /* Data to write */ + + assert( (pList->flags&PGHDR_NEED_SYNC)==0 ); + if( pList->pgno==1 ) pager_write_changecounter(pList); /* Encode the database */ CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData); @@ -35083,8 +41570,8 @@ static int pager_write_pagelist(PgHdr *pList){ rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset); /* If page 1 was just written, update Pager.dbFileVers to match - ** the value now stored in the database file. If writing this - ** page caused the database file to grow, update dbFileSize. + ** the value now stored in the database file. If writing this + ** page caused the database file to grow, update dbFileSize. */ if( pgno==1 ){ memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers)); @@ -35104,9 +41591,7 @@ static int pager_write_pagelist(PgHdr *pList){ }else{ PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno)); } -#ifdef SQLITE_CHECK_PAGES - pList->pageHash = pager_pagehash(pList); -#endif + pager_set_pagehash(pList); pList = pList->pDirty; } @@ -35114,33 +41599,66 @@ static int pager_write_pagelist(PgHdr *pList){ } /* -** Append a record of the current state of page pPg to the sub-journal. -** It is the callers responsibility to use subjRequiresPage() to check +** Ensure that the sub-journal file is open. If it is already open, this +** function is a no-op. +** +** SQLITE_OK is returned if everything goes according to plan. An +** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() +** fails. +*/ +static int openSubJournal(Pager *pPager){ + int rc = SQLITE_OK; + if( !isOpen(pPager->sjfd) ){ + if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){ + sqlite3MemJournalOpen(pPager->sjfd); + }else{ + rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL); + } + } + return rc; +} + +/* +** Append a record of the current state of page pPg to the sub-journal. +** It is the callers responsibility to use subjRequiresPage() to check ** that it is really required before calling this function. ** ** If successful, set the bit corresponding to pPg->pgno in the bitvecs ** for all open savepoints before returning. ** ** This function returns SQLITE_OK if everything is successful, an IO -** error code if the attempt to write to the sub-journal fails, or +** error code if the attempt to write to the sub-journal fails, or ** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint ** bitvec. */ static int subjournalPage(PgHdr *pPg){ int rc = SQLITE_OK; Pager *pPager = pPg->pPager; - if( isOpen(pPager->sjfd) ){ - void *pData = pPg->pData; - i64 offset = pPager->nSubRec*(4+pPager->pageSize); - char *pData2; - - CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); - PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno)); + if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + + /* Open the sub-journal, if it has not already been opened */ + assert( pPager->useJournal ); + assert( isOpen(pPager->jfd) || pagerUseWal(pPager) ); + assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 ); + assert( pagerUseWal(pPager) + || pageInJournal(pPg) + || pPg->pgno>pPager->dbOrigSize + ); + rc = openSubJournal(pPager); - assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize ); - rc = write32bits(pPager->sjfd, offset, pPg->pgno); + /* If the sub-journal was opened successfully (or was already open), + ** write the journal record into the file. */ if( rc==SQLITE_OK ){ - rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4); + void *pData = pPg->pData; + i64 offset = pPager->nSubRec*(4+pPager->pageSize); + char *pData2; + + CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); + PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno)); + rc = write32bits(pPager->sjfd, offset, pPg->pgno); + if( rc==SQLITE_OK ){ + rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4); + } } } if( rc==SQLITE_OK ){ @@ -35151,19 +41669,18 @@ static int subjournalPage(PgHdr *pPg){ return rc; } - /* ** This function is called by the pcache layer when it has reached some ** soft memory limit. The first argument is a pointer to a Pager object ** (cast as a void*). The pager is always 'purgeable' (not an in-memory -** database). The second argument is a reference to a page that is +** database). The second argument is a reference to a page that is ** currently dirty but has no outstanding references. The page -** is always associated with the Pager object passed as the first +** is always associated with the Pager object passed as the first ** argument. ** ** The job of this function is to make pPg clean by writing its contents ** out to the database file, if possible. This may involve syncing the -** journal file. +** journal file. ** ** If successful, sqlite3PcacheMakeClean() is called on the page and ** SQLITE_OK returned. If an IO error occurs while trying to make the @@ -35178,74 +41695,83 @@ static int pagerStress(void *p, PgHdr *pPg){ assert( pPg->pPager==pPager ); assert( pPg->flags&PGHDR_DIRTY ); - /* The doNotSync flag is set by the sqlite3PagerWrite() function while it - ** is journalling a set of two or more database pages that are stored - ** on the same disk sector. Syncing the journal is not allowed while - ** this is happening as it is important that all members of such a - ** set of pages are synced to disk together. So, if the page this function - ** is trying to make clean will require a journal sync and the doNotSync - ** flag is set, return without doing anything. The pcache layer will - ** just have to go ahead and allocate a new page buffer instead of - ** reusing pPg. + /* The doNotSyncSpill flag is set during times when doing a sync of + ** journal (and adding a new header) is not allowed. This occurs + ** during calls to sqlite3PagerWrite() while trying to journal multiple + ** pages belonging to the same sector. ** - ** Similarly, if the pager has already entered the error state, do not - ** try to write the contents of pPg to disk. - */ - if( NEVER(pPager->errCode) - || (pPager->doNotSync && pPg->flags&PGHDR_NEED_SYNC) - ){ + ** The doNotSpill flag inhibits all cache spilling regardless of whether + ** or not a sync is required. This is set during a rollback. + ** + ** Spilling is also prohibited when in an error state since that could + ** lead to database corruption. In the current implementaton it + ** is impossible for sqlite3PCacheFetch() to be called with createFlag==1 + ** while in the error state, hence it is impossible for this routine to + ** be called in the error state. Nevertheless, we include a NEVER() + ** test for the error state as a safeguard against future changes. + */ + if( NEVER(pPager->errCode) ) return SQLITE_OK; + if( pPager->doNotSpill ) return SQLITE_OK; + if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){ return SQLITE_OK; } - /* Sync the journal file if required. */ - if( pPg->flags&PGHDR_NEED_SYNC ){ - rc = syncJournal(pPager); - if( rc==SQLITE_OK && pPager->fullSync && - !(pPager->journalMode==PAGER_JOURNALMODE_MEMORY) && - !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) + pPg->pDirty = 0; + if( pagerUseWal(pPager) ){ + /* Write a single frame for this page to the log. */ + if( subjRequiresPage(pPg) ){ + rc = subjournalPage(pPg); + } + if( rc==SQLITE_OK ){ + rc = pagerWalFrames(pPager, pPg, 0, 0, 0); + } + }else{ + + /* Sync the journal file if required. */ + if( pPg->flags&PGHDR_NEED_SYNC + || pPager->eState==PAGER_WRITER_CACHEMOD ){ - pPager->nRec = 0; - rc = writeJournalHdr(pPager); + rc = syncJournal(pPager, 1); + } + + /* If the page number of this page is larger than the current size of + ** the database image, it may need to be written to the sub-journal. + ** This is because the call to pager_write_pagelist() below will not + ** actually write data to the file in this case. + ** + ** Consider the following sequence of events: + ** + ** BEGIN; + ** <journal page X> + ** <modify page X> + ** SAVEPOINT sp; + ** <shrink database file to Y pages> + ** pagerStress(page X) + ** ROLLBACK TO sp; + ** + ** If (X>Y), then when pagerStress is called page X will not be written + ** out to the database file, but will be dropped from the cache. Then, + ** following the "ROLLBACK TO sp" statement, reading page X will read + ** data from the database file. This will be the copy of page X as it + ** was when the transaction started, not as it was when "SAVEPOINT sp" + ** was executed. + ** + ** The solution is to write the current data for page X into the + ** sub-journal file now (if it is not already there), so that it will + ** be restored to its current value when the "ROLLBACK TO sp" is + ** executed. + */ + if( NEVER( + rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg) + ) ){ + rc = subjournalPage(pPg); + } + + /* Write the contents of the page out to the database file. */ + if( rc==SQLITE_OK ){ + assert( (pPg->flags&PGHDR_NEED_SYNC)==0 ); + rc = pager_write_pagelist(pPager, pPg); } - } - - /* If the page number of this page is larger than the current size of - ** the database image, it may need to be written to the sub-journal. - ** This is because the call to pager_write_pagelist() below will not - ** actually write data to the file in this case. - ** - ** Consider the following sequence of events: - ** - ** BEGIN; - ** <journal page X> - ** <modify page X> - ** SAVEPOINT sp; - ** <shrink database file to Y pages> - ** pagerStress(page X) - ** ROLLBACK TO sp; - ** - ** If (X>Y), then when pagerStress is called page X will not be written - ** out to the database file, but will be dropped from the cache. Then, - ** following the "ROLLBACK TO sp" statement, reading page X will read - ** data from the database file. This will be the copy of page X as it - ** was when the transaction started, not as it was when "SAVEPOINT sp" - ** was executed. - ** - ** The solution is to write the current data for page X into the - ** sub-journal file now (if it is not already there), so that it will - ** be restored to its current value when the "ROLLBACK TO sp" is - ** executed. - */ - if( NEVER( - rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg) - ) ){ - rc = subjournalPage(pPg); - } - - /* Write the contents of the page out to the database file. */ - if( rc==SQLITE_OK ){ - pPg->pDirty = 0; - rc = pager_write_pagelist(pPg); } /* Mark the page as clean. */ @@ -35254,7 +41780,7 @@ static int pagerStress(void *p, PgHdr *pPg){ sqlite3PcacheMakeClean(pPg); } - return pager_error(pPager, rc); + return pager_error(pPager, rc); } @@ -35266,8 +41792,8 @@ static int pagerStress(void *p, PgHdr *pPg){ ** The zFilename argument is the path to the database file to open. ** If zFilename is NULL then a randomly-named temporary file is created ** and used as the file to be cached. Temporary files are be deleted -** automatically when they are closed. If zFilename is ":memory:" then -** all information is held in cache. It is never written to disk. +** automatically when they are closed. If zFilename is ":memory:" then +** all information is held in cache. It is never written to disk. ** This can be used to implement an in-memory database. ** ** The nExtra parameter specifies the number of bytes of space allocated @@ -35279,13 +41805,13 @@ static int pagerStress(void *p, PgHdr *pPg){ ** of the PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK flags. ** ** The vfsFlags parameter is a bitmask to pass to the flags parameter -** of the xOpen() method of the supplied VFS when opening files. +** of the xOpen() method of the supplied VFS when opening files. ** -** If the pager object is allocated and the specified file opened +** If the pager object is allocated and the specified file opened ** successfully, SQLITE_OK is returned and *ppPager set to point to ** the new pager object. If an error occurs, *ppPager is set to NULL ** and error code returned. This function may return SQLITE_NOMEM -** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or +** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or ** various SQLITE_IO_XXX errors. */ SQLITE_PRIVATE int sqlite3PagerOpen( @@ -35309,14 +41835,16 @@ SQLITE_PRIVATE int sqlite3PagerOpen( int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ int noReadlock = (flags & PAGER_NO_READLOCK)!=0; /* True to omit read-lock */ int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ - u16 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ + u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ + const char *zUri = 0; /* URI args to copy */ + int nUri = 0; /* Number of bytes of URI args at *zUri */ /* Figure out how much space is required for each journal file-handle ** (there are two of them, the main journal and the sub-journal). This - ** is the maximum space required for an in-memory journal file handle + ** is the maximum space required for an in-memory journal file handle ** and a regular journal file-handle. Note that a "regular journal-handle" ** may be a wrapper capable of caching the first portion of the journal - ** file in memory to implement the atomic-write optimization (see + ** file in memory to implement the atomic-write optimization (see ** source file journal.c). */ if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){ @@ -35328,28 +41856,33 @@ SQLITE_PRIVATE int sqlite3PagerOpen( /* Set the output variable to NULL in case an error occurs. */ *ppPager = 0; +#ifndef SQLITE_OMIT_MEMORYDB + if( flags & PAGER_MEMORY ){ + memDb = 1; + zFilename = 0; + } +#endif + /* Compute and store the full pathname in an allocated buffer pointed ** to by zPathname, length nPathname. Or, if this is a temporary file, ** leave both nPathname and zPathname set to 0. */ if( zFilename && zFilename[0] ){ + const char *z; nPathname = pVfs->mxPathname+1; zPathname = sqlite3Malloc(nPathname*2); if( zPathname==0 ){ return SQLITE_NOMEM; } -#ifndef SQLITE_OMIT_MEMORYDB - if( strcmp(zFilename,":memory:")==0 ){ - memDb = 1; - zPathname[0] = 0; - }else -#endif - { - zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ - rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); - } - + zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ + rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); nPathname = sqlite3Strlen30(zPathname); + z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1]; + while( *z ){ + z += sqlite3Strlen30(z)+1; + z += sqlite3Strlen30(z)+1; + } + nUri = &z[1] - zUri; if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ /* This branch is taken when the journal path required by ** the database being opened will be more than pVfs->mxPathname @@ -35366,7 +41899,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( } /* Allocate memory for the Pager structure, PCache object, the - ** three file descriptors, the database file name and the journal + ** three file descriptors, the database file name and the journal ** file name. The layout in memory is as follows: ** ** Pager object (sizeof(Pager) bytes) @@ -35381,9 +41914,12 @@ SQLITE_PRIVATE int sqlite3PagerOpen( ROUND8(sizeof(*pPager)) + /* Pager structure */ ROUND8(pcacheSize) + /* PCache object */ ROUND8(pVfs->szOsFile) + /* The main db file */ - journalFileSize * 2 + /* The two journal files */ - nPathname + 1 + /* zFilename */ + journalFileSize * 2 + /* The two journal files */ + nPathname + 1 + nUri + /* zFilename */ nPathname + 8 + 1 /* zJournal */ +#ifndef SQLITE_OMIT_WAL + + nPathname + 4 + 1 /* zWal */ +#endif ); assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); if( !pPtr ){ @@ -35400,11 +41936,19 @@ SQLITE_PRIVATE int sqlite3PagerOpen( /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */ if( zPathname ){ - pPager->zJournal = (char*)(pPtr += nPathname + 1); + assert( nPathname>0 ); + pPager->zJournal = (char*)(pPtr += nPathname + 1 + nUri); memcpy(pPager->zFilename, zPathname, nPathname); + memcpy(&pPager->zFilename[nPathname+1], zUri, nUri); memcpy(pPager->zJournal, zPathname, nPathname); memcpy(&pPager->zJournal[nPathname], "-journal", 8); - if( pPager->zFilename[0]==0 ) pPager->zJournal[0] = 0; + sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal); +#ifndef SQLITE_OMIT_WAL + pPager->zWal = &pPager->zJournal[nPathname+8+1]; + memcpy(pPager->zWal, zPathname, nPathname); + memcpy(&pPager->zWal[nPathname], "-wal", 4); + sqlite3FileSuffix3(pPager->zFilename, pPager->zWal); +#endif sqlite3_free(zPathname); } pPager->pVfs = pVfs; @@ -35412,9 +41956,10 @@ SQLITE_PRIVATE int sqlite3PagerOpen( /* Open the pager file. */ - if( zFilename && zFilename[0] && !memDb ){ + if( zFilename && zFilename[0] ){ int fout = 0; /* VFS flags returned by xOpen() */ rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); + assert( !memDb ); readOnly = (fout&SQLITE_OPEN_READONLY); /* If the file was successfully opened for read/write access, @@ -35432,7 +41977,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; }else{ - szPageDflt = (u16)pPager->sectorSize; + szPageDflt = (u32)pPager->sectorSize; } } #ifdef SQLITE_ENABLE_ATOMIC_WRITE @@ -35458,13 +42003,14 @@ SQLITE_PRIVATE int sqlite3PagerOpen( ** This branch is also run for an in-memory database. An in-memory ** database is the same as a temp-file that is never written out to ** disk and uses an in-memory rollback journal. - */ + */ tempFile = 1; - pPager->state = PAGER_EXCLUSIVE; + pPager->eState = PAGER_READER; + pPager->eLock = EXCLUSIVE_LOCK; readOnly = (vfsFlags&SQLITE_OPEN_READONLY); } - /* The following call to PagerSetPagesize() serves to set the value of + /* The following call to PagerSetPagesize() serves to set the value of ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. */ if( rc==SQLITE_OK ){ @@ -35473,7 +42019,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( testcase( rc!=SQLITE_OK ); } - /* If an error occurred in either of the blocks above, free the + /* If an error occurred in either of the blocks above, free the ** Pager structure and close the file. */ if( rc!=SQLITE_OK ){ @@ -35497,27 +42043,28 @@ SQLITE_PRIVATE int sqlite3PagerOpen( /* pPager->stmtOpen = 0; */ /* pPager->stmtInUse = 0; */ /* pPager->nRef = 0; */ - pPager->dbSizeValid = (u8)memDb; /* pPager->stmtSize = 0; */ /* pPager->stmtJSize = 0; */ /* pPager->nPage = 0; */ pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; /* pPager->state = PAGER_UNLOCK; */ +#if 0 assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) ); +#endif /* pPager->errMask = 0; */ pPager->tempFile = (u8)tempFile; - assert( tempFile==PAGER_LOCKINGMODE_NORMAL + assert( tempFile==PAGER_LOCKINGMODE_NORMAL || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); - pPager->exclusiveMode = (u8)tempFile; + pPager->exclusiveMode = (u8)tempFile; pPager->changeCountDone = pPager->tempFile; pPager->memDb = (u8)memDb; pPager->readOnly = (u8)readOnly; - /* pPager->needSync = 0; */ assert( useJournal || pPager->tempFile ); pPager->noSync = pPager->tempFile; pPager->fullSync = pPager->noSync ?0:1; - pPager->sync_flags = SQLITE_SYNC_NORMAL; + pPager->syncFlags = pPager->noSync ? 0 : SQLITE_SYNC_NORMAL; + pPager->ckptSyncFlags = pPager->syncFlags; /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ @@ -35544,7 +42091,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( /* ** This function is called after transitioning from PAGER_UNLOCK to ** PAGER_SHARED state. It tests if there is a hot journal present in -** the file-system for the given pager. A hot journal is one that +** the file-system for the given pager. A hot journal is one that ** needs to be played back. According to this function, a hot-journal ** file exists if the following criteria are met: ** @@ -35563,10 +42110,10 @@ SQLITE_PRIVATE int sqlite3PagerOpen( ** at the end of the file. If there is, and that master journal file ** does not exist, then the journal file is not really hot. In this ** case this routine will return a false-positive. The pager_playback() -** routine will discover that the journal file is not really hot and -** will not roll it back. +** routine will discover that the journal file is not really hot and +** will not roll it back. ** -** If a hot-journal file is found to exist, *pExists is set to 1 and +** If a hot-journal file is found to exist, *pExists is set to 1 and ** SQLITE_OK returned. If no hot-journal file is present, *pExists is ** set to 0 and SQLITE_OK returned. If an IO error occurs while trying ** to determine whether or not a hot-journal file exists, the IO error @@ -35574,22 +42121,27 @@ SQLITE_PRIVATE int sqlite3PagerOpen( */ static int hasHotJournal(Pager *pPager, int *pExists){ sqlite3_vfs * const pVfs = pPager->pVfs; - int rc; /* Return code */ - int exists; /* True if a journal file is present */ + int rc = SQLITE_OK; /* Return code */ + int exists = 1; /* True if a journal file is present */ + int jrnlOpen = !!isOpen(pPager->jfd); - assert( pPager!=0 ); assert( pPager->useJournal ); assert( isOpen(pPager->fd) ); - assert( !isOpen(pPager->jfd) ); - assert( pPager->state <= PAGER_SHARED ); + assert( pPager->eState==PAGER_OPEN ); + + assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) & + SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN + )); *pExists = 0; - rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists); + if( !jrnlOpen ){ + rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists); + } if( rc==SQLITE_OK && exists ){ - int locked; /* True if some process holds a RESERVED lock */ + int locked = 0; /* True if some process holds a RESERVED lock */ /* Race condition here: Another process might have been holding the - ** the RESERVED lock and have a journal open at the sqlite3OsAccess() + ** the RESERVED lock and have a journal open at the sqlite3OsAccess() ** call above, but then delete the journal and drop the lock before ** we get to the following sqlite3OsCheckReservedLock() call. If that ** is the case, this routine might think there is a hot journal when @@ -35598,39 +42150,43 @@ static int hasHotJournal(Pager *pPager, int *pExists){ */ rc = sqlite3OsCheckReservedLock(pPager->fd, &locked); if( rc==SQLITE_OK && !locked ){ - int nPage; + Pgno nPage; /* Number of pages in database file */ /* Check the size of the database file. If it consists of 0 pages, - ** then delete the journal file. See the header comment above for + ** then delete the journal file. See the header comment above for ** the reasoning here. Delete the obsolete journal file under ** a RESERVED lock to avoid race conditions and to avoid violating ** [H33020]. */ - rc = sqlite3PagerPagecount(pPager, &nPage); + rc = pagerPagecount(pPager, &nPage); if( rc==SQLITE_OK ){ if( nPage==0 ){ sqlite3BeginBenignMalloc(); - if( sqlite3OsLock(pPager->fd, RESERVED_LOCK)==SQLITE_OK ){ + if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){ sqlite3OsDelete(pVfs, pPager->zJournal, 0); - sqlite3OsUnlock(pPager->fd, SHARED_LOCK); + if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK); } sqlite3EndBenignMalloc(); }else{ /* The journal file exists and no other connection has a reserved ** or greater lock on the database file. Now check that there is ** at least one non-zero bytes at the start of the journal file. - ** If there is, then we consider this journal to be hot. If not, + ** If there is, then we consider this journal to be hot. If not, ** it can be ignored. */ - int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL; - rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f); + if( !jrnlOpen ){ + int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL; + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f); + } if( rc==SQLITE_OK ){ u8 first = 0; rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } - sqlite3OsClose(pPager->jfd); + if( !jrnlOpen ){ + sqlite3OsClose(pPager->jfd); + } *pExists = (first!=0); }else if( rc==SQLITE_CANTOPEN ){ /* If we cannot open the rollback journal file in order to see if @@ -35654,67 +42210,6 @@ static int hasHotJournal(Pager *pPager, int *pExists){ } /* -** Read the content for page pPg out of the database file and into -** pPg->pData. A shared lock or greater must be held on the database -** file before this function is called. -** -** If page 1 is read, then the value of Pager.dbFileVers[] is set to -** the value read from the database file. -** -** If an IO error occurs, then the IO error is returned to the caller. -** Otherwise, SQLITE_OK is returned. -*/ -static int readDbPage(PgHdr *pPg){ - Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ - Pgno pgno = pPg->pgno; /* Page number to read */ - int rc; /* Return code */ - i64 iOffset; /* Byte offset of file to read from */ - - assert( pPager->state>=PAGER_SHARED && !MEMDB ); - assert( isOpen(pPager->fd) ); - - if( NEVER(!isOpen(pPager->fd)) ){ - assert( pPager->tempFile ); - memset(pPg->pData, 0, pPager->pageSize); - return SQLITE_OK; - } - iOffset = (pgno-1)*(i64)pPager->pageSize; - rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset); - if( rc==SQLITE_IOERR_SHORT_READ ){ - rc = SQLITE_OK; - } - if( pgno==1 ){ - if( rc ){ - /* If the read is unsuccessful, set the dbFileVers[] to something - ** that will never be a valid file version. dbFileVers[] is a copy - ** of bytes 24..39 of the database. Bytes 28..31 should always be - ** zero. Bytes 32..35 and 35..39 should be page numbers which are - ** never 0xffffffff. So filling pPager->dbFileVers[] with all 0xff - ** bytes should suffice. - ** - ** For an encrypted database, the situation is more complex: bytes - ** 24..39 of the database are white noise. But the probability of - ** white noising equaling 16 bytes of 0xff is vanishingly small so - ** we should still be ok. - */ - memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers)); - }else{ - u8 *dbFileVers = &((u8*)pPg->pData)[24]; - memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); - } - } - CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM); - - PAGER_INCR(sqlite3_pager_readdb_count); - PAGER_INCR(pPager->nRead); - IOTRACE(("PGIN %p %d\n", pPager, pgno)); - PAGERTRACE(("FETCH %d page %d hash(%08x)\n", - PAGERID(pPager), pgno, pager_pagehash(pPg))); - - return rc; -} - -/* ** This function is called to obtain a shared lock on the database file. ** It is illegal to call sqlite3PagerAcquire() until after this function ** has been successfully called. If a shared-lock is already held when @@ -35722,11 +42217,11 @@ static int readDbPage(PgHdr *pPg){ ** ** The following operations are also performed by this function. ** -** 1) If the pager is currently in PAGER_UNLOCK state (no lock held +** 1) If the pager is currently in PAGER_OPEN state (no lock held ** on the database file), then an attempt is made to obtain a ** SHARED lock on the database file. Immediately after obtaining ** the SHARED lock, the file-system is checked for a hot-journal, -** which is played back if present. Following any hot-journal +** which is played back if present. Following any hot-journal ** rollback, the contents of the cache are validated by checking ** the 'change-counter' field of the database file header and ** discarded if they are found to be invalid. @@ -35737,143 +42232,147 @@ static int readDbPage(PgHdr *pPg){ ** the contents of the page cache and rolling back any open journal ** file. ** -** If the operation described by (2) above is not attempted, and if the -** pager is in an error state other than SQLITE_FULL when this is called, -** the error state error code is returned. It is permitted to read the -** database when in SQLITE_FULL error state. -** -** Otherwise, if everything is successful, SQLITE_OK is returned. If an -** IO error occurs while locking the database, checking for a hot-journal -** file or rolling back a journal file, the IO error code is returned. +** If everything is successful, SQLITE_OK is returned. If an IO error +** occurs while locking the database, checking for a hot-journal file or +** rolling back a journal file, the IO error code is returned. */ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){ int rc = SQLITE_OK; /* Return code */ - int isErrorReset = 0; /* True if recovering from error state */ /* This routine is only called from b-tree and only when there are no - ** outstanding pages */ + ** outstanding pages. This implies that the pager state should either + ** be OPEN or READER. READER is only possible if the pager is or was in + ** exclusive access mode. + */ assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); + assert( assert_pager_state(pPager) ); + assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; } - /* If this database is in an error-state, now is a chance to clear - ** the error. Discard the contents of the pager-cache and rollback - ** any hot journal in the file-system. - */ - if( pPager->errCode ){ - if( isOpen(pPager->jfd) || pPager->zJournal ){ - isErrorReset = 1; - } - pPager->errCode = SQLITE_OK; - pager_reset(pPager); - } + if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){ + int bHotJournal = 1; /* True if there exists a hot journal-file */ - if( pPager->state==PAGER_UNLOCK || isErrorReset ){ - sqlite3_vfs * const pVfs = pPager->pVfs; - int isHotJournal = 0; assert( !MEMDB ); - assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); - if( pPager->noReadlock ){ - assert( pPager->readOnly ); - pPager->state = PAGER_SHARED; - }else{ + assert( pPager->noReadlock==0 || pPager->readOnly ); + + if( pPager->noReadlock==0 ){ rc = pager_wait_on_lock(pPager, SHARED_LOCK); if( rc!=SQLITE_OK ){ - assert( pPager->state==PAGER_UNLOCK ); - return pager_error(pPager, rc); + assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK ); + goto failed; } } - assert( pPager->state>=SHARED_LOCK ); /* If a journal file exists, and there is no RESERVED lock on the ** database file, then it either needs to be played back or deleted. */ - if( !isErrorReset ){ - assert( pPager->state <= PAGER_SHARED ); - rc = hasHotJournal(pPager, &isHotJournal); - if( rc!=SQLITE_OK ){ - goto failed; - } + if( pPager->eLock<=SHARED_LOCK ){ + rc = hasHotJournal(pPager, &bHotJournal); + } + if( rc!=SQLITE_OK ){ + goto failed; } - if( isErrorReset || isHotJournal ){ + if( bHotJournal ){ /* Get an EXCLUSIVE lock on the database file. At this point it is ** important that a RESERVED lock is not obtained on the way to the ** EXCLUSIVE lock. If it were, another process might open the ** database file, detect the RESERVED lock, and conclude that the - ** database is safe to read while this process is still rolling the + ** database is safe to read while this process is still rolling the ** hot-journal back. - ** + ** ** Because the intermediate RESERVED lock is not requested, any - ** other process attempting to access the database file will get to - ** this point in the code and fail to obtain its own EXCLUSIVE lock + ** other process attempting to access the database file will get to + ** this point in the code and fail to obtain its own EXCLUSIVE lock ** on the database file. + ** + ** Unless the pager is in locking_mode=exclusive mode, the lock is + ** downgraded to SHARED_LOCK before this function returns. */ - if( pPager->state<EXCLUSIVE_LOCK ){ - rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK); - if( rc!=SQLITE_OK ){ - rc = pager_error(pPager, rc); - goto failed; - } - pPager->state = PAGER_EXCLUSIVE; + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + goto failed; } - - /* Open the journal for read/write access. This is because in - ** exclusive-access mode the file descriptor will be kept open and - ** possibly used for a transaction later on. On some systems, the - ** OsTruncate() call used in exclusive-access mode also requires - ** a read/write file handle. + + /* If it is not already open and the file exists on disk, open the + ** journal for read/write access. Write access is required because + ** in exclusive-access mode the file descriptor will be kept open + ** and possibly used for a transaction later on. Also, write-access + ** is usually required to finalize the journal in journal_mode=persist + ** mode (and also for journal_mode=truncate on some systems). + ** + ** If the journal does not exist, it usually means that some + ** other connection managed to get in and roll it back before + ** this connection obtained the exclusive lock above. Or, it + ** may mean that the pager was in the error-state when this + ** function was called and the journal file does not exist. */ if( !isOpen(pPager->jfd) ){ - int res; - rc = sqlite3OsAccess(pVfs,pPager->zJournal,SQLITE_ACCESS_EXISTS,&res); - if( rc==SQLITE_OK ){ - if( res ){ - int fout = 0; - int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; - assert( !pPager->tempFile ); - rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); - assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); - if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){ - rc = SQLITE_CANTOPEN_BKPT; - sqlite3OsClose(pPager->jfd); - } - }else{ - /* If the journal does not exist, it usually means that some - ** other connection managed to get in and roll it back before - ** this connection obtained the exclusive lock above. Or, it - ** may mean that the pager was in the error-state when this - ** function was called and the journal file does not exist. */ - rc = pager_end_transaction(pPager, 0); + sqlite3_vfs * const pVfs = pPager->pVfs; + int bExists; /* True if journal file exists */ + rc = sqlite3OsAccess( + pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists); + if( rc==SQLITE_OK && bExists ){ + int fout = 0; + int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; + assert( !pPager->tempFile ); + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); + assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); + if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){ + rc = SQLITE_CANTOPEN_BKPT; + sqlite3OsClose(pPager->jfd); } } } - if( rc!=SQLITE_OK ){ - goto failed; - } - - /* TODO: Why are these cleared here? Is it necessary? */ - pPager->journalStarted = 0; - pPager->journalOff = 0; - pPager->setMaster = 0; - pPager->journalHdr = 0; - + /* Playback and delete the journal. Drop the database write ** lock and reacquire the read lock. Purge the cache before ** playing back the hot-journal so that we don't end up with - ** an inconsistent cache. + ** an inconsistent cache. Sync the hot journal before playing + ** it back since the process that crashed and left the hot journal + ** probably did not sync it and we are required to always sync + ** the journal before playing it back. */ if( isOpen(pPager->jfd) ){ - rc = pager_playback(pPager, 1); - if( rc!=SQLITE_OK ){ - rc = pager_error(pPager, rc); - goto failed; + assert( rc==SQLITE_OK ); + rc = pagerSyncHotJournal(pPager); + if( rc==SQLITE_OK ){ + rc = pager_playback(pPager, 1); + pPager->eState = PAGER_OPEN; } + }else if( !pPager->exclusiveMode ){ + pagerUnlockDb(pPager, SHARED_LOCK); + } + + if( rc!=SQLITE_OK ){ + /* This branch is taken if an error occurs while trying to open + ** or roll back a hot-journal while holding an EXCLUSIVE lock. The + ** pager_unlock() routine will be called before returning to unlock + ** the file. If the unlock attempt fails, then Pager.eLock must be + ** set to UNKNOWN_LOCK (see the comment above the #define for + ** UNKNOWN_LOCK above for an explanation). + ** + ** In order to get pager_unlock() to do this, set Pager.eState to + ** PAGER_ERROR now. This is not actually counted as a transition + ** to ERROR state in the state diagram at the top of this file, + ** since we know that the same call to pager_unlock() will very + ** shortly transition the pager object to the OPEN state. Calling + ** assert_pager_state() would fail now, as it should not be possible + ** to be in ERROR state when there are zero outstanding page + ** references. + */ + pager_error(pPager, rc); + goto failed; } - assert( (pPager->state==PAGER_SHARED) - || (pPager->exclusiveMode && pPager->state>PAGER_SHARED) + + assert( pPager->eState==PAGER_OPEN ); + assert( (pPager->eLock==SHARED_LOCK) + || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK) ); } - if( pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0 ){ + if( !pPager->tempFile + && (pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0) + ){ /* The shared-lock has just been acquired on the database file ** and there are already pages in the cache (from a previous ** read or write transaction). Check to see if the database @@ -35885,21 +42384,18 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){ ** a 32-bit counter that is incremented with each change. The ** other bytes change randomly with each file change when ** a codec is in use. - ** - ** There is a vanishingly small chance that a change will not be + ** + ** There is a vanishingly small chance that a change will not be ** detected. The chance of an undetected change is so small that ** it can be neglected. */ + Pgno nPage = 0; char dbFileVers[sizeof(pPager->dbFileVers)]; - sqlite3PagerPagecount(pPager, 0); - if( pPager->errCode ){ - rc = pPager->errCode; - goto failed; - } + rc = pagerPagecount(pPager, &nPage); + if( rc ) goto failed; - assert( pPager->dbSizeValid ); - if( pPager->dbSize>0 ){ + if( nPage>0 ){ IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers))); rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24); if( rc!=SQLITE_OK ){ @@ -35913,13 +42409,32 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){ pager_reset(pPager); } } - assert( pPager->exclusiveMode || pPager->state==PAGER_SHARED ); + + /* If there is a WAL file in the file-system, open this database in WAL + ** mode. Otherwise, the following function call is a no-op. + */ + rc = pagerOpenWalIfPresent(pPager); +#ifndef SQLITE_OMIT_WAL + assert( pPager->pWal==0 || rc==SQLITE_OK ); +#endif + } + + if( pagerUseWal(pPager) ){ + assert( rc==SQLITE_OK ); + rc = pagerBeginReadTransaction(pPager); + } + + if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){ + rc = pagerPagecount(pPager, &pPager->dbSize); } failed: if( rc!=SQLITE_OK ){ - /* pager_unlock() is a no-op for exclusive mode and in-memory databases. */ + assert( !MEMDB ); pager_unlock(pPager); + assert( pPager->eState==PAGER_OPEN ); + }else{ + pPager->eState = PAGER_READER; } return rc; } @@ -35931,36 +42446,34 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){ ** Except, in locking_mode=EXCLUSIVE when there is nothing to in ** the rollback journal, the unlock is not performed and there is ** nothing to rollback, so this routine is a no-op. -*/ +*/ static void pagerUnlockIfUnused(Pager *pPager){ - if( (sqlite3PcacheRefCount(pPager->pPCache)==0) - && (!pPager->exclusiveMode || pPager->journalOff>0) - ){ + if( (sqlite3PcacheRefCount(pPager->pPCache)==0) ){ pagerUnlockAndRollback(pPager); } } /* ** Acquire a reference to page number pgno in pager pPager (a page -** reference has type DbPage*). If the requested reference is +** reference has type DbPage*). If the requested reference is ** successfully obtained, it is copied to *ppPage and SQLITE_OK returned. ** -** If the requested page is already in the cache, it is returned. +** If the requested page is already in the cache, it is returned. ** Otherwise, a new page object is allocated and populated with data ** read from the database file. In some cases, the pcache module may ** choose not to allocate a new page object and may reuse an existing ** object with no outstanding references. ** -** The extra data appended to a page is always initialized to zeros the -** first time a page is loaded into memory. If the page requested is +** The extra data appended to a page is always initialized to zeros the +** first time a page is loaded into memory. If the page requested is ** already in the cache when this function is called, then the extra ** data is left as it was when the page object was last used. ** -** If the database image is smaller than the requested page or if a -** non-zero value is passed as the noContent parameter and the -** requested page is not already stored in the cache, then no -** actual disk read occurs. In this case the memory image of the -** page is initialized to all zeros. +** If the database image is smaller than the requested page or if a +** non-zero value is passed as the noContent parameter and the +** requested page is not already stored in the cache, then no +** actual disk read occurs. In this case the memory image of the +** page is initialized to all zeros. ** ** If noContent is true, it means that we do not care about the contents ** of the page. This occurs in two seperate scenarios: @@ -35968,7 +42481,7 @@ static void pagerUnlockIfUnused(Pager *pPager){ ** a) When reading a free-list leaf page from the database, and ** ** b) When a savepoint is being rolled back and we need to load -** a new page into the cache to populate with the data read +** a new page into the cache to be filled with the data read ** from the savepoint journal. ** ** If noContent is true, then the data returned is zeroed instead of @@ -35999,16 +42512,16 @@ SQLITE_PRIVATE int sqlite3PagerAcquire( int rc; PgHdr *pPg; + assert( pPager->eState>=PAGER_READER ); assert( assert_pager_state(pPager) ); - assert( pPager->state>PAGER_UNLOCK ); if( pgno==0 ){ return SQLITE_CORRUPT_BKPT; } - /* If the pager is in the error state, return an error immediately. + /* If the pager is in the error state, return an error immediately. ** Otherwise, request the page from the PCache layer. */ - if( pPager->errCode!=SQLITE_OK && pPager->errCode!=SQLITE_FULL ){ + if( pPager->errCode!=SQLITE_OK ){ rc = pPager->errCode; }else{ rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage); @@ -36024,7 +42537,7 @@ SQLITE_PRIVATE int sqlite3PagerAcquire( assert( (*ppPage)->pgno==pgno ); assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 ); - if( (*ppPage)->pPager ){ + if( (*ppPage)->pPager && !noContent ){ /* In this case the pcache already contains an initialized copy of ** the page. Return without further ado. */ assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) ); @@ -36032,9 +42545,8 @@ SQLITE_PRIVATE int sqlite3PagerAcquire( return SQLITE_OK; }else{ - /* The pager cache has created a new page. Its content needs to + /* The pager cache has created a new page. Its content needs to ** be initialized. */ - int nMax; PAGER_INCR(pPager->nMiss); pPg = *ppPage; @@ -36047,21 +42559,16 @@ SQLITE_PRIVATE int sqlite3PagerAcquire( goto pager_acquire_err; } - rc = sqlite3PagerPagecount(pPager, &nMax); - if( rc!=SQLITE_OK ){ - goto pager_acquire_err; - } - - if( MEMDB || nMax<(int)pgno || noContent || !isOpen(pPager->fd) ){ + if( MEMDB || pPager->dbSize<pgno || noContent || !isOpen(pPager->fd) ){ if( pgno>pPager->mxPgno ){ - rc = SQLITE_FULL; - goto pager_acquire_err; + rc = SQLITE_FULL; + goto pager_acquire_err; } if( noContent ){ /* Failure to set the bits in the InJournal bit-vectors is benign. - ** It merely means that we might do some extra work to journal a - ** page that does not need to be journaled. Nevertheless, be sure - ** to test the case where a malloc error occurs while trying to set + ** It merely means that we might do some extra work to journal a + ** page that does not need to be journaled. Nevertheless, be sure + ** to test the case where a malloc error occurs while trying to set ** a bit in a bit vector. */ sqlite3BeginBenignMalloc(); @@ -36082,9 +42589,7 @@ SQLITE_PRIVATE int sqlite3PagerAcquire( goto pager_acquire_err; } } -#ifdef SQLITE_CHECK_PAGES - pPg->pageHash = pager_pagehash(pPg); -#endif + pager_set_pagehash(pPg); } return SQLITE_OK; @@ -36103,14 +42608,12 @@ pager_acquire_err: /* ** Acquire a page if it is already in the in-memory cache. Do ** not read the page from disk. Return a pointer to the page, -** or 0 if the page is not in cache. Also, return 0 if the -** pager is in PAGER_UNLOCK state when this function is called, -** or if the pager is in an error state other than SQLITE_FULL. +** or 0 if the page is not in cache. ** ** See also sqlite3PagerGet(). The difference between this routine ** and sqlite3PagerGet() is that _get() will go to the disk and read ** in the page if the page is not already in cache. This routine -** returns NULL if the page is not in cache or if a disk I/O error +** returns NULL if the page is not in cache or if a disk I/O error ** has ever happened. */ SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ @@ -36118,7 +42621,7 @@ SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ assert( pPager!=0 ); assert( pgno!=0 ); assert( pPager->pPCache!=0 ); - assert( pPager->state > PAGER_UNLOCK ); + assert( pPager->eState>=PAGER_READER && pPager->eState!=PAGER_ERROR ); sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg); return pPg; } @@ -36140,204 +42643,180 @@ SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){ } /* -** If the main journal file has already been opened, ensure that the -** sub-journal file is open too. If the main journal is not open, -** this function is a no-op. -** -** SQLITE_OK is returned if everything goes according to plan. -** An SQLITE_IOERR_XXX error code is returned if a call to -** sqlite3OsOpen() fails. -*/ -static int openSubJournal(Pager *pPager){ - int rc = SQLITE_OK; - if( isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ){ - if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){ - sqlite3MemJournalOpen(pPager->sjfd); - }else{ - rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL); - } - } - return rc; -} - -/* ** This function is called at the start of every write transaction. -** There must already be a RESERVED or EXCLUSIVE lock on the database +** There must already be a RESERVED or EXCLUSIVE lock on the database ** file when this routine is called. ** ** Open the journal file for pager pPager and write a journal header ** to the start of it. If there are active savepoints, open the sub-journal -** as well. This function is only used when the journal file is being -** opened to write a rollback log for a transaction. It is not used +** as well. This function is only used when the journal file is being +** opened to write a rollback log for a transaction. It is not used ** when opening a hot journal file to roll it back. ** ** If the journal file is already open (as it may be in exclusive mode), ** then this function just writes a journal header to the start of the -** already open file. +** already open file. ** ** Whether or not the journal file is opened by this function, the ** Pager.pInJournal bitvec structure is allocated. ** -** Return SQLITE_OK if everything is successful. Otherwise, return -** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or +** Return SQLITE_OK if everything is successful. Otherwise, return +** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or ** an IO error code if opening or writing the journal file fails. */ static int pager_open_journal(Pager *pPager){ int rc = SQLITE_OK; /* Return code */ sqlite3_vfs * const pVfs = pPager->pVfs; /* Local cache of vfs pointer */ - assert( pPager->state>=PAGER_RESERVED ); - assert( pPager->useJournal ); - assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF ); + assert( pPager->eState==PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); assert( pPager->pInJournal==0 ); - + /* If already in the error state, this function is a no-op. But on ** the other hand, this routine is never called if we are already in ** an error state. */ if( NEVER(pPager->errCode) ) return pPager->errCode; - /* TODO: Is it really possible to get here with dbSizeValid==0? If not, - ** the call to PagerPagecount() can be removed. - */ - testcase( pPager->dbSizeValid==0 ); - sqlite3PagerPagecount(pPager, 0); - - pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize); - if( pPager->pInJournal==0 ){ - return SQLITE_NOMEM; - } - - /* Open the journal file if it is not already open. */ - if( !isOpen(pPager->jfd) ){ - if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ - sqlite3MemJournalOpen(pPager->jfd); - }else{ - const int flags = /* VFS flags to open journal file */ - SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| - (pPager->tempFile ? - (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL): - (SQLITE_OPEN_MAIN_JOURNAL) + if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize); + if( pPager->pInJournal==0 ){ + return SQLITE_NOMEM; + } + + /* Open the journal file if it is not already open. */ + if( !isOpen(pPager->jfd) ){ + if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ + sqlite3MemJournalOpen(pPager->jfd); + }else{ + const int flags = /* VFS flags to open journal file */ + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| + (pPager->tempFile ? + (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL): + (SQLITE_OPEN_MAIN_JOURNAL) + ); + #ifdef SQLITE_ENABLE_ATOMIC_WRITE + rc = sqlite3JournalOpen( + pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager) ); -#ifdef SQLITE_ENABLE_ATOMIC_WRITE - rc = sqlite3JournalOpen( - pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager) - ); -#else - rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); -#endif + #else + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); + #endif + } + assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); + } + + + /* Write the first journal header to the journal file and open + ** the sub-journal if necessary. + */ + if( rc==SQLITE_OK ){ + /* TODO: Check if all of these are really required. */ + pPager->nRec = 0; + pPager->journalOff = 0; + pPager->setMaster = 0; + pPager->journalHdr = 0; + rc = writeJournalHdr(pPager); } - assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); - } - - - /* Write the first journal header to the journal file and open - ** the sub-journal if necessary. - */ - if( rc==SQLITE_OK ){ - /* TODO: Check if all of these are really required. */ - pPager->dbOrigSize = pPager->dbSize; - pPager->journalStarted = 0; - pPager->needSync = 0; - pPager->nRec = 0; - pPager->journalOff = 0; - pPager->setMaster = 0; - pPager->journalHdr = 0; - rc = writeJournalHdr(pPager); - } - if( rc==SQLITE_OK && pPager->nSavepoint ){ - rc = openSubJournal(pPager); } if( rc!=SQLITE_OK ){ sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; + }else{ + assert( pPager->eState==PAGER_WRITER_LOCKED ); + pPager->eState = PAGER_WRITER_CACHEMOD; } + return rc; } /* -** Begin a write-transaction on the specified pager object. If a +** Begin a write-transaction on the specified pager object. If a ** write-transaction has already been opened, this function is a no-op. ** ** If the exFlag argument is false, then acquire at least a RESERVED ** lock on the database file. If exFlag is true, then acquire at least -** an EXCLUSIVE lock. If such a lock is already held, no locking +** an EXCLUSIVE lock. If such a lock is already held, no locking ** functions need be called. ** -** If this is not a temporary or in-memory file and, the journal file is -** opened if it has not been already. For a temporary file, the opening -** of the journal file is deferred until there is an actual need to -** write to the journal. TODO: Why handle temporary files differently? -** -** If the journal file is opened (or if it is already open), then a -** journal-header is written to the start of it. -** ** If the subjInMemory argument is non-zero, then any sub-journal opened ** within this transaction will be opened as an in-memory file. This ** has no effect if the sub-journal is already opened (as it may be when ** running in exclusive mode) or if the transaction does not require a ** sub-journal. If the subjInMemory argument is zero, then any required -** sub-journal is implemented in-memory if pPager is an in-memory database, +** sub-journal is implemented in-memory if pPager is an in-memory database, ** or using a temporary file otherwise. */ SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){ int rc = SQLITE_OK; - assert( pPager->state!=PAGER_UNLOCK ); + + if( pPager->errCode ) return pPager->errCode; + assert( pPager->eState>=PAGER_READER && pPager->eState<PAGER_ERROR ); pPager->subjInMemory = (u8)subjInMemory; - if( pPager->state==PAGER_SHARED ){ + + if( ALWAYS(pPager->eState==PAGER_READER) ){ assert( pPager->pInJournal==0 ); - assert( !MEMDB && !pPager->tempFile ); - /* Obtain a RESERVED lock on the database file. If the exFlag parameter - ** is true, then immediately upgrade this to an EXCLUSIVE lock. The - ** busy-handler callback can be used when upgrading to the EXCLUSIVE - ** lock, but not when obtaining the RESERVED lock. - */ - rc = sqlite3OsLock(pPager->fd, RESERVED_LOCK); - if( rc==SQLITE_OK ){ - pPager->state = PAGER_RESERVED; - if( exFlag ){ + if( pagerUseWal(pPager) ){ + /* If the pager is configured to use locking_mode=exclusive, and an + ** exclusive lock on the database is not already held, obtain it now. + */ + if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){ + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + return rc; + } + sqlite3WalExclusiveMode(pPager->pWal, 1); + } + + /* Grab the write lock on the log file. If successful, upgrade to + ** PAGER_RESERVED state. Otherwise, return an error code to the caller. + ** The busy-handler is not invoked if another connection already + ** holds the write-lock. If possible, the upper layer will call it. + */ + rc = sqlite3WalBeginWriteTransaction(pPager->pWal); + }else{ + /* Obtain a RESERVED lock on the database file. If the exFlag parameter + ** is true, then immediately upgrade this to an EXCLUSIVE lock. The + ** busy-handler callback can be used when upgrading to the EXCLUSIVE + ** lock, but not when obtaining the RESERVED lock. + */ + rc = pagerLockDb(pPager, RESERVED_LOCK); + if( rc==SQLITE_OK && exFlag ){ rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); } } - /* If the required locks were successfully obtained, open the journal - ** file and write the first journal-header to it. - */ - if( rc==SQLITE_OK && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ - rc = pager_open_journal(pPager); - } - }else if( isOpen(pPager->jfd) && pPager->journalOff==0 ){ - /* This happens when the pager was in exclusive-access mode the last - ** time a (read or write) transaction was successfully concluded - ** by this connection. Instead of deleting the journal file it was - ** kept open and either was truncated to 0 bytes or its header was - ** overwritten with zeros. - */ - assert( pPager->nRec==0 ); - assert( pPager->dbOrigSize==0 ); - assert( pPager->pInJournal==0 ); - rc = pager_open_journal(pPager); + if( rc==SQLITE_OK ){ + /* Change to WRITER_LOCKED state. + ** + ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD + ** when it has an open transaction, but never to DBMOD or FINISHED. + ** This is because in those states the code to roll back savepoint + ** transactions may copy data from the sub-journal into the database + ** file as well as into the page cache. Which would be incorrect in + ** WAL mode. + */ + pPager->eState = PAGER_WRITER_LOCKED; + pPager->dbHintSize = pPager->dbSize; + pPager->dbFileSize = pPager->dbSize; + pPager->dbOrigSize = pPager->dbSize; + pPager->journalOff = 0; + } + + assert( rc==SQLITE_OK || pPager->eState==PAGER_READER ); + assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); } PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); - assert( !isOpen(pPager->jfd) || pPager->journalOff>0 || rc!=SQLITE_OK ); - if( rc!=SQLITE_OK ){ - assert( !pPager->dbModified ); - /* Ignore any IO error that occurs within pager_end_transaction(). The - ** purpose of this call is to reset the internal state of the pager - ** sub-system. It doesn't matter if the journal-file is not properly - ** finalized at this point (since it is not a valid journal file anyway). - */ - pager_end_transaction(pPager, 0); - } return rc; } /* -** Mark a single data page as writeable. The page is written into the +** Mark a single data page as writeable. The page is written into the ** main journal or sub-journal as required. If the page is written into -** one of the journals, the corresponding bit is set in the +** one of the journals, the corresponding bit is set in the ** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs ** of any open savepoints as appropriate. */ @@ -36346,102 +42825,94 @@ static int pager_write(PgHdr *pPg){ Pager *pPager = pPg->pPager; int rc = SQLITE_OK; - /* This routine is not called unless a transaction has already been - ** started. + /* This routine is not called unless a write-transaction has already + ** been started. The journal file may or may not be open at this point. + ** It is never called in the ERROR state. */ - assert( pPager->state>=PAGER_RESERVED ); + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); - /* If an error has been previously detected, we should not be - ** calling this routine. Repeat the error for robustness. - */ + /* If an error has been previously detected, report the same error + ** again. This should not happen, but the check provides robustness. */ if( NEVER(pPager->errCode) ) return pPager->errCode; /* Higher-level routines never call this function if database is not ** writable. But check anyway, just for robustness. */ if( NEVER(pPager->readOnly) ) return SQLITE_PERM; - assert( !pPager->setMaster ); - CHECK_PAGE(pPg); + /* The journal file needs to be opened. Higher level routines have already + ** obtained the necessary locks to begin the write-transaction, but the + ** rollback journal might not yet be open. Open it now if this is the case. + ** + ** This is done before calling sqlite3PcacheMakeDirty() on the page. + ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then + ** an error might occur and the pager would end up in WRITER_LOCKED state + ** with pages marked as dirty in the cache. + */ + if( pPager->eState==PAGER_WRITER_LOCKED ){ + rc = pager_open_journal(pPager); + if( rc!=SQLITE_OK ) return rc; + } + assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); + assert( assert_pager_state(pPager) ); + /* Mark the page as dirty. If the page has already been written ** to the journal then we can return right away. */ sqlite3PcacheMakeDirty(pPg); if( pageInJournal(pPg) && !subjRequiresPage(pPg) ){ - pPager->dbModified = 1; + assert( !pagerUseWal(pPager) ); }else{ - - /* If we get this far, it means that the page needs to be - ** written to the transaction journal or the ckeckpoint journal - ** or both. - ** - ** Higher level routines should have already started a transaction, - ** which means they have acquired the necessary locks and opened - ** a rollback journal. Double-check to makes sure this is the case. - */ - rc = sqlite3PagerBegin(pPager, 0, pPager->subjInMemory); - if( NEVER(rc!=SQLITE_OK) ){ - return rc; - } - if( !isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ - assert( pPager->useJournal ); - rc = pager_open_journal(pPager); - if( rc!=SQLITE_OK ) return rc; - } - pPager->dbModified = 1; - + /* The transaction journal now exists and we have a RESERVED or an ** EXCLUSIVE lock on the main database file. Write the current page to ** the transaction journal if it is not there already. */ - if( !pageInJournal(pPg) && isOpen(pPager->jfd) ){ - if( pPg->pgno<=pPager->dbOrigSize ){ + if( !pageInJournal(pPg) && !pagerUseWal(pPager) ){ + assert( pagerUseWal(pPager)==0 ); + if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){ u32 cksum; char *pData2; + i64 iOff = pPager->journalOff; /* We should never write to the journal file the page that ** contains the database locks. The following assert verifies ** that we do not. */ assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) ); + + assert( pPager->journalHdr<=pPager->journalOff ); CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); cksum = pager_cksum(pPager, (u8*)pData2); - rc = write32bits(pPager->jfd, pPager->journalOff, pPg->pgno); - if( rc==SQLITE_OK ){ - rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, - pPager->journalOff + 4); - pPager->journalOff += pPager->pageSize+4; - } - if( rc==SQLITE_OK ){ - rc = write32bits(pPager->jfd, pPager->journalOff, cksum); - pPager->journalOff += 4; - } - IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, - pPager->journalOff, pPager->pageSize)); - PAGER_INCR(sqlite3_pager_writej_count); - PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n", - PAGERID(pPager), pPg->pgno, - ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg))); - /* Even if an IO or diskfull error occurred while journalling the + /* Even if an IO or diskfull error occurs while journalling the ** page in the block above, set the need-sync flag for the page. ** Otherwise, when the transaction is rolled back, the logic in ** playback_one_page() will think that the page needs to be restored ** in the database file. And if an IO error occurs while doing so, ** then corruption may follow. */ - if( !pPager->noSync ){ - pPg->flags |= PGHDR_NEED_SYNC; - pPager->needSync = 1; - } + pPg->flags |= PGHDR_NEED_SYNC; - /* An error has occurred writing to the journal file. The - ** transaction will be rolled back by the layer above. - */ - if( rc!=SQLITE_OK ){ - return rc; - } + rc = write32bits(pPager->jfd, iOff, pPg->pgno); + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4); + if( rc!=SQLITE_OK ) return rc; + rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum); + if( rc!=SQLITE_OK ) return rc; + IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, + pPager->journalOff, pPager->pageSize)); + PAGER_INCR(sqlite3_pager_writej_count); + PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n", + PAGERID(pPager), pPg->pgno, + ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg))); + + pPager->journalOff += 8 + pPager->pageSize; pPager->nRec++; assert( pPager->pInJournal!=0 ); rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno); @@ -36453,16 +42924,15 @@ static int pager_write(PgHdr *pPg){ return rc; } }else{ - if( !pPager->journalStarted && !pPager->noSync ){ + if( pPager->eState!=PAGER_WRITER_DBMOD ){ pPg->flags |= PGHDR_NEED_SYNC; - pPager->needSync = 1; } PAGERTRACE(("APPEND %d page %d needSync=%d\n", PAGERID(pPager), pPg->pgno, ((pPg->flags&PGHDR_NEED_SYNC)?1:0))); } } - + /* If the statement journal is open and the page is not in it, ** then write the current page to the statement journal. Note that ** the statement journal format differs from the standard journal format @@ -36475,7 +42945,6 @@ static int pager_write(PgHdr *pPg){ /* Update the database size and return. */ - assert( pPager->state>=PAGER_SHARED ); if( pPager->dbSize<pPg->pgno ){ pPager->dbSize = pPg->pgno; } @@ -36483,9 +42952,9 @@ static int pager_write(PgHdr *pPg){ } /* -** Mark a data page as writeable. This routine must be called before -** making changes to a page. The caller must check the return value -** of this function and be careful not to change any page data unless +** Mark a data page as writeable. This routine must be called before +** making changes to a page. The caller must check the return value +** of this function and be careful not to change any page data unless ** this routine returns SQLITE_OK. ** ** The difference between this function and pager_write() is that this @@ -36503,19 +42972,24 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){ Pager *pPager = pPg->pPager; Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + assert( pPager->eState!=PAGER_ERROR ); + assert( assert_pager_state(pPager) ); + if( nPagePerSector>1 ){ Pgno nPageCount; /* Total number of pages in database file */ Pgno pg1; /* First page of the sector pPg is located on. */ - int nPage; /* Number of pages starting at pg1 to journal */ + int nPage = 0; /* Number of pages starting at pg1 to journal */ int ii; /* Loop counter */ int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ - /* Set the doNotSync flag to 1. This is because we cannot allow a journal - ** header to be written between the pages journaled by this function. + /* Set the doNotSyncSpill flag to 1. This is because we cannot allow + ** a journal header to be written between the pages journaled by + ** this function. */ assert( !MEMDB ); - assert( pPager->doNotSync==0 ); - pPager->doNotSync = 1; + assert( pPager->doNotSyncSpill==0 ); + pPager->doNotSyncSpill++; /* This trick assumes that both the page-size and sector-size are ** an integer power of 2. It sets variable pg1 to the identifier @@ -36523,7 +42997,7 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){ */ pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1; - sqlite3PagerPagecount(pPager, (int *)&nPageCount); + nPageCount = pPager->dbSize; if( pPg->pgno>nPageCount ){ nPage = (pPg->pgno - pg1)+1; }else if( (pg1+nPagePerSector-1)>nPageCount ){ @@ -36545,7 +43019,6 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){ rc = pager_write(pPage); if( pPage->flags&PGHDR_NEED_SYNC ){ needSync = 1; - assert(pPager->needSync); } sqlite3PagerUnref(pPage); } @@ -36558,14 +43031,14 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){ } } - /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages + /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages ** starting at pg1, then it needs to be set for all of them. Because ** writing to any of these nPage pages may damage the others, the ** journal file must contain sync()ed copies of all of them ** before any of them can be written out to the database file. */ if( rc==SQLITE_OK && needSync ){ - assert( !MEMDB && pPager->noSync==0 ); + assert( !MEMDB ); for(ii=0; ii<nPage; ii++){ PgHdr *pPage = pager_lookup(pPager, pg1+ii); if( pPage ){ @@ -36573,11 +43046,10 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){ sqlite3PagerUnref(pPage); } } - assert(pPager->needSync); } - assert( pPager->doNotSync==1 ); - pPager->doNotSync = 0; + assert( pPager->doNotSyncSpill==1 ); + pPager->doNotSyncSpill--; }else{ rc = pager_write(pDbPage); } @@ -36606,7 +43078,7 @@ SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){ ** on the given page is unused. The pager marks the page as clean so ** that it does not get written to disk. ** -** Tests show that this optimization can quadruple the speed of large +** Tests show that this optimization can quadruple the speed of large ** DELETE operations. */ SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){ @@ -36615,18 +43087,22 @@ SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){ PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager))); IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno)) pPg->flags |= PGHDR_DONT_WRITE; -#ifdef SQLITE_CHECK_PAGES - pPg->pageHash = pager_pagehash(pPg); -#endif + pager_set_pagehash(pPg); } } /* -** This routine is called to increment the value of the database file -** change-counter, stored as a 4-byte big-endian integer starting at -** byte offset 24 of the pager file. +** This routine is called to increment the value of the database file +** change-counter, stored as a 4-byte big-endian integer starting at +** byte offset 24 of the pager file. The secondary change counter at +** 92 is also updated, as is the SQLite version number at offset 96. ** -** If the isDirectMode flag is zero, then this is done by calling +** But this only happens if the pPager->changeCountDone flag is false. +** To avoid excess churning of page 1, the update only happens once. +** See also the pager_write_changecounter() routine that does an +** unconditional update of the change counters. +** +** If the isDirectMode flag is zero, then this is done by calling ** sqlite3PagerWrite() on page 1, then modifying the contents of the ** page data. In this case the file will be updated when the current ** transaction is committed. @@ -36634,12 +43110,17 @@ SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){ ** The isDirectMode flag may only be non-zero if the library was compiled ** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case, ** if isDirect is non-zero, then the database file is updated directly -** by writing an updated version of page 1 using a call to the +** by writing an updated version of page 1 using a call to the ** sqlite3OsWrite() function. */ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ int rc = SQLITE_OK; + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + /* Declare and initialize constant integer 'isDirect'. If the ** atomic-write optimization is enabled in this build, then isDirect ** is initialized to the value passed as the isDirectMode parameter @@ -36658,10 +43139,8 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ # define DIRECT_MODE isDirectMode #endif - assert( pPager->state>=PAGER_RESERVED ); if( !pPager->changeCountDone && pPager->dbSize>0 ){ PgHdr *pPgHdr; /* Reference to page 1 */ - u32 change_counter; /* Initial value of change-counter field */ assert( !pPager->tempFile && isOpen(pPager->fd) ); @@ -36670,7 +43149,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ assert( pPgHdr==0 || rc==SQLITE_OK ); /* If page one was fetched successfully, and this function is not - ** operating in direct-mode, make page 1 writable. When not in + ** operating in direct-mode, make page 1 writable. When not in ** direct mode, page 1 is always held in cache and hence the PagerGet() ** above is always successful - hence the ALWAYS on rc==SQLITE_OK. */ @@ -36679,16 +43158,17 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ } if( rc==SQLITE_OK ){ - /* Increment the value just read and write it back to byte 24. */ - change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers); - change_counter++; - put32bits(((char*)pPgHdr->pData)+24, change_counter); + /* Actually do the update of the change counter */ + pager_write_changecounter(pPgHdr); /* If running in direct mode, write the contents of page 1 to the file. */ if( DIRECT_MODE ){ - const void *zBuf = pPgHdr->pData; + const void *zBuf; assert( pPager->dbFileSize>0 ); - rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); + CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf); + if( rc==SQLITE_OK ){ + rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); + } if( rc==SQLITE_OK ){ pPager->changeCountDone = 1; } @@ -36704,19 +43184,44 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ } /* -** Sync the pager file to disk. This is a no-op for in-memory files +** Sync the database file to disk. This is a no-op for in-memory databases ** or pages with the Pager.noSync flag set. ** -** If successful, or called on a pager for which it is a no-op, this +** If successful, or if called on a pager for which it is a no-op, this ** function returns SQLITE_OK. Otherwise, an IO error code is returned. */ SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager){ - int rc; /* Return code */ - assert( !MEMDB ); - if( pPager->noSync ){ - rc = SQLITE_OK; - }else{ - rc = sqlite3OsSync(pPager->fd, pPager->sync_flags); + int rc = SQLITE_OK; + if( !pPager->noSync ){ + assert( !MEMDB ); + rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); + }else if( isOpen(pPager->fd) ){ + assert( !MEMDB ); + sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, (void *)&rc); + } + return rc; +} + +/* +** This function may only be called while a write-transaction is active in +** rollback. If the connection is in WAL mode, this call is a no-op. +** Otherwise, if the connection does not already have an EXCLUSIVE lock on +** the database file, an attempt is made to obtain one. +** +** If the EXCLUSIVE lock is already held or the attempt to obtain it is +** successful, or the connection is in WAL mode, SQLITE_OK is returned. +** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is +** returned. +*/ +SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){ + int rc = SQLITE_OK; + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + || pPager->eState==PAGER_WRITER_LOCKED + ); + assert( assert_pager_state(pPager) ); + if( 0==pagerUseWal(pPager) ){ + rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); } return rc; } @@ -36731,12 +43236,12 @@ SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager){ ** ** * The database file change-counter is updated, ** * the journal is synced (unless the atomic-write optimization is used), -** * all dirty pages are written to the database file, +** * all dirty pages are written to the database file, ** * the database file is truncated (if required), and -** * the database file synced. +** * the database file synced. ** -** The only thing that remains to commit the transaction is to finalize -** (delete, truncate or zero the first part of) the journal file (or +** The only thing that remains to commit the transaction is to finalize +** (delete, truncate or zero the first part of) the journal file (or ** delete the master journal file if specified). ** ** Note that if zMaster==NULL, this does not overwrite a previous value @@ -36754,151 +43259,184 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( ){ int rc = SQLITE_OK; /* Return code */ - /* The dbOrigSize is never set if journal_mode=OFF */ - assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF || pPager->dbOrigSize==0 ); + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + || pPager->eState==PAGER_ERROR + ); + assert( assert_pager_state(pPager) ); - /* If a prior error occurred, this routine should not be called. ROLLBACK - ** is the appropriate response to an error, not COMMIT. Guard against - ** coding errors by repeating the prior error. */ + /* If a prior error occurred, report that error again. */ if( NEVER(pPager->errCode) ) return pPager->errCode; - PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", + PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", pPager->zFilename, zMaster, pPager->dbSize)); - if( MEMDB && pPager->dbModified ){ + /* If no database changes have been made, return early. */ + if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK; + + if( MEMDB ){ /* If this is an in-memory db, or no pages have been written to, or this ** function has already been called, it is mostly a no-op. However, any ** backup in progress needs to be restarted. */ sqlite3BackupRestart(pPager->pBackup); - }else if( pPager->state!=PAGER_SYNCED && pPager->dbModified ){ - - /* The following block updates the change-counter. Exactly how it - ** does this depends on whether or not the atomic-update optimization - ** was enabled at compile time, and if this transaction meets the - ** runtime criteria to use the operation: - ** - ** * The file-system supports the atomic-write property for - ** blocks of size page-size, and - ** * This commit is not part of a multi-file transaction, and - ** * Exactly one page has been modified and store in the journal file. - ** - ** If the optimization was not enabled at compile time, then the - ** pager_incr_changecounter() function is called to update the change - ** counter in 'indirect-mode'. If the optimization is compiled in but - ** is not applicable to this transaction, call sqlite3JournalCreate() - ** to make sure the journal file has actually been created, then call - ** pager_incr_changecounter() to update the change-counter in indirect - ** mode. - ** - ** Otherwise, if the optimization is both enabled and applicable, - ** then call pager_incr_changecounter() to update the change-counter - ** in 'direct' mode. In this case the journal file will never be - ** created for this transaction. - */ -#ifdef SQLITE_ENABLE_ATOMIC_WRITE - PgHdr *pPg; - assert( isOpen(pPager->jfd) || pPager->journalMode==PAGER_JOURNALMODE_OFF ); - if( !zMaster && isOpen(pPager->jfd) - && pPager->journalOff==jrnlBufferSize(pPager) - && pPager->dbSize>=pPager->dbFileSize - && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) - ){ - /* Update the db file change counter via the direct-write method. The - ** following call will modify the in-memory representation of page 1 - ** to include the updated change counter and then write page 1 - ** directly to the database file. Because of the atomic-write - ** property of the host file-system, this is safe. - */ - rc = pager_incr_changecounter(pPager, 1); - }else{ - rc = sqlite3JournalCreate(pPager->jfd); + }else{ + if( pagerUseWal(pPager) ){ + PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); + PgHdr *pPageOne = 0; + if( pList==0 ){ + /* Must have at least one page for the WAL commit flag. + ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ + rc = sqlite3PagerGet(pPager, 1, &pPageOne); + pList = pPageOne; + pList->pDirty = 0; + } + assert( rc==SQLITE_OK ); + if( ALWAYS(pList) ){ + rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1, + (pPager->fullSync ? pPager->syncFlags : 0) + ); + } + sqlite3PagerUnref(pPageOne); if( rc==SQLITE_OK ){ - rc = pager_incr_changecounter(pPager, 0); + sqlite3PcacheCleanAll(pPager->pPCache); } - } -#else - rc = pager_incr_changecounter(pPager, 0); -#endif - if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - - /* If this transaction has made the database smaller, then all pages - ** being discarded by the truncation must be written to the journal - ** file. This can only happen in auto-vacuum mode. - ** - ** Before reading the pages with page numbers larger than the - ** current value of Pager.dbSize, set dbSize back to the value - ** that it took at the start of the transaction. Otherwise, the - ** calls to sqlite3PagerGet() return zeroed pages instead of - ** reading data from the database file. - ** - ** When journal_mode==OFF the dbOrigSize is always zero, so this - ** block never runs if journal_mode=OFF. - */ -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pPager->dbSize<pPager->dbOrigSize - && ALWAYS(pPager->journalMode!=PAGER_JOURNALMODE_OFF) - ){ - Pgno i; /* Iterator variable */ - const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */ - const Pgno dbSize = pPager->dbSize; /* Database image size */ - pPager->dbSize = pPager->dbOrigSize; - for( i=dbSize+1; i<=pPager->dbOrigSize; i++ ){ - if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){ - PgHdr *pPage; /* Page to journal */ - rc = sqlite3PagerGet(pPager, i, &pPage); - if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - rc = sqlite3PagerWrite(pPage); - sqlite3PagerUnref(pPage); - if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + }else{ + /* The following block updates the change-counter. Exactly how it + ** does this depends on whether or not the atomic-update optimization + ** was enabled at compile time, and if this transaction meets the + ** runtime criteria to use the operation: + ** + ** * The file-system supports the atomic-write property for + ** blocks of size page-size, and + ** * This commit is not part of a multi-file transaction, and + ** * Exactly one page has been modified and store in the journal file. + ** + ** If the optimization was not enabled at compile time, then the + ** pager_incr_changecounter() function is called to update the change + ** counter in 'indirect-mode'. If the optimization is compiled in but + ** is not applicable to this transaction, call sqlite3JournalCreate() + ** to make sure the journal file has actually been created, then call + ** pager_incr_changecounter() to update the change-counter in indirect + ** mode. + ** + ** Otherwise, if the optimization is both enabled and applicable, + ** then call pager_incr_changecounter() to update the change-counter + ** in 'direct' mode. In this case the journal file will never be + ** created for this transaction. + */ + #ifdef SQLITE_ENABLE_ATOMIC_WRITE + PgHdr *pPg; + assert( isOpen(pPager->jfd) + || pPager->journalMode==PAGER_JOURNALMODE_OFF + || pPager->journalMode==PAGER_JOURNALMODE_WAL + ); + if( !zMaster && isOpen(pPager->jfd) + && pPager->journalOff==jrnlBufferSize(pPager) + && pPager->dbSize>=pPager->dbOrigSize + && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) + ){ + /* Update the db file change counter via the direct-write method. The + ** following call will modify the in-memory representation of page 1 + ** to include the updated change counter and then write page 1 + ** directly to the database file. Because of the atomic-write + ** property of the host file-system, this is safe. + */ + rc = pager_incr_changecounter(pPager, 1); + }else{ + rc = sqlite3JournalCreate(pPager->jfd); + if( rc==SQLITE_OK ){ + rc = pager_incr_changecounter(pPager, 0); } } - pPager->dbSize = dbSize; - } -#endif - - /* Write the master journal name into the journal file. If a master - ** journal file name has already been written to the journal file, - ** or if zMaster is NULL (no master journal), then this call is a no-op. - */ - rc = writeMasterJournal(pPager, zMaster); - if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - - /* Sync the journal file. If the atomic-update optimization is being - ** used, this call will not create the journal file or perform any - ** real IO. - */ - rc = syncJournal(pPager); - if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - - /* Write all dirty pages to the database file. */ - rc = pager_write_pagelist(sqlite3PcacheDirtyList(pPager->pPCache)); - if( rc!=SQLITE_OK ){ - assert( rc!=SQLITE_IOERR_BLOCKED ); - goto commit_phase_one_exit; - } - sqlite3PcacheCleanAll(pPager->pPCache); - - /* If the file on disk is not the same size as the database image, - ** then use pager_truncate to grow or shrink the file here. - */ - if( pPager->dbSize!=pPager->dbFileSize ){ - Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager)); - assert( pPager->state>=PAGER_EXCLUSIVE ); - rc = pager_truncate(pPager, nNew); + #else + rc = pager_incr_changecounter(pPager, 0); + #endif if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + /* If this transaction has made the database smaller, then all pages + ** being discarded by the truncation must be written to the journal + ** file. This can only happen in auto-vacuum mode. + ** + ** Before reading the pages with page numbers larger than the + ** current value of Pager.dbSize, set dbSize back to the value + ** that it took at the start of the transaction. Otherwise, the + ** calls to sqlite3PagerGet() return zeroed pages instead of + ** reading data from the database file. + */ + #ifndef SQLITE_OMIT_AUTOVACUUM + if( pPager->dbSize<pPager->dbOrigSize + && pPager->journalMode!=PAGER_JOURNALMODE_OFF + ){ + Pgno i; /* Iterator variable */ + const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */ + const Pgno dbSize = pPager->dbSize; /* Database image size */ + pPager->dbSize = pPager->dbOrigSize; + for( i=dbSize+1; i<=pPager->dbOrigSize; i++ ){ + if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){ + PgHdr *pPage; /* Page to journal */ + rc = sqlite3PagerGet(pPager, i, &pPage); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + rc = sqlite3PagerWrite(pPage); + sqlite3PagerUnref(pPage); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + } + } + pPager->dbSize = dbSize; + } + #endif + + /* Write the master journal name into the journal file. If a master + ** journal file name has already been written to the journal file, + ** or if zMaster is NULL (no master journal), then this call is a no-op. + */ + rc = writeMasterJournal(pPager, zMaster); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + /* Sync the journal file and write all dirty pages to the database. + ** If the atomic-update optimization is being used, this sync will not + ** create the journal file or perform any real IO. + ** + ** Because the change-counter page was just modified, unless the + ** atomic-update optimization is used it is almost certain that the + ** journal requires a sync here. However, in locking_mode=exclusive + ** on a system under memory pressure it is just possible that this is + ** not the case. In this case it is likely enough that the redundant + ** xSync() call will be changed to a no-op by the OS anyhow. + */ + rc = syncJournal(pPager, 0); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache)); + if( rc!=SQLITE_OK ){ + assert( rc!=SQLITE_IOERR_BLOCKED ); + goto commit_phase_one_exit; + } + sqlite3PcacheCleanAll(pPager->pPCache); + + /* If the file on disk is not the same size as the database image, + ** then use pager_truncate to grow or shrink the file here. + */ + if( pPager->dbSize!=pPager->dbFileSize ){ + Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager)); + assert( pPager->eState==PAGER_WRITER_DBMOD ); + rc = pager_truncate(pPager, nNew); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + } + + /* Finally, sync the database file. */ + if( !noSync ){ + rc = sqlite3PagerSync(pPager); + } + IOTRACE(("DBSYNC %p\n", pPager)) } - - /* Finally, sync the database file. */ - if( !pPager->noSync && !noSync ){ - rc = sqlite3OsSync(pPager->fd, pPager->sync_flags); - } - IOTRACE(("DBSYNC %p\n", pPager)) - - pPager->state = PAGER_SYNCED; } commit_phase_one_exit: + if( rc==SQLITE_OK && !pagerUseWal(pPager) ){ + pPager->eState = PAGER_WRITER_FINISHED; + } return rc; } @@ -36906,12 +43444,12 @@ commit_phase_one_exit: /* ** When this function is called, the database file has been completely ** updated to reflect the changes made by the current transaction and -** synced to disk. The journal file still exists in the file-system +** synced to disk. The journal file still exists in the file-system ** though, and if a failure occurs at this point it will eventually ** be used as a hot-journal and the current transaction rolled back. ** -** This function finalizes the journal file, either by deleting, -** truncating or partially zeroing it, so that it cannot be used +** This function finalizes the journal file, either by deleting, +** truncating or partially zeroing it, so that it cannot be used ** for hot-journal rollback. Once this is done the transaction is ** irrevocably committed. ** @@ -36926,112 +43464,103 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){ ** called, just return the same error code without doing anything. */ if( NEVER(pPager->errCode) ) return pPager->errCode; - /* This function should not be called if the pager is not in at least - ** PAGER_RESERVED state. And indeed SQLite never does this. But it is - ** nice to have this defensive test here anyway. - */ - if( NEVER(pPager->state<PAGER_RESERVED) ) return SQLITE_ERROR; + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_FINISHED + || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD) + ); + assert( assert_pager_state(pPager) ); /* An optimization. If the database was not actually modified during ** this transaction, the pager is running in exclusive-mode and is ** using persistent journals, then this function is a no-op. ** - ** The start of the journal file currently contains a single journal + ** The start of the journal file currently contains a single journal ** header with the nRec field set to 0. If such a journal is used as ** a hot-journal during hot-journal rollback, 0 changes will be made - ** to the database file. So there is no need to zero the journal + ** to the database file. So there is no need to zero the journal ** header. Since the pager is in exclusive mode, there is no need ** to drop any locks either. */ - if( pPager->dbModified==0 && pPager->exclusiveMode + if( pPager->eState==PAGER_WRITER_LOCKED + && pPager->exclusiveMode && pPager->journalMode==PAGER_JOURNALMODE_PERSIST ){ - assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ); + assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff ); + pPager->eState = PAGER_READER; return SQLITE_OK; } PAGERTRACE(("COMMIT %d\n", PAGERID(pPager))); - assert( pPager->state==PAGER_SYNCED || MEMDB || !pPager->dbModified ); rc = pager_end_transaction(pPager, pPager->setMaster); return pager_error(pPager, rc); } /* -** Rollback all changes. The database falls back to PAGER_SHARED mode. +** If a write transaction is open, then all changes made within the +** transaction are reverted and the current write-transaction is closed. +** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR +** state if an error occurs. +** +** If the pager is already in PAGER_ERROR state when this function is called, +** it returns Pager.errCode immediately. No work is performed in this case. ** -** This function performs two tasks: +** Otherwise, in rollback mode, this function performs two functions: ** -** 1) It rolls back the journal file, restoring all database file and +** 1) It rolls back the journal file, restoring all database file and ** in-memory cache pages to the state they were in when the transaction ** was opened, and +** ** 2) It finalizes the journal file, so that it is not used for hot ** rollback at any point in the future. ** -** subject to the following qualifications: -** -** * If the journal file is not yet open when this function is called, -** then only (2) is performed. In this case there is no journal file -** to roll back. -** -** * If in an error state other than SQLITE_FULL, then task (1) is -** performed. If successful, task (2). Regardless of the outcome -** of either, the error state error code is returned to the caller -** (i.e. either SQLITE_IOERR or SQLITE_CORRUPT). -** -** * If the pager is in PAGER_RESERVED state, then attempt (1). Whether -** or not (1) is succussful, also attempt (2). If successful, return -** SQLITE_OK. Otherwise, enter the error state and return the first -** error code encountered. -** -** In this case there is no chance that the database was written to. -** So is safe to finalize the journal file even if the playback -** (operation 1) failed. However the pager must enter the error state -** as the contents of the in-memory cache are now suspect. -** -** * Finally, if in PAGER_EXCLUSIVE state, then attempt (1). Only -** attempt (2) if (1) is successful. Return SQLITE_OK if successful, -** otherwise enter the error state and return the error code from the -** failing operation. +** Finalization of the journal file (task 2) is only performed if the +** rollback is successful. ** -** In this case the database file may have been written to. So if the -** playback operation did not succeed it would not be safe to finalize -** the journal file. It needs to be left in the file-system so that -** some other process can use it to restore the database state (by -** hot-journal rollback). +** In WAL mode, all cache-entries containing data modified within the +** current transaction are either expelled from the cache or reverted to +** their pre-transaction state by re-reading data from the database or +** WAL files. The WAL transaction is then closed. */ SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){ int rc = SQLITE_OK; /* Return code */ PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager))); - if( !pPager->dbModified || !isOpen(pPager->jfd) ){ - rc = pager_end_transaction(pPager, pPager->setMaster); - }else if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){ - if( pPager->state>=PAGER_EXCLUSIVE ){ - pager_playback(pPager, 0); + + /* PagerRollback() is a no-op if called in READER or OPEN state. If + ** the pager is already in the ERROR state, the rollback is not + ** attempted here. Instead, the error code is returned to the caller. + */ + assert( assert_pager_state(pPager) ); + if( pPager->eState==PAGER_ERROR ) return pPager->errCode; + if( pPager->eState<=PAGER_READER ) return SQLITE_OK; + + if( pagerUseWal(pPager) ){ + int rc2; + rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1); + rc2 = pager_end_transaction(pPager, pPager->setMaster); + if( rc==SQLITE_OK ) rc = rc2; + }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){ + int eState = pPager->eState; + rc = pager_end_transaction(pPager, 0); + if( !MEMDB && eState>PAGER_WRITER_LOCKED ){ + /* This can happen using journal_mode=off. Move the pager to the error + ** state to indicate that the contents of the cache may not be trusted. + ** Any active readers will get SQLITE_ABORT. + */ + pPager->errCode = SQLITE_ABORT; + pPager->eState = PAGER_ERROR; + return rc; } - rc = pPager->errCode; }else{ - if( pPager->state==PAGER_RESERVED ){ - int rc2; - rc = pager_playback(pPager, 0); - rc2 = pager_end_transaction(pPager, pPager->setMaster); - if( rc==SQLITE_OK ){ - rc = rc2; - } - }else{ - rc = pager_playback(pPager, 0); - } + rc = pager_playback(pPager, 0); + } - if( !MEMDB ){ - pPager->dbSizeValid = 0; - } + assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK ); + assert( rc==SQLITE_OK || rc==SQLITE_FULL || (rc&0xFF)==SQLITE_IOERR ); - /* If an error occurs during a ROLLBACK, we can no longer trust the pager - ** cache. So call pager_error() on the way out to make any error - ** persistent. - */ - rc = pager_error(pPager, rc); - } - return rc; + /* If an error occurs during a ROLLBACK, we can no longer trust the pager + ** cache. So call pager_error() on the way out to make any error persistent. + */ + return pager_error(pPager, rc); } /* @@ -37050,6 +43579,18 @@ SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){ } /* +** Return the approximate number of bytes of memory currently +** used by the pager and its associated cache. +*/ +SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager *pPager){ + int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr) + + 5*sizeof(void*); + return perPageSize*sqlite3PcachePagecount(pPager->pPCache) + + sqlite3MallocSize(pPager) + + pPager->pageSize; +} + +/* ** Return the number of references to the specified page. */ SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){ @@ -37065,8 +43606,8 @@ SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ a[0] = sqlite3PcacheRefCount(pPager->pPCache); a[1] = sqlite3PcachePagecount(pPager->pPCache); a[2] = sqlite3PcacheGetCachesize(pPager->pPCache); - a[3] = pPager->dbSizeValid ? (int) pPager->dbSize : -1; - a[4] = pPager->state; + a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; + a[4] = pPager->eState; a[5] = pPager->errCode; a[6] = pPager->nHit; a[7] = pPager->nMiss; @@ -37090,7 +43631,7 @@ SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ ** to make up the difference. If the number of savepoints is already ** equal to nSavepoint, then this function is a no-op. ** -** If a memory allocation fails, SQLITE_NOMEM is returned. If an error +** If a memory allocation fails, SQLITE_NOMEM is returned. If an error ** occurs while opening the sub-journal file, then an IO error code is ** returned. Otherwise, SQLITE_OK. */ @@ -37098,17 +43639,15 @@ SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ int rc = SQLITE_OK; /* Return code */ int nCurrent = pPager->nSavepoint; /* Current number of savepoints */ + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + if( nSavepoint>nCurrent && pPager->useJournal ){ int ii; /* Iterator variable */ PagerSavepoint *aNew; /* New Pager.aSavepoint array */ - /* Either there is no active journal or the sub-journal is open or - ** the journal is always stored in memory */ - assert( pPager->nSavepoint==0 || isOpen(pPager->sjfd) || - pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); - /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM - ** if the allocation fails. Otherwise, zero the new portion in case a + ** if the allocation fails. Otherwise, zero the new portion in case a ** malloc failure occurs while populating it in the for(...) loop below. */ aNew = (PagerSavepoint *)sqlite3Realloc( @@ -37119,13 +43658,11 @@ SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ } memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint)); pPager->aSavepoint = aNew; - pPager->nSavepoint = nSavepoint; /* Populate the PagerSavepoint structures just allocated. */ for(ii=nCurrent; ii<nSavepoint; ii++){ - assert( pPager->dbSizeValid ); aNew[ii].nOrig = pPager->dbSize; - if( isOpen(pPager->jfd) && ALWAYS(pPager->journalOff>0) ){ + if( isOpen(pPager->jfd) && pPager->journalOff>0 ){ aNew[ii].iOffset = pPager->journalOff; }else{ aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager); @@ -37135,10 +43672,12 @@ SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ if( !aNew[ii].pInSavepoint ){ return SQLITE_NOMEM; } + if( pagerUseWal(pPager) ){ + sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData); + } + pPager->nSavepoint = ii+1; } - - /* Open the sub-journal, if it is not already opened. */ - rc = openSubJournal(pPager); + assert( pPager->nSavepoint==nSavepoint ); assertTruncateConstraint(pPager); } @@ -37147,7 +43686,7 @@ SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ /* ** This function is called to rollback or release (commit) a savepoint. -** The savepoint to release or rollback need not be the most recently +** The savepoint to release or rollback need not be the most recently ** created savepoint. ** ** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE. @@ -37155,38 +43694,38 @@ SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ ** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes ** that have occurred since the specified savepoint was created. ** -** The savepoint to rollback or release is identified by parameter +** The savepoint to rollback or release is identified by parameter ** iSavepoint. A value of 0 means to operate on the outermost savepoint ** (the first created). A value of (Pager.nSavepoint-1) means operate ** on the most recently created savepoint. If iSavepoint is greater than ** (Pager.nSavepoint-1), then this function is a no-op. ** ** If a negative value is passed to this function, then the current -** transaction is rolled back. This is different to calling +** transaction is rolled back. This is different to calling ** sqlite3PagerRollback() because this function does not terminate -** the transaction or unlock the database, it just restores the -** contents of the database to its original state. +** the transaction or unlock the database, it just restores the +** contents of the database to its original state. ** -** In any case, all savepoints with an index greater than iSavepoint +** In any case, all savepoints with an index greater than iSavepoint ** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE), ** then savepoint iSavepoint is also destroyed. ** ** This function may return SQLITE_NOMEM if a memory allocation fails, -** or an IO error code if an IO error occurs while rolling back a +** or an IO error code if an IO error occurs while rolling back a ** savepoint. If no errors occur, SQLITE_OK is returned. -*/ +*/ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ - int rc = SQLITE_OK; + int rc = pPager->errCode; /* Return code */ assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK ); - if( iSavepoint<pPager->nSavepoint ){ + if( rc==SQLITE_OK && iSavepoint<pPager->nSavepoint ){ int ii; /* Iterator variable */ int nNew; /* Number of remaining savepoints after this op. */ /* Figure out how many savepoints will still be active after this - ** operation. Store this value in nNew. Then free resources associated + ** operation. Store this value in nNew. Then free resources associated ** with any savepoints that are destroyed by this operation. */ nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1); @@ -37195,7 +43734,7 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ } pPager->nSavepoint = nNew; - /* If this is a release of the outermost savepoint, truncate + /* If this is a release of the outermost savepoint, truncate ** the sub-journal to zero bytes in size. */ if( op==SAVEPOINT_RELEASE ){ if( nNew==0 && isOpen(pPager->sjfd) ){ @@ -37212,13 +43751,13 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ ** not yet been opened. In this case there have been no changes to ** the database file, so the playback operation can be skipped. */ - else if( isOpen(pPager->jfd) ){ + else if( pagerUseWal(pPager) || isOpen(pPager->jfd) ){ PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1]; rc = pagerPlaybackSavepoint(pPager, pSavepoint); assert(rc!=SQLITE_DONE); } - } + return rc; } @@ -37264,7 +43803,7 @@ SQLITE_PRIVATE int sqlite3PagerNosync(Pager *pPager){ /* ** Set or retrieve the codec for this pager */ -static void sqlite3PagerSetCodec( +SQLITE_PRIVATE void sqlite3PagerSetCodec( Pager *pPager, void *(*xCodec)(void*,void*,Pgno,int), void (*xCodecSizeChng)(void*,int,int), @@ -37278,7 +43817,7 @@ static void sqlite3PagerSetCodec( pPager->pCodec = pCodec; pagerReportSize(pPager); } -static void *sqlite3PagerGetCodec(Pager *pPager){ +SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){ return pPager->pCodec; } #endif @@ -37302,8 +43841,8 @@ static void *sqlite3PagerGetCodec(Pager *pPager){ ** transaction is active). ** ** If the fourth argument, isCommit, is non-zero, then this page is being -** moved as part of a database reorganization just before the transaction -** is being committed. In this case, it is guaranteed that the database page +** moved as part of a database reorganization just before the transaction +** is being committed. In this case, it is guaranteed that the database page ** pPg refers to will not be written to again within this transaction. ** ** This function may return SQLITE_NOMEM or an IO error code if an error @@ -37316,6 +43855,10 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i Pgno origPgno; /* The original page number */ assert( pPg->nRef>0 ); + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); /* In order to be able to rollback, an in-memory database must journal ** the page we are moving from. @@ -37326,7 +43869,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i } /* If the page being moved is dirty and has not been saved by the latest - ** savepoint, then save the current contents of the page into the + ** savepoint, then save the current contents of the page into the ** sub-journal now. This is required to handle the following scenario: ** ** BEGIN; @@ -37350,7 +43893,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i return rc; } - PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", + PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno)); IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno)) @@ -37358,19 +43901,18 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i ** be written to, store pPg->pgno in local variable needSyncPgno. ** ** If the isCommit flag is set, there is no need to remember that - ** the journal needs to be sync()ed before database page pPg->pgno + ** the journal needs to be sync()ed before database page pPg->pgno ** can be written to. The caller has already promised not to write to it. */ if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){ needSyncPgno = pPg->pgno; assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize ); assert( pPg->flags&PGHDR_DIRTY ); - assert( pPager->needSync ); } /* If the cache contains a page with page-number pgno, remove it - ** from its hash chain. Also, if the PgHdr.needSync was set for - ** page pgno before the 'move' operation, it needs to be retained + ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for + ** page pgno before the 'move' operation, it needs to be retained ** for the page moved there. */ pPg->flags &= ~PGHDR_NEED_SYNC; @@ -37381,7 +43923,6 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i if( MEMDB ){ /* Do not discard pages from an in-memory database since we might ** need to rollback later. Just move the page out of the way. */ - assert( pPager->dbSizeValid ); sqlite3PcacheMove(pPgOld, pPager->dbSize+1); }else{ sqlite3PcacheDrop(pPgOld); @@ -37391,14 +43932,23 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i origPgno = pPg->pgno; sqlite3PcacheMove(pPg, pgno); sqlite3PcacheMakeDirty(pPg); - pPager->dbModified = 1; + + /* For an in-memory database, make sure the original page continues + ** to exist, in case the transaction needs to roll back. Use pPgOld + ** as the original page since it has already been allocated. + */ + if( MEMDB ){ + assert( pPgOld ); + sqlite3PcacheMove(pPgOld, origPgno); + sqlite3PagerUnref(pPgOld); + } if( needSyncPgno ){ - /* If needSyncPgno is non-zero, then the journal file needs to be + /* If needSyncPgno is non-zero, then the journal file needs to be ** sync()ed before any data is written to database file page needSyncPgno. - ** Currently, no such page exists in the page-cache and the + ** Currently, no such page exists in the page-cache and the ** "is journaled" bitvec flag has been set. This needs to be remedied by - ** loading the page into the pager-cache and setting the PgHdr.needSync + ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC ** flag. ** ** If the attempt to load the page into the page-cache fails, (due @@ -37407,12 +43957,8 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i ** this transaction, it may be written to the database file before ** it is synced into the journal file. This way, it may end up in ** the journal file twice, but that is not a problem. - ** - ** The sqlite3PagerGet() call may cause the journal to sync. So make - ** sure the Pager.needSync flag is set too. */ PgHdr *pPgHdr; - assert( pPager->needSync ); rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr); if( rc!=SQLITE_OK ){ if( needSyncPgno<=pPager->dbOrigSize ){ @@ -37421,23 +43967,11 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i } return rc; } - pPager->needSync = 1; - assert( pPager->noSync==0 && !MEMDB ); pPgHdr->flags |= PGHDR_NEED_SYNC; sqlite3PcacheMakeDirty(pPgHdr); sqlite3PagerUnref(pPgHdr); } - /* - ** For an in-memory database, make sure the original page continues - ** to exist, in case the transaction needs to roll back. Use pPgOld - ** as the original page since it has already been allocated. - */ - if( MEMDB ){ - sqlite3PcacheMove(pPgOld, origPgno); - sqlite3PagerUnref(pPgOld); - } - return SQLITE_OK; } #endif @@ -37451,7 +43985,7 @@ SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){ } /* -** Return a pointer to the Pager.nExtra bytes of "extra" space +** Return a pointer to the Pager.nExtra bytes of "extra" space ** allocated along with the specified page. */ SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){ @@ -37460,7 +43994,7 @@ SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){ /* ** Get/set the locking-mode for this pager. Parameter eMode must be one -** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or +** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or ** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then ** the locking-mode is set to the value specified. ** @@ -37474,56 +44008,146 @@ SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){ || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); assert( PAGER_LOCKINGMODE_QUERY<0 ); assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 ); - if( eMode>=0 && !pPager->tempFile ){ + assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) ); + if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){ pPager->exclusiveMode = (u8)eMode; } return (int)pPager->exclusiveMode; } /* -** Get/set the journal-mode for this pager. Parameter eMode must be one of: +** Set the journal-mode for this pager. Parameter eMode must be one of: ** -** PAGER_JOURNALMODE_QUERY ** PAGER_JOURNALMODE_DELETE ** PAGER_JOURNALMODE_TRUNCATE ** PAGER_JOURNALMODE_PERSIST ** PAGER_JOURNALMODE_OFF ** PAGER_JOURNALMODE_MEMORY +** PAGER_JOURNALMODE_WAL ** -** If the parameter is not _QUERY, then the journal_mode is set to the -** value specified if the change is allowed. The change is disallowed -** for the following reasons: +** The journalmode is set to the value specified if the change is allowed. +** The change may be disallowed for the following reasons: ** ** * An in-memory database can only have its journal_mode set to _OFF ** or _MEMORY. ** -** * The journal mode may not be changed while a transaction is active. +** * Temporary databases cannot have _WAL journalmode. ** ** The returned indicate the current (possibly updated) journal-mode. */ -SQLITE_PRIVATE int sqlite3PagerJournalMode(Pager *pPager, int eMode){ - assert( eMode==PAGER_JOURNALMODE_QUERY - || eMode==PAGER_JOURNALMODE_DELETE +SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ + u8 eOld = pPager->journalMode; /* Prior journalmode */ + +#ifdef SQLITE_DEBUG + /* The print_pager_state() routine is intended to be used by the debugger + ** only. We invoke it once here to suppress a compiler warning. */ + print_pager_state(pPager); +#endif + + + /* The eMode parameter is always valid */ + assert( eMode==PAGER_JOURNALMODE_DELETE || eMode==PAGER_JOURNALMODE_TRUNCATE || eMode==PAGER_JOURNALMODE_PERSIST - || eMode==PAGER_JOURNALMODE_OFF + || eMode==PAGER_JOURNALMODE_OFF + || eMode==PAGER_JOURNALMODE_WAL || eMode==PAGER_JOURNALMODE_MEMORY ); - assert( PAGER_JOURNALMODE_QUERY<0 ); - if( eMode>=0 - && (!MEMDB || eMode==PAGER_JOURNALMODE_MEMORY - || eMode==PAGER_JOURNALMODE_OFF) - && !pPager->dbModified - && (!isOpen(pPager->jfd) || 0==pPager->journalOff) - ){ - if( isOpen(pPager->jfd) ){ - sqlite3OsClose(pPager->jfd); + + /* This routine is only called from the OP_JournalMode opcode, and + ** the logic there will never allow a temporary file to be changed + ** to WAL mode. + */ + assert( pPager->tempFile==0 || eMode!=PAGER_JOURNALMODE_WAL ); + + /* Do allow the journalmode of an in-memory database to be set to + ** anything other than MEMORY or OFF + */ + if( MEMDB ){ + assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF ); + if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){ + eMode = eOld; } + } + + if( eMode!=eOld ){ + + /* Change the journal mode. */ + assert( pPager->eState!=PAGER_ERROR ); pPager->journalMode = (u8)eMode; + + /* When transistioning from TRUNCATE or PERSIST to any other journal + ** mode except WAL, unless the pager is in locking_mode=exclusive mode, + ** delete the journal file. + */ + assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); + assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); + assert( (PAGER_JOURNALMODE_DELETE & 5)==0 ); + assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 ); + assert( (PAGER_JOURNALMODE_OFF & 5)==0 ); + assert( (PAGER_JOURNALMODE_WAL & 5)==5 ); + + assert( isOpen(pPager->fd) || pPager->exclusiveMode ); + if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){ + + /* In this case we would like to delete the journal file. If it is + ** not possible, then that is not a problem. Deleting the journal file + ** here is an optimization only. + ** + ** Before deleting the journal file, obtain a RESERVED lock on the + ** database file. This ensures that the journal file is not deleted + ** while it is in use by some other client. + */ + sqlite3OsClose(pPager->jfd); + if( pPager->eLock>=RESERVED_LOCK ){ + sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + }else{ + int rc = SQLITE_OK; + int state = pPager->eState; + assert( state==PAGER_OPEN || state==PAGER_READER ); + if( state==PAGER_OPEN ){ + rc = sqlite3PagerSharedLock(pPager); + } + if( pPager->eState==PAGER_READER ){ + assert( rc==SQLITE_OK ); + rc = pagerLockDb(pPager, RESERVED_LOCK); + } + if( rc==SQLITE_OK ){ + sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + } + if( rc==SQLITE_OK && state==PAGER_READER ){ + pagerUnlockDb(pPager, SHARED_LOCK); + }else if( state==PAGER_OPEN ){ + pager_unlock(pPager); + } + assert( state==pPager->eState ); + } + } } + + /* Return the new journal mode */ return (int)pPager->journalMode; } /* +** Return the current journal mode. +*/ +SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){ + return (int)pPager->journalMode; +} + +/* +** Return TRUE if the pager is in a state where it is OK to change the +** journalmode. Journalmode changes can only happen when the database +** is unmodified. +*/ +SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ + assert( assert_pager_state(pPager) ); + if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0; + if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0; + return 1; +} + +/* ** Get/set the size-limit used for persistent journal files. ** ** Setting the size limit to -1 means no limit is enforced. @@ -37532,6 +44156,7 @@ SQLITE_PRIVATE int sqlite3PagerJournalMode(Pager *pPager, int eMode){ SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){ if( iLimit>=-1 ){ pPager->journalSizeLimit = iLimit; + sqlite3WalLimit(pPager->pWal, iLimit); } return pPager->journalSizeLimit; } @@ -37546,9 +44171,3156 @@ SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ return &pPager->pBackup; } +#ifndef SQLITE_OMIT_WAL +/* +** This function is called when the user invokes "PRAGMA wal_checkpoint", +** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint() +** or wal_blocking_checkpoint() API functions. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +*/ +SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){ + int rc = SQLITE_OK; + if( pPager->pWal ){ + rc = sqlite3WalCheckpoint(pPager->pWal, eMode, + pPager->xBusyHandler, pPager->pBusyHandlerArg, + pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, + pnLog, pnCkpt + ); + } + return rc; +} + +SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){ + return sqlite3WalCallback(pPager->pWal); +} + +/* +** Return true if the underlying VFS for the given pager supports the +** primitives necessary for write-ahead logging. +*/ +SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){ + const sqlite3_io_methods *pMethods = pPager->fd->pMethods; + return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap); +} + +/* +** Attempt to take an exclusive lock on the database file. If a PENDING lock +** is obtained instead, immediately release it. +*/ +static int pagerExclusiveLock(Pager *pPager){ + int rc; /* Return code */ + + assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + /* If the attempt to grab the exclusive lock failed, release the + ** pending lock that may have been obtained instead. */ + pagerUnlockDb(pPager, SHARED_LOCK); + } + + return rc; +} + +/* +** Call sqlite3WalOpen() to open the WAL handle. If the pager is in +** exclusive-locking mode when this function is called, take an EXCLUSIVE +** lock on the database file and use heap-memory to store the wal-index +** in. Otherwise, use the normal shared-memory. +*/ +static int pagerOpenWal(Pager *pPager){ + int rc = SQLITE_OK; + + assert( pPager->pWal==0 && pPager->tempFile==0 ); + assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK || pPager->noReadlock); + + /* If the pager is already in exclusive-mode, the WAL module will use + ** heap-memory for the wal-index instead of the VFS shared-memory + ** implementation. Take the exclusive lock now, before opening the WAL + ** file, to make sure this is safe. + */ + if( pPager->exclusiveMode ){ + rc = pagerExclusiveLock(pPager); + } + + /* Open the connection to the log file. If this operation fails, + ** (e.g. due to malloc() failure), return an error code. + */ + if( rc==SQLITE_OK ){ + rc = sqlite3WalOpen(pPager->pVfs, + pPager->fd, pPager->zWal, pPager->exclusiveMode, + pPager->journalSizeLimit, &pPager->pWal + ); + } + + return rc; +} + + +/* +** The caller must be holding a SHARED lock on the database file to call +** this function. +** +** If the pager passed as the first argument is open on a real database +** file (not a temp file or an in-memory database), and the WAL file +** is not already open, make an attempt to open it now. If successful, +** return SQLITE_OK. If an error occurs or the VFS used by the pager does +** not support the xShmXXX() methods, return an error code. *pbOpen is +** not modified in either case. +** +** If the pager is open on a temp-file (or in-memory database), or if +** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK +** without doing anything. +*/ +SQLITE_PRIVATE int sqlite3PagerOpenWal( + Pager *pPager, /* Pager object */ + int *pbOpen /* OUT: Set to true if call is a no-op */ +){ + int rc = SQLITE_OK; /* Return code */ + + assert( assert_pager_state(pPager) ); + assert( pPager->eState==PAGER_OPEN || pbOpen ); + assert( pPager->eState==PAGER_READER || !pbOpen ); + assert( pbOpen==0 || *pbOpen==0 ); + assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) ); + + if( !pPager->tempFile && !pPager->pWal ){ + if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; + + /* Close any rollback journal previously open */ + sqlite3OsClose(pPager->jfd); + + rc = pagerOpenWal(pPager); + if( rc==SQLITE_OK ){ + pPager->journalMode = PAGER_JOURNALMODE_WAL; + pPager->eState = PAGER_OPEN; + } + }else{ + *pbOpen = 1; + } + + return rc; +} + +/* +** This function is called to close the connection to the log file prior +** to switching from WAL to rollback mode. +** +** Before closing the log file, this function attempts to take an +** EXCLUSIVE lock on the database file. If this cannot be obtained, an +** error (SQLITE_BUSY) is returned and the log connection is not closed. +** If successful, the EXCLUSIVE lock is not released before returning. +*/ +SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){ + int rc = SQLITE_OK; + + assert( pPager->journalMode==PAGER_JOURNALMODE_WAL ); + + /* If the log file is not already open, but does exist in the file-system, + ** it may need to be checkpointed before the connection can switch to + ** rollback mode. Open it now so this can happen. + */ + if( !pPager->pWal ){ + int logexists = 0; + rc = pagerLockDb(pPager, SHARED_LOCK); + if( rc==SQLITE_OK ){ + rc = sqlite3OsAccess( + pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists + ); + } + if( rc==SQLITE_OK && logexists ){ + rc = pagerOpenWal(pPager); + } + } + + /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on + ** the database file, the log and log-summary files will be deleted. + */ + if( rc==SQLITE_OK && pPager->pWal ){ + rc = pagerExclusiveLock(pPager); + if( rc==SQLITE_OK ){ + rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, + pPager->pageSize, (u8*)pPager->pTmpSpace); + pPager->pWal = 0; + } + } + return rc; +} + +#ifdef SQLITE_HAS_CODEC +/* +** This function is called by the wal module when writing page content +** into the log file. +** +** This function returns a pointer to a buffer containing the encrypted +** page content. If a malloc fails, this function may return NULL. +*/ +SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){ + void *aData = 0; + CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData); + return aData; +} +#endif /* SQLITE_HAS_CODEC */ + +#endif /* !SQLITE_OMIT_WAL */ + #endif /* SQLITE_OMIT_DISKIO */ /************** End of pager.c ***********************************************/ +/************** Begin file wal.c *********************************************/ +/* +** 2010 February 1 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains the implementation of a write-ahead log (WAL) used in +** "journal_mode=WAL" mode. +** +** WRITE-AHEAD LOG (WAL) FILE FORMAT +** +** A WAL file consists of a header followed by zero or more "frames". +** Each frame records the revised content of a single page from the +** database file. All changes to the database are recorded by writing +** frames into the WAL. Transactions commit when a frame is written that +** contains a commit marker. A single WAL can and usually does record +** multiple transactions. Periodically, the content of the WAL is +** transferred back into the database file in an operation called a +** "checkpoint". +** +** A single WAL file can be used multiple times. In other words, the +** WAL can fill up with frames and then be checkpointed and then new +** frames can overwrite the old ones. A WAL always grows from beginning +** toward the end. Checksums and counters attached to each frame are +** used to determine which frames within the WAL are valid and which +** are leftovers from prior checkpoints. +** +** The WAL header is 32 bytes in size and consists of the following eight +** big-endian 32-bit unsigned integer values: +** +** 0: Magic number. 0x377f0682 or 0x377f0683 +** 4: File format version. Currently 3007000 +** 8: Database page size. Example: 1024 +** 12: Checkpoint sequence number +** 16: Salt-1, random integer incremented with each checkpoint +** 20: Salt-2, a different random integer changing with each ckpt +** 24: Checksum-1 (first part of checksum for first 24 bytes of header). +** 28: Checksum-2 (second part of checksum for first 24 bytes of header). +** +** Immediately following the wal-header are zero or more frames. Each +** frame consists of a 24-byte frame-header followed by a <page-size> bytes +** of page data. The frame-header is six big-endian 32-bit unsigned +** integer values, as follows: +** +** 0: Page number. +** 4: For commit records, the size of the database image in pages +** after the commit. For all other records, zero. +** 8: Salt-1 (copied from the header) +** 12: Salt-2 (copied from the header) +** 16: Checksum-1. +** 20: Checksum-2. +** +** A frame is considered valid if and only if the following conditions are +** true: +** +** (1) The salt-1 and salt-2 values in the frame-header match +** salt values in the wal-header +** +** (2) The checksum values in the final 8 bytes of the frame-header +** exactly match the checksum computed consecutively on the +** WAL header and the first 8 bytes and the content of all frames +** up to and including the current frame. +** +** The checksum is computed using 32-bit big-endian integers if the +** magic number in the first 4 bytes of the WAL is 0x377f0683 and it +** is computed using little-endian if the magic number is 0x377f0682. +** The checksum values are always stored in the frame header in a +** big-endian format regardless of which byte order is used to compute +** the checksum. The checksum is computed by interpreting the input as +** an even number of unsigned 32-bit integers: x[0] through x[N]. The +** algorithm used for the checksum is as follows: +** +** for i from 0 to n-1 step 2: +** s0 += x[i] + s1; +** s1 += x[i+1] + s0; +** endfor +** +** Note that s0 and s1 are both weighted checksums using fibonacci weights +** in reverse order (the largest fibonacci weight occurs on the first element +** of the sequence being summed.) The s1 value spans all 32-bit +** terms of the sequence whereas s0 omits the final term. +** +** On a checkpoint, the WAL is first VFS.xSync-ed, then valid content of the +** WAL is transferred into the database, then the database is VFS.xSync-ed. +** The VFS.xSync operations serve as write barriers - all writes launched +** before the xSync must complete before any write that launches after the +** xSync begins. +** +** After each checkpoint, the salt-1 value is incremented and the salt-2 +** value is randomized. This prevents old and new frames in the WAL from +** being considered valid at the same time and being checkpointing together +** following a crash. +** +** READER ALGORITHM +** +** To read a page from the database (call it page number P), a reader +** first checks the WAL to see if it contains page P. If so, then the +** last valid instance of page P that is a followed by a commit frame +** or is a commit frame itself becomes the value read. If the WAL +** contains no copies of page P that are valid and which are a commit +** frame or are followed by a commit frame, then page P is read from +** the database file. +** +** To start a read transaction, the reader records the index of the last +** valid frame in the WAL. The reader uses this recorded "mxFrame" value +** for all subsequent read operations. New transactions can be appended +** to the WAL, but as long as the reader uses its original mxFrame value +** and ignores the newly appended content, it will see a consistent snapshot +** of the database from a single point in time. This technique allows +** multiple concurrent readers to view different versions of the database +** content simultaneously. +** +** The reader algorithm in the previous paragraphs works correctly, but +** because frames for page P can appear anywhere within the WAL, the +** reader has to scan the entire WAL looking for page P frames. If the +** WAL is large (multiple megabytes is typical) that scan can be slow, +** and read performance suffers. To overcome this problem, a separate +** data structure called the wal-index is maintained to expedite the +** search for frames of a particular page. +** +** WAL-INDEX FORMAT +** +** Conceptually, the wal-index is shared memory, though VFS implementations +** might choose to implement the wal-index using a mmapped file. Because +** the wal-index is shared memory, SQLite does not support journal_mode=WAL +** on a network filesystem. All users of the database must be able to +** share memory. +** +** The wal-index is transient. After a crash, the wal-index can (and should +** be) reconstructed from the original WAL file. In fact, the VFS is required +** to either truncate or zero the header of the wal-index when the last +** connection to it closes. Because the wal-index is transient, it can +** use an architecture-specific format; it does not have to be cross-platform. +** Hence, unlike the database and WAL file formats which store all values +** as big endian, the wal-index can store multi-byte values in the native +** byte order of the host computer. +** +** The purpose of the wal-index is to answer this question quickly: Given +** a page number P, return the index of the last frame for page P in the WAL, +** or return NULL if there are no frames for page P in the WAL. +** +** The wal-index consists of a header region, followed by an one or +** more index blocks. +** +** The wal-index header contains the total number of frames within the WAL +** in the the mxFrame field. +** +** Each index block except for the first contains information on +** HASHTABLE_NPAGE frames. The first index block contains information on +** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and +** HASHTABLE_NPAGE are selected so that together the wal-index header and +** first index block are the same size as all other index blocks in the +** wal-index. +** +** Each index block contains two sections, a page-mapping that contains the +** database page number associated with each wal frame, and a hash-table +** that allows readers to query an index block for a specific page number. +** The page-mapping is an array of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE +** for the first index block) 32-bit page numbers. The first entry in the +** first index-block contains the database page number corresponding to the +** first frame in the WAL file. The first entry in the second index block +** in the WAL file corresponds to the (HASHTABLE_NPAGE_ONE+1)th frame in +** the log, and so on. +** +** The last index block in a wal-index usually contains less than the full +** complement of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE) page-numbers, +** depending on the contents of the WAL file. This does not change the +** allocated size of the page-mapping array - the page-mapping array merely +** contains unused entries. +** +** Even without using the hash table, the last frame for page P +** can be found by scanning the page-mapping sections of each index block +** starting with the last index block and moving toward the first, and +** within each index block, starting at the end and moving toward the +** beginning. The first entry that equals P corresponds to the frame +** holding the content for that page. +** +** The hash table consists of HASHTABLE_NSLOT 16-bit unsigned integers. +** HASHTABLE_NSLOT = 2*HASHTABLE_NPAGE, and there is one entry in the +** hash table for each page number in the mapping section, so the hash +** table is never more than half full. The expected number of collisions +** prior to finding a match is 1. Each entry of the hash table is an +** 1-based index of an entry in the mapping section of the same +** index block. Let K be the 1-based index of the largest entry in +** the mapping section. (For index blocks other than the last, K will +** always be exactly HASHTABLE_NPAGE (4096) and for the last index block +** K will be (mxFrame%HASHTABLE_NPAGE).) Unused slots of the hash table +** contain a value of 0. +** +** To look for page P in the hash table, first compute a hash iKey on +** P as follows: +** +** iKey = (P * 383) % HASHTABLE_NSLOT +** +** Then start scanning entries of the hash table, starting with iKey +** (wrapping around to the beginning when the end of the hash table is +** reached) until an unused hash slot is found. Let the first unused slot +** be at index iUnused. (iUnused might be less than iKey if there was +** wrap-around.) Because the hash table is never more than half full, +** the search is guaranteed to eventually hit an unused entry. Let +** iMax be the value between iKey and iUnused, closest to iUnused, +** where aHash[iMax]==P. If there is no iMax entry (if there exists +** no hash slot such that aHash[i]==p) then page P is not in the +** current index block. Otherwise the iMax-th mapping entry of the +** current index block corresponds to the last entry that references +** page P. +** +** A hash search begins with the last index block and moves toward the +** first index block, looking for entries corresponding to page P. On +** average, only two or three slots in each index block need to be +** examined in order to either find the last entry for page P, or to +** establish that no such entry exists in the block. Each index block +** holds over 4000 entries. So two or three index blocks are sufficient +** to cover a typical 10 megabyte WAL file, assuming 1K pages. 8 or 10 +** comparisons (on average) suffice to either locate a frame in the +** WAL or to establish that the frame does not exist in the WAL. This +** is much faster than scanning the entire 10MB WAL. +** +** Note that entries are added in order of increasing K. Hence, one +** reader might be using some value K0 and a second reader that started +** at a later time (after additional transactions were added to the WAL +** and to the wal-index) might be using a different value K1, where K1>K0. +** Both readers can use the same hash table and mapping section to get +** the correct result. There may be entries in the hash table with +** K>K0 but to the first reader, those entries will appear to be unused +** slots in the hash table and so the first reader will get an answer as +** if no values greater than K0 had ever been inserted into the hash table +** in the first place - which is what reader one wants. Meanwhile, the +** second reader using K1 will see additional values that were inserted +** later, which is exactly what reader two wants. +** +** When a rollback occurs, the value of K is decreased. Hash table entries +** that correspond to frames greater than the new K value are removed +** from the hash table at this point. +*/ +#ifndef SQLITE_OMIT_WAL + + +/* +** Trace output macros +*/ +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +SQLITE_PRIVATE int sqlite3WalTrace = 0; +# define WALTRACE(X) if(sqlite3WalTrace) sqlite3DebugPrintf X +#else +# define WALTRACE(X) +#endif + +/* +** The maximum (and only) versions of the wal and wal-index formats +** that may be interpreted by this version of SQLite. +** +** If a client begins recovering a WAL file and finds that (a) the checksum +** values in the wal-header are correct and (b) the version field is not +** WAL_MAX_VERSION, recovery fails and SQLite returns SQLITE_CANTOPEN. +** +** Similarly, if a client successfully reads a wal-index header (i.e. the +** checksum test is successful) and finds that the version field is not +** WALINDEX_MAX_VERSION, then no read-transaction is opened and SQLite +** returns SQLITE_CANTOPEN. +*/ +#define WAL_MAX_VERSION 3007000 +#define WALINDEX_MAX_VERSION 3007000 + +/* +** Indices of various locking bytes. WAL_NREADER is the number +** of available reader locks and should be at least 3. +*/ +#define WAL_WRITE_LOCK 0 +#define WAL_ALL_BUT_WRITE 1 +#define WAL_CKPT_LOCK 1 +#define WAL_RECOVER_LOCK 2 +#define WAL_READ_LOCK(I) (3+(I)) +#define WAL_NREADER (SQLITE_SHM_NLOCK-3) + + +/* Object declarations */ +typedef struct WalIndexHdr WalIndexHdr; +typedef struct WalIterator WalIterator; +typedef struct WalCkptInfo WalCkptInfo; + + +/* +** The following object holds a copy of the wal-index header content. +** +** The actual header in the wal-index consists of two copies of this +** object. +** +** The szPage value can be any power of 2 between 512 and 32768, inclusive. +** Or it can be 1 to represent a 65536-byte page. The latter case was +** added in 3.7.1 when support for 64K pages was added. +*/ +struct WalIndexHdr { + u32 iVersion; /* Wal-index version */ + u32 unused; /* Unused (padding) field */ + u32 iChange; /* Counter incremented each transaction */ + u8 isInit; /* 1 when initialized */ + u8 bigEndCksum; /* True if checksums in WAL are big-endian */ + u16 szPage; /* Database page size in bytes. 1==64K */ + u32 mxFrame; /* Index of last valid frame in the WAL */ + u32 nPage; /* Size of database in pages */ + u32 aFrameCksum[2]; /* Checksum of last frame in log */ + u32 aSalt[2]; /* Two salt values copied from WAL header */ + u32 aCksum[2]; /* Checksum over all prior fields */ +}; + +/* +** A copy of the following object occurs in the wal-index immediately +** following the second copy of the WalIndexHdr. This object stores +** information used by checkpoint. +** +** nBackfill is the number of frames in the WAL that have been written +** back into the database. (We call the act of moving content from WAL to +** database "backfilling".) The nBackfill number is never greater than +** WalIndexHdr.mxFrame. nBackfill can only be increased by threads +** holding the WAL_CKPT_LOCK lock (which includes a recovery thread). +** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from +** mxFrame back to zero when the WAL is reset. +** +** There is one entry in aReadMark[] for each reader lock. If a reader +** holds read-lock K, then the value in aReadMark[K] is no greater than +** the mxFrame for that reader. The value READMARK_NOT_USED (0xffffffff) +** for any aReadMark[] means that entry is unused. aReadMark[0] is +** a special case; its value is never used and it exists as a place-holder +** to avoid having to offset aReadMark[] indexs by one. Readers holding +** WAL_READ_LOCK(0) always ignore the entire WAL and read all content +** directly from the database. +** +** The value of aReadMark[K] may only be changed by a thread that +** is holding an exclusive lock on WAL_READ_LOCK(K). Thus, the value of +** aReadMark[K] cannot changed while there is a reader is using that mark +** since the reader will be holding a shared lock on WAL_READ_LOCK(K). +** +** The checkpointer may only transfer frames from WAL to database where +** the frame numbers are less than or equal to every aReadMark[] that is +** in use (that is, every aReadMark[j] for which there is a corresponding +** WAL_READ_LOCK(j)). New readers (usually) pick the aReadMark[] with the +** largest value and will increase an unused aReadMark[] to mxFrame if there +** is not already an aReadMark[] equal to mxFrame. The exception to the +** previous sentence is when nBackfill equals mxFrame (meaning that everything +** in the WAL has been backfilled into the database) then new readers +** will choose aReadMark[0] which has value 0 and hence such reader will +** get all their all content directly from the database file and ignore +** the WAL. +** +** Writers normally append new frames to the end of the WAL. However, +** if nBackfill equals mxFrame (meaning that all WAL content has been +** written back into the database) and if no readers are using the WAL +** (in other words, if there are no WAL_READ_LOCK(i) where i>0) then +** the writer will first "reset" the WAL back to the beginning and start +** writing new content beginning at frame 1. +** +** We assume that 32-bit loads are atomic and so no locks are needed in +** order to read from any aReadMark[] entries. +*/ +struct WalCkptInfo { + u32 nBackfill; /* Number of WAL frames backfilled into DB */ + u32 aReadMark[WAL_NREADER]; /* Reader marks */ +}; +#define READMARK_NOT_USED 0xffffffff + + +/* A block of WALINDEX_LOCK_RESERVED bytes beginning at +** WALINDEX_LOCK_OFFSET is reserved for locks. Since some systems +** only support mandatory file-locks, we do not read or write data +** from the region of the file on which locks are applied. +*/ +#define WALINDEX_LOCK_OFFSET (sizeof(WalIndexHdr)*2 + sizeof(WalCkptInfo)) +#define WALINDEX_LOCK_RESERVED 16 +#define WALINDEX_HDR_SIZE (WALINDEX_LOCK_OFFSET+WALINDEX_LOCK_RESERVED) + +/* Size of header before each frame in wal */ +#define WAL_FRAME_HDRSIZE 24 + +/* Size of write ahead log header, including checksum. */ +/* #define WAL_HDRSIZE 24 */ +#define WAL_HDRSIZE 32 + +/* WAL magic value. Either this value, or the same value with the least +** significant bit also set (WAL_MAGIC | 0x00000001) is stored in 32-bit +** big-endian format in the first 4 bytes of a WAL file. +** +** If the LSB is set, then the checksums for each frame within the WAL +** file are calculated by treating all data as an array of 32-bit +** big-endian words. Otherwise, they are calculated by interpreting +** all data as 32-bit little-endian words. +*/ +#define WAL_MAGIC 0x377f0682 + +/* +** Return the offset of frame iFrame in the write-ahead log file, +** assuming a database page size of szPage bytes. The offset returned +** is to the start of the write-ahead log frame-header. +*/ +#define walFrameOffset(iFrame, szPage) ( \ + WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE) \ +) + +/* +** An open write-ahead log file is represented by an instance of the +** following object. +*/ +struct Wal { + sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ + sqlite3_file *pDbFd; /* File handle for the database file */ + sqlite3_file *pWalFd; /* File handle for WAL file */ + u32 iCallback; /* Value to pass to log callback (or 0) */ + i64 mxWalSize; /* Truncate WAL to this size upon reset */ + int nWiData; /* Size of array apWiData */ + volatile u32 **apWiData; /* Pointer to wal-index content in memory */ + u32 szPage; /* Database page size */ + i16 readLock; /* Which read lock is being held. -1 for none */ + u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ + u8 writeLock; /* True if in a write transaction */ + u8 ckptLock; /* True if holding a checkpoint lock */ + u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ + WalIndexHdr hdr; /* Wal-index header for current transaction */ + const char *zWalName; /* Name of WAL file */ + u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ +#ifdef SQLITE_DEBUG + u8 lockError; /* True if a locking error has occurred */ +#endif +}; + +/* +** Candidate values for Wal.exclusiveMode. +*/ +#define WAL_NORMAL_MODE 0 +#define WAL_EXCLUSIVE_MODE 1 +#define WAL_HEAPMEMORY_MODE 2 + +/* +** Possible values for WAL.readOnly +*/ +#define WAL_RDWR 0 /* Normal read/write connection */ +#define WAL_RDONLY 1 /* The WAL file is readonly */ +#define WAL_SHM_RDONLY 2 /* The SHM file is readonly */ + +/* +** Each page of the wal-index mapping contains a hash-table made up of +** an array of HASHTABLE_NSLOT elements of the following type. +*/ +typedef u16 ht_slot; + +/* +** This structure is used to implement an iterator that loops through +** all frames in the WAL in database page order. Where two or more frames +** correspond to the same database page, the iterator visits only the +** frame most recently written to the WAL (in other words, the frame with +** the largest index). +** +** The internals of this structure are only accessed by: +** +** walIteratorInit() - Create a new iterator, +** walIteratorNext() - Step an iterator, +** walIteratorFree() - Free an iterator. +** +** This functionality is used by the checkpoint code (see walCheckpoint()). +*/ +struct WalIterator { + int iPrior; /* Last result returned from the iterator */ + int nSegment; /* Number of entries in aSegment[] */ + struct WalSegment { + int iNext; /* Next slot in aIndex[] not yet returned */ + ht_slot *aIndex; /* i0, i1, i2... such that aPgno[iN] ascend */ + u32 *aPgno; /* Array of page numbers. */ + int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */ + int iZero; /* Frame number associated with aPgno[0] */ + } aSegment[1]; /* One for every 32KB page in the wal-index */ +}; + +/* +** Define the parameters of the hash tables in the wal-index file. There +** is a hash-table following every HASHTABLE_NPAGE page numbers in the +** wal-index. +** +** Changing any of these constants will alter the wal-index format and +** create incompatibilities. +*/ +#define HASHTABLE_NPAGE 4096 /* Must be power of 2 */ +#define HASHTABLE_HASH_1 383 /* Should be prime */ +#define HASHTABLE_NSLOT (HASHTABLE_NPAGE*2) /* Must be a power of 2 */ + +/* +** The block of page numbers associated with the first hash-table in a +** wal-index is smaller than usual. This is so that there is a complete +** hash-table on each aligned 32KB page of the wal-index. +*/ +#define HASHTABLE_NPAGE_ONE (HASHTABLE_NPAGE - (WALINDEX_HDR_SIZE/sizeof(u32))) + +/* The wal-index is divided into pages of WALINDEX_PGSZ bytes each. */ +#define WALINDEX_PGSZ ( \ + sizeof(ht_slot)*HASHTABLE_NSLOT + HASHTABLE_NPAGE*sizeof(u32) \ +) + +/* +** Obtain a pointer to the iPage'th page of the wal-index. The wal-index +** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are +** numbered from zero. +** +** If this call is successful, *ppPage is set to point to the wal-index +** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs, +** then an SQLite error code is returned and *ppPage is set to 0. +*/ +static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){ + int rc = SQLITE_OK; + + /* Enlarge the pWal->apWiData[] array if required */ + if( pWal->nWiData<=iPage ){ + int nByte = sizeof(u32*)*(iPage+1); + volatile u32 **apNew; + apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte); + if( !apNew ){ + *ppPage = 0; + return SQLITE_NOMEM; + } + memset((void*)&apNew[pWal->nWiData], 0, + sizeof(u32*)*(iPage+1-pWal->nWiData)); + pWal->apWiData = apNew; + pWal->nWiData = iPage+1; + } + + /* Request a pointer to the required page from the VFS */ + if( pWal->apWiData[iPage]==0 ){ + if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ + pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); + if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM; + }else{ + rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, + pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] + ); + if( rc==SQLITE_READONLY ){ + pWal->readOnly |= WAL_SHM_RDONLY; + rc = SQLITE_OK; + } + } + } + + *ppPage = pWal->apWiData[iPage]; + assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); + return rc; +} + +/* +** Return a pointer to the WalCkptInfo structure in the wal-index. +*/ +static volatile WalCkptInfo *walCkptInfo(Wal *pWal){ + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]); +} + +/* +** Return a pointer to the WalIndexHdr structure in the wal-index. +*/ +static volatile WalIndexHdr *walIndexHdr(Wal *pWal){ + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + return (volatile WalIndexHdr*)pWal->apWiData[0]; +} + +/* +** The argument to this macro must be of type u32. On a little-endian +** architecture, it returns the u32 value that results from interpreting +** the 4 bytes as a big-endian value. On a big-endian architecture, it +** returns the value that would be produced by intepreting the 4 bytes +** of the input value as a little-endian integer. +*/ +#define BYTESWAP32(x) ( \ + (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8) \ + + (((x)&0x00FF0000)>>8) + (((x)&0xFF000000)>>24) \ +) + +/* +** Generate or extend an 8 byte checksum based on the data in +** array aByte[] and the initial values of aIn[0] and aIn[1] (or +** initial values of 0 and 0 if aIn==NULL). +** +** The checksum is written back into aOut[] before returning. +** +** nByte must be a positive multiple of 8. +*/ +static void walChecksumBytes( + int nativeCksum, /* True for native byte-order, false for non-native */ + u8 *a, /* Content to be checksummed */ + int nByte, /* Bytes of content in a[]. Must be a multiple of 8. */ + const u32 *aIn, /* Initial checksum value input */ + u32 *aOut /* OUT: Final checksum value output */ +){ + u32 s1, s2; + u32 *aData = (u32 *)a; + u32 *aEnd = (u32 *)&a[nByte]; + + if( aIn ){ + s1 = aIn[0]; + s2 = aIn[1]; + }else{ + s1 = s2 = 0; + } + + assert( nByte>=8 ); + assert( (nByte&0x00000007)==0 ); + + if( nativeCksum ){ + do { + s1 += *aData++ + s2; + s2 += *aData++ + s1; + }while( aData<aEnd ); + }else{ + do { + s1 += BYTESWAP32(aData[0]) + s2; + s2 += BYTESWAP32(aData[1]) + s1; + aData += 2; + }while( aData<aEnd ); + } + + aOut[0] = s1; + aOut[1] = s2; +} + +static void walShmBarrier(Wal *pWal){ + if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){ + sqlite3OsShmBarrier(pWal->pDbFd); + } +} + +/* +** Write the header information in pWal->hdr into the wal-index. +** +** The checksum on pWal->hdr is updated before it is written. +*/ +static void walIndexWriteHdr(Wal *pWal){ + volatile WalIndexHdr *aHdr = walIndexHdr(pWal); + const int nCksum = offsetof(WalIndexHdr, aCksum); + + assert( pWal->writeLock ); + pWal->hdr.isInit = 1; + pWal->hdr.iVersion = WALINDEX_MAX_VERSION; + walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum); + memcpy((void *)&aHdr[1], (void *)&pWal->hdr, sizeof(WalIndexHdr)); + walShmBarrier(pWal); + memcpy((void *)&aHdr[0], (void *)&pWal->hdr, sizeof(WalIndexHdr)); +} + +/* +** This function encodes a single frame header and writes it to a buffer +** supplied by the caller. A frame-header is made up of a series of +** 4-byte big-endian integers, as follows: +** +** 0: Page number. +** 4: For commit records, the size of the database image in pages +** after the commit. For all other records, zero. +** 8: Salt-1 (copied from the wal-header) +** 12: Salt-2 (copied from the wal-header) +** 16: Checksum-1. +** 20: Checksum-2. +*/ +static void walEncodeFrame( + Wal *pWal, /* The write-ahead log */ + u32 iPage, /* Database page number for frame */ + u32 nTruncate, /* New db size (or 0 for non-commit frames) */ + u8 *aData, /* Pointer to page data */ + u8 *aFrame /* OUT: Write encoded frame here */ +){ + int nativeCksum; /* True for native byte-order checksums */ + u32 *aCksum = pWal->hdr.aFrameCksum; + assert( WAL_FRAME_HDRSIZE==24 ); + sqlite3Put4byte(&aFrame[0], iPage); + sqlite3Put4byte(&aFrame[4], nTruncate); + memcpy(&aFrame[8], pWal->hdr.aSalt, 8); + + nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); + walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); + walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); + + sqlite3Put4byte(&aFrame[16], aCksum[0]); + sqlite3Put4byte(&aFrame[20], aCksum[1]); +} + +/* +** Check to see if the frame with header in aFrame[] and content +** in aData[] is valid. If it is a valid frame, fill *piPage and +** *pnTruncate and return true. Return if the frame is not valid. +*/ +static int walDecodeFrame( + Wal *pWal, /* The write-ahead log */ + u32 *piPage, /* OUT: Database page number for frame */ + u32 *pnTruncate, /* OUT: New db size (or 0 if not commit) */ + u8 *aData, /* Pointer to page data (for checksum) */ + u8 *aFrame /* Frame data */ +){ + int nativeCksum; /* True for native byte-order checksums */ + u32 *aCksum = pWal->hdr.aFrameCksum; + u32 pgno; /* Page number of the frame */ + assert( WAL_FRAME_HDRSIZE==24 ); + + /* A frame is only valid if the salt values in the frame-header + ** match the salt values in the wal-header. + */ + if( memcmp(&pWal->hdr.aSalt, &aFrame[8], 8)!=0 ){ + return 0; + } + + /* A frame is only valid if the page number is creater than zero. + */ + pgno = sqlite3Get4byte(&aFrame[0]); + if( pgno==0 ){ + return 0; + } + + /* A frame is only valid if a checksum of the WAL header, + ** all prior frams, the first 16 bytes of this frame-header, + ** and the frame-data matches the checksum in the last 8 + ** bytes of this frame-header. + */ + nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); + walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); + walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); + if( aCksum[0]!=sqlite3Get4byte(&aFrame[16]) + || aCksum[1]!=sqlite3Get4byte(&aFrame[20]) + ){ + /* Checksum failed. */ + return 0; + } + + /* If we reach this point, the frame is valid. Return the page number + ** and the new database size. + */ + *piPage = pgno; + *pnTruncate = sqlite3Get4byte(&aFrame[4]); + return 1; +} + + +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +/* +** Names of locks. This routine is used to provide debugging output and is not +** a part of an ordinary build. +*/ +static const char *walLockName(int lockIdx){ + if( lockIdx==WAL_WRITE_LOCK ){ + return "WRITE-LOCK"; + }else if( lockIdx==WAL_CKPT_LOCK ){ + return "CKPT-LOCK"; + }else if( lockIdx==WAL_RECOVER_LOCK ){ + return "RECOVER-LOCK"; + }else{ + static char zName[15]; + sqlite3_snprintf(sizeof(zName), zName, "READ-LOCK[%d]", + lockIdx-WAL_READ_LOCK(0)); + return zName; + } +} +#endif /*defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ + + +/* +** Set or release locks on the WAL. Locks are either shared or exclusive. +** A lock cannot be moved directly between shared and exclusive - it must go +** through the unlocked state first. +** +** In locking_mode=EXCLUSIVE, all of these routines become no-ops. +*/ +static int walLockShared(Wal *pWal, int lockIdx){ + int rc; + if( pWal->exclusiveMode ) return SQLITE_OK; + rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, + SQLITE_SHM_LOCK | SQLITE_SHM_SHARED); + WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, + walLockName(lockIdx), rc ? "failed" : "ok")); + VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) + return rc; +} +static void walUnlockShared(Wal *pWal, int lockIdx){ + if( pWal->exclusiveMode ) return; + (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, + SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); + WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); +} +static int walLockExclusive(Wal *pWal, int lockIdx, int n){ + int rc; + if( pWal->exclusiveMode ) return SQLITE_OK; + rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, + SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); + WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, + walLockName(lockIdx), n, rc ? "failed" : "ok")); + VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) + return rc; +} +static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ + if( pWal->exclusiveMode ) return; + (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, + SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); + WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal, + walLockName(lockIdx), n)); +} + +/* +** Compute a hash on a page number. The resulting hash value must land +** between 0 and (HASHTABLE_NSLOT-1). The walHashNext() function advances +** the hash to the next value in the event of a collision. +*/ +static int walHash(u32 iPage){ + assert( iPage>0 ); + assert( (HASHTABLE_NSLOT & (HASHTABLE_NSLOT-1))==0 ); + return (iPage*HASHTABLE_HASH_1) & (HASHTABLE_NSLOT-1); +} +static int walNextHash(int iPriorHash){ + return (iPriorHash+1)&(HASHTABLE_NSLOT-1); +} + +/* +** Return pointers to the hash table and page number array stored on +** page iHash of the wal-index. The wal-index is broken into 32KB pages +** numbered starting from 0. +** +** Set output variable *paHash to point to the start of the hash table +** in the wal-index file. Set *piZero to one less than the frame +** number of the first frame indexed by this hash table. If a +** slot in the hash table is set to N, it refers to frame number +** (*piZero+N) in the log. +** +** Finally, set *paPgno so that *paPgno[1] is the page number of the +** first frame indexed by the hash table, frame (*piZero+1). +*/ +static int walHashGet( + Wal *pWal, /* WAL handle */ + int iHash, /* Find the iHash'th table */ + volatile ht_slot **paHash, /* OUT: Pointer to hash index */ + volatile u32 **paPgno, /* OUT: Pointer to page number array */ + u32 *piZero /* OUT: Frame associated with *paPgno[0] */ +){ + int rc; /* Return code */ + volatile u32 *aPgno; + + rc = walIndexPage(pWal, iHash, &aPgno); + assert( rc==SQLITE_OK || iHash>0 ); + + if( rc==SQLITE_OK ){ + u32 iZero; + volatile ht_slot *aHash; + + aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE]; + if( iHash==0 ){ + aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)]; + iZero = 0; + }else{ + iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE; + } + + *paPgno = &aPgno[-1]; + *paHash = aHash; + *piZero = iZero; + } + return rc; +} + +/* +** Return the number of the wal-index page that contains the hash-table +** and page-number array that contain entries corresponding to WAL frame +** iFrame. The wal-index is broken up into 32KB pages. Wal-index pages +** are numbered starting from 0. +*/ +static int walFramePage(u32 iFrame){ + int iHash = (iFrame+HASHTABLE_NPAGE-HASHTABLE_NPAGE_ONE-1) / HASHTABLE_NPAGE; + assert( (iHash==0 || iFrame>HASHTABLE_NPAGE_ONE) + && (iHash>=1 || iFrame<=HASHTABLE_NPAGE_ONE) + && (iHash<=1 || iFrame>(HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE)) + && (iHash>=2 || iFrame<=HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE) + && (iHash<=2 || iFrame>(HASHTABLE_NPAGE_ONE+2*HASHTABLE_NPAGE)) + ); + return iHash; +} + +/* +** Return the page number associated with frame iFrame in this WAL. +*/ +static u32 walFramePgno(Wal *pWal, u32 iFrame){ + int iHash = walFramePage(iFrame); + if( iHash==0 ){ + return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1]; + } + return pWal->apWiData[iHash][(iFrame-1-HASHTABLE_NPAGE_ONE)%HASHTABLE_NPAGE]; +} + +/* +** Remove entries from the hash table that point to WAL slots greater +** than pWal->hdr.mxFrame. +** +** This function is called whenever pWal->hdr.mxFrame is decreased due +** to a rollback or savepoint. +** +** At most only the hash table containing pWal->hdr.mxFrame needs to be +** updated. Any later hash tables will be automatically cleared when +** pWal->hdr.mxFrame advances to the point where those hash tables are +** actually needed. +*/ +static void walCleanupHash(Wal *pWal){ + volatile ht_slot *aHash = 0; /* Pointer to hash table to clear */ + volatile u32 *aPgno = 0; /* Page number array for hash table */ + u32 iZero = 0; /* frame == (aHash[x]+iZero) */ + int iLimit = 0; /* Zero values greater than this */ + int nByte; /* Number of bytes to zero in aPgno[] */ + int i; /* Used to iterate through aHash[] */ + + assert( pWal->writeLock ); + testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 ); + testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE ); + testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE+1 ); + + if( pWal->hdr.mxFrame==0 ) return; + + /* Obtain pointers to the hash-table and page-number array containing + ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed + ** that the page said hash-table and array reside on is already mapped. + */ + assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) ); + assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] ); + walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero); + + /* Zero all hash-table entries that correspond to frame numbers greater + ** than pWal->hdr.mxFrame. + */ + iLimit = pWal->hdr.mxFrame - iZero; + assert( iLimit>0 ); + for(i=0; i<HASHTABLE_NSLOT; i++){ + if( aHash[i]>iLimit ){ + aHash[i] = 0; + } + } + + /* Zero the entries in the aPgno array that correspond to frames with + ** frame numbers greater than pWal->hdr.mxFrame. + */ + nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]); + memset((void *)&aPgno[iLimit+1], 0, nByte); + +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + /* Verify that the every entry in the mapping region is still reachable + ** via the hash table even after the cleanup. + */ + if( iLimit ){ + int i; /* Loop counter */ + int iKey; /* Hash key */ + for(i=1; i<=iLimit; i++){ + for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){ + if( aHash[iKey]==i ) break; + } + assert( aHash[iKey]==i ); + } + } +#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */ +} + + +/* +** Set an entry in the wal-index that will map database page number +** pPage into WAL frame iFrame. +*/ +static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ + int rc; /* Return code */ + u32 iZero = 0; /* One less than frame number of aPgno[1] */ + volatile u32 *aPgno = 0; /* Page number array */ + volatile ht_slot *aHash = 0; /* Hash table */ + + rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero); + + /* Assuming the wal-index file was successfully mapped, populate the + ** page number array and hash table entry. + */ + if( rc==SQLITE_OK ){ + int iKey; /* Hash table key */ + int idx; /* Value to write to hash-table slot */ + int nCollide; /* Number of hash collisions */ + + idx = iFrame - iZero; + assert( idx <= HASHTABLE_NSLOT/2 + 1 ); + + /* If this is the first entry to be added to this hash-table, zero the + ** entire hash table and aPgno[] array before proceding. + */ + if( idx==1 ){ + int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]); + memset((void*)&aPgno[1], 0, nByte); + } + + /* If the entry in aPgno[] is already set, then the previous writer + ** must have exited unexpectedly in the middle of a transaction (after + ** writing one or more dirty pages to the WAL to free up memory). + ** Remove the remnants of that writers uncommitted transaction from + ** the hash-table before writing any new entries. + */ + if( aPgno[idx] ){ + walCleanupHash(pWal); + assert( !aPgno[idx] ); + } + + /* Write the aPgno[] array entry and the hash-table slot. */ + nCollide = idx; + for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){ + if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT; + } + aPgno[idx] = iPage; + aHash[iKey] = (ht_slot)idx; + +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + /* Verify that the number of entries in the hash table exactly equals + ** the number of entries in the mapping region. + */ + { + int i; /* Loop counter */ + int nEntry = 0; /* Number of entries in the hash table */ + for(i=0; i<HASHTABLE_NSLOT; i++){ if( aHash[i] ) nEntry++; } + assert( nEntry==idx ); + } + + /* Verify that the every entry in the mapping region is reachable + ** via the hash table. This turns out to be a really, really expensive + ** thing to check, so only do this occasionally - not on every + ** iteration. + */ + if( (idx&0x3ff)==0 ){ + int i; /* Loop counter */ + for(i=1; i<=idx; i++){ + for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){ + if( aHash[iKey]==i ) break; + } + assert( aHash[iKey]==i ); + } + } +#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */ + } + + + return rc; +} + + +/* +** Recover the wal-index by reading the write-ahead log file. +** +** This routine first tries to establish an exclusive lock on the +** wal-index to prevent other threads/processes from doing anything +** with the WAL or wal-index while recovery is running. The +** WAL_RECOVER_LOCK is also held so that other threads will know +** that this thread is running recovery. If unable to establish +** the necessary locks, this routine returns SQLITE_BUSY. +*/ +static int walIndexRecover(Wal *pWal){ + int rc; /* Return Code */ + i64 nSize; /* Size of log file */ + u32 aFrameCksum[2] = {0, 0}; + int iLock; /* Lock offset to lock for checkpoint */ + int nLock; /* Number of locks to hold */ + + /* Obtain an exclusive lock on all byte in the locking range not already + ** locked by the caller. The caller is guaranteed to have locked the + ** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte. + ** If successful, the same bytes that are locked here are unlocked before + ** this function returns. + */ + assert( pWal->ckptLock==1 || pWal->ckptLock==0 ); + assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 ); + assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE ); + assert( pWal->writeLock ); + iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; + nLock = SQLITE_SHM_NLOCK - iLock; + rc = walLockExclusive(pWal, iLock, nLock); + if( rc ){ + return rc; + } + WALTRACE(("WAL%p: recovery begin...\n", pWal)); + + memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); + + rc = sqlite3OsFileSize(pWal->pWalFd, &nSize); + if( rc!=SQLITE_OK ){ + goto recovery_error; + } + + if( nSize>WAL_HDRSIZE ){ + u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */ + u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */ + int szFrame; /* Number of bytes in buffer aFrame[] */ + u8 *aData; /* Pointer to data part of aFrame buffer */ + int iFrame; /* Index of last frame read */ + i64 iOffset; /* Next offset to read from log file */ + int szPage; /* Page size according to the log */ + u32 magic; /* Magic value read from WAL header */ + u32 version; /* Magic value read from WAL header */ + + /* Read in the WAL header. */ + rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); + if( rc!=SQLITE_OK ){ + goto recovery_error; + } + + /* If the database page size is not a power of two, or is greater than + ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid + ** data. Similarly, if the 'magic' value is invalid, ignore the whole + ** WAL file. + */ + magic = sqlite3Get4byte(&aBuf[0]); + szPage = sqlite3Get4byte(&aBuf[8]); + if( (magic&0xFFFFFFFE)!=WAL_MAGIC + || szPage&(szPage-1) + || szPage>SQLITE_MAX_PAGE_SIZE + || szPage<512 + ){ + goto finished; + } + pWal->hdr.bigEndCksum = (u8)(magic&0x00000001); + pWal->szPage = szPage; + pWal->nCkpt = sqlite3Get4byte(&aBuf[12]); + memcpy(&pWal->hdr.aSalt, &aBuf[16], 8); + + /* Verify that the WAL header checksum is correct */ + walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, + aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum + ); + if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24]) + || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28]) + ){ + goto finished; + } + + /* Verify that the version number on the WAL format is one that + ** are able to understand */ + version = sqlite3Get4byte(&aBuf[4]); + if( version!=WAL_MAX_VERSION ){ + rc = SQLITE_CANTOPEN_BKPT; + goto finished; + } + + /* Malloc a buffer to read frames into. */ + szFrame = szPage + WAL_FRAME_HDRSIZE; + aFrame = (u8 *)sqlite3_malloc(szFrame); + if( !aFrame ){ + rc = SQLITE_NOMEM; + goto recovery_error; + } + aData = &aFrame[WAL_FRAME_HDRSIZE]; + + /* Read all frames from the log file. */ + iFrame = 0; + for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){ + u32 pgno; /* Database page number for frame */ + u32 nTruncate; /* dbsize field from frame header */ + int isValid; /* True if this frame is valid */ + + /* Read and decode the next log frame. */ + rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); + if( rc!=SQLITE_OK ) break; + isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame); + if( !isValid ) break; + rc = walIndexAppend(pWal, ++iFrame, pgno); + if( rc!=SQLITE_OK ) break; + + /* If nTruncate is non-zero, this is a commit record. */ + if( nTruncate ){ + pWal->hdr.mxFrame = iFrame; + pWal->hdr.nPage = nTruncate; + pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16)); + testcase( szPage<=32768 ); + testcase( szPage>=65536 ); + aFrameCksum[0] = pWal->hdr.aFrameCksum[0]; + aFrameCksum[1] = pWal->hdr.aFrameCksum[1]; + } + } + + sqlite3_free(aFrame); + } + +finished: + if( rc==SQLITE_OK ){ + volatile WalCkptInfo *pInfo; + int i; + pWal->hdr.aFrameCksum[0] = aFrameCksum[0]; + pWal->hdr.aFrameCksum[1] = aFrameCksum[1]; + walIndexWriteHdr(pWal); + + /* Reset the checkpoint-header. This is safe because this thread is + ** currently holding locks that exclude all other readers, writers and + ** checkpointers. + */ + pInfo = walCkptInfo(pWal); + pInfo->nBackfill = 0; + pInfo->aReadMark[0] = 0; + for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED; + + /* If more than one frame was recovered from the log file, report an + ** event via sqlite3_log(). This is to help with identifying performance + ** problems caused by applications routinely shutting down without + ** checkpointing the log file. + */ + if( pWal->hdr.nPage ){ + sqlite3_log(SQLITE_OK, "Recovered %d frames from WAL file %s", + pWal->hdr.nPage, pWal->zWalName + ); + } + } + +recovery_error: + WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok")); + walUnlockExclusive(pWal, iLock, nLock); + return rc; +} + +/* +** Close an open wal-index. +*/ +static void walIndexClose(Wal *pWal, int isDelete){ + if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ + int i; + for(i=0; i<pWal->nWiData; i++){ + sqlite3_free((void *)pWal->apWiData[i]); + pWal->apWiData[i] = 0; + } + }else{ + sqlite3OsShmUnmap(pWal->pDbFd, isDelete); + } +} + +/* +** Open a connection to the WAL file zWalName. The database file must +** already be opened on connection pDbFd. The buffer that zWalName points +** to must remain valid for the lifetime of the returned Wal* handle. +** +** A SHARED lock should be held on the database file when this function +** is called. The purpose of this SHARED lock is to prevent any other +** client from unlinking the WAL or wal-index file. If another process +** were to do this just after this client opened one of these files, the +** system would be badly broken. +** +** If the log file is successfully opened, SQLITE_OK is returned and +** *ppWal is set to point to a new WAL handle. If an error occurs, +** an SQLite error code is returned and *ppWal is left unmodified. +*/ +SQLITE_PRIVATE int sqlite3WalOpen( + sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */ + sqlite3_file *pDbFd, /* The open database file */ + const char *zWalName, /* Name of the WAL file */ + int bNoShm, /* True to run in heap-memory mode */ + i64 mxWalSize, /* Truncate WAL to this size on reset */ + Wal **ppWal /* OUT: Allocated Wal handle */ +){ + int rc; /* Return Code */ + Wal *pRet; /* Object to allocate and return */ + int flags; /* Flags passed to OsOpen() */ + + assert( zWalName && zWalName[0] ); + assert( pDbFd ); + + /* In the amalgamation, the os_unix.c and os_win.c source files come before + ** this source file. Verify that the #defines of the locking byte offsets + ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value. + */ +#ifdef WIN_SHM_BASE + assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET ); +#endif +#ifdef UNIX_SHM_BASE + assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET ); +#endif + + + /* Allocate an instance of struct Wal to return. */ + *ppWal = 0; + pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile); + if( !pRet ){ + return SQLITE_NOMEM; + } + + pRet->pVfs = pVfs; + pRet->pWalFd = (sqlite3_file *)&pRet[1]; + pRet->pDbFd = pDbFd; + pRet->readLock = -1; + pRet->mxWalSize = mxWalSize; + pRet->zWalName = zWalName; + pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); + + /* Open file handle on the write-ahead log file. */ + flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); + rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); + if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){ + pRet->readOnly = WAL_RDONLY; + } + + if( rc!=SQLITE_OK ){ + walIndexClose(pRet, 0); + sqlite3OsClose(pRet->pWalFd); + sqlite3_free(pRet); + }else{ + *ppWal = pRet; + WALTRACE(("WAL%d: opened\n", pRet)); + } + return rc; +} + +/* +** Change the size to which the WAL file is trucated on each reset. +*/ +SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){ + if( pWal ) pWal->mxWalSize = iLimit; +} + +/* +** Find the smallest page number out of all pages held in the WAL that +** has not been returned by any prior invocation of this method on the +** same WalIterator object. Write into *piFrame the frame index where +** that page was last written into the WAL. Write into *piPage the page +** number. +** +** Return 0 on success. If there are no pages in the WAL with a page +** number larger than *piPage, then return 1. +*/ +static int walIteratorNext( + WalIterator *p, /* Iterator */ + u32 *piPage, /* OUT: The page number of the next page */ + u32 *piFrame /* OUT: Wal frame index of next page */ +){ + u32 iMin; /* Result pgno must be greater than iMin */ + u32 iRet = 0xFFFFFFFF; /* 0xffffffff is never a valid page number */ + int i; /* For looping through segments */ + + iMin = p->iPrior; + assert( iMin<0xffffffff ); + for(i=p->nSegment-1; i>=0; i--){ + struct WalSegment *pSegment = &p->aSegment[i]; + while( pSegment->iNext<pSegment->nEntry ){ + u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]]; + if( iPg>iMin ){ + if( iPg<iRet ){ + iRet = iPg; + *piFrame = pSegment->iZero + pSegment->aIndex[pSegment->iNext]; + } + break; + } + pSegment->iNext++; + } + } + + *piPage = p->iPrior = iRet; + return (iRet==0xFFFFFFFF); +} + +/* +** This function merges two sorted lists into a single sorted list. +** +** aLeft[] and aRight[] are arrays of indices. The sort key is +** aContent[aLeft[]] and aContent[aRight[]]. Upon entry, the following +** is guaranteed for all J<K: +** +** aContent[aLeft[J]] < aContent[aLeft[K]] +** aContent[aRight[J]] < aContent[aRight[K]] +** +** This routine overwrites aRight[] with a new (probably longer) sequence +** of indices such that the aRight[] contains every index that appears in +** either aLeft[] or the old aRight[] and such that the second condition +** above is still met. +** +** The aContent[aLeft[X]] values will be unique for all X. And the +** aContent[aRight[X]] values will be unique too. But there might be +** one or more combinations of X and Y such that +** +** aLeft[X]!=aRight[Y] && aContent[aLeft[X]] == aContent[aRight[Y]] +** +** When that happens, omit the aLeft[X] and use the aRight[Y] index. +*/ +static void walMerge( + const u32 *aContent, /* Pages in wal - keys for the sort */ + ht_slot *aLeft, /* IN: Left hand input list */ + int nLeft, /* IN: Elements in array *paLeft */ + ht_slot **paRight, /* IN/OUT: Right hand input list */ + int *pnRight, /* IN/OUT: Elements in *paRight */ + ht_slot *aTmp /* Temporary buffer */ +){ + int iLeft = 0; /* Current index in aLeft */ + int iRight = 0; /* Current index in aRight */ + int iOut = 0; /* Current index in output buffer */ + int nRight = *pnRight; + ht_slot *aRight = *paRight; + + assert( nLeft>0 && nRight>0 ); + while( iRight<nRight || iLeft<nLeft ){ + ht_slot logpage; + Pgno dbpage; + + if( (iLeft<nLeft) + && (iRight>=nRight || aContent[aLeft[iLeft]]<aContent[aRight[iRight]]) + ){ + logpage = aLeft[iLeft++]; + }else{ + logpage = aRight[iRight++]; + } + dbpage = aContent[logpage]; + + aTmp[iOut++] = logpage; + if( iLeft<nLeft && aContent[aLeft[iLeft]]==dbpage ) iLeft++; + + assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage ); + assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage ); + } + + *paRight = aLeft; + *pnRight = iOut; + memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut); +} + +/* +** Sort the elements in list aList using aContent[] as the sort key. +** Remove elements with duplicate keys, preferring to keep the +** larger aList[] values. +** +** The aList[] entries are indices into aContent[]. The values in +** aList[] are to be sorted so that for all J<K: +** +** aContent[aList[J]] < aContent[aList[K]] +** +** For any X and Y such that +** +** aContent[aList[X]] == aContent[aList[Y]] +** +** Keep the larger of the two values aList[X] and aList[Y] and discard +** the smaller. +*/ +static void walMergesort( + const u32 *aContent, /* Pages in wal */ + ht_slot *aBuffer, /* Buffer of at least *pnList items to use */ + ht_slot *aList, /* IN/OUT: List to sort */ + int *pnList /* IN/OUT: Number of elements in aList[] */ +){ + struct Sublist { + int nList; /* Number of elements in aList */ + ht_slot *aList; /* Pointer to sub-list content */ + }; + + const int nList = *pnList; /* Size of input list */ + int nMerge = 0; /* Number of elements in list aMerge */ + ht_slot *aMerge = 0; /* List to be merged */ + int iList; /* Index into input list */ + int iSub = 0; /* Index into aSub array */ + struct Sublist aSub[13]; /* Array of sub-lists */ + + memset(aSub, 0, sizeof(aSub)); + assert( nList<=HASHTABLE_NPAGE && nList>0 ); + assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) ); + + for(iList=0; iList<nList; iList++){ + nMerge = 1; + aMerge = &aList[iList]; + for(iSub=0; iList & (1<<iSub); iSub++){ + struct Sublist *p = &aSub[iSub]; + assert( p->aList && p->nList<=(1<<iSub) ); + assert( p->aList==&aList[iList&~((2<<iSub)-1)] ); + walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer); + } + aSub[iSub].aList = aMerge; + aSub[iSub].nList = nMerge; + } + + for(iSub++; iSub<ArraySize(aSub); iSub++){ + if( nList & (1<<iSub) ){ + struct Sublist *p = &aSub[iSub]; + assert( p->nList<=(1<<iSub) ); + assert( p->aList==&aList[nList&~((2<<iSub)-1)] ); + walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer); + } + } + assert( aMerge==aList ); + *pnList = nMerge; + +#ifdef SQLITE_DEBUG + { + int i; + for(i=1; i<*pnList; i++){ + assert( aContent[aList[i]] > aContent[aList[i-1]] ); + } + } +#endif +} + +/* +** Free an iterator allocated by walIteratorInit(). +*/ +static void walIteratorFree(WalIterator *p){ + sqlite3ScratchFree(p); +} + +/* +** Construct a WalInterator object that can be used to loop over all +** pages in the WAL in ascending order. The caller must hold the checkpoint +** lock. +** +** On success, make *pp point to the newly allocated WalInterator object +** return SQLITE_OK. Otherwise, return an error code. If this routine +** returns an error, the value of *pp is undefined. +** +** The calling routine should invoke walIteratorFree() to destroy the +** WalIterator object when it has finished with it. +*/ +static int walIteratorInit(Wal *pWal, WalIterator **pp){ + WalIterator *p; /* Return value */ + int nSegment; /* Number of segments to merge */ + u32 iLast; /* Last frame in log */ + int nByte; /* Number of bytes to allocate */ + int i; /* Iterator variable */ + ht_slot *aTmp; /* Temp space used by merge-sort */ + int rc = SQLITE_OK; /* Return Code */ + + /* This routine only runs while holding the checkpoint lock. And + ** it only runs if there is actually content in the log (mxFrame>0). + */ + assert( pWal->ckptLock && pWal->hdr.mxFrame>0 ); + iLast = pWal->hdr.mxFrame; + + /* Allocate space for the WalIterator object. */ + nSegment = walFramePage(iLast) + 1; + nByte = sizeof(WalIterator) + + (nSegment-1)*sizeof(struct WalSegment) + + iLast*sizeof(ht_slot); + p = (WalIterator *)sqlite3ScratchMalloc(nByte); + if( !p ){ + return SQLITE_NOMEM; + } + memset(p, 0, nByte); + p->nSegment = nSegment; + + /* Allocate temporary space used by the merge-sort routine. This block + ** of memory will be freed before this function returns. + */ + aTmp = (ht_slot *)sqlite3ScratchMalloc( + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) + ); + if( !aTmp ){ + rc = SQLITE_NOMEM; + } + + for(i=0; rc==SQLITE_OK && i<nSegment; i++){ + volatile ht_slot *aHash; + u32 iZero; + volatile u32 *aPgno; + + rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero); + if( rc==SQLITE_OK ){ + int j; /* Counter variable */ + int nEntry; /* Number of entries in this segment */ + ht_slot *aIndex; /* Sorted index for this segment */ + + aPgno++; + if( (i+1)==nSegment ){ + nEntry = (int)(iLast - iZero); + }else{ + nEntry = (int)((u32*)aHash - (u32*)aPgno); + } + aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero]; + iZero++; + + for(j=0; j<nEntry; j++){ + aIndex[j] = (ht_slot)j; + } + walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry); + p->aSegment[i].iZero = iZero; + p->aSegment[i].nEntry = nEntry; + p->aSegment[i].aIndex = aIndex; + p->aSegment[i].aPgno = (u32 *)aPgno; + } + } + sqlite3ScratchFree(aTmp); + + if( rc!=SQLITE_OK ){ + walIteratorFree(p); + } + *pp = p; + return rc; +} + +/* +** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and +** n. If the attempt fails and parameter xBusy is not NULL, then it is a +** busy-handler function. Invoke it and retry the lock until either the +** lock is successfully obtained or the busy-handler returns 0. +*/ +static int walBusyLock( + Wal *pWal, /* WAL connection */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int lockIdx, /* Offset of first byte to lock */ + int n /* Number of bytes to lock */ +){ + int rc; + do { + rc = walLockExclusive(pWal, lockIdx, n); + }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) ); + return rc; +} + +/* +** The cache of the wal-index header must be valid to call this function. +** Return the page-size in bytes used by the database. +*/ +static int walPagesize(Wal *pWal){ + return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); +} + +/* +** Copy as much content as we can from the WAL back into the database file +** in response to an sqlite3_wal_checkpoint() request or the equivalent. +** +** The amount of information copies from WAL to database might be limited +** by active readers. This routine will never overwrite a database page +** that a concurrent reader might be using. +** +** All I/O barrier operations (a.k.a fsyncs) occur in this routine when +** SQLite is in WAL-mode in synchronous=NORMAL. That means that if +** checkpoints are always run by a background thread or background +** process, foreground threads will never block on a lengthy fsync call. +** +** Fsync is called on the WAL before writing content out of the WAL and +** into the database. This ensures that if the new content is persistent +** in the WAL and can be recovered following a power-loss or hard reset. +** +** Fsync is also called on the database file if (and only if) the entire +** WAL content is copied into the database file. This second fsync makes +** it safe to delete the WAL since the new content will persist in the +** database file. +** +** This routine uses and updates the nBackfill field of the wal-index header. +** This is the only routine tha will increase the value of nBackfill. +** (A WAL reset or recovery will revert nBackfill to zero, but not increase +** its value.) +** +** The caller must be holding sufficient locks to ensure that no other +** checkpoint is running (in any other thread or process) at the same +** time. +*/ +static int walCheckpoint( + Wal *pWal, /* Wal connection */ + int eMode, /* One of PASSIVE, FULL or RESTART */ + int (*xBusyCall)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags for OsSync() (or 0) */ + u8 *zBuf /* Temporary buffer to use */ +){ + int rc; /* Return code */ + int szPage; /* Database page-size */ + WalIterator *pIter = 0; /* Wal iterator context */ + u32 iDbpage = 0; /* Next database page to write */ + u32 iFrame = 0; /* Wal frame containing data for iDbpage */ + u32 mxSafeFrame; /* Max frame that can be backfilled */ + u32 mxPage; /* Max database page to write */ + int i; /* Loop counter */ + volatile WalCkptInfo *pInfo; /* The checkpoint status information */ + int (*xBusy)(void*) = 0; /* Function to call when waiting for locks */ + + szPage = walPagesize(pWal); + testcase( szPage<=32768 ); + testcase( szPage>=65536 ); + pInfo = walCkptInfo(pWal); + if( pInfo->nBackfill>=pWal->hdr.mxFrame ) return SQLITE_OK; + + /* Allocate the iterator */ + rc = walIteratorInit(pWal, &pIter); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( pIter ); + + if( eMode!=SQLITE_CHECKPOINT_PASSIVE ) xBusy = xBusyCall; + + /* Compute in mxSafeFrame the index of the last frame of the WAL that is + ** safe to write into the database. Frames beyond mxSafeFrame might + ** overwrite database pages that are in use by active readers and thus + ** cannot be backfilled from the WAL. + */ + mxSafeFrame = pWal->hdr.mxFrame; + mxPage = pWal->hdr.nPage; + for(i=1; i<WAL_NREADER; i++){ + u32 y = pInfo->aReadMark[i]; + if( mxSafeFrame>y ){ + assert( y<=pWal->hdr.mxFrame ); + rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); + if( rc==SQLITE_OK ){ + pInfo->aReadMark[i] = READMARK_NOT_USED; + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + }else if( rc==SQLITE_BUSY ){ + mxSafeFrame = y; + xBusy = 0; + }else{ + goto walcheckpoint_out; + } + } + } + + if( pInfo->nBackfill<mxSafeFrame + && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0), 1))==SQLITE_OK + ){ + i64 nSize; /* Current size of database file */ + u32 nBackfill = pInfo->nBackfill; + + /* Sync the WAL to disk */ + if( sync_flags ){ + rc = sqlite3OsSync(pWal->pWalFd, sync_flags); + } + + /* If the database file may grow as a result of this checkpoint, hint + ** about the eventual size of the db file to the VFS layer. + */ + if( rc==SQLITE_OK ){ + i64 nReq = ((i64)mxPage * szPage); + rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); + if( rc==SQLITE_OK && nSize<nReq ){ + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); + } + } + + /* Iterate through the contents of the WAL, copying data to the db file. */ + while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ + i64 iOffset; + assert( walFramePgno(pWal, iFrame)==iDbpage ); + if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ) continue; + iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE; + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */ + rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset); + if( rc!=SQLITE_OK ) break; + iOffset = (iDbpage-1)*(i64)szPage; + testcase( IS_BIG_INT(iOffset) ); + rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset); + if( rc!=SQLITE_OK ) break; + } + + /* If work was actually accomplished... */ + if( rc==SQLITE_OK ){ + if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){ + i64 szDb = pWal->hdr.nPage*(i64)szPage; + testcase( IS_BIG_INT(szDb) ); + rc = sqlite3OsTruncate(pWal->pDbFd, szDb); + if( rc==SQLITE_OK && sync_flags ){ + rc = sqlite3OsSync(pWal->pDbFd, sync_flags); + } + } + if( rc==SQLITE_OK ){ + pInfo->nBackfill = mxSafeFrame; + } + } + + /* Release the reader lock held while backfilling */ + walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1); + } + + if( rc==SQLITE_BUSY ){ + /* Reset the return code so as not to report a checkpoint failure + ** just because there are active readers. */ + rc = SQLITE_OK; + } + + /* If this is an SQLITE_CHECKPOINT_RESTART operation, and the entire wal + ** file has been copied into the database file, then block until all + ** readers have finished using the wal file. This ensures that the next + ** process to write to the database restarts the wal file. + */ + if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ + assert( pWal->writeLock ); + if( pInfo->nBackfill<pWal->hdr.mxFrame ){ + rc = SQLITE_BUSY; + }else if( eMode==SQLITE_CHECKPOINT_RESTART ){ + assert( mxSafeFrame==pWal->hdr.mxFrame ); + rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1); + if( rc==SQLITE_OK ){ + walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + } + } + } + + walcheckpoint_out: + walIteratorFree(pIter); + return rc; +} + +/* +** Close a connection to a log file. +*/ +SQLITE_PRIVATE int sqlite3WalClose( + Wal *pWal, /* Wal to close */ + int sync_flags, /* Flags to pass to OsSync() (or 0) */ + int nBuf, + u8 *zBuf /* Buffer of at least nBuf bytes */ +){ + int rc = SQLITE_OK; + if( pWal ){ + int isDelete = 0; /* True to unlink wal and wal-index files */ + + /* If an EXCLUSIVE lock can be obtained on the database file (using the + ** ordinary, rollback-mode locking methods, this guarantees that the + ** connection associated with this log file is the only connection to + ** the database. In this case checkpoint the database and unlink both + ** the wal and wal-index files. + ** + ** The EXCLUSIVE lock is not released before returning. + */ + rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE); + if( rc==SQLITE_OK ){ + int bPersistWal = -1; + if( pWal->exclusiveMode==WAL_NORMAL_MODE ){ + pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; + } + rc = sqlite3WalCheckpoint( + pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0 + ); + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersistWal); + if( rc==SQLITE_OK && bPersistWal!=1 ){ + isDelete = 1; + } + } + + walIndexClose(pWal, isDelete); + sqlite3OsClose(pWal->pWalFd); + if( isDelete ){ + sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0); + } + WALTRACE(("WAL%p: closed\n", pWal)); + sqlite3_free((void *)pWal->apWiData); + sqlite3_free(pWal); + } + return rc; +} + +/* +** Try to read the wal-index header. Return 0 on success and 1 if +** there is a problem. +** +** The wal-index is in shared memory. Another thread or process might +** be writing the header at the same time this procedure is trying to +** read it, which might result in inconsistency. A dirty read is detected +** by verifying that both copies of the header are the same and also by +** a checksum on the header. +** +** If and only if the read is consistent and the header is different from +** pWal->hdr, then pWal->hdr is updated to the content of the new header +** and *pChanged is set to 1. +** +** If the checksum cannot be verified return non-zero. If the header +** is read successfully and the checksum verified, return zero. +*/ +static int walIndexTryHdr(Wal *pWal, int *pChanged){ + u32 aCksum[2]; /* Checksum on the header content */ + WalIndexHdr h1, h2; /* Two copies of the header content */ + WalIndexHdr volatile *aHdr; /* Header in shared memory */ + + /* The first page of the wal-index must be mapped at this point. */ + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + + /* Read the header. This might happen concurrently with a write to the + ** same area of shared memory on a different CPU in a SMP, + ** meaning it is possible that an inconsistent snapshot is read + ** from the file. If this happens, return non-zero. + ** + ** There are two copies of the header at the beginning of the wal-index. + ** When reading, read [0] first then [1]. Writes are in the reverse order. + ** Memory barriers are used to prevent the compiler or the hardware from + ** reordering the reads and writes. + */ + aHdr = walIndexHdr(pWal); + memcpy(&h1, (void *)&aHdr[0], sizeof(h1)); + walShmBarrier(pWal); + memcpy(&h2, (void *)&aHdr[1], sizeof(h2)); + + if( memcmp(&h1, &h2, sizeof(h1))!=0 ){ + return 1; /* Dirty read */ + } + if( h1.isInit==0 ){ + return 1; /* Malformed header - probably all zeros */ + } + walChecksumBytes(1, (u8*)&h1, sizeof(h1)-sizeof(h1.aCksum), 0, aCksum); + if( aCksum[0]!=h1.aCksum[0] || aCksum[1]!=h1.aCksum[1] ){ + return 1; /* Checksum does not match */ + } + + if( memcmp(&pWal->hdr, &h1, sizeof(WalIndexHdr)) ){ + *pChanged = 1; + memcpy(&pWal->hdr, &h1, sizeof(WalIndexHdr)); + pWal->szPage = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); + testcase( pWal->szPage<=32768 ); + testcase( pWal->szPage>=65536 ); + } + + /* The header was successfully read. Return zero. */ + return 0; +} + +/* +** Read the wal-index header from the wal-index and into pWal->hdr. +** If the wal-header appears to be corrupt, try to reconstruct the +** wal-index from the WAL before returning. +** +** Set *pChanged to 1 if the wal-index header value in pWal->hdr is +** changed by this opertion. If pWal->hdr is unchanged, set *pChanged +** to 0. +** +** If the wal-index header is successfully read, return SQLITE_OK. +** Otherwise an SQLite error code. +*/ +static int walIndexReadHdr(Wal *pWal, int *pChanged){ + int rc; /* Return code */ + int badHdr; /* True if a header read failed */ + volatile u32 *page0; /* Chunk of wal-index containing header */ + + /* Ensure that page 0 of the wal-index (the page that contains the + ** wal-index header) is mapped. Return early if an error occurs here. + */ + assert( pChanged ); + rc = walIndexPage(pWal, 0, &page0); + if( rc!=SQLITE_OK ){ + return rc; + }; + assert( page0 || pWal->writeLock==0 ); + + /* If the first page of the wal-index has been mapped, try to read the + ** wal-index header immediately, without holding any lock. This usually + ** works, but may fail if the wal-index header is corrupt or currently + ** being modified by another thread or process. + */ + badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1); + + /* If the first attempt failed, it might have been due to a race + ** with a writer. So get a WRITE lock and try again. + */ + assert( badHdr==0 || pWal->writeLock==0 ); + if( badHdr ){ + if( pWal->readOnly & WAL_SHM_RDONLY ){ + if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ + walUnlockShared(pWal, WAL_WRITE_LOCK); + rc = SQLITE_READONLY_RECOVERY; + } + }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ + pWal->writeLock = 1; + if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ + badHdr = walIndexTryHdr(pWal, pChanged); + if( badHdr ){ + /* If the wal-index header is still malformed even while holding + ** a WRITE lock, it can only mean that the header is corrupted and + ** needs to be reconstructed. So run recovery to do exactly that. + */ + rc = walIndexRecover(pWal); + *pChanged = 1; + } + } + pWal->writeLock = 0; + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + } + } + + /* If the header is read successfully, check the version number to make + ** sure the wal-index was not constructed with some future format that + ** this version of SQLite cannot understand. + */ + if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){ + rc = SQLITE_CANTOPEN_BKPT; + } + + return rc; +} + +/* +** This is the value that walTryBeginRead returns when it needs to +** be retried. +*/ +#define WAL_RETRY (-1) + +/* +** Attempt to start a read transaction. This might fail due to a race or +** other transient condition. When that happens, it returns WAL_RETRY to +** indicate to the caller that it is safe to retry immediately. +** +** On success return SQLITE_OK. On a permanent failure (such an +** I/O error or an SQLITE_BUSY because another process is running +** recovery) return a positive error code. +** +** The useWal parameter is true to force the use of the WAL and disable +** the case where the WAL is bypassed because it has been completely +** checkpointed. If useWal==0 then this routine calls walIndexReadHdr() +** to make a copy of the wal-index header into pWal->hdr. If the +** wal-index header has changed, *pChanged is set to 1 (as an indication +** to the caller that the local paget cache is obsolete and needs to be +** flushed.) When useWal==1, the wal-index header is assumed to already +** be loaded and the pChanged parameter is unused. +** +** The caller must set the cnt parameter to the number of prior calls to +** this routine during the current read attempt that returned WAL_RETRY. +** This routine will start taking more aggressive measures to clear the +** race conditions after multiple WAL_RETRY returns, and after an excessive +** number of errors will ultimately return SQLITE_PROTOCOL. The +** SQLITE_PROTOCOL return indicates that some other process has gone rogue +** and is not honoring the locking protocol. There is a vanishingly small +** chance that SQLITE_PROTOCOL could be returned because of a run of really +** bad luck when there is lots of contention for the wal-index, but that +** possibility is so small that it can be safely neglected, we believe. +** +** On success, this routine obtains a read lock on +** WAL_READ_LOCK(pWal->readLock). The pWal->readLock integer is +** in the range 0 <= pWal->readLock < WAL_NREADER. If pWal->readLock==(-1) +** that means the Wal does not hold any read lock. The reader must not +** access any database page that is modified by a WAL frame up to and +** including frame number aReadMark[pWal->readLock]. The reader will +** use WAL frames up to and including pWal->hdr.mxFrame if pWal->readLock>0 +** Or if pWal->readLock==0, then the reader will ignore the WAL +** completely and get all content directly from the database file. +** If the useWal parameter is 1 then the WAL will never be ignored and +** this routine will always set pWal->readLock>0 on success. +** When the read transaction is completed, the caller must release the +** lock on WAL_READ_LOCK(pWal->readLock) and set pWal->readLock to -1. +** +** This routine uses the nBackfill and aReadMark[] fields of the header +** to select a particular WAL_READ_LOCK() that strives to let the +** checkpoint process do as much work as possible. This routine might +** update values of the aReadMark[] array in the header, but if it does +** so it takes care to hold an exclusive lock on the corresponding +** WAL_READ_LOCK() while changing values. +*/ +static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ + volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ + u32 mxReadMark; /* Largest aReadMark[] value */ + int mxI; /* Index of largest aReadMark[] value */ + int i; /* Loop counter */ + int rc = SQLITE_OK; /* Return code */ + + assert( pWal->readLock<0 ); /* Not currently locked */ + + /* Take steps to avoid spinning forever if there is a protocol error. + ** + ** Circumstances that cause a RETRY should only last for the briefest + ** instances of time. No I/O or other system calls are done while the + ** locks are held, so the locks should not be held for very long. But + ** if we are unlucky, another process that is holding a lock might get + ** paged out or take a page-fault that is time-consuming to resolve, + ** during the few nanoseconds that it is holding the lock. In that case, + ** it might take longer than normal for the lock to free. + ** + ** After 5 RETRYs, we begin calling sqlite3OsSleep(). The first few + ** calls to sqlite3OsSleep() have a delay of 1 microsecond. Really this + ** is more of a scheduler yield than an actual delay. But on the 10th + ** an subsequent retries, the delays start becoming longer and longer, + ** so that on the 100th (and last) RETRY we delay for 21 milliseconds. + ** The total delay time before giving up is less than 1 second. + */ + if( cnt>5 ){ + int nDelay = 1; /* Pause time in microseconds */ + if( cnt>100 ){ + VVA_ONLY( pWal->lockError = 1; ) + return SQLITE_PROTOCOL; + } + if( cnt>=10 ) nDelay = (cnt-9)*238; /* Max delay 21ms. Total delay 996ms */ + sqlite3OsSleep(pWal->pVfs, nDelay); + } + + if( !useWal ){ + rc = walIndexReadHdr(pWal, pChanged); + if( rc==SQLITE_BUSY ){ + /* If there is not a recovery running in another thread or process + ** then convert BUSY errors to WAL_RETRY. If recovery is known to + ** be running, convert BUSY to BUSY_RECOVERY. There is a race here + ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY + ** would be technically correct. But the race is benign since with + ** WAL_RETRY this routine will be called again and will probably be + ** right on the second iteration. + */ + if( pWal->apWiData[0]==0 ){ + /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. + ** We assume this is a transient condition, so return WAL_RETRY. The + ** xShmMap() implementation used by the default unix and win32 VFS + ** modules may return SQLITE_BUSY due to a race condition in the + ** code that determines whether or not the shared-memory region + ** must be zeroed before the requested page is returned. + */ + rc = WAL_RETRY; + }else if( SQLITE_OK==(rc = walLockShared(pWal, WAL_RECOVER_LOCK)) ){ + walUnlockShared(pWal, WAL_RECOVER_LOCK); + rc = WAL_RETRY; + }else if( rc==SQLITE_BUSY ){ + rc = SQLITE_BUSY_RECOVERY; + } + } + if( rc!=SQLITE_OK ){ + return rc; + } + } + + pInfo = walCkptInfo(pWal); + if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame ){ + /* The WAL has been completely backfilled (or it is empty). + ** and can be safely ignored. + */ + rc = walLockShared(pWal, WAL_READ_LOCK(0)); + walShmBarrier(pWal); + if( rc==SQLITE_OK ){ + if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){ + /* It is not safe to allow the reader to continue here if frames + ** may have been appended to the log before READ_LOCK(0) was obtained. + ** When holding READ_LOCK(0), the reader ignores the entire log file, + ** which implies that the database file contains a trustworthy + ** snapshoT. Since holding READ_LOCK(0) prevents a checkpoint from + ** happening, this is usually correct. + ** + ** However, if frames have been appended to the log (or if the log + ** is wrapped and written for that matter) before the READ_LOCK(0) + ** is obtained, that is not necessarily true. A checkpointer may + ** have started to backfill the appended frames but crashed before + ** it finished. Leaving a corrupt image in the database file. + */ + walUnlockShared(pWal, WAL_READ_LOCK(0)); + return WAL_RETRY; + } + pWal->readLock = 0; + return SQLITE_OK; + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + + /* If we get this far, it means that the reader will want to use + ** the WAL to get at content from recent commits. The job now is + ** to select one of the aReadMark[] entries that is closest to + ** but not exceeding pWal->hdr.mxFrame and lock that entry. + */ + mxReadMark = 0; + mxI = 0; + for(i=1; i<WAL_NREADER; i++){ + u32 thisMark = pInfo->aReadMark[i]; + if( mxReadMark<=thisMark && thisMark<=pWal->hdr.mxFrame ){ + assert( thisMark!=READMARK_NOT_USED ); + mxReadMark = thisMark; + mxI = i; + } + } + /* There was once an "if" here. The extra "{" is to preserve indentation. */ + { + if( (pWal->readOnly & WAL_SHM_RDONLY)==0 + && (mxReadMark<pWal->hdr.mxFrame || mxI==0) + ){ + for(i=1; i<WAL_NREADER; i++){ + rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); + if( rc==SQLITE_OK ){ + mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame; + mxI = i; + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + break; + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + } + if( mxI==0 ){ + assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); + return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; + } + + rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); + if( rc ){ + return rc==SQLITE_BUSY ? WAL_RETRY : rc; + } + /* Now that the read-lock has been obtained, check that neither the + ** value in the aReadMark[] array or the contents of the wal-index + ** header have changed. + ** + ** It is necessary to check that the wal-index header did not change + ** between the time it was read and when the shared-lock was obtained + ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility + ** that the log file may have been wrapped by a writer, or that frames + ** that occur later in the log than pWal->hdr.mxFrame may have been + ** copied into the database by a checkpointer. If either of these things + ** happened, then reading the database with the current value of + ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry + ** instead. + ** + ** This does not guarantee that the copy of the wal-index header is up to + ** date before proceeding. That would not be possible without somehow + ** blocking writers. It only guarantees that a dangerous checkpoint or + ** log-wrap (either of which would require an exclusive lock on + ** WAL_READ_LOCK(mxI)) has not occurred since the snapshot was valid. + */ + walShmBarrier(pWal); + if( pInfo->aReadMark[mxI]!=mxReadMark + || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) + ){ + walUnlockShared(pWal, WAL_READ_LOCK(mxI)); + return WAL_RETRY; + }else{ + assert( mxReadMark<=pWal->hdr.mxFrame ); + pWal->readLock = (i16)mxI; + } + } + return rc; +} + +/* +** Begin a read transaction on the database. +** +** This routine used to be called sqlite3OpenSnapshot() and with good reason: +** it takes a snapshot of the state of the WAL and wal-index for the current +** instant in time. The current thread will continue to use this snapshot. +** Other threads might append new content to the WAL and wal-index but +** that extra content is ignored by the current thread. +** +** If the database contents have changes since the previous read +** transaction, then *pChanged is set to 1 before returning. The +** Pager layer will use this to know that is cache is stale and +** needs to be flushed. +*/ +SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ + int rc; /* Return code */ + int cnt = 0; /* Number of TryBeginRead attempts */ + + do{ + rc = walTryBeginRead(pWal, pChanged, 0, ++cnt); + }while( rc==WAL_RETRY ); + testcase( (rc&0xff)==SQLITE_BUSY ); + testcase( (rc&0xff)==SQLITE_IOERR ); + testcase( rc==SQLITE_PROTOCOL ); + testcase( rc==SQLITE_OK ); + return rc; +} + +/* +** Finish with a read transaction. All this does is release the +** read-lock. +*/ +SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){ + sqlite3WalEndWriteTransaction(pWal); + if( pWal->readLock>=0 ){ + walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); + pWal->readLock = -1; + } +} + +/* +** Read a page from the WAL, if it is present in the WAL and if the +** current read transaction is configured to use the WAL. +** +** The *pInWal is set to 1 if the requested page is in the WAL and +** has been loaded. Or *pInWal is set to 0 if the page was not in +** the WAL and needs to be read out of the database. +*/ +SQLITE_PRIVATE int sqlite3WalRead( + Wal *pWal, /* WAL handle */ + Pgno pgno, /* Database page number to read data for */ + int *pInWal, /* OUT: True if data is read from WAL */ + int nOut, /* Size of buffer pOut in bytes */ + u8 *pOut /* Buffer to write page data to */ +){ + u32 iRead = 0; /* If !=0, WAL frame to return data from */ + u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */ + int iHash; /* Used to loop through N hash tables */ + + /* This routine is only be called from within a read transaction. */ + assert( pWal->readLock>=0 || pWal->lockError ); + + /* If the "last page" field of the wal-index header snapshot is 0, then + ** no data will be read from the wal under any circumstances. Return early + ** in this case as an optimization. Likewise, if pWal->readLock==0, + ** then the WAL is ignored by the reader so return early, as if the + ** WAL were empty. + */ + if( iLast==0 || pWal->readLock==0 ){ + *pInWal = 0; + return SQLITE_OK; + } + + /* Search the hash table or tables for an entry matching page number + ** pgno. Each iteration of the following for() loop searches one + ** hash table (each hash table indexes up to HASHTABLE_NPAGE frames). + ** + ** This code might run concurrently to the code in walIndexAppend() + ** that adds entries to the wal-index (and possibly to this hash + ** table). This means the value just read from the hash + ** slot (aHash[iKey]) may have been added before or after the + ** current read transaction was opened. Values added after the + ** read transaction was opened may have been written incorrectly - + ** i.e. these slots may contain garbage data. However, we assume + ** that any slots written before the current read transaction was + ** opened remain unmodified. + ** + ** For the reasons above, the if(...) condition featured in the inner + ** loop of the following block is more stringent that would be required + ** if we had exclusive access to the hash-table: + ** + ** (aPgno[iFrame]==pgno): + ** This condition filters out normal hash-table collisions. + ** + ** (iFrame<=iLast): + ** This condition filters out entries that were added to the hash + ** table after the current read-transaction had started. + */ + for(iHash=walFramePage(iLast); iHash>=0 && iRead==0; iHash--){ + volatile ht_slot *aHash; /* Pointer to hash table */ + volatile u32 *aPgno; /* Pointer to array of page numbers */ + u32 iZero; /* Frame number corresponding to aPgno[0] */ + int iKey; /* Hash slot index */ + int nCollide; /* Number of hash collisions remaining */ + int rc; /* Error code */ + + rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero); + if( rc!=SQLITE_OK ){ + return rc; + } + nCollide = HASHTABLE_NSLOT; + for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){ + u32 iFrame = aHash[iKey] + iZero; + if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){ + assert( iFrame>iRead ); + iRead = iFrame; + } + if( (nCollide--)==0 ){ + return SQLITE_CORRUPT_BKPT; + } + } + } + +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + /* If expensive assert() statements are available, do a linear search + ** of the wal-index file content. Make sure the results agree with the + ** result obtained using the hash indexes above. */ + { + u32 iRead2 = 0; + u32 iTest; + for(iTest=iLast; iTest>0; iTest--){ + if( walFramePgno(pWal, iTest)==pgno ){ + iRead2 = iTest; + break; + } + } + assert( iRead==iRead2 ); + } +#endif + + /* If iRead is non-zero, then it is the log frame number that contains the + ** required page. Read and return data from the log file. + */ + if( iRead ){ + int sz; + i64 iOffset; + sz = pWal->hdr.szPage; + sz = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); + testcase( sz<=32768 ); + testcase( sz>=65536 ); + iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE; + *pInWal = 1; + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ + return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset); + } + + *pInWal = 0; + return SQLITE_OK; +} + + +/* +** Return the size of the database in pages (or zero, if unknown). +*/ +SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){ + if( pWal && ALWAYS(pWal->readLock>=0) ){ + return pWal->hdr.nPage; + } + return 0; +} + + +/* +** This function starts a write transaction on the WAL. +** +** A read transaction must have already been started by a prior call +** to sqlite3WalBeginReadTransaction(). +** +** If another thread or process has written into the database since +** the read transaction was started, then it is not possible for this +** thread to write as doing so would cause a fork. So this routine +** returns SQLITE_BUSY in that case and no write transaction is started. +** +** There can only be a single writer active at a time. +*/ +SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){ + int rc; + + /* Cannot start a write transaction without first holding a read + ** transaction. */ + assert( pWal->readLock>=0 ); + + if( pWal->readOnly ){ + return SQLITE_READONLY; + } + + /* Only one writer allowed at a time. Get the write lock. Return + ** SQLITE_BUSY if unable. + */ + rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); + if( rc ){ + return rc; + } + pWal->writeLock = 1; + + /* If another connection has written to the database file since the + ** time the read transaction on this connection was started, then + ** the write is disallowed. + */ + if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){ + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + pWal->writeLock = 0; + rc = SQLITE_BUSY; + } + + return rc; +} + +/* +** End a write transaction. The commit has already been done. This +** routine merely releases the lock. +*/ +SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){ + if( pWal->writeLock ){ + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + pWal->writeLock = 0; + } + return SQLITE_OK; +} + +/* +** If any data has been written (but not committed) to the log file, this +** function moves the write-pointer back to the start of the transaction. +** +** Additionally, the callback function is invoked for each frame written +** to the WAL since the start of the transaction. If the callback returns +** other than SQLITE_OK, it is not invoked again and the error code is +** returned to the caller. +** +** Otherwise, if the callback function does not return an error, this +** function returns SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){ + int rc = SQLITE_OK; + if( ALWAYS(pWal->writeLock) ){ + Pgno iMax = pWal->hdr.mxFrame; + Pgno iFrame; + + /* Restore the clients cache of the wal-index header to the state it + ** was in before the client began writing to the database. + */ + memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr)); + + for(iFrame=pWal->hdr.mxFrame+1; + ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; + iFrame++ + ){ + /* This call cannot fail. Unless the page for which the page number + ** is passed as the second argument is (a) in the cache and + ** (b) has an outstanding reference, then xUndo is either a no-op + ** (if (a) is false) or simply expels the page from the cache (if (b) + ** is false). + ** + ** If the upper layer is doing a rollback, it is guaranteed that there + ** are no outstanding references to any page other than page 1. And + ** page 1 is never written to the log until the transaction is + ** committed. As a result, the call to xUndo may not fail. + */ + assert( walFramePgno(pWal, iFrame)!=1 ); + rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); + } + walCleanupHash(pWal); + } + assert( rc==SQLITE_OK ); + return rc; +} + +/* +** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32 +** values. This function populates the array with values required to +** "rollback" the write position of the WAL handle back to the current +** point in the event of a savepoint rollback (via WalSavepointUndo()). +*/ +SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ + assert( pWal->writeLock ); + aWalData[0] = pWal->hdr.mxFrame; + aWalData[1] = pWal->hdr.aFrameCksum[0]; + aWalData[2] = pWal->hdr.aFrameCksum[1]; + aWalData[3] = pWal->nCkpt; +} + +/* +** Move the write position of the WAL back to the point identified by +** the values in the aWalData[] array. aWalData must point to an array +** of WAL_SAVEPOINT_NDATA u32 values that has been previously populated +** by a call to WalSavepoint(). +*/ +SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ + int rc = SQLITE_OK; + + assert( pWal->writeLock ); + assert( aWalData[3]!=pWal->nCkpt || aWalData[0]<=pWal->hdr.mxFrame ); + + if( aWalData[3]!=pWal->nCkpt ){ + /* This savepoint was opened immediately after the write-transaction + ** was started. Right after that, the writer decided to wrap around + ** to the start of the log. Update the savepoint values to match. + */ + aWalData[0] = 0; + aWalData[3] = pWal->nCkpt; + } + + if( aWalData[0]<pWal->hdr.mxFrame ){ + pWal->hdr.mxFrame = aWalData[0]; + pWal->hdr.aFrameCksum[0] = aWalData[1]; + pWal->hdr.aFrameCksum[1] = aWalData[2]; + walCleanupHash(pWal); + } + + return rc; +} + +/* +** This function is called just before writing a set of frames to the log +** file (see sqlite3WalFrames()). It checks to see if, instead of appending +** to the current log file, it is possible to overwrite the start of the +** existing log file with the new frames (i.e. "reset" the log). If so, +** it sets pWal->hdr.mxFrame to 0. Otherwise, pWal->hdr.mxFrame is left +** unchanged. +** +** SQLITE_OK is returned if no error is encountered (regardless of whether +** or not pWal->hdr.mxFrame is modified). An SQLite error code is returned +** if an error occurs. +*/ +static int walRestartLog(Wal *pWal){ + int rc = SQLITE_OK; + int cnt; + + if( pWal->readLock==0 ){ + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + assert( pInfo->nBackfill==pWal->hdr.mxFrame ); + if( pInfo->nBackfill>0 ){ + u32 salt1; + sqlite3_randomness(4, &salt1); + rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + if( rc==SQLITE_OK ){ + /* If all readers are using WAL_READ_LOCK(0) (in other words if no + ** readers are currently using the WAL), then the transactions + ** frames will overwrite the start of the existing log. Update the + ** wal-index header to reflect this. + ** + ** In theory it would be Ok to update the cache of the header only + ** at this point. But updating the actual wal-index header is also + ** safe and means there is no special case for sqlite3WalUndo() + ** to handle if this transaction is rolled back. + */ + int i; /* Loop counter */ + u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */ + + /* Limit the size of WAL file if the journal_size_limit PRAGMA is + ** set to a non-negative value. Log errors encountered + ** during the truncation attempt. */ + if( pWal->mxWalSize>=0 ){ + i64 sz; + int rx; + sqlite3BeginBenignMalloc(); + rx = sqlite3OsFileSize(pWal->pWalFd, &sz); + if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){ + rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize); + } + sqlite3EndBenignMalloc(); + if( rx ){ + sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); + } + } + + pWal->nCkpt++; + pWal->hdr.mxFrame = 0; + sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); + aSalt[1] = salt1; + walIndexWriteHdr(pWal); + pInfo->nBackfill = 0; + for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED; + assert( pInfo->aReadMark[0]==0 ); + walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + walUnlockShared(pWal, WAL_READ_LOCK(0)); + pWal->readLock = -1; + cnt = 0; + do{ + int notUsed; + rc = walTryBeginRead(pWal, ¬Used, 1, ++cnt); + }while( rc==WAL_RETRY ); + assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */ + testcase( (rc&0xff)==SQLITE_IOERR ); + testcase( rc==SQLITE_PROTOCOL ); + testcase( rc==SQLITE_OK ); + } + return rc; +} + +/* +** Write a set of frames to the log. The caller must hold the write-lock +** on the log file (obtained using sqlite3WalBeginWriteTransaction()). +*/ +SQLITE_PRIVATE int sqlite3WalFrames( + Wal *pWal, /* Wal handle to write to */ + int szPage, /* Database page-size in bytes */ + PgHdr *pList, /* List of dirty pages to write */ + Pgno nTruncate, /* Database size after this commit */ + int isCommit, /* True if this is a commit */ + int sync_flags /* Flags to pass to OsSync() (or 0) */ +){ + int rc; /* Used to catch return codes */ + u32 iFrame; /* Next frame address */ + u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ + PgHdr *p; /* Iterator to run through pList with. */ + PgHdr *pLast = 0; /* Last frame in list */ + int nLast = 0; /* Number of extra copies of last page */ + + assert( pList ); + assert( pWal->writeLock ); + +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) + { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} + WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n", + pWal, cnt, pWal->hdr.mxFrame, isCommit ? "Commit" : "Spill")); + } +#endif + + /* See if it is possible to write these frames into the start of the + ** log file, instead of appending to it at pWal->hdr.mxFrame. + */ + if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){ + return rc; + } + + /* If this is the first frame written into the log, write the WAL + ** header to the start of the WAL file. See comments at the top of + ** this source file for a description of the WAL header format. + */ + iFrame = pWal->hdr.mxFrame; + if( iFrame==0 ){ + u8 aWalHdr[WAL_HDRSIZE]; /* Buffer to assemble wal-header in */ + u32 aCksum[2]; /* Checksum for wal-header */ + + sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); + sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION); + sqlite3Put4byte(&aWalHdr[8], szPage); + sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); + sqlite3_randomness(8, pWal->hdr.aSalt); + memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); + walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); + sqlite3Put4byte(&aWalHdr[24], aCksum[0]); + sqlite3Put4byte(&aWalHdr[28], aCksum[1]); + + pWal->szPage = szPage; + pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; + pWal->hdr.aFrameCksum[0] = aCksum[0]; + pWal->hdr.aFrameCksum[1] = aCksum[1]; + + rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); + WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok")); + if( rc!=SQLITE_OK ){ + return rc; + } + } + assert( (int)pWal->szPage==szPage ); + + /* Write the log file. */ + for(p=pList; p; p=p->pDirty){ + u32 nDbsize; /* Db-size field for frame header */ + i64 iOffset; /* Write offset in log file */ + void *pData; + + iOffset = walFrameOffset(++iFrame, szPage); + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ + + /* Populate and write the frame header */ + nDbsize = (isCommit && p->pDirty==0) ? nTruncate : 0; +#if defined(SQLITE_HAS_CODEC) + if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM; +#else + pData = p->pData; +#endif + walEncodeFrame(pWal, p->pgno, nDbsize, pData, aFrame); + rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Write the page data */ + rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOffset+sizeof(aFrame)); + if( rc!=SQLITE_OK ){ + return rc; + } + pLast = p; + } + + /* Sync the log file if the 'isSync' flag was specified. */ + if( sync_flags ){ + i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd); + i64 iOffset = walFrameOffset(iFrame+1, szPage); + + assert( isCommit ); + assert( iSegment>0 ); + + iSegment = (((iOffset+iSegment-1)/iSegment) * iSegment); + while( iOffset<iSegment ){ + void *pData; +#if defined(SQLITE_HAS_CODEC) + if( (pData = sqlite3PagerCodec(pLast))==0 ) return SQLITE_NOMEM; +#else + pData = pLast->pData; +#endif + walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame); + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ + rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset); + if( rc!=SQLITE_OK ){ + return rc; + } + iOffset += WAL_FRAME_HDRSIZE; + rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOffset); + if( rc!=SQLITE_OK ){ + return rc; + } + nLast++; + iOffset += szPage; + } + + rc = sqlite3OsSync(pWal->pWalFd, sync_flags); + } + + /* Append data to the wal-index. It is not necessary to lock the + ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index + ** guarantees that there are no other writers, and no data that may + ** be in use by existing readers is being overwritten. + */ + iFrame = pWal->hdr.mxFrame; + for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){ + iFrame++; + rc = walIndexAppend(pWal, iFrame, p->pgno); + } + while( nLast>0 && rc==SQLITE_OK ){ + iFrame++; + nLast--; + rc = walIndexAppend(pWal, iFrame, pLast->pgno); + } + + if( rc==SQLITE_OK ){ + /* Update the private copy of the header. */ + pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16)); + testcase( szPage<=32768 ); + testcase( szPage>=65536 ); + pWal->hdr.mxFrame = iFrame; + if( isCommit ){ + pWal->hdr.iChange++; + pWal->hdr.nPage = nTruncate; + } + /* If this is a commit, update the wal-index header too. */ + if( isCommit ){ + walIndexWriteHdr(pWal); + pWal->iCallback = iFrame; + } + } + + WALTRACE(("WAL%p: frame write %s\n", pWal, rc ? "failed" : "ok")); + return rc; +} + +/* +** This routine is called to implement sqlite3_wal_checkpoint() and +** related interfaces. +** +** Obtain a CHECKPOINT lock and then backfill as much information as +** we can from WAL into the database. +** +** If parameter xBusy is not NULL, it is a pointer to a busy-handler +** callback. In this case this function runs a blocking checkpoint. +*/ +SQLITE_PRIVATE int sqlite3WalCheckpoint( + Wal *pWal, /* Wal connection */ + int eMode, /* PASSIVE, FULL or RESTART */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags to sync db file with (or 0) */ + int nBuf, /* Size of temporary buffer */ + u8 *zBuf, /* Temporary buffer to use */ + int *pnLog, /* OUT: Number of frames in WAL */ + int *pnCkpt /* OUT: Number of backfilled frames in WAL */ +){ + int rc; /* Return code */ + int isChanged = 0; /* True if a new wal-index header is loaded */ + int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ + + assert( pWal->ckptLock==0 ); + assert( pWal->writeLock==0 ); + + if( pWal->readOnly ) return SQLITE_READONLY; + WALTRACE(("WAL%p: checkpoint begins\n", pWal)); + rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); + if( rc ){ + /* Usually this is SQLITE_BUSY meaning that another thread or process + ** is already running a checkpoint, or maybe a recovery. But it might + ** also be SQLITE_IOERR. */ + return rc; + } + pWal->ckptLock = 1; + + /* If this is a blocking-checkpoint, then obtain the write-lock as well + ** to prevent any writers from running while the checkpoint is underway. + ** This has to be done before the call to walIndexReadHdr() below. + ** + ** If the writer lock cannot be obtained, then a passive checkpoint is + ** run instead. Since the checkpointer is not holding the writer lock, + ** there is no point in blocking waiting for any readers. Assuming no + ** other error occurs, this function will return SQLITE_BUSY to the caller. + */ + if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){ + rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1); + if( rc==SQLITE_OK ){ + pWal->writeLock = 1; + }else if( rc==SQLITE_BUSY ){ + eMode2 = SQLITE_CHECKPOINT_PASSIVE; + rc = SQLITE_OK; + } + } + + /* Read the wal-index header. */ + if( rc==SQLITE_OK ){ + rc = walIndexReadHdr(pWal, &isChanged); + } + + /* Copy data from the log to the database file. */ + if( rc==SQLITE_OK ){ + if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = walCheckpoint(pWal, eMode2, xBusy, pBusyArg, sync_flags, zBuf); + } + + /* If no error occurred, set the output variables. */ + if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ + if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; + if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill); + } + } + + if( isChanged ){ + /* If a new wal-index header was loaded before the checkpoint was + ** performed, then the pager-cache associated with pWal is now + ** out of date. So zero the cached wal-index header to ensure that + ** next time the pager opens a snapshot on this database it knows that + ** the cache needs to be reset. + */ + memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); + } + + /* Release the locks. */ + sqlite3WalEndWriteTransaction(pWal); + walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); + pWal->ckptLock = 0; + WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok")); + return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc); +} + +/* Return the value to pass to a sqlite3_wal_hook callback, the +** number of frames in the WAL at the point of the last commit since +** sqlite3WalCallback() was called. If no commits have occurred since +** the last call, then return 0. +*/ +SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal){ + u32 ret = 0; + if( pWal ){ + ret = pWal->iCallback; + pWal->iCallback = 0; + } + return (int)ret; +} + +/* +** This function is called to change the WAL subsystem into or out +** of locking_mode=EXCLUSIVE. +** +** If op is zero, then attempt to change from locking_mode=EXCLUSIVE +** into locking_mode=NORMAL. This means that we must acquire a lock +** on the pWal->readLock byte. If the WAL is already in locking_mode=NORMAL +** or if the acquisition of the lock fails, then return 0. If the +** transition out of exclusive-mode is successful, return 1. This +** operation must occur while the pager is still holding the exclusive +** lock on the main database file. +** +** If op is one, then change from locking_mode=NORMAL into +** locking_mode=EXCLUSIVE. This means that the pWal->readLock must +** be released. Return 1 if the transition is made and 0 if the +** WAL is already in exclusive-locking mode - meaning that this +** routine is a no-op. The pager must already hold the exclusive lock +** on the main database file before invoking this operation. +** +** If op is negative, then do a dry-run of the op==1 case but do +** not actually change anything. The pager uses this to see if it +** should acquire the database exclusive lock prior to invoking +** the op==1 case. +*/ +SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){ + int rc; + assert( pWal->writeLock==0 ); + assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 ); + + /* pWal->readLock is usually set, but might be -1 if there was a + ** prior error while attempting to acquire are read-lock. This cannot + ** happen if the connection is actually in exclusive mode (as no xShmLock + ** locks are taken in this case). Nor should the pager attempt to + ** upgrade to exclusive-mode following such an error. + */ + assert( pWal->readLock>=0 || pWal->lockError ); + assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) ); + + if( op==0 ){ + if( pWal->exclusiveMode ){ + pWal->exclusiveMode = 0; + if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){ + pWal->exclusiveMode = 1; + } + rc = pWal->exclusiveMode==0; + }else{ + /* Already in locking_mode=NORMAL */ + rc = 0; + } + }else if( op>0 ){ + assert( pWal->exclusiveMode==0 ); + assert( pWal->readLock>=0 ); + walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); + pWal->exclusiveMode = 1; + rc = 1; + }else{ + rc = pWal->exclusiveMode==0; + } + return rc; +} + +/* +** Return true if the argument is non-NULL and the WAL module is using +** heap-memory for the wal-index. Otherwise, if the argument is NULL or the +** WAL module is using shared-memory, return false. +*/ +SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){ + return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ); +} + +#endif /* #ifndef SQLITE_OMIT_WAL */ + +/************** End of wal.c *************************************************/ /************** Begin file btmutex.c *****************************************/ /* ** 2007 August 27 @@ -37600,16 +47372,16 @@ SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ ** on Ptr(N) and its subpages have values greater than Key(N-1). And ** so forth. ** -** Finding a particular key requires reading O(log(M)) pages from the +** Finding a particular key requires reading O(log(M)) pages from the ** disk where M is the number of entries in the tree. ** -** In this implementation, a single file can hold one or more separate +** In this implementation, a single file can hold one or more separate ** BTrees. Each BTree is identified by the index of its root page. The ** key and data for any entry are combined to form the "payload". A ** fixed amount of payload can be carried directly on the database ** page. If the payload is larger than the preset amount then surplus ** bytes are stored on overflow pages. The payload for an entry -** and the preceding pointer are combined to form a "Cell". Each +** and the preceding pointer are combined to form a "Cell". Each ** page has a small header which contains the Ptr(N) pointer and other ** information such as the size of key and data. ** @@ -37617,7 +47389,7 @@ SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ ** ** The file is divided into pages. The first page is called page 1, ** the second is page 2, and so forth. A page number of zero indicates -** "no such page". The page size can be any power of 2 between 512 and 32768. +** "no such page". The page size can be any power of 2 between 512 and 65536. ** Each page can be either a btree page, a freelist page, an overflow ** page, or a pointer-map page. ** @@ -37627,7 +47399,7 @@ SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ ** ** OFFSET SIZE DESCRIPTION ** 0 16 Header string: "SQLite format 3\000" -** 16 2 Page size in bytes. +** 16 2 Page size in bytes. ** 18 1 File format write version ** 19 1 File format read version ** 20 1 Bytes of unused space at the end of each page @@ -37738,7 +47510,7 @@ SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ ** contiguous or in order, but cell pointers are contiguous and in order. ** ** Cell content makes use of variable length integers. A variable -** length integer is 1 to 9 bytes where the lower 7 bits of each +** length integer is 1 to 9 bytes where the lower 7 bits of each ** byte are used. The integer consists of all bytes that have bit 8 set and ** the first byte with bit 8 clear. The most significant byte of the integer ** appears first. A variable-length integer may not be more than 9 bytes long. @@ -37788,7 +47560,7 @@ SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ /* The following value is the maximum cell size assuming a maximum page ** size give above. */ -#define MX_CELL_SIZE(pBt) (pBt->pageSize-8) +#define MX_CELL_SIZE(pBt) ((int)(pBt->pageSize-8)) /* The maximum number of cells on a single page of the database. This ** assumes a minimum cell size of 6 bytes (4 bytes for the cell itself @@ -37809,7 +47581,7 @@ typedef struct BtLock BtLock; ** -DSQLITE_FILE_HEADER="..." on the compiler command-line. The ** header must be exactly 16 bytes including the zero-terminator so ** the string itself should be 15 characters long. If you change -** the header, then your custom library will not be able to read +** the header, then your custom library will not be able to read ** databases generated by the standard tools and the standard tools ** will not be able to read databases created by your custom library. */ @@ -37872,7 +47644,7 @@ struct MemPage { /* ** A linked list of the following structures is stored at BtShared.pLock. -** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor +** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor ** is opened on the table with root page BtShared.iTable. Locks are removed ** from this list when a transaction is committed or rolled back, or when ** a btree handle is closed. @@ -37896,7 +47668,7 @@ struct BtLock { ** see the internals of this structure and only deals with pointers to ** this structure. ** -** For some database files, the same underlying database cache might be +** For some database files, the same underlying database cache might be ** shared between multiple connections. In that case, each connection ** has it own instance of this object. But each instance of this object ** points to the same BtShared object. The database cache and the @@ -37904,9 +47676,9 @@ struct BtLock { ** the BtShared object. ** ** All fields in this structure are accessed under sqlite3.mutex. -** The pBt pointer itself may not be changed while there exists cursors +** The pBt pointer itself may not be changed while there exists cursors ** in the referenced BtShared that point back to this Btree since those -** cursors have to do go through this Btree to find their BtShared and +** cursors have to go through this Btree to find their BtShared and ** they often do so without holding sqlite3.mutex. */ struct Btree { @@ -37937,7 +47709,7 @@ struct Btree { /* ** An instance of this object represents a single database file. -** +** ** A single database file can be in use as the same time by two ** or more database connections. When two or more connections are ** sharing the same database file, each connection has it own @@ -37978,21 +47750,25 @@ struct BtShared { u8 readOnly; /* True if the underlying file is readonly */ u8 pageSizeFixed; /* True if the page size can no longer be changed */ u8 secureDelete; /* True if secure_delete is enabled */ + u8 initiallyEmpty; /* Database is empty at start of transaction */ + u8 openFlags; /* Flags to sqlite3BtreeOpen() */ #ifndef SQLITE_OMIT_AUTOVACUUM u8 autoVacuum; /* True if auto-vacuum is enabled */ u8 incrVacuum; /* True if incr-vacuum is enabled */ #endif - u16 pageSize; /* Total number of bytes on a page */ - u16 usableSize; /* Number of usable bytes on each page */ + u8 inTransaction; /* Transaction state */ + u8 doNotUseWAL; /* If true, do not open write-ahead-log file */ u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */ u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */ u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */ u16 minLeaf; /* Minimum local payload in a LEAFDATA table */ - u8 inTransaction; /* Transaction state */ + u32 pageSize; /* Total number of bytes on a page */ + u32 usableSize; /* Number of usable bytes on each page */ int nTransaction; /* Number of open transactions (read + write) */ + u32 nPage; /* Number of pages in the database */ void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */ void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */ - sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */ + sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */ Bitvec *pHasContent; /* Set of pages moved to free-list this transaction */ #ifndef SQLITE_OMIT_SHARED_CACHE int nRef; /* Number of references to this structure */ @@ -38012,8 +47788,8 @@ struct BtShared { */ typedef struct CellInfo CellInfo; struct CellInfo { - u8 *pCell; /* Pointer to the start of cell content */ i64 nKey; /* The key for INTKEY tables, or number of bytes in key */ + u8 *pCell; /* Pointer to the start of cell content */ u32 nData; /* Number of bytes of data */ u32 nPayload; /* Total amount of payload */ u16 nHeader; /* Size of the cell content header in bytes */ @@ -38045,7 +47821,7 @@ struct CellInfo { ** particular database connection identified BtCursor.pBtree.db. ** ** Fields in this structure are accessed under the BtShared.mutex -** found at self->pBt->mutex. +** found at self->pBt->mutex. */ struct BtCursor { Btree *pBtree; /* The Btree to which this cursor belongs */ @@ -38055,20 +47831,20 @@ struct BtCursor { Pgno pgnoRoot; /* The root page of this tree */ sqlite3_int64 cachedRowid; /* Next rowid cache. 0 means not valid */ CellInfo info; /* A parse of the cell we are pointing at */ + i64 nKey; /* Size of pKey, or last integer key */ + void *pKey; /* Saved key that was cursor's last known position */ + int skipNext; /* Prev() is noop if negative. Next() is noop if positive */ u8 wrFlag; /* True if writable */ u8 atLast; /* Cursor pointing to the last entry */ u8 validNKey; /* True if info.nKey is valid */ u8 eState; /* One of the CURSOR_XXX constants (see below) */ - void *pKey; /* Saved key that was cursor's last known position */ - i64 nKey; /* Size of pKey, or last integer key */ - int skipNext; /* Prev() is noop if negative. Next() is noop if positive */ #ifndef SQLITE_OMIT_INCRBLOB - u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ Pgno *aOverflow; /* Cache of overflow page locations */ + u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ #endif i16 iPage; /* Index of current page in apPage */ - MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ + MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ }; /* @@ -38078,14 +47854,14 @@ struct BtCursor { ** Cursor points to a valid entry. getPayload() etc. may be called. ** ** CURSOR_INVALID: -** Cursor does not point to a valid entry. This can happen (for example) +** Cursor does not point to a valid entry. This can happen (for example) ** because the table is empty or because BtreeCursorFirst() has not been ** called. ** ** CURSOR_REQUIRESEEK: -** The table that this cursor was opened on still exists, but has been +** The table that this cursor was opened on still exists, but has been ** modified since the cursor was last used. The cursor position is saved -** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in +** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in ** this state, restoreCursorPosition() can be called to attempt to ** seek the cursor to the saved position. ** @@ -38101,13 +47877,13 @@ struct BtCursor { #define CURSOR_REQUIRESEEK 2 #define CURSOR_FAULT 3 -/* +/* ** The database page the PENDING_BYTE occupies. This page is never used. */ # define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt) /* -** These macros define the location of the pointer-map entry for a +** These macros define the location of the pointer-map entry for a ** database page. The first argument to each is the number of usable ** bytes on each page of the database (often 1024). The second is the ** page number to look up in the pointer map. @@ -38142,10 +47918,10 @@ struct BtCursor { ** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not ** used in this case. ** -** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number +** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number ** is not used in this case. ** -** PTRMAP_OVERFLOW1: The database page is the first page in a list of +** PTRMAP_OVERFLOW1: The database page is the first page in a list of ** overflow pages. The page number identifies the page that ** contains the cell with a pointer to this overflow page. ** @@ -38167,13 +47943,13 @@ struct BtCursor { */ #define btreeIntegrity(p) \ assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \ - assert( p->pBt->inTransaction>=p->inTrans ); + assert( p->pBt->inTransaction>=p->inTrans ); /* ** The ISAUTOVACUUM macro is used within balance_nonroot() to determine ** if the database supports auto-vacuum or not. Because it is used -** within an expression that is an argument to another macro +** 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. */ @@ -38233,12 +48009,13 @@ static void lockBtreeMutex(Btree *p){ ** clear the p->locked boolean. */ static void unlockBtreeMutex(Btree *p){ + BtShared *pBt = p->pBt; assert( p->locked==1 ); - assert( sqlite3_mutex_held(p->pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); assert( sqlite3_mutex_held(p->db->mutex) ); - assert( p->db==p->pBt->db ); + assert( p->db==pBt->db ); - sqlite3_mutex_leave(p->pBt->mutex); + sqlite3_mutex_leave(pBt->mutex); p->locked = 0; } @@ -38379,30 +48156,11 @@ SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){ */ SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ int i; - Btree *p, *pLater; + Btree *p; assert( sqlite3_mutex_held(db->mutex) ); for(i=0; i<db->nDb; i++){ p = db->aDb[i].pBt; - assert( !p || (p->locked==0 && p->sharable) || p->pBt->db==p->db ); - if( p && p->sharable ){ - p->wantToLock++; - if( !p->locked ){ - assert( p->wantToLock==1 ); - while( p->pPrev ) p = p->pPrev; - /* Reason for ALWAYS: There must be at least on unlocked Btree in - ** the chain. Otherwise the !p->locked test above would have failed */ - while( p->locked && ALWAYS(p->pNext) ) p = p->pNext; - for(pLater = p->pNext; pLater; pLater=pLater->pNext){ - if( pLater->locked ){ - unlockBtreeMutex(pLater); - } - } - while( p ){ - lockBtreeMutex(p); - p = p->pNext; - } - } - } + if( p ) sqlite3BtreeEnter(p); } } SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){ @@ -38411,16 +48169,18 @@ SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){ assert( sqlite3_mutex_held(db->mutex) ); for(i=0; i<db->nDb; i++){ p = db->aDb[i].pBt; - if( p && p->sharable ){ - assert( p->wantToLock>0 ); - p->wantToLock--; - if( p->wantToLock==0 ){ - unlockBtreeMutex(p); - } - } + if( p ) sqlite3BtreeLeave(p); } } +/* +** Return true if a particular Btree requires a lock. Return FALSE if +** no lock is ever required since it is not sharable. +*/ +SQLITE_PRIVATE int sqlite3BtreeSharable(Btree *p){ + return p->sharable; +} + #ifndef NDEBUG /* ** Return true if the current thread holds the database connection @@ -38445,97 +48205,42 @@ SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){ } #endif /* NDEBUG */ +#ifndef NDEBUG /* -** Add a new Btree pointer to a BtreeMutexArray. -** if the pointer can possibly be shared with -** another database connection. +** Return true if the correct mutexes are held for accessing the +** db->aDb[iDb].pSchema structure. The mutexes required for schema +** access are: ** -** The pointers are kept in sorted order by pBtree->pBt. That -** way when we go to enter all the mutexes, we can enter them -** in order without every having to backup and retry and without -** worrying about deadlock. +** (1) The mutex on db +** (2) if iDb!=1, then the mutex on db->aDb[iDb].pBt. ** -** The number of shared btrees will always be small (usually 0 or 1) -** so an insertion sort is an adequate algorithm here. +** If pSchema is not NULL, then iDb is computed from pSchema and +** db using sqlite3SchemaToIndex(). */ -SQLITE_PRIVATE void sqlite3BtreeMutexArrayInsert(BtreeMutexArray *pArray, Btree *pBtree){ - int i, j; - BtShared *pBt; - if( pBtree==0 || pBtree->sharable==0 ) return; -#ifndef NDEBUG - { - for(i=0; i<pArray->nMutex; i++){ - assert( pArray->aBtree[i]!=pBtree ); - } - } -#endif - assert( pArray->nMutex>=0 ); - assert( pArray->nMutex<ArraySize(pArray->aBtree)-1 ); - pBt = pBtree->pBt; - for(i=0; i<pArray->nMutex; i++){ - assert( pArray->aBtree[i]!=pBtree ); - if( pArray->aBtree[i]->pBt>pBt ){ - for(j=pArray->nMutex; j>i; j--){ - pArray->aBtree[j] = pArray->aBtree[j-1]; - } - pArray->aBtree[i] = pBtree; - pArray->nMutex++; - return; - } - } - pArray->aBtree[pArray->nMutex++] = pBtree; -} - -/* -** Enter the mutex of every btree in the array. This routine is -** called at the beginning of sqlite3VdbeExec(). The mutexes are -** exited at the end of the same function. -*/ -SQLITE_PRIVATE void sqlite3BtreeMutexArrayEnter(BtreeMutexArray *pArray){ - int i; - for(i=0; i<pArray->nMutex; i++){ - Btree *p = pArray->aBtree[i]; - /* Some basic sanity checking */ - assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt ); - assert( !p->locked || p->wantToLock>0 ); - - /* We should already hold a lock on the database connection */ - assert( sqlite3_mutex_held(p->db->mutex) ); - - /* The Btree is sharable because only sharable Btrees are entered - ** into the array in the first place. */ - assert( p->sharable ); - - p->wantToLock++; - if( !p->locked ){ - lockBtreeMutex(p); - } - } +SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3 *db, int iDb, Schema *pSchema){ + Btree *p; + assert( db!=0 ); + if( pSchema ) iDb = sqlite3SchemaToIndex(db, pSchema); + assert( iDb>=0 && iDb<db->nDb ); + if( !sqlite3_mutex_held(db->mutex) ) return 0; + if( iDb==1 ) return 1; + p = db->aDb[iDb].pBt; + assert( p!=0 ); + return p->sharable==0 || p->locked==1; } +#endif /* NDEBUG */ +#else /* SQLITE_THREADSAFE>0 above. SQLITE_THREADSAFE==0 below */ /* -** Leave the mutex of every btree in the group. +** The following are special cases for mutex enter routines for use +** in single threaded applications that use shared cache. Except for +** these two routines, all mutex operations are no-ops in that case and +** are null #defines in btree.h. +** +** If shared cache is disabled, then all btree mutex routines, including +** the ones below, are no-ops and are null #defines in btree.h. */ -SQLITE_PRIVATE void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pArray){ - int i; - for(i=0; i<pArray->nMutex; i++){ - Btree *p = pArray->aBtree[i]; - /* Some basic sanity checking */ - assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt ); - assert( p->locked ); - assert( p->wantToLock>0 ); - - /* We should already hold a lock on the database connection */ - assert( sqlite3_mutex_held(p->db->mutex) ); - p->wantToLock--; - if( p->wantToLock==0 ){ - unlockBtreeMutex(p); - } - } -} - -#else SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){ p->pBt->db = p->db; } @@ -38586,13 +48291,22 @@ int sqlite3BtreeTrace=1; /* True to enable tracing */ # define TRACE(X) #endif - +/* +** Extract a 2-byte big-endian integer from an array of unsigned bytes. +** But if the value is zero, make it 65536. +** +** This routine is used to extract the "offset to cell content area" value +** from the header of a btree page. If the page size is 65536 and the page +** is empty, the offset should be 65536, but the 2-byte value stores zero. +** This routine makes the necessary adjustment to 65536. +*/ +#define get2byteNotZero(X) (((((int)get2byte(X))-1)&0xffff)+1) #ifndef SQLITE_OMIT_SHARED_CACHE /* ** A list of BtShared objects that are eligible for participation ** in shared cache. This variable has file scope during normal builds, -** but the test harness needs to access it so we make it global for +** but the test harness needs to access it so we make it global for ** test builds. ** ** Access to this variable is protected by SQLITE_MUTEX_STATIC_MASTER. @@ -38627,7 +48341,7 @@ SQLITE_API int sqlite3_enable_shared_cache(int enable){ ** manipulate entries in the BtShared.pLock linked list used to store ** shared-cache table level locks. If the library is compiled with the ** shared-cache feature disabled, then there is only ever one user - ** of each BtShared structure and so this locking is not necessary. + ** of each BtShared structure and so this locking is not necessary. ** So define the lock related functions as no-ops. */ #define querySharedCacheTableLock(a,b,c) SQLITE_OK @@ -38644,15 +48358,15 @@ SQLITE_API int sqlite3_enable_shared_cache(int enable){ /* **** This function is only used as part of an assert() statement. *** ** -** Check to see if pBtree holds the required locks to read or write to the +** Check to see if pBtree holds the required locks to read or write to the ** table with root page iRoot. Return 1 if it does and 0 if not. ** -** For example, when writing to a table with root-page iRoot via +** For example, when writing to a table with root-page iRoot via ** Btree connection pBtree: ** ** assert( hasSharedCacheTableLock(pBtree, iRoot, 0, WRITE_LOCK) ); ** -** When writing to an index that resides in a sharable database, the +** When writing to an index that resides in a sharable database, the ** caller should have first obtained a lock specifying the root page of ** the corresponding table. This makes things a bit more complicated, ** as this module treats each table as a separate structure. To determine @@ -38674,7 +48388,7 @@ static int hasSharedCacheTableLock( BtLock *pLock; /* If this database is not shareable, or if the client is reading - ** and has the read-uncommitted flag set, then no lock is required. + ** and has the read-uncommitted flag set, then no lock is required. ** Return true immediately. */ if( (pBtree->sharable==0) @@ -38708,13 +48422,13 @@ static int hasSharedCacheTableLock( iTab = iRoot; } - /* Search for the required lock. Either a write-lock on root-page iTab, a + /* Search for the required lock. Either a write-lock on root-page iTab, a ** write-lock on the schema table, or (if the client is reading) a ** read-lock on iTab will suffice. Return 1 if any of these are found. */ for(pLock=pBtree->pBt->pLock; pLock; pLock=pLock->pNext){ - if( pLock->pBtree==pBtree + if( pLock->pBtree==pBtree && (pLock->iTable==iTab || (pLock->eLock==WRITE_LOCK && pLock->iTable==1)) - && pLock->eLock>=eLockType + && pLock->eLock>=eLockType ){ return 1; } @@ -38747,7 +48461,7 @@ static int hasSharedCacheTableLock( static int hasReadConflicts(Btree *pBtree, Pgno iRoot){ BtCursor *p; for(p=pBtree->pBt->pCursor; p; p=p->pNext){ - if( p->pgnoRoot==iRoot + if( p->pgnoRoot==iRoot && p->pBtree!=pBtree && 0==(p->pBtree->db->flags & SQLITE_ReadUncommitted) ){ @@ -38759,7 +48473,7 @@ static int hasReadConflicts(Btree *pBtree, Pgno iRoot){ #endif /* #ifdef SQLITE_DEBUG */ /* -** Query to see if Btree handle p may obtain a lock of type eLock +** Query to see if Btree handle p may obtain a lock of type eLock ** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return ** SQLITE_OK if the lock may be obtained (by calling ** setSharedCacheTableLock()), or SQLITE_LOCKED if not. @@ -38772,14 +48486,14 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); assert( p->db!=0 ); assert( !(p->db->flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 ); - + /* If requesting a write-lock, then the Btree must have an open write - ** transaction on this file. And, obviously, for this to be so there + ** transaction on this file. And, obviously, for this to be so there ** must be an open write transaction on the file itself. */ assert( eLock==READ_LOCK || (p==pBt->pWriter && p->inTrans==TRANS_WRITE) ); assert( eLock==READ_LOCK || pBt->inTransaction==TRANS_WRITE ); - + /* This routine is a no-op if the shared-cache is not enabled */ if( !p->sharable ){ return SQLITE_OK; @@ -38794,7 +48508,7 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ } for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ - /* The condition (pIter->eLock!=eLock) in the following if(...) + /* The condition (pIter->eLock!=eLock) in the following if(...) ** statement is a simplification of: ** ** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK) @@ -38821,7 +48535,7 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ #ifndef SQLITE_OMIT_SHARED_CACHE /* ** Add a lock on the table with root-page iTable to the shared-btree used -** by Btree handle p. Parameter eLock must be either READ_LOCK or +** by Btree handle p. Parameter eLock must be either READ_LOCK or ** WRITE_LOCK. ** ** This function assumes the following: @@ -38833,7 +48547,7 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ ** with the requested lock (i.e. querySharedCacheTableLock() has ** already been called and returned SQLITE_OK). ** -** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM +** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM ** is returned if a malloc attempt fails. */ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ @@ -38847,11 +48561,11 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ /* A connection with the read-uncommitted flag set will never try to ** obtain a read-lock using this function. The only read-lock obtained - ** by a connection in read-uncommitted mode is on the sqlite_master + ** by a connection in read-uncommitted mode is on the sqlite_master ** table, and that lock is obtained in BtreeBeginTrans(). */ assert( 0==(p->db->flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK ); - /* This function should only be called on a sharable b-tree after it + /* This function should only be called on a sharable b-tree after it ** has been determined that no other b-tree holds a conflicting lock. */ assert( p->sharable ); assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) ); @@ -38896,7 +48610,7 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ ** Release all the table locks (locks obtained via calls to ** the setSharedCacheTableLock() procedure) held by Btree object p. ** -** This function assumes that Btree p has an open read or write +** This function assumes that Btree p has an open read or write ** transaction. If it does not, then the BtShared.isPending variable ** may be incorrectly cleared. */ @@ -38929,7 +48643,7 @@ static void clearAllSharedCacheTableLocks(Btree *p){ pBt->isExclusive = 0; pBt->isPending = 0; }else if( pBt->nTransaction==2 ){ - /* This function is called when Btree p is concluding its + /* This function is called when Btree p is concluding its ** transaction. If there currently exists a writer, and p is not ** that writer, then the number of locks held by connections other ** than the writer must be about to drop to zero. In this case @@ -39033,8 +48747,8 @@ static void invalidateIncrblobCursors( #endif /* SQLITE_OMIT_INCRBLOB */ /* -** Set bit pgno of the BtShared.pHasContent bitvec. This is called -** when a page that previously contained data becomes a free-list leaf +** Set bit pgno of the BtShared.pHasContent bitvec. This is called +** when a page that previously contained data becomes a free-list leaf ** page. ** ** The BtShared.pHasContent bitvec exists to work around an obscure @@ -39060,7 +48774,7 @@ static void invalidateIncrblobCursors( ** may be lost. In the event of a rollback, it may not be possible ** to restore the database to its original configuration. ** -** The solution is the BtShared.pHasContent bitvec. Whenever a page is +** The solution is the BtShared.pHasContent bitvec. Whenever a page is ** moved to become a free-list leaf page, the corresponding bit is ** set in the bitvec. Whenever a leaf page is extracted from the free-list, ** optimization 2 above is omitted if the corresponding bit is already @@ -39070,11 +48784,8 @@ static void invalidateIncrblobCursors( static int btreeSetHasContent(BtShared *pBt, Pgno pgno){ int rc = SQLITE_OK; if( !pBt->pHasContent ){ - int nPage = 100; - sqlite3PagerPagecount(pBt->pPager, &nPage); - /* If sqlite3PagerPagecount() fails there is no harm because the - ** nPage variable is unchanged from its default value of 100 */ - pBt->pHasContent = sqlite3BitvecCreate((u32)nPage); + assert( pgno<=pBt->nPage ); + pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage); if( !pBt->pHasContent ){ rc = SQLITE_NOMEM; } @@ -39107,11 +48818,11 @@ static void btreeClearHasContent(BtShared *pBt){ } /* -** Save the current cursor position in the variables BtCursor.nKey +** Save the current cursor position in the variables BtCursor.nKey ** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. ** ** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID) -** prior to calling this routine. +** prior to calling this routine. */ static int saveCursorPosition(BtCursor *pCur){ int rc; @@ -39126,7 +48837,7 @@ static int saveCursorPosition(BtCursor *pCur){ /* If this is an intKey table, then the above call to BtreeKeySize() ** stores the integer key in pCur->nKey. In this case this value is ** all that is required. Otherwise, if pCur is not open on an intKey - ** table, then malloc space for and store the pCur->nKey bytes of key + ** table, then malloc space for and store the pCur->nKey bytes of key ** data. */ if( 0==pCur->apPage[0]->intKey ){ @@ -39168,7 +48879,7 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ assert( sqlite3_mutex_held(pBt->mutex) ); assert( pExcept==0 || pExcept->pBt==pBt ); for(p=pBt->pCursor; p; p=p->pNext){ - if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && + if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && p->eState==CURSOR_VALID ){ int rc = saveCursorPosition(p); if( SQLITE_OK!=rc ){ @@ -39204,27 +48915,30 @@ static int btreeMoveto( int rc; /* Status code */ UnpackedRecord *pIdxKey; /* Unpacked index key */ char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */ + char *pFree = 0; if( pKey ){ assert( nKey==(i64)(int)nKey ); - pIdxKey = sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, - aSpace, sizeof(aSpace)); + pIdxKey = sqlite3VdbeAllocUnpackedRecord( + pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree + ); if( pIdxKey==0 ) return SQLITE_NOMEM; + sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); }else{ pIdxKey = 0; } rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); - if( pKey ){ - sqlite3VdbeDeleteUnpackedRecord(pIdxKey); + if( pFree ){ + sqlite3DbFree(pCur->pKeyInfo->db, pFree); } return rc; } /* ** Restore the cursor to the position it was in (or as close to as possible) -** when saveCursorPosition() was called. Note that this call deletes the +** when saveCursorPosition() was called. Note that this call deletes the ** saved position info stored by saveCursorPosition(), so there can be -** at most one effective restoreCursorPosition() call after each +** at most one effective restoreCursorPosition() call after each ** saveCursorPosition(). */ static int btreeRestoreCursorPosition(BtCursor *pCur){ @@ -39278,14 +48992,19 @@ SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){ ** Given a page number of a regular database page, return the page ** number for the pointer-map page that contains the entry for the ** input page number. +** +** Return 0 (not a valid page) for pgno==1 since there is +** no pointer map associated with page 1. The integrity_check logic +** requires that ptrmapPageno(*,1)!=1. */ static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){ int nPagesPerMapPage; Pgno iPtrMap, ret; assert( sqlite3_mutex_held(pBt->mutex) ); + if( pgno<2 ) return 0; nPagesPerMapPage = (pBt->usableSize/5)+1; iPtrMap = (pgno-2)/nPagesPerMapPage; - ret = (iPtrMap*nPagesPerMapPage) + 2; + ret = (iPtrMap*nPagesPerMapPage) + 2; if( ret==PENDING_BYTE_PAGE(pBt) ){ ret++; } @@ -39331,6 +49050,7 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ *pRC = SQLITE_CORRUPT_BKPT; goto ptrmap_exit; } + assert( offset <= (int)pBt->usableSize-5 ); pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ @@ -39370,6 +49090,11 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); offset = PTRMAP_PTROFFSET(iPtrmap, key); + if( offset<0 ){ + sqlite3PagerUnref(pDbPage); + return SQLITE_CORRUPT_BKPT; + } + assert( offset <= (int)pBt->usableSize-5 ); assert( pEType!=0 ); *pEType = pPtrmap[offset]; if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); @@ -39394,6 +49119,8 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ */ #define findCell(P,I) \ ((P)->aData + ((P)->maskPage & get2byte(&(P)->aData[(P)->cellOffset+2*(I)]))) +#define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I))))) + /* ** This a more complex version of findCell() that works for @@ -39419,8 +49146,8 @@ static u8 *findOverflowCell(MemPage *pPage, int iCell){ /* ** Parse a cell content block and fill in the CellInfo structure. There -** are two versions of this function. btreeParseCell() takes a -** cell index as the second argument and btreeParseCellPtr() +** are two versions of this function. btreeParseCell() takes a +** cell index as the second argument and btreeParseCellPtr() ** takes a pointer to the body of the cell as its second argument. ** ** Within this file, the parseCell() macro can be called instead of @@ -39461,14 +49188,9 @@ static void btreeParseCellPtr( /* This is the (easy) common case where the entire payload fits ** on the local page. No overflow is required. */ - int nSize; /* Total size of cell content in bytes */ - nSize = nPayload + n; + if( (pInfo->nSize = (u16)(n+nPayload))<4 ) pInfo->nSize = 4; pInfo->nLocal = (u16)nPayload; pInfo->iOverflow = 0; - if( (nSize & ~3)==0 ){ - nSize = 4; /* Minimum cell size is 4 */ - } - pInfo->nSize = (u16)nSize; }else{ /* If the payload will not fit completely on the local page, we have ** to decide how much to store locally and how much to spill onto @@ -39534,7 +49256,7 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ nSize = 0; } - /* pIter now points at the 64-bit integer key value, a variable length + /* pIter now points at the 64-bit integer key value, a variable length ** integer. The following block moves pIter to point at the first byte ** past the end of the key value. */ pEnd = &pIter[9]; @@ -39640,7 +49362,7 @@ static int defragmentPage(MemPage *pPage){ testcase( pc==iCellLast ); #if !defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) /* These conditions have already been verified in btreeInitPage() - ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined + ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined */ if( pc<iCellFirst || pc>iCellLast ){ return SQLITE_CORRUPT_BKPT; @@ -39698,7 +49420,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ int gap; /* First byte of gap between cell pointers and cell content */ int rc; /* Integer return code */ int usableSize; /* Usable size of the page */ - + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); @@ -39711,7 +49433,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ nFrag = data[hdr+7]; assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); gap = pPage->cellOffset + 2*pPage->nCell; - top = get2byte(&data[hdr+5]); + top = get2byteNotZero(&data[hdr+5]); if( gap>top ) return SQLITE_CORRUPT_BKPT; testcase( gap+2==top ); testcase( gap+1==top ); @@ -39721,10 +49443,10 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ /* Always defragment highly fragmented pages */ rc = defragmentPage(pPage); if( rc ) return rc; - top = get2byte(&data[hdr+5]); + top = get2byteNotZero(&data[hdr+5]); }else if( gap+2<=top ){ - /* Search the freelist looking for a free slot big enough to satisfy - ** the request. The allocation is made from the first free slot in + /* Search the freelist looking for a free slot big enough to satisfy + ** the request. The allocation is made from the first free slot in ** the list that is large enough to accomadate it. */ int pc, addr; @@ -39763,7 +49485,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ if( gap+2+nByte>top ){ rc = defragmentPage(pPage); if( rc ) return rc; - top = get2byte(&data[hdr+5]); + top = get2byteNotZero(&data[hdr+5]); assert( gap+nByte<=top ); } @@ -39776,7 +49498,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ */ top -= nByte; put2byte(&data[hdr+5], top); - assert( top+nByte <= pPage->pBt->usableSize ); + assert( top+nByte <= (int)pPage->pBt->usableSize ); *pIdx = top; return SQLITE_OK; } @@ -39797,7 +49519,7 @@ static int freeSpace(MemPage *pPage, int start, int size){ assert( pPage->pBt!=0 ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( start>=pPage->hdrOffset+6+pPage->childPtrSize ); - assert( (start + size)<=pPage->pBt->usableSize ); + assert( (start + size) <= (int)pPage->pBt->usableSize ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( size>=0 ); /* Minimum cell size is 4 */ @@ -39840,7 +49562,7 @@ static int freeSpace(MemPage *pPage, int start, int size){ while( (pbegin = get2byte(&data[addr]))>0 ){ int pnext, psize, x; assert( pbegin>addr ); - assert( pbegin<=pPage->pBt->usableSize-4 ); + assert( pbegin <= (int)pPage->pBt->usableSize-4 ); pnext = get2byte(&data[pbegin]); psize = get2byte(&data[pbegin+2]); if( pbegin + psize + 3 >= pnext && pnext>0 ){ @@ -39911,7 +49633,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){ ** Initialize the auxiliary information for a disk block. ** ** Return SQLITE_OK on success. If we see that the page does -** not contain a well-formed database page, then return +** not contain a well-formed database page, then return ** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not ** guarantee that the page is well-formed. It only shows that ** we failed to detect any corruption. @@ -39929,10 +49651,10 @@ static int btreeInitPage(MemPage *pPage){ u8 hdr; /* Offset to beginning of page header */ u8 *data; /* Equal to pPage->aData */ BtShared *pBt; /* The main btree structure */ - u16 usableSize; /* Amount of usable space on each page */ + int usableSize; /* Amount of usable space on each page */ u16 cellOffset; /* Offset from start of page to first cell pointer */ - u16 nFree; /* Number of unused bytes on the page */ - u16 top; /* First byte of the cell content area */ + int nFree; /* Number of unused bytes on the page */ + int top; /* First byte of the cell content area */ int iCellFirst; /* First allowable cell or freeblock offset */ int iCellLast; /* Last possible cell or freeblock offset */ @@ -39941,12 +49663,12 @@ static int btreeInitPage(MemPage *pPage){ hdr = pPage->hdrOffset; data = pPage->aData; if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT; - assert( pBt->pageSize>=512 && pBt->pageSize<=32768 ); - pPage->maskPage = pBt->pageSize - 1; + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); pPage->nOverflow = 0; usableSize = pBt->usableSize; pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf; - top = get2byte(&data[hdr+5]); + top = get2byteNotZero(&data[hdr+5]); pPage->nCell = get2byte(&data[hdr+3]); if( pPage->nCell>MX_CELL(pBt) ){ /* To many cells for a single page. The page must be corrupt */ @@ -39955,10 +49677,10 @@ static int btreeInitPage(MemPage *pPage){ testcase( pPage->nCell==MX_CELL(pBt) ); /* A malformed database page might cause us to read past the end - ** of page when parsing a cell. + ** of page when parsing a cell. ** ** The following block of code checks early to see if a cell extends - ** past the end of a page boundary and causes SQLITE_CORRUPT to be + ** past the end of a page boundary and causes SQLITE_CORRUPT to be ** returned if it does. */ iCellFirst = cellOffset + 2*pPage->nCell; @@ -39983,7 +49705,7 @@ static int btreeInitPage(MemPage *pPage){ } } if( !pPage->leaf ) iCellLast++; - } + } #endif /* Compute the total free space on the page */ @@ -39993,14 +49715,14 @@ static int btreeInitPage(MemPage *pPage){ u16 next, size; if( pc<iCellFirst || pc>iCellLast ){ /* Start of free block is off the page */ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_BKPT; } next = get2byte(&data[pc]); size = get2byte(&data[pc+2]); if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){ /* Free blocks must be in ascending order. And the last byte of ** the free-block must lie on the database page. */ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_BKPT; } nFree = nFree + size; pc = next; @@ -40014,7 +49736,7 @@ static int btreeInitPage(MemPage *pPage){ ** area, according to the page header, lies within the page. */ if( nFree>usableSize ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_BKPT; } pPage->nFree = (u16)(nFree - iCellFirst); pPage->isInit = 1; @@ -40045,13 +49767,13 @@ static void zeroPage(MemPage *pPage, int flags){ memset(&data[hdr+1], 0, 4); data[hdr+7] = 0; put2byte(&data[hdr+5], pBt->usableSize); - pPage->nFree = pBt->usableSize - first; + pPage->nFree = (u16)(pBt->usableSize - first); decodeFlags(pPage, flags); pPage->hdrOffset = hdr; pPage->cellOffset = first; pPage->nOverflow = 0; - assert( pBt->pageSize>=512 && pBt->pageSize<=32768 ); - pPage->maskPage = pBt->pageSize - 1; + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); pPage->nCell = 0; pPage->isInit = 1; } @@ -40068,7 +49790,7 @@ static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){ pPage->pBt = pBt; pPage->pgno = pgno; pPage->hdrOffset = pPage->pgno==1 ? 100 : 0; - return pPage; + return pPage; } /* @@ -40117,18 +49839,18 @@ static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){ ** Return the size of the database file in pages. If there is any kind of ** error, return ((unsigned int)-1). */ -static Pgno pagerPagecount(BtShared *pBt){ - int nPage = -1; - int rc; - assert( pBt->pPage1 ); - rc = sqlite3PagerPagecount(pBt->pPager, &nPage); - assert( rc==SQLITE_OK || nPage==-1 ); - return (Pgno)nPage; +static Pgno btreePagecount(BtShared *pBt){ + return pBt->nPage; +} +SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){ + assert( sqlite3BtreeHoldsMutex(p) ); + assert( ((p->pBt->nPage)&0x8000000)==0 ); + return (int)btreePagecount(p->pBt); } /* ** Get a page from the pager and initialize it. This routine is just a -** convenience wrapper around separate calls to btreeGetPage() and +** convenience wrapper around separate calls to btreeGetPage() and ** btreeInitPage(). ** ** If an error occurs, then the value *ppPage is set to is undefined. It @@ -40140,25 +49862,22 @@ static int getAndInitPage( MemPage **ppPage /* Write the page pointer here */ ){ int rc; - TESTONLY( Pgno iLastPg = pagerPagecount(pBt); ) assert( sqlite3_mutex_held(pBt->mutex) ); - rc = btreeGetPage(pBt, pgno, ppPage, 0); - if( rc==SQLITE_OK ){ - rc = btreeInitPage(*ppPage); - if( rc!=SQLITE_OK ){ - releasePage(*ppPage); + if( pgno>btreePagecount(pBt) ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = btreeGetPage(pBt, pgno, ppPage, 0); + if( rc==SQLITE_OK ){ + rc = btreeInitPage(*ppPage); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + } } } - /* If the requested page number was either 0 or greater than the page - ** number of the last page in the database, this function should return - ** SQLITE_CORRUPT or some other error (i.e. SQLITE_FULL). Check that this - ** is the case. */ - assert( (pgno>0 && pgno<=iLastPg) || rc!=SQLITE_OK ); testcase( pgno==0 ); - testcase( pgno==iLastPg ); - + assert( pgno!=0 || rc==SQLITE_CORRUPT ); return rc; } @@ -40216,13 +49935,22 @@ static int btreeInvokeBusyHandler(void *pArg){ /* ** Open a database file. -** +** ** zFilename is the name of the database file. If zFilename is NULL -** a new database with a random name is created. This randomly named -** database file will be deleted when sqlite3BtreeClose() is called. +** then an ephemeral database is created. The ephemeral database might +** be exclusively in memory, or it might use a disk-based memory cache. +** Either way, the ephemeral database will be automatically deleted +** when sqlite3BtreeClose() is called. +** ** If zFilename is ":memory:" then an in-memory database is created ** that is automatically destroyed when it is closed. ** +** The "flags" parameter is a bitmask that might contain bits +** BTREE_OMIT_JOURNAL and/or BTREE_NO_READLOCK. The BTREE_NO_READLOCK +** bit is also set if the SQLITE_NoReadlock flags is set in db->flags. +** These flags are passed through into sqlite3PagerOpen() and must +** be the same values as PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK. +** ** If the database is already opened in the same database connection ** and we are in shared cache mode, then the open will fail with an ** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared @@ -40230,13 +49958,13 @@ static int btreeInvokeBusyHandler(void *pArg){ ** to problems with locking. */ SQLITE_PRIVATE int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, /* VFS to use for this b-tree */ const char *zFilename, /* Name of the file containing the BTree database */ sqlite3 *db, /* Associated database handle */ Btree **ppBtree, /* Pointer to new Btree object written here */ int flags, /* Options */ int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */ ){ - sqlite3_vfs *pVfs; /* The VFS to use for this btree */ BtShared *pBt = 0; /* Shared part of btree structure */ Btree *p; /* Handle to return */ sqlite3_mutex *mutexOpen = 0; /* Prevents a race condition. Ticket #3537 */ @@ -40244,23 +49972,39 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( u8 nReserve; /* Byte of unused space on each page */ unsigned char zDbHeader[100]; /* Database header content */ - /* Set the variable isMemdb to true for an in-memory database, or - ** false for a file-based database. This symbol is only required if - ** either of the shared-data or autovacuum features are compiled - ** into the library. + /* True if opening an ephemeral, temporary database */ + const int isTempDb = zFilename==0 || zFilename[0]==0; + + /* Set the variable isMemdb to true for an in-memory database, or + ** false for a file-based database. */ -#if !defined(SQLITE_OMIT_SHARED_CACHE) || !defined(SQLITE_OMIT_AUTOVACUUM) - #ifdef SQLITE_OMIT_MEMORYDB - const int isMemdb = 0; - #else - const int isMemdb = zFilename && !strcmp(zFilename, ":memory:"); - #endif +#ifdef SQLITE_OMIT_MEMORYDB + const int isMemdb = 0; +#else + const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) + || (isTempDb && sqlite3TempInMemory(db)); #endif assert( db!=0 ); + assert( pVfs!=0 ); assert( sqlite3_mutex_held(db->mutex) ); + assert( (flags&0xff)==flags ); /* flags fit in 8 bits */ + + /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */ + assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); - pVfs = db->pVfs; + /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ + assert( (flags & BTREE_SINGLE)==0 || isTempDb ); + + if( db->flags & SQLITE_NoReadlock ){ + flags |= BTREE_NO_READLOCK; + } + if( isMemdb ){ + flags |= BTREE_MEMORY; + } + if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ + vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; + } p = sqlite3MallocZero(sizeof(Btree)); if( !p ){ return SQLITE_NOMEM; @@ -40277,7 +50021,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( ** If this Btree is a candidate for shared cache, try to find an ** existing BtShared object that we can share with */ - if( isMemdb==0 && zFilename && zFilename[0] ){ + if( isMemdb==0 && isTempDb==0 ){ if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ int nFullPathname = pVfs->mxPathname+1; char *zFullPathname = sqlite3Malloc(nFullPathname); @@ -40338,7 +50082,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( assert( sizeof(u32)==4 ); assert( sizeof(u16)==2 ); assert( sizeof(Pgno)==4 ); - + pBt = sqlite3MallocZero( sizeof(*pBt) ); if( pBt==0 ){ rc = SQLITE_NOMEM; @@ -40352,17 +50096,18 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( if( rc!=SQLITE_OK ){ goto btree_open_out; } + pBt->openFlags = (u8)flags; pBt->db = db; sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt); p->pBt = pBt; - + pBt->pCursor = 0; pBt->pPage1 = 0; pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager); #ifdef SQLITE_SECURE_DELETE pBt->secureDelete = 1; #endif - pBt->pageSize = get2byte(&zDbHeader[16]); + pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16); if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ pBt->pageSize = 0; @@ -40391,7 +50136,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( if( rc ) goto btree_open_out; pBt->usableSize = pBt->pageSize - nReserve; assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ - + #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) /* Add the new BtShared object to the linked list sharable BtShareds. */ @@ -40456,6 +50201,14 @@ btree_open_out: sqlite3_free(pBt); sqlite3_free(p); *ppBtree = 0; + }else{ + /* If the B-Tree was successfully opened, set the pager-cache size to the + ** default value. Except, when opening on an existing shared pager-cache, + ** do not change the pager-cache size. + */ + if( sqlite3BtreeSchema(p, 0, 0)==0 ){ + sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE); + } } if( mutexOpen ){ assert( sqlite3_mutex_held(mutexOpen) ); @@ -40505,7 +50258,7 @@ static int removeFromSharingList(BtShared *pBt){ } /* -** Make sure pBt->pTmpSpace points to an allocation of +** Make sure pBt->pTmpSpace points to an allocation of ** MX_CELL_SIZE(pBt) bytes. */ static void allocateTempSpace(BtShared *pBt){ @@ -40549,7 +50302,7 @@ SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){ sqlite3BtreeLeave(p); /* If there are still other outstanding references to the shared-btree - ** structure, return now. The remainder of this procedure cleans + ** structure, return now. The remainder of this procedure cleans ** up the shared-btree. */ assert( p->wantToLock==0 && p->locked==0 ); @@ -40564,7 +50317,7 @@ SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){ if( pBt->xFreeSchema && pBt->pSchema ){ pBt->xFreeSchema(pBt->pSchema); } - sqlite3_free(pBt->pSchema); + sqlite3DbFree(0, pBt->pSchema); freeTempSpace(pBt); sqlite3_free(pBt); } @@ -40613,11 +50366,17 @@ SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){ ** probability of damage to near zero but with a write performance reduction. */ #ifndef SQLITE_OMIT_PAGER_PRAGMAS -SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){ +SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel( + Btree *p, /* The btree to set the safety level on */ + int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */ + int fullSync, /* PRAGMA fullfsync. */ + int ckptFullSync /* PRAGMA checkpoint_fullfync */ +){ BtShared *pBt = p->pBt; assert( sqlite3_mutex_held(p->db->mutex) ); + assert( level>=1 && level<=3 ); sqlite3BtreeEnter(p); - sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync); + sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync, ckptFullSync); sqlite3BtreeLeave(p); return SQLITE_OK; } @@ -40630,7 +50389,7 @@ SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync) SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree *p){ BtShared *pBt = p->pBt; int rc; - assert( sqlite3_mutex_held(p->db->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); sqlite3BtreeEnter(p); assert( pBt && pBt->pPager ); rc = sqlite3PagerNosync(pBt->pPager); @@ -40638,10 +50397,9 @@ SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree *p){ return rc; } -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) /* ** Change the default pages size and the number of reserved bytes per page. -** Or, if the page size has already been fixed, return SQLITE_READONLY +** Or, if the page size has already been fixed, return SQLITE_READONLY ** without changing anything. ** ** The page size must be a power of 2 between 512 and 65536. If the page @@ -40676,7 +50434,7 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, ((pageSize-1)&pageSize)==0 ){ assert( (pageSize & 7)==0 ); assert( !pBt->pPage1 && !pBt->pCursor ); - pBt->pageSize = (u16)pageSize; + pBt->pageSize = (u32)pageSize; freeTempSpace(pBt); } rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); @@ -40693,6 +50451,7 @@ SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){ return p->pBt->pageSize; } +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) /* ** Return the number of bytes of space at the end of every page that ** are intentually left unused. This is the "reserved" space that is @@ -40730,7 +50489,7 @@ SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ sqlite3BtreeEnter(p); if( newFlag>=0 ){ p->pBt->secureDelete = (newFlag!=0) ? 1 : 0; - } + } b = p->pBt->secureDelete; sqlite3BtreeLeave(p); return b; @@ -40740,7 +50499,7 @@ SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ /* ** Change the 'auto-vacuum' property of the database. If the 'autoVacuum' ** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it -** is disabled. The default value for the auto-vacuum property is +** is disabled. The default value for the auto-vacuum property is ** determined by the SQLITE_DEFAULT_AUTOVACUUM macro. */ SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ @@ -40764,7 +50523,7 @@ SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ } /* -** Return the value of the 'auto-vacuum' property. If auto-vacuum is +** Return the value of the 'auto-vacuum' property. If auto-vacuum is ** enabled 1 is returned. Otherwise 0. */ SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){ @@ -40791,12 +50550,14 @@ SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){ ** SQLITE_OK is returned on success. If the file is not a ** well-formed database file, then SQLITE_CORRUPT is returned. ** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM -** is returned if we run out of memory. +** is returned if we run out of memory. */ static int lockBtree(BtShared *pBt){ - int rc; - MemPage *pPage1; - int nPage; + int rc; /* Result code from subfunctions */ + MemPage *pPage1; /* Page 1 of the database file */ + int nPage; /* Number of pages in the database */ + int nPageFile = 0; /* Number of pages in the database file */ + int nPageHeader; /* Number of pages in the database according to hdr */ assert( sqlite3_mutex_held(pBt->mutex) ); assert( pBt->pPage1==0 ); @@ -40806,25 +50567,57 @@ static int lockBtree(BtShared *pBt){ if( rc!=SQLITE_OK ) return rc; /* Do some checking to help insure the file we opened really is - ** a valid database file. + ** a valid database file. */ - rc = sqlite3PagerPagecount(pBt->pPager, &nPage); - if( rc!=SQLITE_OK ){ - goto page1_init_failed; - }else if( nPage>0 ){ - int pageSize; - int usableSize; + nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData); + sqlite3PagerPagecount(pBt->pPager, &nPageFile); + if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ + nPage = nPageFile; + } + if( nPage>0 ){ + u32 pageSize; + u32 usableSize; u8 *page1 = pPage1->aData; rc = SQLITE_NOTADB; if( memcmp(page1, zMagicHeader, 16)!=0 ){ goto page1_init_failed; } + +#ifdef SQLITE_OMIT_WAL if( page1[18]>1 ){ pBt->readOnly = 1; } if( page1[19]>1 ){ goto page1_init_failed; } +#else + if( page1[18]>2 ){ + pBt->readOnly = 1; + } + if( page1[19]>2 ){ + goto page1_init_failed; + } + + /* If the write version is set to 2, this database should be accessed + ** in WAL mode. If the log is not already open, open it now. Then + ** return SQLITE_OK and return without populating BtShared.pPage1. + ** The caller detects this and calls this function again. This is + ** required as the version of page 1 currently in the page1 buffer + ** may not be the latest version - there may be a newer one in the log + ** file. + */ + if( page1[19]==2 && pBt->doNotUseWAL==0 ){ + int isOpen = 0; + rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); + if( rc!=SQLITE_OK ){ + goto page1_init_failed; + }else if( isOpen==0 ){ + releasePage(pPage1); + return SQLITE_OK; + } + rc = SQLITE_NOTADB; + } +#endif /* The maximum embedded fraction must be exactly 25%. And the minimum ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data. @@ -40834,15 +50627,16 @@ static int lockBtree(BtShared *pBt){ if( memcmp(&page1[21], "\100\040\040",3)!=0 ){ goto page1_init_failed; } - pageSize = get2byte(&page1[16]); - if( ((pageSize-1)&pageSize)!=0 || pageSize<512 || - (SQLITE_MAX_PAGE_SIZE<32768 && pageSize>SQLITE_MAX_PAGE_SIZE) + pageSize = (page1[16]<<8) | (page1[17]<<16); + if( ((pageSize-1)&pageSize)!=0 + || pageSize>SQLITE_MAX_PAGE_SIZE + || pageSize<=256 ){ goto page1_init_failed; } assert( (pageSize & 7)==0 ); usableSize = pageSize - page1[20]; - if( pageSize!=pBt->pageSize ){ + if( (u32)pageSize!=pBt->pageSize ){ /* After reading the first page of the database assuming a page size ** of BtShared.pageSize, we have discovered that the page-size is ** actually pageSize. Unlock the database, leave pBt->pPage1 at @@ -40850,18 +50644,22 @@ static int lockBtree(BtShared *pBt){ ** again with the correct page-size. */ releasePage(pPage1); - pBt->usableSize = (u16)usableSize; - pBt->pageSize = (u16)pageSize; + pBt->usableSize = usableSize; + pBt->pageSize = pageSize; freeTempSpace(pBt); rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, pageSize-usableSize); return rc; } + if( (pBt->db->flags & SQLITE_RecoveryMode)==0 && nPage>nPageFile ){ + rc = SQLITE_CORRUPT_BKPT; + goto page1_init_failed; + } if( usableSize<480 ){ goto page1_init_failed; } - pBt->pageSize = (u16)pageSize; - pBt->usableSize = (u16)usableSize; + pBt->pageSize = pageSize; + pBt->usableSize = usableSize; #ifndef SQLITE_OMIT_AUTOVACUUM pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0); pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0); @@ -40877,16 +50675,17 @@ static int lockBtree(BtShared *pBt){ ** 9-byte nKey value ** 4-byte nData value ** 4-byte overflow page pointer - ** So a cell consists of a 2-byte poiner, a header which is as much as + ** So a cell consists of a 2-byte pointer, a header which is as much as ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow ** page pointer. */ - pBt->maxLocal = (pBt->usableSize-12)*64/255 - 23; - pBt->minLocal = (pBt->usableSize-12)*32/255 - 23; - pBt->maxLeaf = pBt->usableSize - 35; - pBt->minLeaf = (pBt->usableSize-12)*32/255 - 23; + pBt->maxLocal = (u16)((pBt->usableSize-12)*64/255 - 23); + pBt->minLocal = (u16)((pBt->usableSize-12)*32/255 - 23); + pBt->maxLeaf = (u16)(pBt->usableSize - 35); + pBt->minLeaf = (u16)((pBt->usableSize-12)*32/255 - 23); assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); pBt->pPage1 = pPage1; + pBt->nPage = nPage; return SQLITE_OK; page1_init_failed: @@ -40898,7 +50697,7 @@ page1_init_failed: /* ** If there are no outstanding cursors and we are not in the middle ** of a transaction but there is a read lock on the database, then -** this routine unrefs the first page of the database file which +** this routine unrefs the first page of the database file which ** has the effect of releasing the read lock. ** ** If there is a transaction in progress, this routine is a no-op. @@ -40924,12 +50723,10 @@ static int newDatabase(BtShared *pBt){ MemPage *pP1; unsigned char *data; int rc; - int nPage; assert( sqlite3_mutex_held(pBt->mutex) ); - rc = sqlite3PagerPagecount(pBt->pPager, &nPage); - if( rc!=SQLITE_OK || nPage>0 ){ - return rc; + if( pBt->nPage>0 ){ + return SQLITE_OK; } pP1 = pBt->pPage1; assert( pP1!=0 ); @@ -40938,7 +50735,8 @@ static int newDatabase(BtShared *pBt){ if( rc ) return rc; memcpy(data, zMagicHeader, sizeof(zMagicHeader)); assert( sizeof(zMagicHeader)==16 ); - put2byte(&data[16], pBt->pageSize); + data[16] = (u8)((pBt->pageSize>>8)&0xff); + data[17] = (u8)((pBt->pageSize>>16)&0xff); data[18] = 1; data[19] = 1; assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize); @@ -40955,6 +50753,8 @@ static int newDatabase(BtShared *pBt){ put4byte(&data[36 + 4*4], pBt->autoVacuum); put4byte(&data[36 + 7*4], pBt->incrVacuum); #endif + pBt->nPage = 1; + data[31] = 1; return SQLITE_OK; } @@ -40967,8 +50767,8 @@ static int newDatabase(BtShared *pBt){ ** upgraded to exclusive by calling this routine a second time - the ** exclusivity flag only works for a new transaction. ** -** A write-transaction must be started before attempting any -** changes to the database. None of the following routines +** A write-transaction must be started before attempting any +** changes to the database. None of the following routines ** will work unless a transaction is started first: ** ** sqlite3BtreeCreateTable() @@ -40982,7 +50782,7 @@ static int newDatabase(BtShared *pBt){ ** If an initial attempt to acquire the lock fails because of lock contention ** and the database was previously unlocked, then invoke the busy handler ** if there is one. But if there was previously a read-lock, do not -** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is +** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is ** returned when there is already a read-lock in order to avoid a deadlock. ** ** Suppose there are two processes A and B. A has a read lock and B has @@ -41016,7 +50816,7 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ } #ifndef SQLITE_OMIT_SHARED_CACHE - /* If another database handle has already opened a write transaction + /* If another database handle has already opened a write transaction ** on this shared-btree structure and a second write transaction is ** requested, return SQLITE_LOCKED. */ @@ -41038,17 +50838,18 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ } #endif - /* Any read-only or read-write transaction implies a read-lock on - ** page 1. So if some other shared-cache client already has a write-lock + /* Any read-only or read-write transaction implies a read-lock on + ** page 1. So if some other shared-cache client already has a write-lock ** on page 1, the transaction cannot be opened. */ rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); if( SQLITE_OK!=rc ) goto trans_begun; + pBt->initiallyEmpty = (u8)(pBt->nPage==0); do { /* Call lockBtree() until either pBt->pPage1 is populated or ** lockBtree() returns something other than SQLITE_OK. lockBtree() ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after - ** reading page 1 it discovers that the page-size of the database + ** reading page 1 it discovers that the page-size of the database ** file is not pBt->pageSize. In this case lockBtree() will update ** pBt->pageSize to the page-size of the file on disk. */ @@ -41064,11 +50865,11 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ } } } - + if( rc!=SQLITE_OK ){ unlockBtreeIfUnused(pBt); } - }while( rc==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && + }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && btreeInvokeBusyHandler(pBt) ); if( rc==SQLITE_OK ){ @@ -41087,13 +50888,27 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ if( p->inTrans>pBt->inTransaction ){ pBt->inTransaction = p->inTrans; } -#ifndef SQLITE_OMIT_SHARED_CACHE if( wrflag ){ + MemPage *pPage1 = pBt->pPage1; +#ifndef SQLITE_OMIT_SHARED_CACHE assert( !pBt->pWriter ); pBt->pWriter = p; pBt->isExclusive = (u8)(wrflag>1); - } #endif + + /* If the db-size header field is incorrect (as it may be if an old + ** client has been writing the database file), update it now. Doing + ** this sooner rather than later means the database size can safely + ** re-read the database size from page 1 if a savepoint or transaction + ** rollback occurs within the transaction. + */ + if( pBt->nPage!=get4byte(&pPage1->aData[28]) ){ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pPage1->aData[28], pBt->nPage); + } + } + } } @@ -41159,7 +50974,7 @@ set_child_ptrmaps_out: ** that it points to iTo. Parameter eType describes the type of pointer to ** be modified, as follows: ** -** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child +** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child ** page of pPage. ** ** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow @@ -41190,11 +51005,12 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ if( eType==PTRMAP_OVERFLOW1 ){ CellInfo info; btreeParseCellPtr(pPage, pCell, &info); - if( info.iOverflow ){ - if( iFrom==get4byte(&pCell[info.iOverflow]) ){ - put4byte(&pCell[info.iOverflow], iTo); - break; - } + if( info.iOverflow + && pCell+info.iOverflow+3<=pPage->aData+pPage->maskPage + && iFrom==get4byte(&pCell[info.iOverflow]) + ){ + put4byte(&pCell[info.iOverflow], iTo); + break; } }else{ if( get4byte(pCell)==iFrom ){ @@ -41203,9 +51019,9 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ } } } - + if( i==nCell ){ - if( eType!=PTRMAP_BTREE || + if( eType!=PTRMAP_BTREE || get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ return SQLITE_CORRUPT_BKPT; } @@ -41219,11 +51035,11 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ /* -** Move the open database page pDbPage to location iFreePage in the +** Move the open database page pDbPage to location iFreePage in the ** database. The pDbPage reference remains valid. ** ** The isCommit flag indicates that there is no need to remember that -** the journal needs to be sync()ed before database page pDbPage->pgno +** the journal needs to be sync()ed before database page pDbPage->pgno ** can be written to. The caller has already promised not to write to that ** page. */ @@ -41240,13 +51056,13 @@ static int relocatePage( Pager *pPager = pBt->pPager; int rc; - assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || + assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); assert( sqlite3_mutex_held(pBt->mutex) ); assert( pDbPage->pBt==pBt ); /* Move page iDbPage from its current location to page number iFreePage */ - TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", + TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", iDbPage, iFreePage, iPtrPage, eType)); rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); if( rc!=SQLITE_OK ){ @@ -41308,14 +51124,14 @@ static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8); ** return SQLITE_OK. If there is no work to do (and therefore no ** point in calling this function again), return SQLITE_DONE. ** -** More specificly, this function attempts to re-organize the +** More specificly, this function attempts to re-organize the ** database so that the last page of the file currently in use ** is no longer in use. ** ** If the nFin parameter is non-zero, this function assumes ** that the caller will keep calling incrVacuumStep() until ** it returns SQLITE_DONE or an error, and that nFin is the -** number of pages the database file will contain after this +** number of pages the database file will contain after this ** process is complete. If nFin is zero, it is assumed that ** incrVacuumStep() will be called a finite amount of times ** which may or may not empty the freelist. A full autovacuum @@ -41323,12 +51139,12 @@ static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8); */ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){ Pgno nFreeList; /* Number of pages still on the free-list */ + int rc; assert( sqlite3_mutex_held(pBt->mutex) ); assert( iLastPg>nFin ); if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){ - int rc; u8 eType; Pgno iPtrPage; @@ -41349,7 +51165,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){ if( nFin==0 ){ /* Remove the page from the files free-list. This is not required ** if nFin is non-zero. In that case, the free-list will be - ** truncated to zero after this function returns, so it doesn't + ** truncated to zero after this function returns, so it doesn't ** matter if it still contains some garbage entries. */ Pgno iFreePg; @@ -41387,7 +51203,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){ releasePage(pFreePg); }while( nFin!=0 && iFreePg>nFin ); assert( iFreePg<iLastPg ); - + rc = sqlite3PagerWrite(pLastPg->pDbPage); if( rc==SQLITE_OK ){ rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, nFin!=0); @@ -41404,7 +51220,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){ while( iLastPg==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, iLastPg) ){ if( PTRMAP_ISPAGE(pBt, iLastPg) ){ MemPage *pPg; - int rc = btreeGetPage(pBt, iLastPg, &pPg, 0); + rc = btreeGetPage(pBt, iLastPg, &pPg, 0); if( rc!=SQLITE_OK ){ return rc; } @@ -41417,6 +51233,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){ iLastPg--; } sqlite3PagerTruncateImage(pBt->pPager, iLastPg); + pBt->nPage = iLastPg; } return SQLITE_OK; } @@ -41427,7 +51244,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){ ** ** If the incremental vacuum is finished after this function has run, ** SQLITE_DONE is returned. If it is not finished, but no error occurred, -** SQLITE_OK is returned. Otherwise an SQLite error code. +** SQLITE_OK is returned. Otherwise an SQLite error code. */ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){ int rc; @@ -41439,7 +51256,11 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){ rc = SQLITE_DONE; }else{ invalidateAllOverflowCache(pBt); - rc = incrVacuumStep(pBt, 0, pagerPagecount(pBt)); + rc = incrVacuumStep(pBt, 0, btreePagecount(pBt)); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + put4byte(&pBt->pPage1->aData[28], pBt->nPage); + } } sqlite3BtreeLeave(p); return rc; @@ -41450,7 +51271,7 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){ ** is commited for an auto-vacuum database. ** ** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages -** the database file should be truncated to during the commit process. +** the database file should be truncated to during the commit process. ** i.e. the database has been reorganized so that only the first *pnTrunc ** pages are in use. */ @@ -41470,7 +51291,7 @@ static int autoVacuumCommit(BtShared *pBt){ int nEntry; /* Number of entries on one ptrmap page */ Pgno nOrig; /* Database size before freeing */ - nOrig = pagerPagecount(pBt); + nOrig = btreePagecount(pBt); if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){ /* It is not possible to create a database for which the final page ** is either a pointer-map page or the pending-byte page. If one @@ -41495,11 +51316,12 @@ static int autoVacuumCommit(BtShared *pBt){ rc = incrVacuumStep(pBt, nFin, iFree); } if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){ - rc = SQLITE_OK; rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); put4byte(&pBt->pPage1->aData[32], 0); put4byte(&pBt->pPage1->aData[36], 0); + put4byte(&pBt->pPage1->aData[28], nFin); sqlite3PagerTruncateImage(pBt->pPager, nFin); + pBt->nPage = nFin; } if( rc!=SQLITE_OK ){ sqlite3PagerRollback(pPager); @@ -41531,7 +51353,7 @@ static int autoVacuumCommit(BtShared *pBt){ ** ** Otherwise, sync the database file for the btree pBt. zMaster points to ** the name of a master journal file that should be written into the -** individual journal file, or is NULL, indicating no master journal file +** individual journal file, or is NULL, indicating no master journal file ** (single database transaction). ** ** When this is called, the master journal should already have been @@ -41576,8 +51398,8 @@ static void btreeEndTransaction(Btree *p){ downgradeAllSharedCacheTableLocks(p); p->inTrans = TRANS_READ; }else{ - /* If the handle had any kind of transaction open, decrement the - ** transaction count of the shared btree. If the transaction count + /* If the handle had any kind of transaction open, decrement the + ** transaction count of the shared btree. If the transaction count ** reaches 0, set the shared state to TRANS_NONE. The unlockBtreeIfUnused() ** call below will unlock the pager. */ if( p->inTrans!=TRANS_NONE ){ @@ -41588,7 +51410,7 @@ static void btreeEndTransaction(Btree *p){ } } - /* Set the current transaction state to TRANS_NONE and unlock the + /* Set the current transaction state to TRANS_NONE and unlock the ** pager if this call closed the only read or write transaction. */ p->inTrans = TRANS_NONE; unlockBtreeIfUnused(pBt); @@ -41609,24 +51431,36 @@ static void btreeEndTransaction(Btree *p){ ** the rollback journal (which causes the transaction to commit) and ** drop locks. ** +** Normally, if an error occurs while the pager layer is attempting to +** finalize the underlying journal file, this function returns an error and +** the upper layer will attempt a rollback. However, if the second argument +** is non-zero then this b-tree transaction is part of a multi-file +** transaction. In this case, the transaction has already been committed +** (by deleting a master journal file) and the caller will ignore this +** functions return code. So, even if an error occurs in the pager layer, +** reset the b-tree objects internal state to indicate that the write +** transaction has been closed. This is quite safe, as the pager will have +** transitioned to the error state. +** ** This will release the write lock on the database file. If there ** are no active cursors, it also releases the read lock. */ -SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p){ - BtShared *pBt = p->pBt; +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ + if( p->inTrans==TRANS_NONE ) return SQLITE_OK; sqlite3BtreeEnter(p); btreeIntegrity(p); - /* If the handle has a write-transaction open, commit the shared-btrees + /* If the handle has a write-transaction open, commit the shared-btrees ** transaction and set the shared state to TRANS_READ. */ if( p->inTrans==TRANS_WRITE ){ int rc; + BtShared *pBt = p->pBt; assert( pBt->inTransaction==TRANS_WRITE ); assert( pBt->nTransaction>0 ); rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); - if( rc!=SQLITE_OK ){ + if( rc!=SQLITE_OK && bCleanup==0 ){ sqlite3BtreeLeave(p); return rc; } @@ -41646,7 +51480,7 @@ SQLITE_PRIVATE int sqlite3BtreeCommit(Btree *p){ sqlite3BtreeEnter(p); rc = sqlite3BtreeCommitPhaseOne(p, 0); if( rc==SQLITE_OK ){ - rc = sqlite3BtreeCommitPhaseTwo(p); + rc = sqlite3BtreeCommitPhaseTwo(p, 0); } sqlite3BtreeLeave(p); return rc; @@ -41667,7 +51501,7 @@ static int countWriteCursors(BtShared *pBt){ BtCursor *pCur; int r = 0; for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ - if( pCur->wrFlag && pCur->eState!=CURSOR_FAULT ) r++; + if( pCur->wrFlag && pCur->eState!=CURSOR_FAULT ) r++; } return r; } @@ -41726,9 +51560,9 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p){ if( rc!=SQLITE_OK ){ /* This is a horrible situation. An IO or malloc() error occurred whilst ** trying to save cursor positions. If this is an automatic rollback (as - ** the result of a constraint, malloc() failure or IO error) then + ** the result of a constraint, malloc() failure or IO error) then ** the cache may be internally inconsistent (not contain valid trees) so - ** we cannot simply return the error to the caller. Instead, abort + ** we cannot simply return the error to the caller. Instead, abort ** all queries that may be using any of the cursors that failed to save. */ sqlite3BtreeTripAllCursors(p, rc); @@ -41749,6 +51583,11 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p){ ** call btreeGetPage() on page 1 again to make ** sure pPage1->aData is set correctly. */ if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){ + int nPage = get4byte(28+(u8*)pPage1->aData); + testcase( nPage==0 ); + if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); + testcase( pBt->nPage!=nPage ); + pBt->nPage = nPage; releasePage(pPage1); } assert( countWriteCursors(pBt)==0 ); @@ -41762,8 +51601,8 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p){ /* ** Start a statement subtransaction. The subtransaction can can be rolled -** back independently of the main transaction. You must start a transaction -** before starting a subtransaction. The subtransaction is ended automatically +** back independently of the main transaction. You must start a transaction +** before starting a subtransaction. The subtransaction is ended automatically ** if the main transaction commits or rolls back. ** ** Statement subtransactions are used around individual SQL statements @@ -41786,17 +51625,13 @@ SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree *p, int iStatement){ assert( pBt->readOnly==0 ); assert( iStatement>0 ); assert( iStatement>p->db->nSavepoint ); - if( NEVER(p->inTrans!=TRANS_WRITE || pBt->readOnly) ){ - rc = SQLITE_INTERNAL; - }else{ - assert( pBt->inTransaction==TRANS_WRITE ); - /* At the pager level, a statement transaction is a savepoint with - ** an index greater than all savepoints created explicitly using - ** SQL statements. It is illegal to open, release or rollback any - ** such savepoints while the statement transaction savepoint is active. - */ - rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement); - } + assert( pBt->inTransaction==TRANS_WRITE ); + /* At the pager level, a statement transaction is a savepoint with + ** an index greater than all savepoints created explicitly using + ** SQL statements. It is illegal to open, release or rollback any + ** such savepoints while the statement transaction savepoint is active. + */ + rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement); sqlite3BtreeLeave(p); return rc; } @@ -41804,11 +51639,11 @@ SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree *p, int iStatement){ /* ** The second argument to this function, op, is always SAVEPOINT_ROLLBACK ** or SAVEPOINT_RELEASE. This function either releases or rolls back the -** savepoint identified by parameter iSavepoint, depending on the value +** savepoint identified by parameter iSavepoint, depending on the value ** of op. ** ** Normally, iSavepoint is greater than or equal to zero. However, if op is -** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the +** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the ** contents of the entire transaction are rolled back. This is different ** from a normal transaction rollback, as no locks are released and the ** transaction remains open. @@ -41822,7 +51657,14 @@ SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ sqlite3BtreeEnter(p); rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); if( rc==SQLITE_OK ){ + if( iSavepoint<0 && pBt->initiallyEmpty ) pBt->nPage = 0; rc = newDatabase(pBt); + pBt->nPage = get4byte(28 + pBt->pPage1->aData); + + /* The database size was written into the offset 28 of the header + ** when the transaction started, so we know that the value at offset + ** 28 is nonzero. */ + assert( pBt->nPage>0 ); } sqlite3BtreeLeave(p); } @@ -41873,9 +51715,9 @@ static int btreeCursor( assert( sqlite3BtreeHoldsMutex(p) ); assert( wrFlag==0 || wrFlag==1 ); - /* The following assert statements verify that if this is a sharable - ** b-tree database, the connection is holding the required table locks, - ** and that no other connection has any open cursor that conflicts with + /* The following assert statements verify that if this is a sharable + ** b-tree database, the connection is holding the required table locks, + ** and that no other connection has any open cursor that conflicts with ** this lock. */ assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, wrFlag+1) ); assert( wrFlag==0 || !hasReadConflicts(p, iTable) ); @@ -41888,8 +51730,9 @@ static int btreeCursor( if( NEVER(wrFlag && pBt->readOnly) ){ return SQLITE_READONLY; } - if( iTable==1 && pagerPagecount(pBt)==0 ){ - return SQLITE_EMPTY; + if( iTable==1 && btreePagecount(pBt)==0 ){ + assert( wrFlag==0 ); + iTable = 0; } /* Now that no other errors can occur, finish filling in the BtCursor @@ -42070,14 +51913,14 @@ SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){ /* ** Set *pSize to the size of the buffer needed to hold the value of ** the key for the current entry. If the cursor is not pointing -** to a valid entry, *pSize is set to 0. +** to a valid entry, *pSize is set to 0. ** ** For a table with the INTKEY flag set, this routine returns the key ** itself, not the number of bytes in the key. ** ** The caller must position the cursor prior to invoking this routine. -** -** This routine cannot fail. It always returns SQLITE_OK. +** +** This routine cannot fail. It always returns SQLITE_OK. */ SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){ assert( cursorHoldsMutex(pCur) ); @@ -42113,15 +51956,15 @@ SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){ /* ** Given the page number of an overflow page in the database (parameter -** ovfl), this function finds the page number of the next page in the +** ovfl), this function finds the page number of the next page in the ** linked list of overflow pages. If possible, it uses the auto-vacuum -** pointer-map data instead of reading the content of page ovfl to do so. +** pointer-map data instead of reading the content of page ovfl to do so. ** ** If an error occurs an SQLite error code is returned. Otherwise: ** -** The page number of the next overflow page in the linked list is -** written to *pPgnoNext. If page ovfl is the last page in its linked -** list, *pPgnoNext is set to zero. +** The page number of the next overflow page in the linked list is +** written to *pPgnoNext. If page ovfl is the last page in its linked +** list, *pPgnoNext is set to zero. ** ** If ppPage is not NULL, and a reference to the MemPage object corresponding ** to page number pOvfl was obtained, then *ppPage is set to point to that @@ -42145,9 +51988,9 @@ static int getOverflowPage( #ifndef SQLITE_OMIT_AUTOVACUUM /* Try to find the next page in the overflow list using the - ** autovacuum pointer-map pages. Guess that the next page in - ** the overflow list is page number (ovfl+1). If that guess turns - ** out to be wrong, fall back to loading the data of page + ** autovacuum pointer-map pages. Guess that the next page in + ** the overflow list is page number (ovfl+1). If that guess turns + ** out to be wrong, fall back to loading the data of page ** number ovfl to determine the next page number. */ if( pBt->autoVacuum ){ @@ -42159,7 +52002,7 @@ static int getOverflowPage( iGuess++; } - if( iGuess<=pagerPagecount(pBt) ){ + if( iGuess<=btreePagecount(pBt) ){ rc = ptrmapGet(pBt, iGuess, &eType, &pgno); if( rc==SQLITE_OK && eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){ next = iGuess; @@ -42234,7 +52077,7 @@ static int copyPayload( ** ** If the BtCursor.isIncrblobHandle flag is set, and the current ** cursor entry uses one or more overflow pages, this function -** allocates space for and lazily popluates the overflow page-list +** allocates space for and lazily popluates the overflow page-list ** cache array (BtCursor.aOverflow). Subsequent calls use this ** cache to make seeking to the supplied offset more efficient. ** @@ -42251,7 +52094,7 @@ static int accessPayload( BtCursor *pCur, /* Cursor pointing to entry to read from */ u32 offset, /* Begin reading this far into payload */ u32 amt, /* Read this many bytes */ - unsigned char *pBuf, /* Write the bytes into this buffer */ + unsigned char *pBuf, /* Write the bytes into this buffer */ int eOp /* zero to read. non-zero to write. */ ){ unsigned char *aPayload; @@ -42270,7 +52113,7 @@ static int accessPayload( aPayload = pCur->info.pCell + pCur->info.nHeader; nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey); - if( NEVER(offset+amt > nKey+pCur->info.nData) + if( NEVER(offset+amt > nKey+pCur->info.nData) || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ){ /* Trying to read or write past the end of the data is an error */ @@ -42346,7 +52189,7 @@ static int accessPayload( #ifndef SQLITE_OMIT_INCRBLOB if( pCur->aOverflow && pCur->aOverflow[iIdx+1] ){ nextPage = pCur->aOverflow[iIdx+1]; - } else + } else #endif rc = getOverflowPage(pBt, nextPage, 0, &nextPage); offset -= ovflSize; @@ -42429,7 +52272,7 @@ SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *p } /* -** Return a pointer to payload information from the entry that the +** Return a pointer to payload information from the entry that the ** pCur cursor is pointing to. The pointer is to the beginning of ** the key if skipKey==0 and it points to the beginning of data if ** skipKey==1. The number of bytes of available key/data is written @@ -42556,7 +52399,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ #ifndef NDEBUG /* -** Page pParent is an internal (non-leaf) tree page. This function +** Page pParent is an internal (non-leaf) tree page. This function ** asserts that page number iChild is the left-child if the iIdx'th ** cell in page pParent. Or, if iIdx is equal to the total number of ** cells in pParent, that page number iChild is the right-child of @@ -42571,7 +52414,7 @@ static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){ } } #else -# define assertParentIndex(x,y,z) +# define assertParentIndex(x,y,z) #endif /* @@ -42588,8 +52431,8 @@ static void moveToParent(BtCursor *pCur){ assert( pCur->iPage>0 ); assert( pCur->apPage[pCur->iPage] ); assertParentIndex( - pCur->apPage[pCur->iPage-1], - pCur->aiIdx[pCur->iPage-1], + pCur->apPage[pCur->iPage-1], + pCur->aiIdx[pCur->iPage-1], pCur->apPage[pCur->iPage]->pgno ); releasePage(pCur->apPage[pCur->iPage]); @@ -42603,19 +52446,19 @@ static void moveToParent(BtCursor *pCur){ ** ** If the table has a virtual root page, then the cursor is moved to point ** to the virtual root page instead of the actual root page. A table has a -** virtual root page when the actual root page contains no cells and a +** virtual root page when the actual root page contains no cells and a ** single child page. This can only happen with the table rooted at page 1. ** -** If the b-tree structure is empty, the cursor state is set to +** If the b-tree structure is empty, the cursor state is set to ** CURSOR_INVALID. Otherwise, the cursor is set to point to the first ** cell located on the root (or virtual root) page and the cursor state ** is set to CURSOR_VALID. ** ** If this function returns successfully, it may be assumed that the -** page-header flags indicate that the [virtual] root-page is the expected +** page-header flags indicate that the [virtual] root-page is the expected ** kind of b-tree page (i.e. if when opening the cursor the caller did not ** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D, -** indicating a table b-tree, or if the caller did specify a KeyInfo +** indicating a table b-tree, or if the caller did specify a KeyInfo ** structure the flags byte is set to 0x02 or 0x0A, indicating an index ** b-tree). */ @@ -42643,6 +52486,9 @@ static int moveToRoot(BtCursor *pCur){ releasePage(pCur->apPage[i]); } pCur->iPage = 0; + }else if( pCur->pgnoRoot==0 ){ + pCur->eState = CURSOR_INVALID; + return SQLITE_OK; }else{ rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0]); if( rc!=SQLITE_OK ){ @@ -42663,8 +52509,8 @@ static int moveToRoot(BtCursor *pCur){ /* Assert that the root page is of the correct type. This must be the ** case as the call to this function that loaded the root-page (either - ** this call or a previous invocation) would have detected corruption - ** if the assumption were not true, and it is not possible for the flags + ** this call or a previous invocation) would have detected corruption + ** if the assumption were not true, and it is not possible for the flags ** byte to have been modified while this cursor is holding a reference ** to the page. */ pRoot = pCur->apPage[0]; @@ -42752,9 +52598,8 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ rc = moveToRoot(pCur); if( rc==SQLITE_OK ){ if( pCur->eState==CURSOR_INVALID ){ - assert( pCur->apPage[pCur->iPage]->nCell==0 ); + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); *pRes = 1; - rc = SQLITE_OK; }else{ assert( pCur->apPage[pCur->iPage]->nCell>0 ); *pRes = 0; @@ -42770,14 +52615,14 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ */ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ int rc; - + assert( cursorHoldsMutex(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->atLast ){ #ifdef SQLITE_DEBUG - /* This block serves to assert() that the cursor really does point + /* This block serves to assert() that the cursor really does point ** to the last entry in the b-tree. */ int ii; for(ii=0; ii<pCur->iPage; ii++){ @@ -42792,7 +52637,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ rc = moveToRoot(pCur); if( rc==SQLITE_OK ){ if( CURSOR_INVALID==pCur->eState ){ - assert( pCur->apPage[pCur->iPage]->nCell==0 ); + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); *pRes = 1; }else{ assert( pCur->eState==CURSOR_VALID ); @@ -42804,10 +52649,10 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ return rc; } -/* Move the cursor so that it points to an entry near the key +/* Move the cursor so that it points to an entry near the key ** specified by pIdxKey or intKey. Return a success code. ** -** For INTKEY tables, the intKey parameter is used. pIdxKey +** For INTKEY tables, the intKey parameter is used. pIdxKey ** must be NULL. For index tables, pIdxKey is used and intKey ** is ignored. ** @@ -42817,7 +52662,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ ** before or after the key. ** ** An integer is written into *pRes which is the result of -** comparing the key with the entry to which the cursor is +** comparing the key with the entry to which the cursor is ** pointing. The meaning of the integer written into ** *pRes is as follows: ** @@ -42848,8 +52693,8 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( /* If the cursor is already positioned at the point we are trying ** to move to, then just return without doing any work */ - if( pCur->eState==CURSOR_VALID && pCur->validNKey - && pCur->apPage[0]->intKey + if( pCur->eState==CURSOR_VALID && pCur->validNKey + && pCur->apPage[0]->intKey ){ if( pCur->info.nKey==intKey ){ *pRes = 0; @@ -42865,17 +52710,17 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( if( rc ){ return rc; } - assert( pCur->apPage[pCur->iPage] ); - assert( pCur->apPage[pCur->iPage]->isInit ); - assert( pCur->apPage[pCur->iPage]->nCell>0 || pCur->eState==CURSOR_INVALID ); + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage] ); + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->isInit ); + assert( pCur->eState==CURSOR_INVALID || pCur->apPage[pCur->iPage]->nCell>0 ); if( pCur->eState==CURSOR_INVALID ){ *pRes = -1; - assert( pCur->apPage[pCur->iPage]->nCell==0 ); + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); return SQLITE_OK; } assert( pCur->apPage[0]->intKey || pIdxKey ); for(;;){ - int lwr, upr; + int lwr, upr, idx; Pgno chldPg; MemPage *pPage = pCur->apPage[pCur->iPage]; int c; @@ -42891,14 +52736,14 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( lwr = 0; upr = pPage->nCell-1; if( biasRight ){ - pCur->aiIdx[pCur->iPage] = (u16)upr; + pCur->aiIdx[pCur->iPage] = (u16)(idx = upr); }else{ - pCur->aiIdx[pCur->iPage] = (u16)((upr+lwr)/2); + pCur->aiIdx[pCur->iPage] = (u16)(idx = (upr+lwr)/2); } for(;;){ - int idx = pCur->aiIdx[pCur->iPage]; /* Index of current cell in pPage */ u8 *pCell; /* Pointer to current cell in pPage */ + assert( idx==pCur->aiIdx[pCur->iPage] ); pCur->info.nSize = 0; pCell = findCell(pPage, idx) + pPage->childPtrSize; if( pPage->intKey ){ @@ -42919,12 +52764,12 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( pCur->validNKey = 1; pCur->info.nKey = nCellKey; }else{ - /* The maximum supported page-size is 32768 bytes. This means that + /* The maximum supported page-size is 65536 bytes. This means that ** the maximum number of record bytes stored on an index B-Tree - ** page is at most 8198 bytes, which may be stored as a 2-byte - ** varint. This information is used to attempt to avoid parsing - ** the entire cell by checking for the cases where the record is - ** stored entirely within the b-tree page by inspecting the first + ** page is less than 16384 bytes and may be stored as a 2-byte + ** varint. This information is used to attempt to avoid parsing + ** the entire cell by checking for the cases where the record is + ** stored entirely within the b-tree page by inspecting the first ** 2 bytes of the cell. */ int nCell = pCell[0]; @@ -42933,10 +52778,10 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( ** single byte varint and the record fits entirely on the main ** b-tree page. */ c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey); - }else if( !(pCell[1] & 0x80) + }else if( !(pCell[1] & 0x80) && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal ){ - /* The record-size field is a 2 byte varint and the record + /* The record-size field is a 2 byte varint and the record ** fits entirely on the main b-tree page. */ c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey); }else{ @@ -42981,7 +52826,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( if( lwr>upr ){ break; } - pCur->aiIdx[pCur->iPage] = (u16)((lwr+upr)/2); + pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2); } assert( lwr==upr+1 ); assert( pPage->isInit ); @@ -43165,19 +53010,19 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ ** an error. *ppPage and *pPgno are undefined in the event of an error. ** Do not invoke sqlite3PagerUnref() on *ppPage if an error is returned. ** -** If the "nearby" parameter is not 0, then a (feeble) effort is made to +** If the "nearby" parameter is not 0, then a (feeble) effort is made to ** locate a page close to the page number "nearby". This can be used in an ** attempt to keep related pages close to each other in the database file, ** which in turn can make database access faster. ** -** If the "exact" parameter is not 0, and the page-number nearby exists +** If the "exact" parameter is not 0, and the page-number nearby exists ** anywhere on the free-list, then it is guarenteed to be returned. This ** is only used by auto-vacuum databases when allocating a new table. */ static int allocateBtreePage( - BtShared *pBt, - MemPage **ppPage, - Pgno *pPgno, + BtShared *pBt, + MemPage **ppPage, + Pgno *pPgno, Pgno nearby, u8 exact ){ @@ -43191,7 +53036,7 @@ static int allocateBtreePage( assert( sqlite3_mutex_held(pBt->mutex) ); pPage1 = pBt->pPage1; - mxPage = pagerPagecount(pBt); + mxPage = btreePagecount(pBt); n = get4byte(&pPage1->aData[36]); testcase( n==mxPage-1 ); if( n>=mxPage ){ @@ -43201,7 +53046,7 @@ static int allocateBtreePage( /* There are pages on the freelist. Reuse one of those pages. */ Pgno iTrunk; u8 searchList = 0; /* If the free-list must be searched for 'nearby' */ - + /* If the 'exact' parameter was true and a query of the pointer-map ** shows that the page 'nearby' is somewhere on the free-list, then ** the entire-list will be searched for that page. @@ -43249,10 +53094,10 @@ static int allocateBtreePage( goto end_allocate_page; } - k = get4byte(&pTrunk->aData[4]); + k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */ if( k==0 && !searchList ){ - /* The trunk has no leaves and the list is not being searched. - ** So extract the trunk page itself and use it as the newly + /* The trunk has no leaves and the list is not being searched. + ** So extract the trunk page itself and use it as the newly ** allocated page */ assert( pPrevTrunk==0 ); rc = sqlite3PagerWrite(pTrunk->pDbPage); @@ -43284,16 +53129,20 @@ static int allocateBtreePage( if( !pPrevTrunk ){ memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); }else{ + rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); + if( rc!=SQLITE_OK ){ + goto end_allocate_page; + } memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4); } }else{ - /* The trunk page is required by the caller but it contains + /* The trunk page is required by the caller but it contains ** pointers to free-list leaves. The first leaf becomes a trunk ** page in this case. */ MemPage *pNewTrunk; Pgno iNewTrunk = get4byte(&pTrunk->aData[8]); - if( iNewTrunk>mxPage ){ + if( iNewTrunk>mxPage ){ rc = SQLITE_CORRUPT_BKPT; goto end_allocate_page; } @@ -43330,19 +53179,13 @@ static int allocateBtreePage( u32 closest; Pgno iPage; unsigned char *aData = pTrunk->aData; - rc = sqlite3PagerWrite(pTrunk->pDbPage); - if( rc ){ - goto end_allocate_page; - } if( nearby>0 ){ u32 i; int dist; closest = 0; - dist = get4byte(&aData[8]) - nearby; - if( dist<0 ) dist = -dist; + dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby); for(i=1; i<k; i++){ - int d2 = get4byte(&aData[8+i*4]) - nearby; - if( d2<0 ) d2 = -d2; + int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby); if( d2<dist ){ closest = i; dist = d2; @@ -43365,11 +53208,12 @@ static int allocateBtreePage( TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d" ": %d more free pages\n", *pPgno, closest+1, k, pTrunk->pgno, n-1)); + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc ) goto end_allocate_page; if( closest<k-1 ){ memcpy(&aData[8+closest*4], &aData[4+k*4], 4); } put4byte(&aData[4], k-1); - assert( sqlite3PagerIswriteable(pTrunk->pDbPage) ); noContent = !btreeGetHasContent(pBt, *pPgno); rc = btreeGetPage(pBt, *pPgno, ppPage, noContent); if( rc==SQLITE_OK ){ @@ -43387,35 +53231,35 @@ static int allocateBtreePage( }else{ /* There are no pages on the freelist, so create a new page at the ** end of the file */ - int nPage = pagerPagecount(pBt); - *pPgno = nPage + 1; - - if( *pPgno==PENDING_BYTE_PAGE(pBt) ){ - (*pPgno)++; - } + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc ) return rc; + pBt->nPage++; + if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++; #ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, *pPgno) ){ + if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, pBt->nPage) ){ /* If *pPgno refers to a pointer-map page, allocate two new pages ** at the end of the file instead of one. The first allocated page ** becomes a new pointer-map page, the second is used by the caller. */ MemPage *pPg = 0; - TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno)); - assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); - rc = btreeGetPage(pBt, *pPgno, &pPg, 0); + TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage)); + assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); + rc = btreeGetPage(pBt, pBt->nPage, &pPg, 1); if( rc==SQLITE_OK ){ rc = sqlite3PagerWrite(pPg->pDbPage); releasePage(pPg); } if( rc ) return rc; - (*pPgno)++; - if( *pPgno==PENDING_BYTE_PAGE(pBt) ){ (*pPgno)++; } + pBt->nPage++; + if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; } } #endif + put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage); + *pPgno = pBt->nPage; assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); - rc = btreeGetPage(pBt, *pPgno, ppPage, 0); + rc = btreeGetPage(pBt, *pPgno, ppPage, 1); if( rc ) return rc; rc = sqlite3PagerWrite((*ppPage)->pDbPage); if( rc!=SQLITE_OK ){ @@ -43438,16 +53282,17 @@ end_allocate_page: }else{ *ppPage = 0; } + assert( rc!=SQLITE_OK || sqlite3PagerIswriteable((*ppPage)->pDbPage) ); return rc; } /* -** This function is used to add page iPage to the database file free-list. +** This function is used to add page iPage to the database file free-list. ** It is assumed that the page is not already a part of the free-list. ** ** The value passed as the second argument to this function is optional. -** If the caller happens to have a pointer to the MemPage object -** corresponding to page iPage handy, it may pass it as the second value. +** If the caller happens to have a pointer to the MemPage object +** corresponding to page iPage handy, it may pass it as the second value. ** Otherwise, it may pass NULL. ** ** If a pointer to a MemPage object is passed as the second argument, @@ -43455,7 +53300,7 @@ end_allocate_page: */ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ MemPage *pTrunk = 0; /* Free-list trunk page */ - Pgno iTrunk = 0; /* Page number of free-list trunk page */ + Pgno iTrunk = 0; /* Page number of free-list trunk page */ MemPage *pPage1 = pBt->pPage1; /* Local reference to page 1 */ MemPage *pPage; /* Page being freed. May be NULL. */ int rc; /* Return Code */ @@ -43551,7 +53396,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ /* If control flows to this point, then it was not possible to add the ** the page being freed as a leaf page of the first trunk in the free-list. - ** Possibly because the free-list is empty, or possibly because the + ** Possibly because the free-list is empty, or possibly because the ** first trunk in the free-list is full. Either way, the page being freed ** will become the new first trunk page in the free-list. */ @@ -43590,13 +53435,16 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){ Pgno ovflPgno; int rc; int nOvfl; - u16 ovflPageSize; + u32 ovflPageSize; assert( sqlite3_mutex_held(pPage->pBt->mutex) ); btreeParseCellPtr(pPage, pCell, &info); if( info.iOverflow==0 ){ return SQLITE_OK; /* No overflow pages. Return without doing anything */ } + if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){ + return SQLITE_CORRUPT; /* Cell extends past end of page */ + } ovflPgno = get4byte(&pCell[info.iOverflow]); assert( pBt->usableSize > 4 ); ovflPageSize = pBt->usableSize - 4; @@ -43605,9 +53453,9 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){ while( nOvfl-- ){ Pgno iNext = 0; MemPage *pOvfl = 0; - if( ovflPgno<2 || ovflPgno>pagerPagecount(pBt) ){ - /* 0 is not a legal page number and page 1 cannot be an - ** overflow page. Therefore if ovflPgno<2 or past the end of the + if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){ + /* 0 is not a legal page number and page 1 cannot be an + ** overflow page. Therefore if ovflPgno<2 or past the end of the ** file the database must be corrupt. */ return SQLITE_CORRUPT_BKPT; } @@ -43619,11 +53467,11 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){ if( ( pOvfl || ((pOvfl = btreePageLookup(pBt, ovflPgno))!=0) ) && sqlite3PagerPageRefcount(pOvfl->pDbPage)!=1 ){ - /* There is no reason any cursor should have an outstanding reference + /* There is no reason any cursor should have an outstanding reference ** to an overflow page belonging to a cell that is being deleted/updated. - ** So if there exists more than one reference to this page, then it - ** must not really be an overflow page and the database must be corrupt. - ** It is helpful to detect this before calling freePage2(), as + ** So if there exists more than one reference to this page, then it + ** must not really be an overflow page and the database must be corrupt. + ** It is helpful to detect this before calling freePage2(), as ** freePage2() may zero the page contents if secure-delete mode is ** enabled. If this 'overflow' page happens to be a page that the ** caller is iterating through or using in some other way, this @@ -43698,14 +53546,14 @@ static int fillInCell( assert( info.nHeader==nHeader ); assert( info.nKey==nKey ); assert( info.nData==(u32)(nData+nZero) ); - + /* Fill in the payload */ nPayload = nData + nZero; if( pPage->intKey ){ pSrc = pData; nSrc = nData; nData = 0; - }else{ + }else{ if( NEVER(nKey>0x7fffffff || pKey==0) ){ return SQLITE_CORRUPT_BKPT; } @@ -43725,8 +53573,8 @@ static int fillInCell( if( pBt->autoVacuum ){ do{ pgnoOvfl++; - } while( - PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt) + } while( + PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt) ); } #endif @@ -43734,9 +53582,9 @@ static int fillInCell( #ifndef SQLITE_OMIT_AUTOVACUUM /* If the database supports auto-vacuum, and the second or subsequent ** overflow page is being allocated, add an entry to the pointer-map - ** for that page now. + ** for that page now. ** - ** If this is the first overflow page, then write a partial entry + ** If this is the first overflow page, then write a partial entry ** to the pointer-map. If we write nothing to this pointer-map slot, ** then the optimistic overflow chain processing in clearCell() ** may misinterpret the uninitialised values and delete the @@ -43814,10 +53662,10 @@ static int fillInCell( ** "sz" must be the number of bytes in the cell. */ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ - int i; /* Loop counter */ - int pc; /* Offset to cell content of cell being deleted */ + u32 pc; /* Offset to cell content of cell being deleted */ u8 *data; /* pPage->aData */ u8 *ptr; /* Used to move bytes around within data[] */ + u8 *endPtr; /* End of loop */ int rc; /* The return code */ int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ @@ -43833,7 +53681,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ hdr = pPage->hdrOffset; testcase( pc==get2byte(&data[hdr+5]) ); testcase( pc+sz==pPage->pBt->usableSize ); - if( pc < get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){ + if( pc < (u32)get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){ *pRC = SQLITE_CORRUPT_BKPT; return; } @@ -43842,9 +53690,11 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ *pRC = rc; return; } - for(i=idx+1; i<pPage->nCell; i++, ptr+=2){ - ptr[0] = ptr[2]; - ptr[1] = ptr[3]; + endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2]; + assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */ + while( ptr<endPtr ){ + *(u16*)ptr = *(u16*)&ptr[2]; + ptr += 2; } pPage->nCell--; put2byte(&data[hdr+3], pPage->nCell); @@ -43859,13 +53709,13 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ ** will not fit, then make a copy of the cell content into pTemp if ** pTemp is not null. Regardless of pTemp, allocate a new entry ** in pPage->aOvfl[] 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 +** in pTemp or the original pCell) and also record its index. +** Allocating a new entry in pPage->aCell[] implies that ** pPage->nOverflow is incremented. ** ** If nSkip is non-zero, then do not copy the first nSkip bytes of the ** cell. The caller will overwrite them after this function returns. If -** nSkip is non-zero, then pCell may not point to an invalid memory location +** nSkip is non-zero, then pCell may not point to an invalid memory location ** (but pCell+nSkip is always valid). */ static void insertCell( @@ -43884,13 +53734,14 @@ static void insertCell( int cellOffset; /* Address of first cell pointer in data[] */ u8 *data; /* The content of the whole page */ u8 *ptr; /* Used for moving information around in data[] */ + u8 *endPtr; /* End of the loop */ int nSkip = (iChild ? 4 : 0); if( *pRC ) return; assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); - assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 ); + assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=10921 ); assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); /* The cell should normally be sized correctly. However, when moving a @@ -43927,16 +53778,19 @@ static void insertCell( /* The allocateSpace() routine guarantees the following two properties ** if it returns success */ assert( idx >= end+2 ); - assert( idx+sz <= pPage->pBt->usableSize ); + assert( idx+sz <= (int)pPage->pBt->usableSize ); pPage->nCell++; pPage->nFree -= (u16)(2 + sz); memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip); if( iChild ){ put4byte(&data[idx], iChild); } - for(j=end, ptr=&data[j]; j>ins; j-=2, ptr-=2){ - ptr[0] = ptr[-2]; - ptr[1] = ptr[-1]; + ptr = &data[end]; + endPtr = &data[ins]; + assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */ + while( ptr>endPtr ){ + *(u16*)ptr = *(u16*)&ptr[-2]; + ptr -= 2; } put2byte(&data[ins], idx); put2byte(&data[pPage->hdrOffset+3], pPage->nCell); @@ -43970,20 +53824,22 @@ static void assemblePage( assert( pPage->nOverflow==0 ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( nCell>=0 && nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 ); + assert( nCell>=0 && nCell<=(int)MX_CELL(pPage->pBt) + && (int)MX_CELL(pPage->pBt)<=10921); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); /* Check that the page has just been zeroed by zeroPage() */ assert( pPage->nCell==0 ); - assert( get2byte(&data[hdr+5])==nUsable ); + assert( get2byteNotZero(&data[hdr+5])==nUsable ); pCellptr = &data[pPage->cellOffset + nCell*2]; cellbody = nUsable; for(i=nCell-1; i>=0; i--){ + u16 sz = aSize[i]; pCellptr -= 2; - cellbody -= aSize[i]; + cellbody -= sz; put2byte(pCellptr, cellbody); - memcpy(&data[cellbody], apCell[i], aSize[i]); + memcpy(&data[cellbody], apCell[i], sz); } put2byte(&data[hdr+3], nCell); put2byte(&data[hdr+5], cellbody); @@ -44041,9 +53897,10 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ assert( sqlite3PagerIswriteable(pParent->pDbPage) ); assert( pPage->nOverflow==1 ); + /* This error condition is now caught prior to reaching this function */ if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT; - /* Allocate a new page. This page will become the right-sibling of + /* Allocate a new page. This page will become the right-sibling of ** pPage. Make the parent page writable, so that the new divider cell ** may be inserted. If both these operations are successful, proceed. */ @@ -44062,7 +53919,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ assemblePage(pNew, 1, &pCell, &szCell); /* If this is an auto-vacuum database, update the pointer map - ** with entries for the new page, and any pointer from the + ** with entries for the new page, and any pointer from the ** cell on the page to an overflow page. If either of these ** operations fails, the return code is set, but the contents ** of the parent page are still manipulated by thh code below. @@ -44076,14 +53933,14 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ ptrmapPutOvflPtr(pNew, pCell, &rc); } } - + /* Create a divider cell to insert into pParent. The divider cell ** consists of a 4-byte page number (the page number of pPage) and ** a variable length key value (which must be the same value as the ** largest key on pPage). ** - ** To find the largest key value on pPage, first find the right-most - ** cell on pPage. The first two fields of this cell are the + ** To find the largest key value on pPage, first find the right-most + ** cell on pPage. The first two fields of this cell are the ** record-length (a variable length integer at most 32-bits in size) ** and the key value (a variable length integer, may have any value). ** The first of the while(...) loops below skips over the record-length @@ -44102,7 +53959,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ /* Set the right-child pointer of pParent to point to the new page. */ put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); - + /* Release the reference to the new page. */ releasePage(pNew); } @@ -44114,7 +53971,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ #if 0 /* ** This function does not contribute anything to the operation of SQLite. -** it is sometimes activated temporarily while debugging code responsible +** it is sometimes activated temporarily while debugging code responsible ** for setting pointer-map entries. */ static int ptrmapCheckPages(MemPage **apPage, int nPage){ @@ -44129,7 +53986,7 @@ static int ptrmapCheckPages(MemPage **apPage, int nPage){ for(j=0; j<pPage->nCell; j++){ CellInfo info; u8 *z; - + z = findCell(pPage, j); btreeParseCellPtr(pPage, z, &info); if( info.iOverflow ){ @@ -44154,7 +54011,7 @@ static int ptrmapCheckPages(MemPage **apPage, int nPage){ #endif /* -** This function is used to copy the contents of the b-tree node stored +** This function is used to copy the contents of the b-tree node stored ** on page pFrom to page pTo. If page pFrom was not a leaf page, then ** the pointer-map entries for each child page are updated so that the ** parent page stored in the pointer map is page pTo. If pFrom contained @@ -44162,11 +54019,11 @@ static int ptrmapCheckPages(MemPage **apPage, int nPage){ ** map entries are also updated so that the parent page is page pTo. ** ** If pFrom is currently carrying any overflow cells (entries in the -** MemPage.aOvfl[] array), they are not copied to pTo. +** MemPage.aOvfl[] array), they are not copied to pTo. ** ** Before returning, page pTo is reinitialized using btreeInitPage(). ** -** The performance of this function is not critical. It is only used by +** The performance of this function is not critical. It is only used by ** the balance_shallower() and balance_deeper() procedures, neither of ** which are called often under normal circumstances. */ @@ -44179,20 +54036,20 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){ int const iToHdr = ((pTo->pgno==1) ? 100 : 0); int rc; int iData; - - + + assert( pFrom->isInit ); assert( pFrom->nFree>=iToHdr ); - assert( get2byte(&aFrom[iFromHdr+5])<=pBt->usableSize ); - + assert( get2byte(&aFrom[iFromHdr+5]) <= (int)pBt->usableSize ); + /* Copy the b-tree node content from page pFrom to page pTo. */ iData = get2byte(&aFrom[iFromHdr+5]); memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData); memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell); - + /* Reinitialize page pTo so that the contents of the MemPage structure ** match the new data. The initialization of pTo can actually fail under - ** fairly obscure circumstances, even though it is a copy of initialized + ** fairly obscure circumstances, even though it is a copy of initialized ** page pFrom. */ pTo->isInit = 0; @@ -44201,7 +54058,7 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){ *pRC = rc; return; } - + /* 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. */ @@ -44216,13 +54073,13 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){ ** (hereafter "the page") and up to 2 siblings so that all pages have about the ** same amount of free space. Usually a single sibling on either side of the ** page are used in the balancing, though both siblings might come from one -** side if the page is the first or last child of its parent. If the page +** side if the page is the first or last child of its parent. If the page ** has fewer than 2 siblings (something which can only happen if the page ** is a root page or a child of a root page) then all available siblings ** participate in the balancing. ** -** The number of siblings of the page might be increased or decreased by -** one or two in an effort to keep pages nearly full but not over full. +** The number of siblings of the page might be increased or decreased by +** one or two in an effort to keep pages nearly full but not over full. ** ** Note that when this routine is called, some of the cells on the page ** might not actually be stored in MemPage.aData[]. This can happen @@ -44233,7 +54090,7 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){ ** inserted into or removed from the parent page (pParent). Doing so ** may cause the parent page to become overfull or underfull. If this ** happens, it is the responsibility of the caller to invoke the correct -** balancing routine to fix this problem (see the balance() routine). +** balancing routine to fix this problem (see the balance() routine). ** ** If this routine fails for any reason, it might leave the database ** in a corrupted state. So if this routine fails, the database should @@ -44248,7 +54105,7 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){ ** of the page-size, the aOvflSpace[] buffer is guaranteed to be large ** enough for all overflow cells. ** -** If aOvflSpace is set to a null pointer, this function returns +** If aOvflSpace is set to a null pointer, this function returns ** SQLITE_NOMEM. */ static int balance_nonroot( @@ -44294,7 +54151,7 @@ static int balance_nonroot( #endif /* At this point pParent may have at most one overflow cell. And if - ** this overflow cell is present, it must be the cell with + ** this overflow cell is present, it must be the cell with ** index iParentIdx. This scenario comes about when this function ** is called (indirectly) from sqlite3BtreeDelete(). */ @@ -44305,11 +54162,11 @@ static int balance_nonroot( return SQLITE_NOMEM; } - /* Find the sibling pages to balance. Also locate the cells in pParent - ** that divide the siblings. An attempt is made to find NN siblings on - ** either side of pPage. More siblings are taken from one side, however, + /* Find the sibling pages to balance. Also locate the cells in pParent + ** that divide the siblings. An attempt is made to find NN siblings on + ** either side of pPage. More siblings are taken from one side, however, ** if there are fewer than NN siblings on the other side. If pParent - ** has NB or fewer children then all children of pParent are taken. + ** has NB or fewer children then all children of pParent are taken. ** ** This loop also drops the divider cells from the parent page. This ** way, the remainder of the function does not have to deal with any @@ -44322,7 +54179,7 @@ static int balance_nonroot( nOld = i+1; }else{ nOld = 3; - if( iParentIdx==0 ){ + if( iParentIdx==0 ){ nxDiv = 0; }else if( iParentIdx==i ){ nxDiv = i-2; @@ -44361,7 +54218,7 @@ static int balance_nonroot( ** This is safe because dropping a cell only overwrites the first ** four bytes of it, and this function does not need the first ** four bytes of the divider cell. So the pointer is safe to use - ** later on. + ** later on. ** ** Unless SQLite is compiled in secure-delete mode. In this case, ** the dropCell() routine will overwrite the entire cell with zeroes. @@ -44370,7 +54227,7 @@ static int balance_nonroot( ** is allocated. */ if( pBt->secureDelete ){ int iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData); - if( (iOff+szNew[i])>pBt->usableSize ){ + if( (iOff+szNew[i])>(int)pBt->usableSize ){ rc = SQLITE_CORRUPT_BKPT; memset(apOld, 0, (i+1)*sizeof(MemPage*)); goto balance_cleanup; @@ -44396,7 +54253,7 @@ static int balance_nonroot( + nMaxCells*sizeof(u16) /* szCell */ + pBt->pageSize /* aSpace1 */ + k*nOld; /* Page copies (apCopy) */ - apCell = sqlite3ScratchMalloc( szScratch ); + apCell = sqlite3ScratchMalloc( szScratch ); if( apCell==0 ){ rc = SQLITE_NOMEM; goto balance_cleanup; @@ -44425,7 +54282,7 @@ static int balance_nonroot( leafData = apOld[0]->hasData; for(i=0; i<nOld; i++){ int limit; - + /* Before doing anything else, take a copy of the i'th original sibling ** The rest of this function will use data from the copies rather ** that the original pages since the original pages will be in the @@ -44436,12 +54293,24 @@ static int balance_nonroot( memcpy(pOld->aData, apOld[i]->aData, pBt->pageSize); limit = pOld->nCell+pOld->nOverflow; - for(j=0; j<limit; j++){ - assert( nCell<nMaxCells ); - apCell[nCell] = findOverflowCell(pOld, j); - szCell[nCell] = cellSizePtr(pOld, apCell[nCell]); - nCell++; - } + if( pOld->nOverflow>0 ){ + for(j=0; j<limit; j++){ + assert( nCell<nMaxCells ); + apCell[nCell] = findOverflowCell(pOld, j); + szCell[nCell] = cellSizePtr(pOld, apCell[nCell]); + nCell++; + } + }else{ + u8 *aData = pOld->aData; + u16 maskPage = pOld->maskPage; + u16 cellOffset = pOld->cellOffset; + for(j=0; j<limit; j++){ + assert( nCell<nMaxCells ); + apCell[nCell] = findCellv2(aData, maskPage, cellOffset, j); + szCell[nCell] = cellSizePtr(pOld, apCell[nCell]); + nCell++; + } + } if( i<nOld-1 && !leafData){ u16 sz = (u16)szNew[i]; u8 *pTemp; @@ -44449,8 +54318,8 @@ static int balance_nonroot( szCell[nCell] = sz; pTemp = &aSpace1[iSpace1]; iSpace1 += sz; - assert( sz<=pBt->pageSize/4 ); - assert( iSpace1<=pBt->pageSize ); + assert( sz<=pBt->maxLocal+23 ); + assert( iSpace1 <= (int)pBt->pageSize ); memcpy(pTemp, apDiv[i], sz); apCell[nCell] = pTemp+leafCorrection; assert( leafCorrection==0 || leafCorrection==4 ); @@ -44476,7 +54345,7 @@ static int balance_nonroot( ** Figure out the number of pages needed to hold all nCell cells. ** Store this number in "k". Also compute szNew[] which is the total ** size of all cells on the i-th page and cntNew[] which is the index - ** in apCell[] of the cell that divides page i from page i+1. + ** in apCell[] of the cell that divides page i from page i+1. ** cntNew[k] should equal nCell. ** ** Values computed by this block: @@ -44486,7 +54355,7 @@ static int balance_nonroot( ** cntNew[i]: Index in apCell[] and szCell[] for the first cell to ** the right of the i-th sibling page. ** usableSpace: Number of bytes of space available on each sibling. - ** + ** */ usableSpace = pBt->usableSize - 12 + leafCorrection; for(subtotal=k=i=0; i<nCell; i++){ @@ -44543,7 +54412,7 @@ static int balance_nonroot( assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) ); TRACE(("BALANCE: old: %d %d %d ", - apOld[0]->pgno, + apOld[0]->pgno, nOld>=2 ? apOld[1]->pgno : 0, nOld>=3 ? apOld[2]->pgno : 0 )); @@ -44615,9 +54484,7 @@ static int balance_nonroot( } } if( minI>i ){ - int t; MemPage *pT; - t = apNew[i]->pgno; pT = apNew[i]; apNew[i] = apNew[minI]; apNew[minI] = pT; @@ -44665,9 +54532,9 @@ static int balance_nonroot( if( !pNew->leaf ){ memcpy(&pNew->aData[8], pCell, 4); }else if( leafData ){ - /* If the tree is a leaf-data tree, and the siblings are leaves, - ** then there is no divider cell in apCell[]. Instead, the divider - ** cell consists of the integer key for the right-most cell of + /* If the tree is a leaf-data tree, and the siblings are leaves, + ** then there is no divider cell in apCell[]. Instead, the divider + ** cell consists of the integer key for the right-most cell of ** the sibling-page assembled above only. */ CellInfo info; @@ -44680,9 +54547,9 @@ static int balance_nonroot( pCell -= 4; /* Obscure case for non-leaf-data trees: If the cell at pCell was ** previously stored on a leaf node, and its reported size was 4 - ** bytes, then it may actually be smaller than this + ** bytes, then it may actually be smaller than this ** (see btreeParseCellPtr(), 4 bytes is the minimum size of - ** any cell). But it is important to pass the correct size to + ** any cell). But it is important to pass the correct size to ** insertCell(), so reparse the cell now. ** ** Note that this can never happen in an SQLite data file, as all @@ -44695,8 +54562,8 @@ static int balance_nonroot( } } iOvflSpace += sz; - assert( sz<=pBt->pageSize/4 ); - assert( iOvflSpace<=pBt->pageSize ); + assert( sz<=pBt->maxLocal+23 ); + assert( iOvflSpace <= (int)pBt->pageSize ); insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno, &rc); if( rc!=SQLITE_OK ) goto balance_cleanup; assert( sqlite3PagerIswriteable(pParent->pDbPage) ); @@ -44720,8 +54587,8 @@ static int balance_nonroot( ** b-tree structure by one. This is described as the "balance-shallower" ** sub-algorithm in some documentation. ** - ** If this is an auto-vacuum database, the call to copyNodeContent() - ** sets all pointer-map entries corresponding to database image pages + ** If this is an auto-vacuum database, the call to copyNodeContent() + ** sets all pointer-map entries corresponding to database image pages ** for which the pointer is stored within the content being copied. ** ** The second assert below verifies that the child page is defragmented @@ -44729,13 +54596,13 @@ static int balance_nonroot( ** is important if the parent page happens to be page 1 of the database ** image. */ assert( nNew==1 ); - assert( apNew[0]->nFree == - (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) + assert( apNew[0]->nFree == + (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) ); copyNodeContent(apNew[0], pParent, &rc); freePage(apNew[0], &rc); }else if( ISAUTOVACUUM ){ - /* Fix the pointer-map entries for all the cells that were shifted around. + /* Fix the pointer-map entries for all the cells that were shifted around. ** There are several different types of pointer-map entries that need to ** be dealt with by this routine. Some of these have been set already, but ** many have not. The following is a summary: @@ -44747,7 +54614,7 @@ static int balance_nonroot( ** of those. ** ** 2) The pointer-map entries associated with the first overflow - ** page in any overflow chains used by new divider cells. These + ** page in any overflow chains used by new divider cells. These ** have also already been taken care of by the insertCell() code. ** ** 3) If the sibling pages are not leaves, then the child pages of @@ -44785,7 +54652,7 @@ static int balance_nonroot( nOverflow = pOld->nOverflow; iOverflow = i + !leafData + pOld->aOvfl[0].idx; } - isDivider = !leafData; + isDivider = !leafData; } assert(nOverflow>0 || iOverflow<i ); @@ -44831,7 +54698,7 @@ static int balance_nonroot( #if 0 /* The ptrmapCheckPages() contains assert() statements that verify that - ** all pointer map pages are set correctly. This is helpful while + ** 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); @@ -44865,15 +54732,15 @@ balance_cleanup: ** ** A new child page is allocated and the contents of the current root ** page, including overflow cells, are copied into the child. The root -** page is then overwritten to make it an empty page with the right-child +** page is then overwritten to make it an empty page with the right-child ** pointer pointing to the new page. ** -** Before returning, all pointer-map entries corresponding to pages +** Before returning, all pointer-map entries corresponding to pages ** that the new child-page now contains pointers to are updated. The ** entry corresponding to the new right-child pointer of the root ** page is also updated. ** -** If successful, *ppChild is set to contain a reference to the child +** If successful, *ppChild is set to contain a reference to the child ** page and SQLITE_OK is returned. In this case the caller is required ** to call releasePage() on *ppChild exactly once. If an error occurs, ** an error code is returned and *ppChild is set to 0. @@ -44887,7 +54754,7 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ assert( pRoot->nOverflow>0 ); assert( sqlite3_mutex_held(pBt->mutex) ); - /* Make pRoot, the root page of the b-tree, writable. Allocate a new + /* Make pRoot, the root page of the b-tree, writable. Allocate a new ** page that will become the new right-child of pPage. Copy the contents ** of the node stored on pRoot into the new child page. */ @@ -44925,7 +54792,7 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ /* ** The page that pCur currently points to has just been modified in ** some way. This function figures out if this modification means the -** tree needs to be balanced, and if so calls the appropriate balancing +** tree needs to be balanced, and if so calls the appropriate balancing ** routine. Balancing routines are: ** ** balance_quick() @@ -44951,7 +54818,7 @@ static int balance(BtCursor *pCur){ ** balance_deeper() function to create a new child for the root-page ** and copy the current contents of the root-page to it. The ** next iteration of the do-loop will balance the child page. - */ + */ assert( (balance_deeper_called++)==0 ); rc = balance_deeper(pPage, &pCur->apPage[1]); if( rc==SQLITE_OK ){ @@ -44981,10 +54848,10 @@ static int balance(BtCursor *pCur){ /* Call balance_quick() to create a new sibling of pPage on which ** to store the overflow cell. balance_quick() inserts a new cell ** into pParent, which may cause pParent overflow. If this - ** happens, the next interation of the do-loop will balance pParent + ** happens, the next interation of the do-loop will balance pParent ** use either balance_nonroot() or balance_deeper(). Until this ** happens, the overflow cell is stored in the aBalanceQuickSpace[] - ** buffer. + ** buffer. ** ** The purpose of the following assert() is to check that only a ** single call to balance_quick() is made for each call to this @@ -45001,24 +54868,24 @@ static int balance(BtCursor *pCur){ ** modifying the contents of pParent, which may cause pParent to ** become overfull or underfull. The next iteration of the do-loop ** will balance the parent page to correct this. - ** + ** ** If the parent page becomes overfull, the overflow cell or cells - ** are stored in the pSpace buffer allocated immediately below. + ** are stored in the pSpace buffer allocated immediately below. ** A subsequent iteration of the do-loop will deal with this by ** calling balance_nonroot() (balance_deeper() may be called first, ** but it doesn't deal with overflow cells - just moves them to a - ** different page). Once this subsequent call to balance_nonroot() + ** different page). Once this subsequent call to balance_nonroot() ** has completed, it is safe to release the pSpace buffer used by - ** the previous call, as the overflow cell data will have been + ** the previous call, as the overflow cell data will have been ** copied either into the body of a database page or into the new ** pSpace buffer passed to the latter call to balance_nonroot(). */ u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1); if( pFree ){ - /* If pFree is not NULL, it points to the pSpace buffer used + /* If pFree is not NULL, it points to the pSpace buffer used ** by a previous call to balance_nonroot(). Its contents are - ** now stored either on real database pages or within the + ** now stored either on real database pages or within the ** new pSpace buffer, so it may be safely freed here. */ sqlite3PageFree(pFree); } @@ -45058,8 +54925,8 @@ static int balance(BtCursor *pCur){ ** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already ** been performed. seekResult is the search result returned (a negative ** number if pCur points at an entry that is smaller than (pKey, nKey), or -** a positive value if pCur points at an etry that is larger than -** (pKey, nKey)). +** a positive value if pCur points at an etry that is larger than +** (pKey, nKey)). ** ** If the seekResult parameter is non-zero, then the caller guarantees that ** cursor pCur is pointing at the existing copy of a row that is to be @@ -45101,7 +54968,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( ** blob of associated data. */ assert( (pKey==0)==(pCur->pKeyInfo==0) ); - /* If this is an insert into a table b-tree, invalidate any incrblob + /* If this is an insert into a table b-tree, invalidate any incrblob ** cursors open on the row being replaced (assuming this is a replace ** operation - if it is not, the following is a no-op). */ if( pCur->pKeyInfo==0 ){ @@ -45112,8 +54979,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( ** ** In some cases, the call to btreeMoveto() below is a no-op. For ** example, when inserting data into a table with auto-generated integer - ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the - ** integer key to use. It then calls this function to actually insert the + ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the + ** integer key to use. It then calls this function to actually insert the ** data into the intkey B-Tree. In this case btreeMoveto() recognizes ** that the cursor is already where it needs to be and returns without ** doing any work. To avoid thwarting these optimizations, it is important @@ -45141,7 +55008,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew); if( rc ) goto end_insert; assert( szNew==cellSizePtr(pPage, newCell) ); - assert( szNew<=MX_CELL_SIZE(pBt) ); + assert( szNew <= MX_CELL_SIZE(pBt) ); idx = pCur->aiIdx[pCur->iPage]; if( loc==0 ){ u16 szOld; @@ -45167,7 +55034,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( insertCell(pPage, idx, newCell, szNew, 0, 0, &rc); assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); - /* If no error has occured and pPage has an overflow cell, call balance() + /* If no error has occured and pPage has an overflow cell, call balance() ** to redistribute the cells within the tree. Since balance() may move ** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey ** variables. @@ -45193,7 +55060,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( rc = balance(pCur); /* Must make sure nOverflow is reset to zero even if the balance() - ** fails. Internal data structure corruption will result otherwise. + ** fails. Internal data structure corruption will result otherwise. ** Also, set the cursor state to invalid. This stops saveCursorPosition() ** from trying to save the current position of the cursor. */ pCur->apPage[pCur->iPage]->nOverflow = 0; @@ -45211,12 +55078,12 @@ end_insert: */ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){ Btree *p = pCur->pBtree; - BtShared *pBt = p->pBt; + BtShared *pBt = p->pBt; int rc; /* Return code */ MemPage *pPage; /* Page to delete cell from */ unsigned char *pCell; /* Pointer to cell to delete */ int iCellIdx; /* Index of cell to delete */ - int iCellDepth; /* Depth of node containing pCell */ + int iCellDepth; /* Depth of node containing pCell */ assert( cursorHoldsMutex(pCur) ); assert( pBt->inTransaction==TRANS_WRITE ); @@ -45225,7 +55092,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){ assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); assert( !hasReadConflicts(p, pCur->pgnoRoot) ); - if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell) + if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell) || NEVER(pCur->eState!=CURSOR_VALID) ){ return SQLITE_ERROR; /* Something has gone awry. */ @@ -45256,9 +55123,9 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){ } /* Save the positions of any other cursors open on this table before - ** making any modifications. Make the page containing the entry to be - ** deleted writable. Then free any overflow pages associated with the - ** entry and finally remove the cell itself from within the page. + ** making any modifications. Make the page containing the entry to be + ** deleted writable. Then free any overflow pages associated with the + ** entry and finally remove the cell itself from within the page. */ rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); if( rc ) return rc; @@ -45281,7 +55148,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){ pCell = findCell(pLeaf, pLeaf->nCell-1); nCell = cellSizePtr(pLeaf, pCell); - assert( MX_CELL_SIZE(pBt)>=nCell ); + assert( MX_CELL_SIZE(pBt) >= nCell ); allocateTempSpace(pBt); pTmp = pBt->pTmpSpace; @@ -45305,7 +55172,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){ ** on the leaf node first. If the balance proceeds far enough up the ** tree that we can be sure that any problem in the internal node has ** been corrected, so be it. Otherwise, after balancing the leaf node, - ** walk the cursor up the tree to the internal node and balance it as + ** walk the cursor up the tree to the internal node and balance it as ** well. */ rc = balance(pCur); if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){ @@ -45332,11 +55199,12 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){ ** BTREE_INTKEY|BTREE_LEAFDATA Used for SQL tables with rowid keys ** BTREE_ZERODATA Used for SQL indices */ -static int btreeCreateTable(Btree *p, int *piTable, int flags){ +static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){ BtShared *pBt = p->pBt; MemPage *pRoot; Pgno pgnoRoot; int rc; + int ptfFlags; /* Page-type flage for the root page of new table */ assert( sqlite3BtreeHoldsMutex(p) ); assert( pBt->inTransaction==TRANS_WRITE ); @@ -45429,7 +55297,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int flags){ } }else{ pRoot = pPageMove; - } + } /* Update the pointer-map and meta-data with the new root-page number. */ ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, &rc); @@ -45437,8 +55305,14 @@ static int btreeCreateTable(Btree *p, int *piTable, int flags){ releasePage(pRoot); return rc; } + + /* When the new root page was allocated, page 1 was made writable in + ** order either to increase the database filesize, or to decrement the + ** freelist count. Hence, the sqlite3BtreeUpdateMeta() call cannot fail. + */ + assert( sqlite3PagerIswriteable(pBt->pPage1->pDbPage) ); rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot); - if( rc ){ + if( NEVER(rc) ){ releasePage(pRoot); return rc; } @@ -45449,8 +55323,14 @@ static int btreeCreateTable(Btree *p, int *piTable, int flags){ } #endif assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); - zeroPage(pRoot, flags | PTF_LEAF); + if( createTabFlags & BTREE_INTKEY ){ + ptfFlags = PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF; + }else{ + ptfFlags = PTF_ZERODATA | PTF_LEAF; + } + zeroPage(pRoot, ptfFlags); sqlite3PagerUnref(pRoot->pDbPage); + assert( (pBt->openFlags & BTREE_SINGLE)==0 || pgnoRoot==2 ); *piTable = (int)pgnoRoot; return SQLITE_OK; } @@ -45478,7 +55358,7 @@ static int clearDatabasePage( int i; assert( sqlite3_mutex_held(pBt->mutex) ); - if( pgno>pagerPagecount(pBt) ){ + if( pgno>btreePagecount(pBt) ){ return SQLITE_CORRUPT_BKPT; } @@ -45552,12 +55432,12 @@ SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ ** cursors on the table. ** ** If AUTOVACUUM is enabled and the page at iTable is not the last -** root page in the database file, then the last root page +** root page in the database file, then the last root page ** in the database file is moved into the slot formerly occupied by ** iTable and that last slot formerly occupied by the last root page ** is added to the freelist instead of iTable. In this say, all ** root pages are kept at the beginning of the database file, which -** is necessary for AUTOVACUUM to work right. *piMoved is set to the +** is necessary for AUTOVACUUM to work right. *piMoved is set to the ** page number that used to be the last root page in the file before ** the move. If no page gets moved, *piMoved is set to 0. ** The last root page is recorded in meta[3] and the value of @@ -45574,7 +55454,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ /* It is illegal to drop a table if any cursors are open on the ** database. This is because in auto-vacuum mode the backend may ** need to move another root-page to fill a gap left by the deleted - ** root page. If an open cursor was using this page a problem would + ** root page. If an open cursor was using this page a problem would ** occur. ** ** This error is caught long before control reaches this point. @@ -45605,7 +55485,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ if( iTable==maxRootPgno ){ /* If the table being dropped is the table with the largest root-page - ** number in the database, put the root page on the free list. + ** number in the database, put the root page on the free list. */ freePage(pPage, &rc); releasePage(pPage); @@ -45614,7 +55494,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ } }else{ /* The table being dropped does not have the largest root-page - ** number in the database. So move the page that does into the + ** number in the database. So move the page that does into the ** gap left by the deleted root-page. */ MemPage *pMove; @@ -45659,12 +55539,12 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ }else{ /* If sqlite3BtreeDropTable was called on page 1. ** This really never should happen except in a corrupt - ** database. + ** database. */ zeroPage(pPage, PTF_INTKEY|PTF_LEAF ); releasePage(pPage); } - return rc; + return rc; } SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ int rc; @@ -45683,7 +55563,7 @@ SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ ** is the number of free pages currently in the database. Meta[1] ** through meta[15] are available for use by higher layers. Meta[0] ** is read-only, the others are read/write. -** +** ** The schema layer numbers meta values differently. At the schema ** layer (and the SetCookie and ReadCookie opcodes) the number of ** free pages is not visible. So Cookie[0] is the same as Meta[1]. @@ -45741,23 +55621,28 @@ SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ ** The first argument, pCur, is a cursor opened on some b-tree. Count the ** number of entries in the b-tree and write the result to *pnEntry. ** -** SQLITE_OK is returned if the operation is successfully executed. +** SQLITE_OK is returned if the operation is successfully executed. ** Otherwise, if an error is encountered (i.e. an IO error or database ** corruption) an SQLite error code is returned. */ SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ i64 nEntry = 0; /* Value to return in *pnEntry */ int rc; /* Return code */ + + if( pCur->pgnoRoot==0 ){ + *pnEntry = 0; + return SQLITE_OK; + } rc = moveToRoot(pCur); /* Unless an error occurs, the following loop runs one iteration for each - ** page in the B-Tree structure (not including overflow pages). + ** page in the B-Tree structure (not including overflow pages). */ while( rc==SQLITE_OK ){ int iIdx; /* Index of child node in parent */ MemPage *pPage; /* Current page of the b-tree */ - /* If this is a leaf page or the tree is not an int-key tree, then + /* If this is a leaf page or the tree is not an int-key tree, then ** this page contains countable entries. Increment the entry counter ** accordingly. */ @@ -45766,7 +55651,7 @@ SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ nEntry += pPage->nCell; } - /* pPage is a leaf node. This loop navigates the cursor so that it + /* pPage is a leaf node. This loop navigates the cursor so that it ** points to the first interior cell that it points to the parent of ** the next page in the tree that has not yet been visited. The ** pCur->aiIdx[pCur->iPage] value is set to the index of the parent cell @@ -45790,7 +55675,7 @@ SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ pPage = pCur->apPage[pCur->iPage]; } - /* Descend to the child node of the cell that the cursor currently + /* Descend to the child node of the cell that the cursor currently ** points at. This is the right-child if (iIdx==pPage->nCell). */ iIdx = pCur->aiIdx[pCur->iPage]; @@ -45867,7 +55752,7 @@ static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){ #ifndef SQLITE_OMIT_AUTOVACUUM /* -** Check that the entry in the pointer-map for page iChild maps to +** Check that the entry in the pointer-map for page iChild maps to ** page iParent, pointer type ptrType. If not, append an error message ** to pCheck. */ @@ -45890,8 +55775,8 @@ static void checkPtrmap( } if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ - checkAppendMsg(pCheck, zContext, - "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", + checkAppendMsg(pCheck, zContext, + "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", iChild, eType, iParent, ePtrmapType, iPtrmapParent); } } @@ -45933,7 +55818,7 @@ static void checkList( checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext); } #endif - if( n>pCheck->pBt->usableSize/4-2 ){ + if( n>(int)pCheck->pBt->usableSize/4-2 ){ checkAppendMsg(pCheck, zContext, "freelist leaf count too big on page %d", iPage); N--; @@ -45973,7 +55858,7 @@ static void checkList( ** Do various sanity checks on a single page of a tree. Return ** the tree depth. Root pages return 0. Parents of root pages ** return 1, and so forth. -** +** ** These checks are done: ** ** 1. Make sure that cells and freeblocks do not overlap @@ -45991,7 +55876,7 @@ static int checkTreePage( IntegrityCk *pCheck, /* Context for the sanity check */ int iPage, /* Page number of the page to check */ char *zParentContext, /* Parent context */ - i64 *pnParentMinKey, + i64 *pnParentMinKey, i64 *pnParentMaxKey ){ MemPage *pPage; @@ -46025,7 +55910,7 @@ static int checkTreePage( pPage->isInit = 0; if( (rc = btreeInitPage(pPage))!=0 ){ assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */ - checkAppendMsg(pCheck, zContext, + checkAppendMsg(pCheck, zContext, "btreeInitPage() returns error code %d", rc); releasePage(pPage); return 0; @@ -46052,13 +55937,13 @@ static int checkTreePage( else if( i==0 ) nMinKey = nMaxKey = info.nKey; else{ if( info.nKey <= nMaxKey ){ - checkAppendMsg(pCheck, zContext, + checkAppendMsg(pCheck, zContext, "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey); } nMaxKey = info.nKey; } assert( sz==info.nPayload ); - if( (sz>info.nLocal) + if( (sz>info.nLocal) && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize]) ){ int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4); @@ -46090,7 +55975,7 @@ static int checkTreePage( if( !pPage->leaf ){ pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); - sqlite3_snprintf(sizeof(zContext), zContext, + sqlite3_snprintf(sizeof(zContext), zContext, "On page %d at right child: ", iPage); #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ @@ -46099,7 +55984,7 @@ static int checkTreePage( #endif checkTreePage(pCheck, pgno, zContext, NULL, !pPage->nCell ? NULL : &nMaxKey); } - + /* For intKey leaf pages, check that the min/max keys are in order ** with any left/parent/right pages. */ @@ -46109,18 +55994,18 @@ static int checkTreePage( /* if we are the left most child page */ if( !pnParentMaxKey ){ if( nMaxKey > *pnParentMinKey ){ - checkAppendMsg(pCheck, zContext, + checkAppendMsg(pCheck, zContext, "Rowid %lld out of order (max larger than parent min of %lld)", nMaxKey, *pnParentMinKey); } }else{ if( nMinKey <= *pnParentMinKey ){ - checkAppendMsg(pCheck, zContext, + checkAppendMsg(pCheck, zContext, "Rowid %lld out of order (min less than parent min of %lld)", nMinKey, *pnParentMinKey); } if( nMaxKey > *pnParentMaxKey ){ - checkAppendMsg(pCheck, zContext, + checkAppendMsg(pCheck, zContext, "Rowid %lld out of order (max larger than parent max of %lld)", nMaxKey, *pnParentMaxKey); } @@ -46129,7 +56014,7 @@ static int checkTreePage( /* else if we're a right child page */ } else if( pnParentMaxKey ){ if( nMinKey <= *pnParentMaxKey ){ - checkAppendMsg(pCheck, zContext, + checkAppendMsg(pCheck, zContext, "Rowid %lld out of order (min less than parent max of %lld)", nMinKey, *pnParentMaxKey); } @@ -46144,7 +56029,7 @@ static int checkTreePage( if( hit==0 ){ pCheck->mallocFailed = 1; }else{ - u16 contentOffset = get2byte(&data[hdr+5]); + int contentOffset = get2byteNotZero(&data[hdr+5]); assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ memset(hit+contentOffset, 0, usableSize-contentOffset); memset(hit, 1, contentOffset); @@ -46152,13 +56037,13 @@ static int checkTreePage( cellStart = hdr + 12 - 4*pPage->leaf; for(i=0; i<nCell; i++){ int pc = get2byte(&data[cellStart+i*2]); - u16 size = 1024; + u32 size = 65536; int j; if( pc<=usableSize-4 ){ size = cellSizePtr(pPage, &data[pc]); } - if( (pc+size-1)>=usableSize ){ - checkAppendMsg(pCheck, 0, + if( (int)(pc+size-1)>=usableSize ){ + checkAppendMsg(pCheck, 0, "Corruption detected in cell %d on page %d",i,iPage); }else{ for(j=pc+size-1; j>=pc; j--) hit[j]++; @@ -46186,7 +56071,7 @@ static int checkTreePage( } } if( cnt!=data[hdr+7] ){ - checkAppendMsg(pCheck, 0, + checkAppendMsg(pCheck, 0, "Fragmentation of %d bytes reported as %d on page %d", cnt, data[hdr+7], iPage); } @@ -46229,7 +56114,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( nRef = sqlite3PagerRefcount(pBt->pPager); sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; - sCheck.nPage = pagerPagecount(sCheck.pBt); + sCheck.nPage = btreePagecount(sCheck.pBt); sCheck.mxErr = mxErr; sCheck.nErr = 0; sCheck.mallocFailed = 0; @@ -46250,6 +56135,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( sCheck.anRef[i] = 1; } sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000); + sCheck.errMsg.useMalloc = 2; /* Check the integrity of the freelist */ @@ -46279,11 +56165,11 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( /* If the database supports auto-vacuum, make sure no tables contain ** references to pointer-map pages. */ - if( sCheck.anRef[i]==0 && + if( sCheck.anRef[i]==0 && (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ checkAppendMsg(&sCheck, 0, "Page %d is never used", i); } - if( sCheck.anRef[i]!=0 && + if( sCheck.anRef[i]!=0 && (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i); } @@ -46295,7 +56181,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( ** of the integrity check. */ if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){ - checkAppendMsg(&sCheck, 0, + checkAppendMsg(&sCheck, 0, "Outstanding page count goes from %d to %d during this analysis", nRef, sqlite3PagerRefcount(pBt->pPager) ); @@ -46348,6 +56234,31 @@ SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree *p){ return (p && (p->inTrans==TRANS_WRITE)); } +#ifndef SQLITE_OMIT_WAL +/* +** Run a checkpoint on the Btree passed as the first argument. +** +** Return SQLITE_LOCKED if this or any other connection has an open +** transaction on the shared-cache the argument Btree is connected to. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +*/ +SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){ + int rc = SQLITE_OK; + if( p ){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + if( pBt->inTransaction!=TRANS_NONE ){ + rc = SQLITE_LOCKED; + }else{ + rc = sqlite3PagerCheckpoint(pBt->pPager, eMode, pnLog, pnCkpt); + } + sqlite3BtreeLeave(p); + } + return rc; +} +#endif + /* ** Return non-zero if a read (or write) transaction is active. */ @@ -46366,28 +56277,28 @@ SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){ /* ** This function returns a pointer to a blob of memory associated with ** a single shared-btree. The memory is used by client code for its own -** purposes (for example, to store a high-level schema associated with +** purposes (for example, to store a high-level schema associated with ** the shared-btree). The btree layer manages reference counting issues. ** ** The first time this is called on a shared-btree, nBytes bytes of memory -** are allocated, zeroed, and returned to the caller. For each subsequent +** are allocated, zeroed, and returned to the caller. For each subsequent ** call the nBytes parameter is ignored and a pointer to the same blob -** of memory returned. +** of memory returned. ** ** If the nBytes parameter is 0 and the blob of memory has not yet been ** allocated, a null pointer is returned. If the blob has already been ** allocated, it is returned as normal. ** -** Just before the shared-btree is closed, the function passed as the -** xFree argument when the memory allocation was made is invoked on the -** blob of allocated memory. This function should not call sqlite3_free() +** Just before the shared-btree is closed, the function passed as the +** xFree argument when the memory allocation was made is invoked on the +** blob of allocated memory. The xFree function should not call sqlite3_free() ** on the memory, the btree layer does that. */ SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); if( !pBt->pSchema && nBytes ){ - pBt->pSchema = sqlite3MallocZero(nBytes); + pBt->pSchema = sqlite3DbMallocZero(0, nBytes); pBt->xFreeSchema = xFree; } sqlite3BtreeLeave(p); @@ -46395,8 +56306,8 @@ SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void } /* -** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared -** btree as the argument handle holds an exclusive lock on the +** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared +** btree as the argument handle holds an exclusive lock on the ** sqlite_master table. Otherwise SQLITE_OK. */ SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ @@ -46437,11 +56348,11 @@ SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ #ifndef SQLITE_OMIT_INCRBLOB /* -** Argument pCsr must be a cursor opened for writing on an -** INTKEY table currently pointing at a valid table entry. +** Argument pCsr must be a cursor opened for writing on an +** INTKEY table currently pointing at a valid table entry. ** This function modifies the data stored as part of that entry. ** -** Only the data content may only be modified, it is not possible to +** Only the data content may only be modified, it is not possible to ** change the length of the data stored. If this function is called with ** parameters that attempt to write past the end of the existing data, ** no modifications are made and SQLITE_CORRUPT is returned. @@ -46461,7 +56372,7 @@ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void return SQLITE_ABORT; } - /* Check some assumptions: + /* Check some assumptions: ** (a) the cursor is open for writing, ** (b) there is a read/write transaction open, ** (c) the connection holds a write-lock on the table (if required), @@ -46479,8 +56390,8 @@ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); } -/* -** Set a flag on this cursor to cache the locations of pages from the +/* +** Set a flag on this cursor to cache the locations of pages from the ** overflow list for the current row. This is used by cursors opened ** for incremental blob IO only. ** @@ -46492,12 +56403,46 @@ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *pCur){ assert( cursorHoldsMutex(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - assert(!pCur->isIncrblobHandle); - assert(!pCur->aOverflow); + invalidateOverflowCache(pCur); pCur->isIncrblobHandle = 1; } #endif +/* +** Set both the "read version" (single byte at byte offset 18) and +** "write version" (single byte at byte offset 19) fields in the database +** header to iVersion. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ + BtShared *pBt = pBtree->pBt; + int rc; /* Return code */ + + assert( iVersion==1 || iVersion==2 ); + + /* If setting the version fields to 1, do not automatically open the + ** WAL connection, even if the version fields are currently set to 2. + */ + pBt->doNotUseWAL = (u8)(iVersion==1); + + rc = sqlite3BtreeBeginTrans(pBtree, 0); + if( rc==SQLITE_OK ){ + u8 *aData = pBt->pPage1->aData; + if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ + rc = sqlite3BtreeBeginTrans(pBtree, 2); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc==SQLITE_OK ){ + aData[18] = (u8)iVersion; + aData[19] = (u8)iVersion; + } + } + } + } + + pBt->doNotUseWAL = 0; + return rc; +} + /************** End of btree.c ***********************************************/ /************** Begin file backup.c ******************************************/ /* @@ -46511,7 +56456,7 @@ SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *pCur){ ** May you share freely, never taking more than you give. ** ************************************************************************* -** This file contains the implementation of the sqlite3_backup_XXX() +** This file contains the implementation of the sqlite3_backup_XXX() ** API functions and the related features. */ @@ -46552,15 +56497,15 @@ struct sqlite3_backup { ** Once it has been created using backup_init(), a single sqlite3_backup ** structure may be accessed via two groups of thread-safe entry points: ** -** * Via the sqlite3_backup_XXX() API function backup_step() and +** * Via the sqlite3_backup_XXX() API function backup_step() and ** backup_finish(). Both these functions obtain the source database -** handle mutex and the mutex associated with the source BtShared +** handle mutex and the mutex associated with the source BtShared ** structure, in that order. ** ** * Via the BackupUpdate() and BackupRestart() functions, which are ** invoked by the pager layer to report various state changes in ** the page cache associated with the source database. The mutex -** associated with the source database BtShared structure will always +** associated with the source database BtShared structure will always ** be held when either of these functions are invoked. ** ** The other sqlite3_backup_XXX() API functions, backup_remaining() and @@ -46581,8 +56526,8 @@ struct sqlite3_backup { ** in connection handle pDb. If such a database cannot be found, return ** a NULL pointer and write an error message to pErrorDb. ** -** If the "temp" database is requested, it may need to be opened by this -** function. If an error occurs while doing so, return 0 and write an +** If the "temp" database is requested, it may need to be opened by this +** function. If an error occurs while doing so, return 0 and write an ** error message to pErrorDb. */ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ @@ -46618,6 +56563,16 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ } /* +** Attempt to set the page size of the destination to match the page size +** of the source. +*/ +static int setDestPgsz(sqlite3_backup *p){ + int rc; + rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0); + return rc; +} + +/* ** Create an sqlite3_backup process to copy the contents of zSrcDb from ** connection handle pSrcDb to zDestDb in pDestDb. If successful, return ** a pointer to the new sqlite3_backup object. @@ -46650,7 +56605,10 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init( ); p = 0; }else { - /* Allocate space for a new sqlite3_backup object */ + /* Allocate space for a new sqlite3_backup object... + ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a + ** call to sqlite3_backup_init() and is destroyed by a call to + ** sqlite3_backup_finish(). */ p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup)); if( !p ){ sqlite3Error(pDestDb, SQLITE_NOMEM, 0); @@ -46667,10 +56625,11 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init( p->iNext = 1; p->isAttached = 0; - if( 0==p->pSrc || 0==p->pDest ){ - /* One (or both) of the named databases did not exist. An error has - ** already been written into the pDestDb handle. All that is left - ** to do here is free the sqlite3_backup structure. + if( 0==p->pSrc || 0==p->pDest || setDestPgsz(p)==SQLITE_NOMEM ){ + /* One (or both) of the named databases did not exist or an OOM + ** error was hit. The error has already been written into the + ** pDestDb handle. All that is left to do here is free the + ** sqlite3_backup structure. */ sqlite3_free(p); p = 0; @@ -46686,7 +56645,7 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init( } /* -** Argument rc is an SQLite error code. Return true if this error is +** Argument rc is an SQLite error code. Return true if this error is ** considered fatal if encountered during a backup operation. All errors ** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED. */ @@ -46695,8 +56654,8 @@ static int isFatalError(int rc){ } /* -** Parameter zSrcData points to a buffer containing the data for -** page iSrcPg from the source database. Copy this data into the +** Parameter zSrcData points to a buffer containing the data for +** page iSrcPg from the source database. Copy this data into the ** destination database. */ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){ @@ -46705,6 +56664,10 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){ int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest); const int nCopy = MIN(nSrcPgsz, nDestPgsz); const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; +#ifdef SQLITE_HAS_CODEC + int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc); + int nDestReserve = sqlite3BtreeGetReserve(p->pDest); +#endif int rc = SQLITE_OK; i64 iOff; @@ -46715,13 +56678,33 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){ assert( zSrcData ); /* Catch the case where the destination is an in-memory database and the - ** page sizes of the source and destination differ. + ** page sizes of the source and destination differ. */ - if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(sqlite3BtreePager(p->pDest)) ){ + if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){ rc = SQLITE_READONLY; } - /* This loop runs once for each destination page spanned by the source +#ifdef SQLITE_HAS_CODEC + /* Backup is not possible if the page size of the destination is changing + ** and a codec is in use. + */ + if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){ + rc = SQLITE_READONLY; + } + + /* Backup is not possible if the number of bytes of reserve space differ + ** between source and destination. If there is a difference, try to + ** fix the destination to agree with the source. If that is not possible, + ** then the backup cannot proceed. + */ + if( nSrcReserve!=nDestReserve ){ + u32 newPgsz = nSrcPgsz; + rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve); + if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY; + } +#endif + + /* This loop runs once for each destination page spanned by the source ** page. For each iteration, variable iOff is set to the byte offset ** of the destination page. */ @@ -46740,7 +56723,7 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){ ** Then clear the Btree layer MemPage.isInit flag. Both this module ** and the pager code use this trick (clearing the first byte ** of the page 'extra' space to invalidate the Btree layers - ** cached parse of the page). MemPage.isInit is marked + ** cached parse of the page). MemPage.isInit is marked ** "MUST BE FIRST" for this purpose. */ memcpy(zOut, zIn, nCopy); @@ -46757,7 +56740,7 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){ ** exactly iSize bytes. If pFile is not larger than iSize bytes, then ** this function is a no-op. ** -** Return SQLITE_OK if everything is successful, or an SQLite error +** Return SQLITE_OK if everything is successful, or an SQLite error ** code if an error occurs. */ static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){ @@ -46787,6 +56770,9 @@ static void attachBackupObject(sqlite3_backup *p){ */ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ int rc; + int destMode; /* Destination journal mode */ + int pgszSrc = 0; /* Source page size */ + int pgszDest = 0; /* Destination page size */ sqlite3_mutex_enter(p->pSrcDb->mutex); sqlite3BtreeEnter(p->pSrc); @@ -46813,7 +56799,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ /* Lock the destination database, if it is not locked already. */ if( SQLITE_OK==rc && p->bDestLocked==0 - && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) + && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) ){ p->bDestLocked = 1; sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); @@ -46828,12 +56814,20 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ bCloseTrans = 1; } + /* Do not allow backup if the destination database is in WAL mode + ** and the page sizes are different between source and destination */ + pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); + pgszDest = sqlite3BtreeGetPageSize(p->pDest); + destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest)); + if( SQLITE_OK==rc && destMode==PAGER_JOURNALMODE_WAL && pgszSrc!=pgszDest ){ + rc = SQLITE_READONLY; + } + /* Now that there is a read-lock on the source database, query the ** source pager for the number of pages in the database. */ - if( rc==SQLITE_OK ){ - rc = sqlite3PagerPagecount(pSrcPager, &nSrcPage); - } + nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc); + assert( nSrcPage>=0 ); for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){ const Pgno iSrcPg = p->iNext; /* Source page number */ if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){ @@ -46855,97 +56849,115 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ attachBackupObject(p); } } - + /* Update the schema version field in the destination database. This ** is to make sure that the schema-version really does change in ** the case where the source and destination databases have the ** same schema version. */ - if( rc==SQLITE_DONE - && (rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1))==SQLITE_OK - ){ - const int nSrcPagesize = sqlite3BtreeGetPageSize(p->pSrc); - const int nDestPagesize = sqlite3BtreeGetPageSize(p->pDest); - int nDestTruncate; - - if( p->pDestDb ){ - sqlite3ResetInternalSchema(p->pDestDb, 0); - } - - /* Set nDestTruncate to the final number of pages in the destination - ** database. The complication here is that the destination page - ** size may be different to the source page size. - ** - ** If the source page size is smaller than the destination page size, - ** round up. In this case the call to sqlite3OsTruncate() below will - ** fix the size of the file. However it is important to call - ** sqlite3PagerTruncateImage() here so that any pages in the - ** destination file that lie beyond the nDestTruncate page mark are - ** journalled by PagerCommitPhaseOne() before they are destroyed - ** by the file truncation. - */ - if( nSrcPagesize<nDestPagesize ){ - int ratio = nDestPagesize/nSrcPagesize; - nDestTruncate = (nSrcPage+ratio-1)/ratio; - if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){ - nDestTruncate--; + if( rc==SQLITE_DONE ){ + rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1); + if( rc==SQLITE_OK ){ + if( p->pDestDb ){ + sqlite3ResetInternalSchema(p->pDestDb, -1); + } + if( destMode==PAGER_JOURNALMODE_WAL ){ + rc = sqlite3BtreeSetVersion(p->pDest, 2); } - }else{ - nDestTruncate = nSrcPage * (nSrcPagesize/nDestPagesize); } - sqlite3PagerTruncateImage(pDestPager, nDestTruncate); - - if( nSrcPagesize<nDestPagesize ){ - /* If the source page-size is smaller than the destination page-size, - ** two extra things may need to happen: - ** - ** * The destination may need to be truncated, and + if( rc==SQLITE_OK ){ + int nDestTruncate; + /* Set nDestTruncate to the final number of pages in the destination + ** database. The complication here is that the destination page + ** size may be different to the source page size. ** - ** * Data stored on the pages immediately following the - ** pending-byte page in the source database may need to be - ** copied into the destination database. + ** If the source page size is smaller than the destination page size, + ** round up. In this case the call to sqlite3OsTruncate() below will + ** fix the size of the file. However it is important to call + ** sqlite3PagerTruncateImage() here so that any pages in the + ** destination file that lie beyond the nDestTruncate page mark are + ** journalled by PagerCommitPhaseOne() before they are destroyed + ** by the file truncation. */ - const i64 iSize = (i64)nSrcPagesize * (i64)nSrcPage; - sqlite3_file * const pFile = sqlite3PagerFile(pDestPager); + assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) ); + assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) ); + if( pgszSrc<pgszDest ){ + int ratio = pgszDest/pgszSrc; + nDestTruncate = (nSrcPage+ratio-1)/ratio; + if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){ + nDestTruncate--; + } + }else{ + nDestTruncate = nSrcPage * (pgszSrc/pgszDest); + } + sqlite3PagerTruncateImage(pDestPager, nDestTruncate); - assert( pFile ); - assert( (i64)nDestTruncate*(i64)nDestPagesize >= iSize || ( - nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1) - && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+nDestPagesize - )); - if( SQLITE_OK==(rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1)) - && SQLITE_OK==(rc = backupTruncateFile(pFile, iSize)) - && SQLITE_OK==(rc = sqlite3PagerSync(pDestPager)) - ){ + if( pgszSrc<pgszDest ){ + /* If the source page-size is smaller than the destination page-size, + ** two extra things may need to happen: + ** + ** * The destination may need to be truncated, and + ** + ** * Data stored on the pages immediately following the + ** pending-byte page in the source database may need to be + ** copied into the destination database. + */ + const i64 iSize = (i64)pgszSrc * (i64)nSrcPage; + sqlite3_file * const pFile = sqlite3PagerFile(pDestPager); i64 iOff; - i64 iEnd = MIN(PENDING_BYTE + nDestPagesize, iSize); + i64 iEnd; + + assert( pFile ); + assert( (i64)nDestTruncate*(i64)pgszDest >= iSize || ( + nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1) + && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest + )); + + /* This call ensures that all data required to recreate the original + ** database has been stored in the journal for pDestPager and the + ** journal synced to disk. So at this point we may safely modify + ** the database file in any way, knowing that if a power failure + ** occurs, the original database will be reconstructed from the + ** journal file. */ + rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1); + + /* Write the extra pages and truncate the database file as required */ + iEnd = MIN(PENDING_BYTE + pgszDest, iSize); for( - iOff=PENDING_BYTE+nSrcPagesize; - rc==SQLITE_OK && iOff<iEnd; - iOff+=nSrcPagesize + iOff=PENDING_BYTE+pgszSrc; + rc==SQLITE_OK && iOff<iEnd; + iOff+=pgszSrc ){ PgHdr *pSrcPg = 0; - const Pgno iSrcPg = (Pgno)((iOff/nSrcPagesize)+1); + const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1); rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg); if( rc==SQLITE_OK ){ u8 *zData = sqlite3PagerGetData(pSrcPg); - rc = sqlite3OsWrite(pFile, zData, nSrcPagesize, iOff); + rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff); } sqlite3PagerUnref(pSrcPg); } - } - }else{ - rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0); - } + if( rc==SQLITE_OK ){ + rc = backupTruncateFile(pFile, iSize); + } - /* Finish committing the transaction to the destination database. */ - if( SQLITE_OK==rc - && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest)) - ){ - rc = SQLITE_DONE; + /* Sync the database file to disk. */ + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSync(pDestPager); + } + }else{ + rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0); + } + + /* Finish committing the transaction to the destination database. */ + if( SQLITE_OK==rc + && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest, 0)) + ){ + rc = SQLITE_DONE; + } } } - + /* If bCloseTrans is true, then this function opened a read transaction ** on the source database. Close the read transaction here. There is ** no need to check the return values of the btree methods here, as @@ -46954,10 +56966,13 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ if( bCloseTrans ){ TESTONLY( int rc2 ); TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0); - TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc); + TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0); assert( rc2==SQLITE_OK ); } - + + if( rc==SQLITE_IOERR_NOMEM ){ + rc = SQLITE_NOMEM; + } p->rc = rc; } if( p->pDestDb ){ @@ -47010,6 +57025,9 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){ } sqlite3BtreeLeave(p->pSrc); if( p->pDestDb ){ + /* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a + ** call to sqlite3_backup_init() and is destroyed by a call to + ** sqlite3_backup_finish(). */ sqlite3_free(p); } sqlite3_mutex_leave(mutex); @@ -47025,7 +57043,7 @@ SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){ } /* -** Return the total number of pages in the source database as of the most +** Return the total number of pages in the source database as of the most ** recent call to sqlite3_backup_step(). */ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){ @@ -47034,7 +57052,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){ /* ** This function is called after the contents of page iPage of the -** source database have been modified. If page iPage has already been +** source database have been modified. If page iPage has already been ** copied into the destination database, then the data written to the ** destination is now invalidated. The destination copy of iPage needs ** to be updated with the new data before the backup operation is @@ -47053,7 +57071,11 @@ SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, con ** has been modified by a transaction on the source pager. Copy ** the new data into the backup. */ - int rc = backupOnePage(p, iPage, aData); + int rc; + assert( p->pDestDb ); + sqlite3_mutex_enter(p->pDestDb->mutex); + rc = backupOnePage(p, iPage, aData); + sqlite3_mutex_leave(p->pDestDb->mutex); assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED ); if( rc!=SQLITE_OK ){ p->rc = rc; @@ -47066,7 +57088,7 @@ SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, con ** Restart the backup process. This is called when the pager layer ** detects that the database has been modified by an external database ** connection. In this case there is no way of knowing which of the -** pages that have been copied into the destination database are still +** pages that have been copied into the destination database are still ** valid and which are not, so the entire process needs to be restarted. ** ** It is assumed that the mutex associated with the BtShared object @@ -47086,8 +57108,8 @@ SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *pBackup){ ** Copy the complete content of pBtFrom into pBtTo. A transaction ** must be active for both files. ** -** The size of file pTo may be reduced by this operation. If anything -** goes wrong, the transaction on pTo is rolled back. If successful, the +** The size of file pTo may be reduced by this operation. If anything +** goes wrong, the transaction on pTo is rolled back. If successful, the ** transaction is committed before returning. */ SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ @@ -47109,9 +57131,9 @@ SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ /* 0x7FFFFFFF is the hard limit for the number of pages in a database ** file. By passing this as the number of pages to copy to - ** sqlite3_backup_step(), we can guarantee that the copy finishes + ** sqlite3_backup_step(), we can guarantee that the copy finishes ** within a single call (unless an error occurs). The assert() statement - ** checks this assumption - (p->rc) should be set to either SQLITE_DONE + ** checks this assumption - (p->rc) should be set to either SQLITE_DONE ** or an error code. */ sqlite3_backup_step(&b, 0x7FFFFFFF); @@ -47191,23 +57213,23 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ } /* -** Make sure pMem->z points to a writable allocation of at least +** Make sure pMem->z points to a writable allocation of at least ** n bytes. ** ** If the memory cell currently contains string or blob data -** and the third argument passed to this function is true, the +** and the third argument passed to this function is true, the ** current content of the cell is preserved. Otherwise, it may -** be discarded. +** be discarded. ** ** This function sets the MEM_Dyn flag and clears any xDel callback. -** It also clears MEM_Ephem and MEM_Static. If the preserve flag is +** It also clears MEM_Ephem and MEM_Static. If the preserve flag is ** not set, Mem.n is zeroed. */ SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){ assert( 1 >= ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) + - (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) + - ((pMem->flags&MEM_Ephem) ? 1 : 0) + + (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) + + ((pMem->flags&MEM_Ephem) ? 1 : 0) + ((pMem->flags&MEM_Static) ? 1 : 0) ); assert( (pMem->flags&MEM_RowSet)==0 ); @@ -47261,6 +57283,9 @@ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ pMem->z[pMem->n] = 0; pMem->z[pMem->n+1] = 0; pMem->flags |= MEM_Term; +#ifdef SQLITE_DEBUG + pMem->pScopyFrom = 0; +#endif } return SQLITE_OK; @@ -47346,7 +57371,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, int enc){ /* For a Real or Integer, use sqlite3_mprintf() to produce the UTF-8 ** string representation of the value. Then, if the required encoding ** is UTF-16le or UTF-16be do a translation. - ** + ** ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16. */ if( fg & MEM_Int ){ @@ -47381,7 +57406,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ ctx.s.db = pMem->db; ctx.pMem = pMem; ctx.pFunc = pFunc; - pFunc->xFinalize(&ctx); + pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel ); sqlite3DbFree(pMem->db, pMem->zMalloc); memcpy(pMem, &ctx.s, sizeof(ctx.s)); @@ -47397,24 +57422,18 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ */ SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){ assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) ); - testcase( p->flags & MEM_Agg ); - testcase( p->flags & MEM_Dyn ); - testcase( p->flags & MEM_RowSet ); - testcase( p->flags & MEM_Frame ); - if( p->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame) ){ - if( p->flags&MEM_Agg ){ - sqlite3VdbeMemFinalize(p, p->u.pDef); - assert( (p->flags & MEM_Agg)==0 ); - sqlite3VdbeMemRelease(p); - }else if( p->flags&MEM_Dyn && p->xDel ){ - assert( (p->flags&MEM_RowSet)==0 ); - p->xDel((void *)p->z); - p->xDel = 0; - }else if( p->flags&MEM_RowSet ){ - sqlite3RowSetClear(p->u.pRowSet); - }else if( p->flags&MEM_Frame ){ - sqlite3VdbeMemSetNull(p); - } + if( p->flags&MEM_Agg ){ + sqlite3VdbeMemFinalize(p, p->u.pDef); + assert( (p->flags & MEM_Agg)==0 ); + sqlite3VdbeMemRelease(p); + }else if( p->flags&MEM_Dyn && p->xDel ){ + assert( (p->flags&MEM_RowSet)==0 ); + p->xDel((void *)p->z); + p->xDel = 0; + }else if( p->flags&MEM_RowSet ){ + sqlite3RowSetClear(p->u.pRowSet); + }else if( p->flags&MEM_Frame ){ + sqlite3VdbeMemSetNull(p); } } @@ -47424,7 +57443,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){ ** (Mem.type==SQLITE_TEXT). */ SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){ - sqlite3VdbeMemReleaseExternal(p); + MemReleaseExt(p); sqlite3DbFree(p->db, p->zMalloc); p->z = 0; p->zMalloc = 0; @@ -47493,14 +57512,10 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){ }else if( flags & MEM_Real ){ return doubleToInt64(pMem->r); }else if( flags & (MEM_Str|MEM_Blob) ){ - i64 value; - pMem->flags |= MEM_Str; - if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8) - || sqlite3VdbeMemNulTerminate(pMem) ){ - return 0; - } - assert( pMem->z ); - sqlite3Atoi64(pMem->z, &value); + i64 value = 0; + assert( pMem->z || pMem->n==0 ); + testcase( pMem->z==0 ); + sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); return value; }else{ return 0; @@ -47523,14 +57538,7 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){ }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ double val = (double)0; - pMem->flags |= MEM_Str; - if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8) - || sqlite3VdbeMemNulTerminate(pMem) ){ - /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ - return (double)0; - } - assert( pMem->z ); - sqlite3AtoF(pMem->z, &val); + sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc); return val; }else{ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ @@ -47603,21 +57611,19 @@ SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){ ** as much of the string as we can and ignore the rest. */ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ - int rc; - assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ); - assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - rc = sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8); - if( rc ) return rc; - rc = sqlite3VdbeMemNulTerminate(pMem); - if( rc ) return rc; - if( sqlite3Atoi64(pMem->z, &pMem->u.i) ){ - MemSetTypeFlag(pMem, MEM_Int); - }else{ - pMem->r = sqlite3VdbeRealValue(pMem); - MemSetTypeFlag(pMem, MEM_Real); - sqlite3VdbeIntegerAffinity(pMem); + if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){ + assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){ + MemSetTypeFlag(pMem, MEM_Int); + }else{ + pMem->r = sqlite3VdbeRealValue(pMem); + MemSetTypeFlag(pMem, MEM_Real); + sqlite3VdbeIntegerAffinity(pMem); + } } + assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 ); + pMem->flags &= ~(MEM_Str|MEM_Blob); return SQLITE_OK; } @@ -47626,7 +57632,9 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ */ SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){ if( pMem->flags & MEM_Frame ){ - sqlite3VdbeFrameDelete(pMem->u.pFrame); + VdbeFrame *pFrame = pMem->u.pFrame; + pFrame->pParent = pFrame->v->pDelFrame; + pFrame->v->pDelFrame = pFrame; } if( pMem->flags & MEM_RowSet ){ sqlite3RowSetClear(pMem->u.pRowSet); @@ -47699,7 +57707,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){ pMem->flags = MEM_Null; }else{ assert( pMem->zMalloc ); - pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, + pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, sqlite3DbMallocSize(db, pMem->zMalloc)); assert( pMem->u.pRowSet!=0 ); pMem->flags = MEM_RowSet; @@ -47719,8 +57727,30 @@ SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){ } return n>p->db->aLimit[SQLITE_LIMIT_LENGTH]; } - return 0; + return 0; +} + +#ifdef SQLITE_DEBUG +/* +** This routine prepares a memory cell for modication by breaking +** its link to a shallow copy and by marking any current shallow +** copies of this cell as invalid. +** +** This is used for testing and debugging only - to make sure shallow +** copies are not misused. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemPrepareToChange(Vdbe *pVdbe, Mem *pMem){ + int i; + Mem *pX; + for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){ + if( pX->pScopyFrom==pMem ){ + pX->flags |= MEM_Invalid; + pX->pScopyFrom = 0; + } + } + pMem->pScopyFrom = 0; } +#endif /* SQLITE_DEBUG */ /* ** Size of struct Mem not including the Mem.zMalloc member. @@ -47735,7 +57765,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){ */ SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ assert( (pFrom->flags & MEM_RowSet)==0 ); - sqlite3VdbeMemReleaseExternal(pTo); + MemReleaseExt(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->xDel = 0; if( (pFrom->flags&MEM_Static)==0 ){ @@ -47753,7 +57783,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ int rc = SQLITE_OK; assert( (pFrom->flags & MEM_RowSet)==0 ); - sqlite3VdbeMemReleaseExternal(pTo); + MemReleaseExt(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->flags &= ~MEM_Dyn; @@ -47789,8 +57819,8 @@ SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ ** Change the value of a Mem to be a string or a BLOB. ** ** The memory management strategy depends on the value of the xDel -** parameter. If the value passed is SQLITE_TRANSIENT, then the -** string is copied into a (possibly existing) buffer managed by the +** parameter. If the value passed is SQLITE_TRANSIENT, then the +** string is copied into a (possibly existing) buffer managed by the ** Mem structure. Otherwise, any existing buffer is freed and the ** pointer copied. ** @@ -47899,7 +57929,7 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C f2 = pMem2->flags; combined_flags = f1|f2; assert( (combined_flags & MEM_RowSet)==0 ); - + /* If one value is NULL, it is less than the other. If both values ** are NULL, return 0. */ @@ -47954,7 +57984,7 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C } assert( pMem1->enc==pMem2->enc ); - assert( pMem1->enc==SQLITE_UTF8 || + assert( pMem1->enc==SQLITE_UTF8 || pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE ); /* The collation sequence must be defined at this point, even if @@ -47990,7 +58020,7 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C /* If a NULL pointer was passed as the collate function, fall through ** to the blob case and use memcmp(). */ } - + /* Both values must be blobs. Compare using memcmp(). */ rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n); if( rc==0 ){ @@ -48025,7 +58055,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( assert( sqlite3BtreeCursorIsValid(pCur) ); - /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() + /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() ** that both the BtShared and database handle mutexes are held. */ assert( (pMem->flags & MEM_RowSet)==0 ); if( key ){ @@ -48090,7 +58120,7 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ return 0; } } - sqlite3VdbeMemNulTerminate(pVal); + sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-59893-45467 */ }else{ assert( (pVal->flags&MEM_Blob)==0 ); sqlite3VdbeMemStringify(pVal, enc); @@ -48138,23 +58168,43 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr( int op; char *zVal = 0; sqlite3_value *pVal = 0; + int negInt = 1; + const char *zNeg = ""; if( !pExpr ){ *ppVal = 0; return SQLITE_OK; } op = pExpr->op; - if( op==TK_REGISTER ){ - op = pExpr->op2; /* This only happens with SQLITE_ENABLE_STAT2 */ + + /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT2. + ** The ifdef here is to enable us to achieve 100% branch test coverage even + ** when SQLITE_ENABLE_STAT2 is omitted. + */ +#ifdef SQLITE_ENABLE_STAT2 + if( op==TK_REGISTER ) op = pExpr->op2; +#else + if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; +#endif + + /* Handle negative integers in a single step. This is needed in the + ** case when the value is -9223372036854775808. + */ + if( op==TK_UMINUS + && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){ + pExpr = pExpr->pLeft; + op = pExpr->op; + negInt = -1; + zNeg = "-"; } if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ pVal = sqlite3ValueNew(db); if( pVal==0 ) goto no_mem; if( ExprHasProperty(pExpr, EP_IntValue) ){ - sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue); + sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); }else{ - zVal = sqlite3DbStrDup(db, pExpr->u.zToken); + zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); if( zVal==0 ) goto no_mem; sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT; @@ -48164,15 +58214,27 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr( }else{ sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); } + if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str; if( enc!=SQLITE_UTF8 ){ sqlite3VdbeChangeEncoding(pVal, enc); } }else if( op==TK_UMINUS ) { + /* This branch happens for multiple negative signs. Ex: -(-5) */ if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){ - pVal->u.i = -1 * pVal->u.i; - /* (double)-1 In case of SQLITE_OMIT_FLOATING_POINT... */ - pVal->r = (double)-1 * pVal->r; + sqlite3VdbeMemNumerify(pVal); + if( pVal->u.i==SMALLEST_INT64 ){ + pVal->flags &= MEM_Int; + pVal->flags |= MEM_Real; + pVal->r = (double)LARGEST_INT64; + }else{ + pVal->u.i = -pVal->u.i; + } + pVal->r = -pVal->r; + sqlite3ValueApplyAffinity(pVal, affinity, enc); } + }else if( op==TK_NULL ){ + pVal = sqlite3ValueNew(db); + if( pVal==0 ) goto no_mem; } #ifndef SQLITE_OMIT_BLOB_LITERAL else if( op==TK_BLOB ){ @@ -48343,12 +58405,12 @@ SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe *p, FILE *trace){ #endif /* -** Resize the Vdbe.aOp array so that it is at least one op larger than +** Resize the Vdbe.aOp array so that it is at least one op larger than ** it was. ** ** If an out-of-memory error occurs while resizing the array, return -** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain -** unchanged (this is so that any opcodes already allocated can be +** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain +** unchanged (this is so that any opcodes already allocated can be ** correctly deallocated along with the rest of the Vdbe). */ static int growOpArray(Vdbe *p){ @@ -48399,7 +58461,6 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ pOp->p3 = p3; pOp->p4.p = 0; pOp->p4type = P4_NOTUSED; - p->expired = 0; #ifdef SQLITE_DEBUG pOp->zComment = 0; if( sqlite3VdbeAddopTrace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]); @@ -48439,6 +58500,20 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp4( } /* +** Add an OP_ParseSchema opcode. This routine is broken out from +** sqlite3VdbeAddOp4() since it needs to also local all btrees. +** +** The zWhere string must have been obtained from sqlite3_malloc(). +** This routine will take ownership of the allocated memory. +*/ +SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){ + int j; + int addr = sqlite3VdbeAddOp3(p, OP_ParseSchema, iDb, 0, 0); + sqlite3VdbeChangeP4(p, addr, zWhere, P4_DYNAMIC); + for(j=0; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j); +} + +/* ** Add an opcode that includes the p4 value as an integer. */ SQLITE_PRIVATE int sqlite3VdbeAddOp4Int( @@ -48509,19 +58584,19 @@ SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){ /* ** The following type and function are used to iterate through all opcodes -** in a Vdbe main program and each of the sub-programs (triggers) it may +** in a Vdbe main program and each of the sub-programs (triggers) it may ** invoke directly or indirectly. It should be used as follows: ** ** Op *pOp; ** VdbeOpIter sIter; ** ** memset(&sIter, 0, sizeof(sIter)); -** sIter.v = v; // v is of type Vdbe* +** sIter.v = v; // v is of type Vdbe* ** while( (pOp = opIterNext(&sIter)) ){ ** // Do something with pOp ** } ** sqlite3DbFree(v->db, sIter.apSub); -** +** */ typedef struct VdbeOpIter VdbeOpIter; struct VdbeOpIter { @@ -48554,7 +58629,7 @@ static Op *opIterNext(VdbeOpIter *p){ p->iSub++; p->iAddr = 0; } - + if( pRet->p4type==P4_SUBPROGRAM ){ int nByte = (p->nSub+1)*sizeof(SubProgram*); int j; @@ -48604,11 +58679,11 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ while( (pOp = opIterNext(&sIter))!=0 ){ int opcode = pOp->opcode; - if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename + if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename #ifndef SQLITE_OMIT_FOREIGN_KEY - || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1) + || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1) #endif - || ((opcode==OP_Halt || opcode==OP_HaltIfNull) + || ((opcode==OP_Halt || opcode==OP_HaltIfNull) && (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort)) ){ hasAbort = 1; @@ -48633,8 +58708,8 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ ** ** This routine is called once after all opcodes have been inserted. ** -** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument -** to an OP_Function, OP_AggStep or OP_VFilter opcode. This is used by +** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument +** to an OP_Function, OP_AggStep or OP_VFilter opcode. This is used by ** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array. ** ** The Op.opflags field is set on all opcodes. @@ -48651,7 +58726,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ pOp->opflags = sqlite3OpcodeProperty[opcode]; if( opcode==OP_Function || opcode==OP_AggStep ){ if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5; - }else if( opcode==OP_Transaction && pOp->p2!=0 ){ + }else if( (opcode==OP_Transaction && pOp->p2!=0) || opcode==OP_Vacuum ){ p->readOnly = 0; #ifndef SQLITE_OMIT_VIRTUALTABLE }else if( opcode==OP_VUpdate ){ @@ -48663,6 +58738,12 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ n = pOp[-1].p1; if( n>nMaxArgs ) nMaxArgs = n; #endif + }else if( opcode==OP_Next || opcode==OP_SorterNext ){ + pOp->p4.xAdvance = sqlite3BtreeNext; + pOp->p4type = P4_ADVANCE; + }else if( opcode==OP_Prev ){ + pOp->p4.xAdvance = sqlite3BtreePrevious; + pOp->p4type = P4_ADVANCE; } if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){ @@ -48687,12 +58768,12 @@ SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){ /* ** This function returns a pointer to the array of opcodes associated with ** the Vdbe passed as the first argument. It is the callers responsibility -** to arrange for the returned array to be eventually freed using the +** to arrange for the returned array to be eventually freed using the ** vdbeFreeOpArray() function. ** ** Before returning, *pnOp is set to the number of entries in the returned -** array. Also, *pnMaxArg is set to the larger of its current value and -** the number of entries in the Vdbe.apArg[] array required to execute the +** array. Also, *pnMaxArg is set to the larger of its current value and +** the number of entries in the Vdbe.apArg[] array required to execute the ** returned program. */ SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ @@ -48700,7 +58781,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg) assert( aOp && !p->db->mallocFailed ); /* Check that sqlite3VdbeUsesBtree() was not called on this VM */ - assert( p->aMutex.nMutex==0 ); + assert( p->btreeMask==0 ); resolveP2Values(p, pnMaxArg); *pnOp = p->nOp; @@ -48754,10 +58835,9 @@ SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp) ** static array using sqlite3VdbeAddOpList but we want to make a ** few minor changes to the program. */ -SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){ +SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){ assert( p!=0 ); - assert( addr>=0 ); - if( p->nOp>addr ){ + if( ((u32)p->nOp)>addr ){ p->aOp[addr].p1 = val; } } @@ -48766,10 +58846,9 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){ ** Change the value of the P2 operand for a specific instruction. ** This routine is useful for setting a jump destination. */ -SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ +SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){ assert( p!=0 ); - assert( addr>=0 ); - if( p->nOp>addr ){ + if( ((u32)p->nOp)>addr ){ p->aOp[addr].p2 = val; } } @@ -48777,10 +58856,9 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ /* ** Change the value of the P3 operand for a specific instruction. */ -SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){ +SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){ assert( p!=0 ); - assert( addr>=0 ); - if( p->nOp>addr ){ + if( ((u32)p->nOp)>addr ){ p->aOp[addr].p3 = val; } } @@ -48802,6 +58880,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 val){ ** the address of the next instruction to be coded. */ SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){ + assert( addr>=0 ); sqlite3VdbeChangeP2(p, addr, p->nOp); } @@ -48816,15 +58895,17 @@ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ } } +static void vdbeFreeOpArray(sqlite3 *, Op *, int); + /* ** Delete a P4 value if necessary. */ static void freeP4(sqlite3 *db, int p4type, void *p4){ if( p4 ){ + assert( db ); switch( p4type ){ case P4_REAL: case P4_INT64: - case P4_MPRINTF: case P4_DYNAMIC: case P4_KEYINFO: case P4_INTARRAY: @@ -48832,10 +58913,14 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ sqlite3DbFree(db, p4); break; } + case P4_MPRINTF: { + if( db->pnBytesFreed==0 ) sqlite3_free(p4); + break; + } case P4_VDBEFUNC: { VdbeFunc *pVdbeFunc = (VdbeFunc *)p4; freeEphemeralFunction(db, pVdbeFunc->pFunc); - sqlite3VdbeDeleteAuxData(pVdbeFunc, 0); + if( db->pnBytesFreed==0 ) sqlite3VdbeDeleteAuxData(pVdbeFunc, 0); sqlite3DbFree(db, pVdbeFunc); break; } @@ -48844,15 +58929,17 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ break; } case P4_MEM: { - sqlite3ValueFree((sqlite3_value*)p4); + if( db->pnBytesFreed==0 ){ + sqlite3ValueFree((sqlite3_value*)p4); + }else{ + Mem *p = (Mem*)p4; + sqlite3DbFree(db, p->zMalloc); + sqlite3DbFree(db, p); + } break; } case P4_VTAB : { - sqlite3VtabUnlock((VTable *)p4); - break; - } - case P4_SUBPROGRAM : { - sqlite3VdbeProgramDelete(db, (SubProgram *)p4, 1); + if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); break; } } @@ -48861,8 +58948,8 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ /* ** Free the space allocated for aOp and any p4 values allocated for the -** opcodes contained within. If aOp is not NULL it is assumed to contain -** nOp entries. +** opcodes contained within. If aOp is not NULL it is assumed to contain +** nOp entries. */ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ if( aOp ){ @@ -48871,55 +58958,32 @@ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ freeP4(db, pOp->p4type, pOp->p4.p); #ifdef SQLITE_DEBUG sqlite3DbFree(db, pOp->zComment); -#endif +#endif } } sqlite3DbFree(db, aOp); } /* -** Decrement the ref-count on the SubProgram structure passed as the -** second argument. If the ref-count reaches zero, free the structure. -** -** The array of VDBE opcodes stored as SubProgram.aOp is freed if -** either the ref-count reaches zero or parameter freeop is non-zero. -** -** Since the array of opcodes pointed to by SubProgram.aOp may directly -** or indirectly contain a reference to the SubProgram structure itself. -** By passing a non-zero freeop parameter, the caller may ensure that all -** SubProgram structures and their aOp arrays are freed, even when there -** are such circular references. +** Link the SubProgram object passed as the second argument into the linked +** list at Vdbe.pSubProgram. This list is used to delete all sub-program +** objects when the VM is no longer required. */ -SQLITE_PRIVATE void sqlite3VdbeProgramDelete(sqlite3 *db, SubProgram *p, int freeop){ - if( p ){ - assert( p->nRef>0 ); - if( freeop || p->nRef==1 ){ - Op *aOp = p->aOp; - p->aOp = 0; - vdbeFreeOpArray(db, aOp, p->nOp); - p->nOp = 0; - } - p->nRef--; - if( p->nRef==0 ){ - sqlite3DbFree(db, p); - } - } +SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ + p->pNext = pVdbe->pProgram; + pVdbe->pProgram = p; } - /* -** Change N opcodes starting at addr to No-ops. +** Change the opcode at addr into OP_Noop */ -SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){ +SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ if( p->aOp ){ VdbeOp *pOp = &p->aOp[addr]; sqlite3 *db = p->db; - while( N-- ){ - freeP4(db, pOp->p4type, pOp->p4.p); - memset(pOp, 0, sizeof(pOp[0])); - pOp->opcode = OP_Noop; - pOp++; - } + freeP4(db, pOp->p4type, pOp->p4.p); + memset(pOp, 0, sizeof(pOp[0])); + pOp->opcode = OP_Noop; } } @@ -48938,10 +59002,10 @@ SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){ ** A copy is made of the KeyInfo structure into memory obtained from ** sqlite3_malloc, to be freed when the Vdbe is finalized. ** n==P4_KEYINFO_HANDOFF indicates that zP4 points to a KeyInfo structure -** stored in memory that the caller has obtained from sqlite3_malloc. The +** stored in memory that the caller has obtained from sqlite3_malloc. The ** caller should not free the allocation, it will be freed when the Vdbe is ** finalized. -** +** ** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points ** to a string or structure that is guaranteed to exist for the lifetime of ** the Vdbe. In these cases we can just copy the pointer. @@ -48982,11 +59046,11 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int nField = ((KeyInfo*)zP4)->nField; nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField; - pKeyInfo = sqlite3Malloc( nByte ); + pKeyInfo = sqlite3DbMallocRaw(0, nByte); pOp->p4.pKeyInfo = pKeyInfo; if( pKeyInfo ){ u8 *aSortOrder; - memcpy(pKeyInfo, zP4, nByte); + memcpy((char*)pKeyInfo, zP4, nByte - nField); aSortOrder = pKeyInfo->aSortOrder; if( aSortOrder ){ pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField]; @@ -49057,9 +59121,12 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ ** ** 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 and writable, but it has no effect. The return of a dummy -** opcode allows the call to continue functioning after a OOM fault without -** having to check to see if the return from this routine is a valid pointer. +** 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 +** after a OOM fault without having to check to see if the return from +** this routine is a valid pointer. But because the dummy.opcode is 0, +** dummy will never be written to. This is verified by code inspection and +** by running with Valgrind. ** ** About the #ifdef SQLITE_OMIT_TRACE: Normally, this routine is never called ** unless p->nOp>0. This is because in the absense of SQLITE_OMIT_TRACE, @@ -49070,17 +59137,19 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ ** check the value of p->nOp-1 before continuing. */ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ - static VdbeOp dummy; + /* 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->magic==VDBE_MAGIC_INIT ); if( addr<0 ){ #ifdef SQLITE_OMIT_TRACE - if( p->nOp==0 ) return &dummy; + if( p->nOp==0 ) return (VdbeOp*)&dummy; #endif addr = p->nOp - 1; } assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed ); if( p->db->mallocFailed ){ - return &dummy; + return (VdbeOp*)&dummy; }else{ return &p->aOp[addr]; } @@ -49178,6 +59247,10 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ sqlite3_snprintf(nTemp, zTemp, "program"); break; } + case P4_ADVANCE: { + zTemp[0] = 0; + break; + } default: { zP4 = pOp->p4.z; if( zP4==0 ){ @@ -49193,18 +59266,81 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ /* ** Declare to the Vdbe that the BTree object at db->aDb[i] is used. +** +** The prepared statements need to know in advance the complete set of +** attached databases that they will be using. A mask of these databases +** is maintained in p->btreeMask and is used for locking and other purposes. */ SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ - int mask; - assert( i>=0 && i<p->db->nDb && i<sizeof(u32)*8 ); + assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 ); assert( i<(int)sizeof(p->btreeMask)*8 ); - mask = ((u32)1)<<i; - if( (p->btreeMask & mask)==0 ){ - p->btreeMask |= mask; - sqlite3BtreeMutexArrayInsert(&p->aMutex, p->db->aDb[i].pBt); + p->btreeMask |= ((yDbMask)1)<<i; + if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ + p->lockMask |= ((yDbMask)1)<<i; } } +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 +/* +** If SQLite is compiled to support shared-cache mode and to be threadsafe, +** this routine obtains the mutex associated with each BtShared structure +** that may be accessed by the VM passed as an argument. In doing so it also +** sets the BtShared.db member of each of the BtShared structures, ensuring +** that the correct busy-handler callback is invoked if required. +** +** If SQLite is not threadsafe but does support shared-cache mode, then +** sqlite3BtreeEnter() is invoked to set the BtShared.db variables +** of all of BtShared structures accessible via the database handle +** associated with the VM. +** +** If SQLite is not threadsafe and does not support shared-cache mode, this +** function is a no-op. +** +** The p->btreeMask field is a bitmask of all btrees that the prepared +** statement p will ever use. Let N be the number of bits in p->btreeMask +** corresponding to btrees that use shared cache. Then the runtime of +** this routine is N*N. But as N is rarely more than 1, this should not +** be a problem. +*/ +SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){ + int i; + yDbMask mask; + sqlite3 *db; + Db *aDb; + int nDb; + if( p->lockMask==0 ) return; /* The common case */ + db = p->db; + aDb = db->aDb; + nDb = db->nDb; + for(i=0, mask=1; i<nDb; i++, mask += mask){ + if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ + sqlite3BtreeEnter(aDb[i].pBt); + } + } +} +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 +/* +** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). +*/ +SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){ + int i; + yDbMask mask; + sqlite3 *db; + Db *aDb; + int nDb; + if( p->lockMask==0 ) return; /* The common case */ + db = p->db; + aDb = db->aDb; + nDb = db->nDb; + for(i=0, mask=1; i<nDb; i++, mask += mask){ + if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ + sqlite3BtreeLeave(aDb[i].pBt); + } + } +} +#endif #if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) /* @@ -49216,7 +59352,7 @@ SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){ static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-4s %.2X %s\n"; if( pOut==0 ) pOut = stdout; zP4 = displayP4(pOp, zPtr, sizeof(zPtr)); - fprintf(pOut, zFormat1, pc, + fprintf(pOut, zFormat1, pc, sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5, #ifdef SQLITE_DEBUG pOp->zComment ? pOp->zComment : "" @@ -49236,19 +59372,25 @@ static void releaseMemArray(Mem *p, int N){ Mem *pEnd; sqlite3 *db = p->db; u8 malloc_failed = db->mallocFailed; + if( db->pnBytesFreed ){ + for(pEnd=&p[N]; p<pEnd; p++){ + sqlite3DbFree(db, p->zMalloc); + } + return; + } for(pEnd=&p[N]; p<pEnd; p++){ assert( (&p[1])==pEnd || p[0].db==p[1].db ); /* This block is really an inlined version of sqlite3VdbeMemRelease() - ** that takes advantage of the fact that the memory cell value is + ** that takes advantage of the fact that the memory cell value is ** being set to NULL after releasing any dynamic resources. ** - ** The justification for duplicating code is that according to - ** callgrind, this causes a certain test case to hit the CPU 4.7 - ** percent less (x86 linux, gcc version 4.1.2, -O6) than if + ** The justification for duplicating code is that according to + ** callgrind, this causes a certain test case to hit the CPU 4.7 + ** percent less (x86 linux, gcc version 4.1.2, -O6) than if ** sqlite3MemRelease() were called from here. With -O2, this jumps - ** to 6.6 percent. The test case is inserting 1000 rows into a table - ** with no indexes using a single prepared INSERT statement, bind() + ** to 6.6 percent. The test case is inserting 1000 rows into a table + ** with no indexes using a single prepared INSERT statement, bind() ** and reset(). Inserts are grouped into a transaction. */ if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){ @@ -49382,7 +59524,7 @@ SQLITE_PRIVATE int sqlite3VdbeList( pMem->type = SQLITE_INTEGER; pMem->u.i = i; /* Program counter */ pMem++; - + pMem->flags = MEM_Static|MEM_Str|MEM_Term; pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */ assert( pMem->z!=0 ); @@ -49421,12 +59563,10 @@ SQLITE_PRIVATE int sqlite3VdbeList( pMem->type = SQLITE_INTEGER; pMem++; - if( p->explain==1 ){ - pMem->flags = MEM_Int; - pMem->u.i = pOp->p3; /* P3 */ - pMem->type = SQLITE_INTEGER; - pMem++; - } + pMem->flags = MEM_Int; + pMem->u.i = pOp->p3; /* P3 */ + pMem->type = SQLITE_INTEGER; + pMem++; if( sqlite3VdbeMemGrow(pMem, 32, 0) ){ /* P4 */ assert( p->db->mallocFailed ); @@ -49455,7 +59595,7 @@ SQLITE_PRIVATE int sqlite3VdbeList( pMem->type = SQLITE_TEXT; pMem->enc = SQLITE_UTF8; pMem++; - + #ifdef SQLITE_DEBUG if( pOp->zComment ){ pMem->flags = MEM_Str|MEM_Term; @@ -49471,7 +59611,7 @@ SQLITE_PRIVATE int sqlite3VdbeList( } } - p->nResColumn = 8 - 5*(p->explain-1); + p->nResColumn = 8 - 4*(p->explain-1); p->rc = SQLITE_OK; rc = SQLITE_ROW; } @@ -49567,34 +59707,13 @@ static void *allocSpace( } /* -** Prepare a virtual machine for execution. This involves things such -** as allocating stack space and initializing the program counter. -** After the VDBE has be prepped, it can be executed by one or more -** calls to sqlite3VdbeExec(). -** -** This is the only way to move a VDBE from VDBE_MAGIC_INIT to -** VDBE_MAGIC_RUN. -** -** This function may be called more than once on a single virtual machine. -** The first call is made while compiling the SQL statement. Subsequent -** calls are made as part of the process of resetting a statement to be -** re-executed (from a call to sqlite3_reset()). The nVar, nMem, nCursor -** and isExplain parameters are only passed correct values the first time -** the function is called. On subsequent calls, from sqlite3_reset(), nVar -** is passed -1 and nMem, nCursor and isExplain are all passed zero. +** Rewind the VDBE back to the beginning in preparation for +** running it. */ -SQLITE_PRIVATE void sqlite3VdbeMakeReady( - Vdbe *p, /* The VDBE */ - int nVar, /* Number of '?' see in the SQL statement */ - int nMem, /* Number of memory cells to allocate */ - int nCursor, /* Number of cursors to allocate */ - int nArg, /* Maximum number of args in SubPrograms */ - int isExplain, /* True if the EXPLAIN keywords is present */ - int usesStmtJournal /* True to set Vdbe.usesStmtJournal */ -){ - int n; - sqlite3 *db = p->db; - +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) + int i; +#endif assert( p!=0 ); assert( p->magic==VDBE_MAGIC_INIT ); @@ -49605,10 +59724,75 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ p->magic = VDBE_MAGIC_RUN; +#ifdef SQLITE_DEBUG + for(i=1; i<p->nMem; i++){ + assert( p->aMem[i].db==p->db ); + } +#endif + p->pc = -1; + p->rc = SQLITE_OK; + p->errorAction = OE_Abort; + p->magic = VDBE_MAGIC_RUN; + p->nChange = 0; + p->cacheCtr = 1; + p->minWriteFileFormat = 255; + p->iStatement = 0; + p->nFkConstraint = 0; +#ifdef VDBE_PROFILE + for(i=0; i<p->nOp; i++){ + p->aOp[i].cnt = 0; + p->aOp[i].cycles = 0; + } +#endif +} + +/* +** Prepare a virtual machine for execution for the first time after +** creating the virtual machine. This involves things such +** as allocating stack space and initializing the program counter. +** After the VDBE has be prepped, it can be executed by one or more +** calls to sqlite3VdbeExec(). +** +** This function may be called exact once on a each virtual machine. +** After this routine is called the VM has been "packaged" and is ready +** to run. After this routine is called, futher calls to +** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects +** the Vdbe from the Parse object that helped generate it so that the +** the Vdbe becomes an independent entity and the Parse object can be +** destroyed. +** +** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back +** to its initial state after it has been run. +*/ +SQLITE_PRIVATE void sqlite3VdbeMakeReady( + Vdbe *p, /* The VDBE */ + Parse *pParse /* Parsing context */ +){ + sqlite3 *db; /* The database connection */ + int nVar; /* Number of parameters */ + int nMem; /* Number of VM memory registers */ + int nCursor; /* Number of cursors required */ + int nArg; /* Number of arguments in subprograms */ + int n; /* Loop counter */ + u8 *zCsr; /* Memory available for allocation */ + u8 *zEnd; /* First byte past allocated memory */ + int nByte; /* How much extra memory is needed */ + + assert( p!=0 ); + assert( p->nOp>0 ); + assert( pParse!=0 ); + assert( p->magic==VDBE_MAGIC_INIT ); + db = p->db; + assert( db->mallocFailed==0 ); + nVar = pParse->nVar; + nMem = pParse->nMem; + nCursor = pParse->nTab; + nArg = pParse->nMaxArg; + /* For each cursor required, also allocate a memory cell. Memory ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by ** the vdbe program. Instead they are used to allocate space for - ** VdbeCursor/BtCursor structures. The blob of memory associated with + ** VdbeCursor/BtCursor structures. The blob of memory associated with ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) ** stores the blob of memory associated with cursor 1, etc. ** @@ -49616,101 +59800,81 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( */ nMem += nCursor; - /* Allocate space for memory registers, SQL variables, VDBE cursors and - ** an array to marshal SQL function arguments in. This is only done the - ** first time this function is called for a given VDBE, not when it is - ** being called from sqlite3_reset() to reset the virtual machine. - */ - if( nVar>=0 && ALWAYS(db->mallocFailed==0) ){ - u8 *zCsr = (u8 *)&p->aOp[p->nOp]; /* Memory avaliable for alloation */ - u8 *zEnd = (u8 *)&p->aOp[p->nOpAlloc]; /* First byte past available mem */ - int nByte; /* How much extra memory needed */ - - resolveP2Values(p, &nArg); - p->usesStmtJournal = (u8)usesStmtJournal; - if( isExplain && nMem<10 ){ - nMem = 10; - } - memset(zCsr, 0, zEnd-zCsr); - zCsr += (zCsr - (u8*)0)&7; - assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); - - /* Memory for registers, parameters, cursor, etc, is allocated in two - ** passes. On the first pass, we try to reuse unused space at the - ** end of the opcode array. If we are unable to satisfy all memory - ** requirements by reusing the opcode array tail, then the second - ** pass will fill in the rest using a fresh allocation. - ** - ** This two-pass approach that reuses as much memory as possible from - ** the leftover space at the end of the opcode array can significantly - ** reduce the amount of memory held by a prepared statement. - */ - do { - nByte = 0; - p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte); - p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte); - p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte); - p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); - p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), - &zCsr, zEnd, &nByte); - if( nByte ){ - p->pFree = sqlite3DbMallocZero(db, nByte); - } - zCsr = p->pFree; - zEnd = &zCsr[nByte]; - }while( nByte && !db->mallocFailed ); + /* Allocate space for memory registers, SQL variables, VDBE cursors and + ** an array to marshal SQL function arguments in. + */ + zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */ + zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */ - p->nCursor = (u16)nCursor; - if( p->aVar ){ - p->nVar = (ynVar)nVar; - for(n=0; n<nVar; n++){ - p->aVar[n].flags = MEM_Null; - p->aVar[n].db = db; - } + resolveP2Values(p, &nArg); + p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); + if( pParse->explain && nMem<10 ){ + nMem = 10; + } + memset(zCsr, 0, zEnd-zCsr); + zCsr += (zCsr - (u8*)0)&7; + assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); + p->expired = 0; + + /* Memory for registers, parameters, cursor, etc, is allocated in two + ** passes. On the first pass, we try to reuse unused space at the + ** end of the opcode array. If we are unable to satisfy all memory + ** requirements by reusing the opcode array tail, then the second + ** pass will fill in the rest using a fresh allocation. + ** + ** This two-pass approach that reuses as much memory as possible from + ** the leftover space at the end of the opcode array can significantly + ** reduce the amount of memory held by a prepared statement. + */ + do { + nByte = 0; + p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte); + p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte); + p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte); + p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); + p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), + &zCsr, zEnd, &nByte); + if( nByte ){ + p->pFree = sqlite3DbMallocZero(db, nByte); } - if( p->aMem ){ - p->aMem--; /* aMem[] goes from 1..nMem */ - p->nMem = nMem; /* not from 0..nMem-1 */ - for(n=1; n<=nMem; n++){ - p->aMem[n].flags = MEM_Null; - p->aMem[n].db = db; - } + zCsr = p->pFree; + zEnd = &zCsr[nByte]; + }while( nByte && !db->mallocFailed ); + + p->nCursor = (u16)nCursor; + if( p->aVar ){ + p->nVar = (ynVar)nVar; + for(n=0; n<nVar; n++){ + p->aVar[n].flags = MEM_Null; + p->aVar[n].db = db; } } -#ifdef SQLITE_DEBUG - for(n=1; n<p->nMem; n++){ - assert( p->aMem[n].db==db ); + if( p->azVar ){ + p->nzVar = pParse->nzVar; + memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0])); + memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0])); } -#endif - - p->pc = -1; - p->rc = SQLITE_OK; - p->errorAction = OE_Abort; - p->explain |= isExplain; - p->magic = VDBE_MAGIC_RUN; - p->nChange = 0; - p->cacheCtr = 1; - p->minWriteFileFormat = 255; - p->iStatement = 0; -#ifdef VDBE_PROFILE - { - int i; - for(i=0; i<p->nOp; i++){ - p->aOp[i].cnt = 0; - p->aOp[i].cycles = 0; + if( p->aMem ){ + p->aMem--; /* aMem[] goes from 1..nMem */ + p->nMem = nMem; /* not from 0..nMem-1 */ + for(n=1; n<=nMem; n++){ + p->aMem[n].flags = MEM_Null; + p->aMem[n].db = db; } } -#endif + p->explain = pParse->explain; + sqlite3VdbeRewind(p); } /* -** Close a VDBE cursor and release all the resources that cursor +** Close a VDBE cursor and release all the resources that cursor ** happens to hold. */ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ if( pCx==0 ){ return; } + sqlite3VdbeSorterClose(p->db, pCx); if( pCx->pBt ){ sqlite3BtreeClose(pCx->pBt); /* The pCx->pCursor will be close automatically, if it exists, by @@ -49750,14 +59914,14 @@ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ /* ** Close all cursors. ** -** Also release any dynamic memory held by the VM in the Vdbe.aMem memory +** Also release any dynamic memory held by the VM in the Vdbe.aMem memory ** cell array. This is necessary as the memory cell array may contain ** pointers to VdbeFrame objects, which may in turn contain pointers to ** open cursors. */ static void closeAllCursors(Vdbe *p){ if( p->pFrame ){ - VdbeFrame *pFrame = p->pFrame; + VdbeFrame *pFrame; for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); sqlite3VdbeFrameRestore(pFrame); } @@ -49777,6 +59941,11 @@ static void closeAllCursors(Vdbe *p){ if( p->aMem ){ releaseMemArray(&p->aMem[1], p->nMem); } + while( p->pDelFrame ){ + VdbeFrame *pDel = p->pDelFrame; + p->pDelFrame = pDel->pParent; + sqlite3VdbeFrameDelete(pDel); + } } /* @@ -49790,7 +59959,7 @@ static void Cleanup(Vdbe *p){ sqlite3 *db = p->db; #ifdef SQLITE_DEBUG - /* Execute assert() statements to ensure that the Vdbe.apCsr[] and + /* Execute assert() statements to ensure that the Vdbe.apCsr[] and ** Vdbe.aMem[] arrays have already been cleaned up. */ int i; for(i=0; i<p->nCursor; i++) assert( p->apCsr==0 || p->apCsr[i]==0 ); @@ -49871,36 +60040,37 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ int needXcommit = 0; #ifdef SQLITE_OMIT_VIRTUALTABLE - /* With this option, sqlite3VtabSync() is defined to be simply - ** SQLITE_OK so p is not used. + /* With this option, sqlite3VtabSync() is defined to be simply + ** SQLITE_OK so p is not used. */ UNUSED_PARAMETER(p); #endif /* Before doing anything else, call the xSync() callback for any ** virtual module tables written in this transaction. This has to - ** be done before determining whether a master journal file is + ** be done before determining whether a master journal file is ** required, as an xSync() callback may add an attached database ** to the transaction. */ rc = sqlite3VtabSync(db, &p->zErrMsg); - if( rc!=SQLITE_OK ){ - return rc; - } /* This loop determines (a) if the commit hook should be invoked and - ** (b) how many database files have open write transactions, not - ** including the temp database. (b) is important because if more than + ** (b) how many database files have open write transactions, not + ** including the temp database. (b) is important because if more than ** one database file has an open write transaction, a master journal ** file is required for an atomic commit. - */ - for(i=0; i<db->nDb; i++){ + */ + for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( sqlite3BtreeIsInTrans(pBt) ){ needXcommit = 1; if( i!=1 ) nTrans++; + rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt)); } } + if( rc!=SQLITE_OK ){ + return rc; + } /* If there are any write-transactions at all, invoke the commit hook */ if( needXcommit && db->xCommitCallback ){ @@ -49915,8 +60085,8 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ ** master-journal. ** ** If the return value of sqlite3BtreeGetFilename() is a zero length - ** string, it means the main database is :memory: or a temp file. In - ** that case we do not support atomic multi-file commits, so use the + ** string, it means the main database is :memory: or a temp file. In + ** that case we do not support atomic multi-file commits, so use the ** simple case then too. */ if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt)) @@ -49929,7 +60099,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ } } - /* Do the commit only if all databases successfully complete phase 1. + /* Do the commit only if all databases successfully complete phase 1. ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an ** IO error while deleting or truncating a journal file. It is unlikely, ** but could happen. In this case abandon processing and return the error. @@ -49937,7 +60107,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ - rc = sqlite3BtreeCommitPhaseTwo(pBt); + rc = sqlite3BtreeCommitPhaseTwo(pBt, 0); } } if( rc==SQLITE_OK ){ @@ -49968,11 +60138,12 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ if( !zMaster ){ return SQLITE_NOMEM; } + sqlite3FileSuffix3(zMainFile, zMaster); rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); }while( rc==SQLITE_OK && res ); if( rc==SQLITE_OK ){ /* Open the master journal. */ - rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, + rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0 ); @@ -49981,7 +60152,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ sqlite3DbFree(db, zMaster); return rc; } - + /* Write the name of each database file in the transaction into the new ** master journal file. If an error occurs at this point close ** and delete the master journal file. All the individual journal files @@ -49992,9 +60163,10 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ Btree *pBt = db->aDb[i].pBt; if( sqlite3BtreeIsInTrans(pBt) ){ char const *zFile = sqlite3BtreeGetJournalname(pBt); - if( zFile==0 || zFile[0]==0 ){ + if( zFile==0 ){ continue; /* Ignore TEMP and :memory: databases */ } + assert( zFile[0]!=0 ); if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){ needSync = 1; } @@ -50012,7 +60184,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ /* Sync the master journal file. If the IOCAP_SEQUENTIAL device ** flag is set this is not required. */ - if( needSync + if( needSync && 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL) && SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL)) ){ @@ -50032,13 +60204,14 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ ** in case the master journal file name was written into the journal ** file before the failure occurred. */ - for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ + for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster); } } sqlite3OsCloseFree(pMaster); + assert( rc!=SQLITE_BUSY ); if( rc!=SQLITE_OK ){ sqlite3DbFree(db, zMaster); return rc; @@ -50064,10 +60237,10 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ */ disable_simulated_io_errors(); sqlite3BeginBenignMalloc(); - for(i=0; i<db->nDb; i++){ + for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ - sqlite3BtreeCommitPhaseTwo(pBt); + sqlite3BtreeCommitPhaseTwo(pBt, 1); } } sqlite3EndBenignMalloc(); @@ -50080,7 +60253,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ return rc; } -/* +/* ** This routine checks that the sqlite3.activeVdbeCnt count variable ** matches the number of vdbe's in the list sqlite3.pVdbe that are ** currently active. An assertion fails if the two counts do not match. @@ -50110,7 +60283,7 @@ static void checkActiveVdbeCnt(sqlite3 *db){ #endif /* -** For every Btree that in database connection db which +** For every Btree that in database connection db which ** has been modified, "trip" or invalidate each cursor in ** that Btree might have been modified so that the cursor ** can never be used again. This happens when a rollback @@ -50139,17 +60312,17 @@ static void invalidateCursorsOnModifiedBtrees(sqlite3 *db){ ** If the Vdbe passed as the first argument opened a statement-transaction, ** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or ** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement -** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the +** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the ** statement transaction is commtted. ** -** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. +** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. ** Otherwise SQLITE_OK. */ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ sqlite3 *const db = p->db; int rc = SQLITE_OK; - /* If p->iStatement is greater than zero, then this Vdbe opened a + /* If p->iStatement is greater than zero, then this Vdbe opened a ** statement transaction that should be closed here. The only exception ** is that an IO error may have occured, causing an emergency rollback. ** In this case (db->nStatement==0), and there is nothing to do. @@ -50162,7 +60335,7 @@ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ assert( db->nStatement>0 ); assert( p->iStatement==(db->nStatement+db->nSavepoint) ); - for(i=0; i<db->nDb; i++){ + for(i=0; i<db->nDb; i++){ int rc2 = SQLITE_OK; Btree *pBt = db->aDb[i].pBt; if( pBt ){ @@ -50180,8 +60353,17 @@ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ db->nStatement--; p->iStatement = 0; - /* If the statement transaction is being rolled back, also restore the - ** database handles deferred constraint counter to the value it had when + if( rc==SQLITE_OK ){ + if( eOp==SAVEPOINT_ROLLBACK ){ + rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint); + } + if( rc==SQLITE_OK ){ + rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint); + } + } + + /* If the statement transaction is being rolled back, also restore the + ** database handles deferred constraint counter to the value it had when ** the statement transaction was opened. */ if( eOp==SAVEPOINT_ROLLBACK ){ db->nDeferredCons = p->nStmtDefCons; @@ -50191,39 +60373,12 @@ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ } /* -** If SQLite is compiled to support shared-cache mode and to be threadsafe, -** this routine obtains the mutex associated with each BtShared structure -** that may be accessed by the VM passed as an argument. In doing so it -** sets the BtShared.db member of each of the BtShared structures, ensuring -** that the correct busy-handler callback is invoked if required. -** -** If SQLite is not threadsafe but does support shared-cache mode, then -** sqlite3BtreeEnterAll() is invoked to set the BtShared.db variables -** of all of BtShared structures accessible via the database handle -** associated with the VM. Of course only a subset of these structures -** will be accessed by the VM, and we could use Vdbe.btreeMask to figure -** that subset out, but there is no advantage to doing so. -** -** If SQLite is not threadsafe and does not support shared-cache mode, this -** function is a no-op. -*/ -#ifndef SQLITE_OMIT_SHARED_CACHE -SQLITE_PRIVATE void sqlite3VdbeMutexArrayEnter(Vdbe *p){ -#if SQLITE_THREADSAFE - sqlite3BtreeMutexArrayEnter(&p->aMutex); -#else - sqlite3BtreeEnterAll(p->db); -#endif -} -#endif - -/* -** This function is called when a transaction opened by the database -** handle associated with the VM passed as an argument is about to be +** This function is called when a transaction opened by the database +** handle associated with the VM passed as an argument is about to be ** committed. If there are outstanding deferred foreign key constraint ** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK. ** -** If there are outstanding FK violations and this function returns +** If there are outstanding FK violations and this function returns ** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT and write ** an error message to it. Then return SQLITE_ERROR. */ @@ -50259,7 +60414,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ /* This function contains the logic that determines if a statement or ** transaction will be committed or rolled back as a result of the - ** execution of this virtual machine. + ** execution of this virtual machine. ** ** If any of the following errors occur: ** @@ -50289,7 +60444,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ int isSpecialError; /* Set to true if a 'special' error */ /* Lock all btrees used by the statement */ - sqlite3VdbeMutexArrayEnter(p); + sqlite3VdbeEnter(p); /* Check for one of the special errors */ mrc = p->rc & 0xff; @@ -50297,8 +60452,17 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL; if( isSpecialError ){ - /* If the query was read-only, we need do no rollback at all. Otherwise, - ** proceed with the special handling. + /* If the query was read-only and the error code is SQLITE_INTERRUPT, + ** no rollback is necessary. Otherwise, at least a savepoint + ** transaction must be rolled back to restore the database to a + ** consistent state. + ** + ** Even if the statement is read-only, it is important to perform + ** a statement or transaction rollback operation. If the error + ** occured while writing to the journal, sub-journal or database + ** file as part of an effort to free up cache space (see function + ** pagerStress() in pager.c), the rollback is required to restore + ** the pager to a consistent state. */ if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){ if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && p->usesStmtJournal ){ @@ -50319,29 +60483,34 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ if( p->rc==SQLITE_OK ){ sqlite3VdbeCheckFk(p, 0); } - - /* If the auto-commit flag is set and this is the only active writer - ** VM, then we do either a commit or rollback of the current transaction. + + /* If the auto-commit flag is set and this is the only active writer + ** VM, then we do either a commit or rollback of the current transaction. ** - ** Note: This block also runs if one of the special errors handled - ** above has occurred. + ** Note: This block also runs if one of the special errors handled + ** above has occurred. */ - if( !sqlite3VtabInSync(db) - && db->autoCommit - && db->writeVdbeCnt==(p->readOnly==0) + if( !sqlite3VtabInSync(db) + && db->autoCommit + && db->writeVdbeCnt==(p->readOnly==0) ){ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ - if( sqlite3VdbeCheckFk(p, 1) ){ - sqlite3BtreeMutexArrayLeave(&p->aMutex); - return SQLITE_ERROR; + rc = sqlite3VdbeCheckFk(p, 1); + if( rc!=SQLITE_OK ){ + if( NEVER(p->readOnly) ){ + sqlite3VdbeLeave(p); + return SQLITE_ERROR; + } + rc = SQLITE_CONSTRAINT; + }else{ + /* The auto-commit flag is true, the vdbe program was successful + ** or hit an 'OR FAIL' constraint and there are no deferred foreign + ** key constraints to hold up the transaction. This means a commit + ** is required. */ + rc = vdbeCommit(db, p); } - /* The auto-commit flag is true, the vdbe program was successful - ** or hit an 'OR FAIL' constraint and there are no deferred foreign - ** key constraints to hold up the transaction. This means a commit - ** is required. */ - rc = vdbeCommit(db, p); - if( rc==SQLITE_BUSY ){ - sqlite3BtreeMutexArrayLeave(&p->aMutex); + if( rc==SQLITE_BUSY && p->readOnly ){ + sqlite3VdbeLeave(p); return SQLITE_BUSY; }else if( rc!=SQLITE_OK ){ p->rc = rc; @@ -50366,29 +60535,30 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ db->autoCommit = 1; } } - + /* If eStatementOp is non-zero, then a statement transaction needs to ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to ** do so. If this operation returns an error, and the current statement ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the ** current statement error code. - ** - ** Note that sqlite3VdbeCloseStatement() can only fail if eStatementOp - ** is SAVEPOINT_ROLLBACK. But if p->rc==SQLITE_OK then eStatementOp - ** must be SAVEPOINT_RELEASE. Hence the NEVER(p->rc==SQLITE_OK) in - ** the following code. */ if( eStatementOp ){ rc = sqlite3VdbeCloseStatement(p, eStatementOp); - if( rc && (NEVER(p->rc==SQLITE_OK) || p->rc==SQLITE_CONSTRAINT) ){ - p->rc = rc; - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = 0; + if( rc ){ + if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){ + p->rc = rc; + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = 0; + } + invalidateCursorsOnModifiedBtrees(db); + sqlite3RollbackAll(db); + sqlite3CloseSavepoints(db); + db->autoCommit = 1; } } - + /* If this was an INSERT, UPDATE or DELETE and no statement transaction - ** has been rolled back, update the database connection change-counter. + ** has been rolled back, update the database connection change-counter. */ if( p->changeCntOn ){ if( eStatementOp!=SAVEPOINT_ROLLBACK ){ @@ -50398,15 +60568,15 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ } p->nChange = 0; } - + /* Rollback or commit any schema changes that occurred. */ if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){ - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); db->flags = (db->flags | SQLITE_InternChanges); } /* Release the locks */ - sqlite3BtreeMutexArrayLeave(&p->aMutex); + sqlite3VdbeLeave(p); } /* We have successfully halted and closed the VM. Record this fact. */ @@ -50424,7 +60594,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ } /* If the auto-commit flag is set to true, then any locks that were held - ** by connection db have now been released. Call sqlite3ConnectionUnlocked() + ** by connection db have now been released. Call sqlite3ConnectionUnlocked() ** to invoke any required unlock-notify callbacks. */ if( db->autoCommit ){ @@ -50432,7 +60602,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ } assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 ); - return SQLITE_OK; + return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK); } @@ -50526,7 +60696,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ p->magic = VDBE_MAGIC_INIT; return p->rc & db->errMask; } - + /* ** Clean up and delete a VDBE after execution. Return an integer which is ** the result code. Write any error message text into *pzErrMsg. @@ -50561,6 +60731,32 @@ SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){ } /* +** Free all memory associated with the Vdbe passed as the second argument. +** The difference between this function and sqlite3VdbeDelete() is that +** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with +** the database connection. +*/ +SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ + SubProgram *pSub, *pNext; + int i; + assert( p->db==0 || p->db==db ); + releaseMemArray(p->aVar, p->nVar); + releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); + for(pSub=p->pProgram; pSub; pSub=pNext){ + pNext = pSub->pNext; + vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); + sqlite3DbFree(db, pSub); + } + for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); + vdbeFreeOpArray(db, p->aOp, p->nOp); + sqlite3DbFree(db, p->aLabel); + sqlite3DbFree(db, p->aColName); + sqlite3DbFree(db, p->zSql); + sqlite3DbFree(db, p->pFree); + sqlite3DbFree(db, p); +} + +/* ** Delete an entire VDBE. */ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ @@ -50577,16 +60773,9 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ if( p->pNext ){ p->pNext->pPrev = p->pPrev; } - releaseMemArray(p->aVar, p->nVar); - releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); - vdbeFreeOpArray(db, p->aOp, p->nOp); - sqlite3DbFree(db, p->aLabel); - sqlite3DbFree(db, p->aColName); - sqlite3DbFree(db, p->zSql); p->magic = VDBE_MAGIC_DEAD; - sqlite3DbFree(db, p->pFree); p->db = 0; - sqlite3DbFree(db, p); + sqlite3VdbeDeleteObject(db, p); } /* @@ -50612,11 +60801,8 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){ rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); if( rc ) return rc; p->lastRowid = p->movetoTarget; - p->rowidIsValid = ALWAYS(res==0) ?1:0; - if( NEVER(res<0) ){ - rc = sqlite3BtreeNext(p->pCursor, &res); - if( rc ) return rc; - } + if( res!=0 ) return SQLITE_CORRUPT_BKPT; + p->rowidIsValid = 1; #ifdef SQLITE_TEST sqlite3_search_count++; #endif @@ -50694,7 +60880,13 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ if( file_format>=4 && (i&1)==i ){ return 8+(u32)i; } - u = i<0 ? -i : i; + if( i<0 ){ + if( i<(-MAX_6BYTE) ) return 6; + /* Previous test prevents: u = -(-9223372036854775808) */ + u = -i; + }else{ + u = i; + } if( u<=127 ) return 1; if( u<=32767 ) return 2; if( u<=8388607 ) return 3; @@ -50727,8 +60919,8 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){ } /* -** If we are on an architecture with mixed-endian floating -** points (ex: ARM7) then swap the lower 4 bytes with the +** If we are on an architecture with mixed-endian floating +** points (ex: ARM7) then swap the lower 4 bytes with the ** upper 4 bytes. Return the result. ** ** For most architectures, this is a no-op. @@ -50750,7 +60942,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){ ** (2007-08-30) Frank van Vugt has studied this problem closely ** and has send his findings to the SQLite developers. Frank ** writes that some Linux kernels offer floating point hardware -** emulation that uses only 32-bit mantissas instead of a full +** emulation that uses only 32-bit mantissas instead of a full ** 48-bits as required by the IEEE standard. (This is the ** CONFIG_FPE_FASTFPE option.) On such systems, floating point ** byte swapping becomes very complicated. To avoid problems, @@ -50780,7 +60972,7 @@ static u64 floatSwap(u64 in){ #endif /* -** Write the serialized data blob for the value stored in pMem into +** Write the serialized data blob for the value stored in pMem into ** buf. It is assumed that the caller has allocated sufficient space. ** Return the number of bytes written. ** @@ -50796,7 +60988,7 @@ static u64 floatSwap(u64 in){ ** Return the number of bytes actually written into buf[]. The number ** of bytes in the zero-filled tail is included in the return value only ** if those bytes were zeroed in buf[]. -*/ +*/ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){ u32 serial_type = sqlite3VdbeSerialType(pMem, file_format); u32 len; @@ -50846,7 +61038,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_f /* ** Deserialize the data blob pointed to by buf as serial type serial_type ** and store the result in pMem. Return the number of bytes read. -*/ +*/ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ @@ -50940,57 +61132,70 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( return 0; } - /* -** Given the nKey-byte encoding of a record in pKey[], parse the -** record into a UnpackedRecord structure. Return a pointer to -** that structure. +** This routine is used to allocate sufficient space for an UnpackedRecord +** structure large enough to be used with sqlite3VdbeRecordUnpack() if +** the first argument is a pointer to KeyInfo structure pKeyInfo. ** -** The calling function might provide szSpace bytes of memory -** space at pSpace. This space can be used to hold the returned -** VDbeParsedRecord structure if it is large enough. If it is -** not big enough, space is obtained from sqlite3_malloc(). +** The space is either allocated using sqlite3DbMallocRaw() or from within +** the unaligned buffer passed via the second and third arguments (presumably +** stack space). If the former, then *ppFree is set to a pointer that should +** be eventually freed by the caller using sqlite3DbFree(). Or, if the +** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL +** before returning. ** -** The returned structure should be closed by a call to -** sqlite3VdbeDeleteUnpackedRecord(). +** If an OOM error occurs, NULL is returned. */ -SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack( - KeyInfo *pKeyInfo, /* Information about the record format */ - int nKey, /* Size of the binary record */ - const void *pKey, /* The binary record */ - char *pSpace, /* Unaligned space available to hold the object */ - int szSpace /* Size of pSpace[] in bytes */ +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( + KeyInfo *pKeyInfo, /* Description of the record */ + char *pSpace, /* Unaligned space available */ + int szSpace, /* Size of pSpace[] in bytes */ + char **ppFree /* OUT: Caller should free this pointer */ ){ - const unsigned char *aKey = (const unsigned char *)pKey; - UnpackedRecord *p; /* The unpacked record that we will return */ - int nByte; /* Memory space needed to hold p, in bytes */ - int d; - u32 idx; - u16 u; /* Unsigned loop counter */ - u32 szHdr; - Mem *pMem; - int nOff; /* Increase pSpace by this much to 8-byte align it */ + UnpackedRecord *p; /* Unpacked record to return */ + int nOff; /* Increment pSpace by nOff to align it */ + int nByte; /* Number of bytes required for *p */ - /* - ** We want to shift the pointer pSpace up such that it is 8-byte aligned. - ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift + /* We want to shift the pointer pSpace up such that it is 8-byte aligned. + ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift ** it by. If pSpace is already 8-byte aligned, nOff should be zero. */ nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7; - pSpace += nOff; - szSpace -= nOff; nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1); - if( nByte>szSpace ){ - p = sqlite3DbMallocRaw(pKeyInfo->db, nByte); - if( p==0 ) return 0; - p->flags = UNPACKED_NEED_FREE | UNPACKED_NEED_DESTROY; + if( nByte>szSpace+nOff ){ + p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); + *ppFree = (char *)p; + if( !p ) return 0; }else{ - p = (UnpackedRecord*)pSpace; - p->flags = UNPACKED_NEED_DESTROY; + p = (UnpackedRecord*)&pSpace[nOff]; + *ppFree = 0; } + + p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; p->pKeyInfo = pKeyInfo; p->nField = pKeyInfo->nField + 1; - p->aMem = pMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; + return p; +} + +/* +** Given the nKey-byte encoding of a record in pKey[], populate the +** UnpackedRecord structure indicated by the fourth argument with the +** contents of the decoded record. +*/ +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( + KeyInfo *pKeyInfo, /* Information about the record format */ + int nKey, /* Size of the binary record */ + const void *pKey, /* The binary record */ + UnpackedRecord *p /* Populate this structure before returning. */ +){ + const unsigned char *aKey = (const unsigned char *)pKey; + int d; + u32 idx; /* Offset in aKey[] to read from */ + u16 u; /* Unsigned loop counter */ + u32 szHdr; + Mem *pMem = p->aMem; + + p->flags = 0; assert( EIGHT_BYTE_ALIGNMENT(pMem) ); idx = getVarint32(aKey, szHdr); d = szHdr; @@ -51001,7 +61206,7 @@ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack( idx += getVarint32(&aKey[idx], serial_type); pMem->enc = pKeyInfo->enc; pMem->db = pKeyInfo->db; - pMem->flags = 0; + /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ pMem->zMalloc = 0; d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); pMem++; @@ -51009,42 +61214,19 @@ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack( } assert( u<=pKeyInfo->nField + 1 ); p->nField = u; - return (void*)p; -} - -/* -** This routine destroys a UnpackedRecord object. -*/ -SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ - int i; - Mem *pMem; - - assert( p!=0 ); - assert( p->flags & UNPACKED_NEED_DESTROY ); - for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){ - /* The unpacked record is always constructed by the - ** sqlite3VdbeUnpackRecord() function above, which makes all - ** strings and blobs static. And none of the elements are - ** ever transformed, so there is never anything to delete. - */ - if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem); - } - if( p->flags & UNPACKED_NEED_FREE ){ - sqlite3DbFree(p->pKeyInfo->db, p); - } } /* ** This function compares the two table rows or index records ** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero -** or positive integer if key1 is less than, equal to or +** or positive integer if key1 is less than, equal to or ** greater than key2. The {nKey1, pKey1} key must be a blob ** created by th OP_MakeRecord opcode of the VDBE. The pPKey2 ** key must be a parsed key such as obtained from ** sqlite3VdbeParseRecord. ** ** Key1 and Key2 do not have to contain the same number of fields. -** The key with fewer fields is usually compares less than the +** The key with fewer fields is usually compares less than the ** longer key. However if the UNPACKED_INCRKEY flags in pPKey2 is set ** and the common prefixes are equal, then key1 is less than key2. ** Or if the UNPACKED_MATCH_PREFIX flag is set and the prefixes are @@ -51082,13 +61264,13 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare( /* Compilers may complain that mem1.u.i is potentially uninitialized. ** We could initialize it, as shown here, to silence those complaints. - ** But in fact, mem1.u.i will never actually be used initialized, and doing + ** But in fact, mem1.u.i will never actually be used uninitialized, and doing ** the unnecessary initialization has a measurable negative performance ** impact, since this routine is a very high runner. And so, we choose ** to ignore the compiler warnings and leave this variable uninitialized. */ /* mem1.u.i = 0; // not needed, here to silence compiler warning */ - + idx1 = getVarint32(aKey1, szHdr1); d1 = szHdr1; if( pPKey2->flags & UNPACKED_IGNORE_ROWID ){ @@ -51117,9 +61299,9 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare( if( pKeyInfo->aSortOrder && i<nField && pKeyInfo->aSortOrder[i] ){ rc = -rc; } - + /* If the PREFIX_SEARCH flag is set and all fields except the final - ** rowid field were equal, then clear the PREFIX_SEARCH flag and set + ** rowid field were equal, then clear the PREFIX_SEARCH flag and set ** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1). ** This is used by the OP_IsUnique opcode. */ @@ -51129,7 +61311,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare( pPKey2->flags &= ~UNPACKED_PREFIX_SEARCH; pPKey2->rowid = mem1.u.i; } - + return rc; } i++; @@ -51145,7 +61327,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare( ** all the fields up to that point were equal. If the UNPACKED_INCRKEY ** flag is set, then break the tie by treating key2 as larger. ** If the UPACKED_PREFIX_MATCH flag is set, then keys with common prefixes - ** are considered to be equal. Otherwise, the longer key is the + ** are considered to be equal. Otherwise, the longer key is the ** larger. As it happens, the pPKey2 will always be the longer ** if there is a difference. */ @@ -51159,7 +61341,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare( } return rc; } - + /* ** pCur points at an index entry created using the OP_MakeRecord opcode. @@ -51182,7 +61364,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ /* Get the size of the index entry. Only indices entries of less ** than 2GiB are support - anything large must be database corruption. ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so - ** this code can safely assume that nCellKey is 32-bits + ** this code can safely assume that nCellKey is 32-bits */ assert( sqlite3BtreeCursorIsValid(pCur) ); rc = sqlite3BtreeKeySize(pCur, &nCellKey); @@ -51246,7 +61428,7 @@ idx_rowid_corruption: ** ** pUnpacked is either created without a rowid or is truncated so that it ** omits the rowid at the end. The rowid at the end of the index entry -** is ignored as well. Hence, this routine only compares the prefixes +** is ignored as well. Hence, this routine only compares the prefixes ** of the keys prior to the final rowid, not the entire key. */ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare( @@ -51281,7 +61463,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare( /* ** This routine sets the value to be returned by subsequent calls to -** sqlite3_changes() on the database handle 'db'. +** sqlite3_changes() on the database handle 'db'. */ SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){ assert( sqlite3_mutex_held(db->mutex) ); @@ -51323,7 +61505,7 @@ SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){ /* ** Return a pointer to an sqlite3_value structure containing the value bound -** parameter iVar of VM v. Except, if the value is an SQL NULL, return +** parameter iVar of VM v. Except, if the value is an SQL NULL, return ** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_* ** constants) to the value before returning it. ** @@ -51427,6 +61609,8 @@ static int vdbeSafetyNotNull(Vdbe *p){ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ + /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL + ** pointer is a harmless no-op. */ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; @@ -51462,7 +61646,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){ Vdbe *v = (Vdbe*)pStmt; sqlite3_mutex_enter(v->db->mutex); rc = sqlite3VdbeReset(v); - sqlite3VdbeMakeReady(v, -1, 0, 0, 0, 0, 0); + sqlite3VdbeRewind(v); assert( (rc & (v->db->errMask))==rc ); rc = sqlite3ApiExit(v->db, rc); sqlite3_mutex_leave(v->db->mutex); @@ -51503,7 +61687,7 @@ SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){ sqlite3VdbeMemExpandBlob(p); p->flags &= ~MEM_Str; p->flags |= MEM_Blob; - return p->z; + return p->n ? p->z : 0; }else{ return sqlite3_value_text(pVal); } @@ -51561,9 +61745,9 @@ static void setResultStrOrError( } } SQLITE_API void sqlite3_result_blob( - sqlite3_context *pCtx, - const void *z, - int n, + sqlite3_context *pCtx, + const void *z, + int n, void (*xDel)(void *) ){ assert( n>=0 ); @@ -51599,8 +61783,8 @@ SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){ sqlite3VdbeMemSetNull(&pCtx->s); } SQLITE_API void sqlite3_result_text( - sqlite3_context *pCtx, - const char *z, + sqlite3_context *pCtx, + const char *z, int n, void (*xDel)(void *) ){ @@ -51609,27 +61793,27 @@ SQLITE_API void sqlite3_result_text( } #ifndef SQLITE_OMIT_UTF16 SQLITE_API void sqlite3_result_text16( - sqlite3_context *pCtx, - const void *z, - int n, + sqlite3_context *pCtx, + const void *z, + int n, void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel); } SQLITE_API void sqlite3_result_text16be( - sqlite3_context *pCtx, - const void *z, - int n, + sqlite3_context *pCtx, + const void *z, + int n, void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel); } SQLITE_API void sqlite3_result_text16le( - sqlite3_context *pCtx, - const void *z, - int n, + sqlite3_context *pCtx, + const void *z, + int n, void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); @@ -51647,7 +61831,7 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ pCtx->isError = errCode; if( pCtx->s.flags & MEM_Null ){ - sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1, + sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1, SQLITE_UTF8, SQLITE_STATIC); } } @@ -51656,7 +61840,7 @@ SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); pCtx->isError = SQLITE_TOOBIG; - sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1, + sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1, SQLITE_UTF8, SQLITE_STATIC); } @@ -51669,11 +61853,32 @@ SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ } /* +** This function is called after a transaction has been committed. It +** invokes callbacks registered with sqlite3_wal_hook() as required. +*/ +static int doWalCallbacks(sqlite3 *db){ + int rc = SQLITE_OK; +#ifndef SQLITE_OMIT_WAL + int i; + for(i=0; i<db->nDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + int nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt)); + if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){ + rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry); + } + } + } +#endif + return rc; +} + +/* ** Execute the statement pStmt, either until a row of data is ready, the ** statement is completely executed or an error occurs. ** ** This routine implements the bulk of the logic behind the sqlite_step() -** API. The only thing omitted is the automatic recompile if a +** API. The only thing omitted is the automatic recompile if a ** schema change has occurred. That detail is handled by the ** outer sqlite3_step() wrapper procedure. */ @@ -51683,9 +61888,31 @@ static int sqlite3Step(Vdbe *p){ assert(p); if( p->magic!=VDBE_MAGIC_RUN ){ - sqlite3_log(SQLITE_MISUSE, - "attempt to step a halted statement: [%s]", p->zSql); - return SQLITE_MISUSE_BKPT; + /* We used to require that sqlite3_reset() be called before retrying + ** sqlite3_step() after any error or after SQLITE_DONE. But beginning + ** with version 3.7.0, we changed this so that sqlite3_reset() would + ** be called automatically instead of throwing the SQLITE_MISUSE error. + ** This "automatic-reset" change is not technically an incompatibility, + ** since any application that receives an SQLITE_MISUSE is broken by + ** definition. + ** + ** Nevertheless, some published applications that were originally written + ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE + ** returns, and the so were broken by the automatic-reset change. As a + ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the + ** legacy behavior of returning SQLITE_MISUSE for cases where the + ** previous sqlite3_step() returned something other than a SQLITE_LOCKED + ** or SQLITE_BUSY error. + */ +#ifdef SQLITE_OMIT_AUTORESET + if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){ + sqlite3_reset((sqlite3_stmt*)p); + }else{ + return SQLITE_MISUSE_BKPT; + } +#else + sqlite3_reset((sqlite3_stmt*)p); +#endif } /* Check that malloc() has not failed. If it has, return early. */ @@ -51713,9 +61940,7 @@ static int sqlite3Step(Vdbe *p){ #ifndef SQLITE_OMIT_TRACE if( db->xProfile && !db->init.busy ){ - double rNow; - sqlite3OsCurrentTime(db->pVfs, &rNow); - p->startTime = (u64)((rNow - (int)rNow)*3600.0*24.0*1000000000.0); + sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); } #endif @@ -51729,36 +61954,42 @@ static int sqlite3Step(Vdbe *p){ }else #endif /* SQLITE_OMIT_EXPLAIN */ { + db->vdbeExecCnt++; rc = sqlite3VdbeExec(p); + db->vdbeExecCnt--; } #ifndef SQLITE_OMIT_TRACE /* Invoke the profile callback if there is one */ if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy && p->zSql ){ - double rNow; - u64 elapseTime; - - sqlite3OsCurrentTime(db->pVfs, &rNow); - elapseTime = (u64)((rNow - (int)rNow)*3600.0*24.0*1000000000.0); - elapseTime -= p->startTime; - db->xProfile(db->pProfileArg, p->zSql, elapseTime); + sqlite3_int64 iNow; + sqlite3OsCurrentTimeInt64(db->pVfs, &iNow); + db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000); } #endif + if( rc==SQLITE_DONE ){ + assert( p->rc==SQLITE_OK ); + p->rc = doWalCallbacks(db); + if( p->rc!=SQLITE_OK ){ + rc = SQLITE_ERROR; + } + } + db->errCode = rc; if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){ p->rc = SQLITE_NOMEM; } end_of_step: - /* At this point local variable rc holds the value that should be - ** returned if this statement was compiled using the legacy + /* At this point local variable rc holds the value that should be + ** returned if this statement was compiled using the legacy ** sqlite3_prepare() interface. According to the docs, this can only - ** be one of the values in the first assert() below. Variable p->rc - ** contains the value that would be returned if sqlite3_finalize() + ** be one of the values in the first assert() below. Variable p->rc + ** contains the value that would be returned if sqlite3_finalize() ** were called on statement p. */ - assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR + assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR || rc==SQLITE_BUSY || rc==SQLITE_MISUSE ); assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE ); @@ -51766,13 +61997,21 @@ end_of_step: /* If this statement was prepared using sqlite3_prepare_v2(), and an ** error has occured, then return the error code in p->rc to the ** caller. Set the error code in the database handle to the same value. - */ + */ rc = db->errCode = p->rc; } return (rc&db->errMask); } /* +** The maximum number of times that a statement will try to reparse +** itself before giving up and returning SQLITE_SCHEMA. +*/ +#ifndef SQLITE_MAX_SCHEMA_RETRY +# define SQLITE_MAX_SCHEMA_RETRY 5 +#endif + +/* ** This is the top-level implementation of sqlite3_step(). Call ** sqlite3Step() to do most of the work. If a schema error occurs, ** call sqlite3Reprepare() and try again. @@ -51790,21 +62029,21 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ db = v->db; sqlite3_mutex_enter(db->mutex); while( (rc = sqlite3Step(v))==SQLITE_SCHEMA - && cnt++ < 5 + && cnt++ < SQLITE_MAX_SCHEMA_RETRY && (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){ sqlite3_reset(pStmt); - v->expired = 0; + assert( v->expired==0 ); } if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){ - /* This case occurs after failing to recompile an sql statement. - ** The error message from the SQL compiler has already been loaded - ** into the database handle. This block copies the error message + /* This case occurs after failing to recompile an sql statement. + ** The error message from the SQL compiler has already been loaded + ** into the database handle. This block copies the error message ** from the database handle into the statement and sets the statement - ** program counter to 0 to ensure that when the statement is + ** program counter to 0 to ensure that when the statement is ** finalized or reset the parser error message is available via ** sqlite3_errmsg() and sqlite3_errcode(). */ - const char *zErr = (const char *)sqlite3_value_text(db->pErr); + const char *zErr = (const char *)sqlite3_value_text(db->pErr); sqlite3DbFree(db, v->zErrMsg); if( !db->mallocFailed ){ v->zErrMsg = sqlite3DbStrDup(db, zErr); @@ -51831,6 +62070,12 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ /* ** Extract the user data from a sqlite3_context structure and return a ** pointer to it. +** +** IMPLEMENTATION-OF: R-46798-50301 The sqlite3_context_db_handle() interface +** returns a copy of the pointer to the database connection (the 1st +** parameter) of the sqlite3_create_function() and +** sqlite3_create_function16() routines that originally registered the +** application defined function. */ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ assert( p && p->pFunc ); @@ -51908,9 +62153,9 @@ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ ** deleted by calling the delete function specified when it was set. */ SQLITE_API void sqlite3_set_auxdata( - sqlite3_context *pCtx, - int iArg, - void *pAux, + sqlite3_context *pCtx, + int iArg, + void *pAux, void (*xDelete)(void*) ){ struct AuxData *pAuxData; @@ -51948,7 +62193,7 @@ failed: #ifndef SQLITE_OMIT_DEPRECATED /* -** Return the number of times the Step function of a aggregate has been +** Return the number of times the Step function of a aggregate has been ** called. ** ** This function is deprecated. Do not use it for new code. It is @@ -51989,13 +62234,11 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){ */ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ Vdbe *pVm; - int vals; Mem *pOut; pVm = (Vdbe *)pStmt; if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){ sqlite3_mutex_enter(pVm->db->mutex); - vals = sqlite3_data_count(pStmt); pOut = &pVm->pResultSet[i]; }else{ /* If the value passed as the second argument is out of range, return @@ -52009,11 +62252,15 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ ** this assert() from failing, when building with SQLITE_DEBUG defined ** using gcc, force nullMem to be 8-byte aligned using the magical ** __attribute__((aligned(8))) macro. */ - static const Mem nullMem + static const Mem nullMem #if defined(SQLITE_DEBUG) && defined(__GNUC__) - __attribute__((aligned(8))) + __attribute__((aligned(8))) #endif - = {{0}, (double)0, 0, "", 0, MEM_Null, SQLITE_NULL, 0, 0, 0 }; + = {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0, +#ifdef SQLITE_DEBUG + 0, 0, /* pScopyFrom, pFiller */ +#endif + 0, 0 }; if( pVm && ALWAYS(pVm->db) ){ sqlite3_mutex_enter(pVm->db->mutex); @@ -52025,9 +62272,9 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ } /* -** This function is called after invoking an sqlite3_value_XXX function on a +** This function is called after invoking an sqlite3_value_XXX function on a ** column value (i.e. a value returned by evaluating an SQL expression in the -** select list of a SELECT statement) that may cause a malloc() failure. If +** select list of a SELECT statement) that may cause a malloc() failure. If ** malloc() has failed, the threads mallocFailed flag is cleared and the result ** code of statement pStmt set to SQLITE_NOMEM. ** @@ -52040,8 +62287,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ ** sqlite3_column_real() ** sqlite3_column_bytes() ** sqlite3_column_bytes16() -** -** But not for sqlite3_column_blob(), which never calls malloc(). +** sqiite3_column_blob() */ static void columnMallocFailure(sqlite3_stmt *pStmt) { @@ -52065,8 +62311,8 @@ SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){ const void *val; val = sqlite3_value_blob( columnMem(pStmt,i) ); /* Even though there is no encoding conversion, value_blob() might - ** need to call malloc() to expand the result of a zeroblob() - ** expression. + ** need to call malloc() to expand the result of a zeroblob() + ** expression. */ columnMallocFailure(pStmt); return val; @@ -52156,7 +62402,7 @@ static const void *columnName( Vdbe *p = (Vdbe *)pStmt; int n; sqlite3 *db = p->db; - + assert( db!=0 ); n = sqlite3_column_count(pStmt); if( N<n && N>=0 ){ @@ -52269,11 +62515,11 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ /******************************* sqlite3_bind_ *************************** -** +** ** Routines used to attach values to wildcards in a compiled SQL statement. */ /* -** Unbind the value bound to variable i in virtual machine p. This is the +** Unbind the value bound to variable i in virtual machine p. This is the ** the same as binding a NULL value to the column. If the "i" parameter is ** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK. ** @@ -52292,7 +62538,7 @@ static int vdbeUnbind(Vdbe *p, int i){ if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){ sqlite3Error(p->db, SQLITE_MISUSE, 0); sqlite3_mutex_leave(p->db->mutex); - sqlite3_log(SQLITE_MISUSE, + sqlite3_log(SQLITE_MISUSE, "bind on a busy prepared statement: [%s]", p->zSql); return SQLITE_MISUSE_BKPT; } @@ -52307,8 +62553,14 @@ static int vdbeUnbind(Vdbe *p, int i){ pVar->flags = MEM_Null; sqlite3Error(p->db, SQLITE_OK, 0); - /* If the bit corresponding to this variable in Vdbe.expmask is set, then + /* If the bit corresponding to this variable in Vdbe.expmask is set, then ** binding a new value to this variable invalidates the current query plan. + ** + ** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host + ** parameter in the WHERE clause might influence the choice of query plan + ** for a statement, then the statement will be automatically recompiled, + ** as if there had been a schema change, on the first sqlite3_step() call + ** following any change to the bindings of that parameter. */ if( p->isPrepareV2 && ((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff) @@ -52345,6 +62597,8 @@ static int bindText( rc = sqlite3ApiExit(p->db, rc); } sqlite3_mutex_leave(p->db->mutex); + }else if( xDel!=SQLITE_STATIC && xDel!=SQLITE_TRANSIENT ){ + xDel((void*)zData); } return rc; } @@ -52354,10 +62608,10 @@ static int bindText( ** Bind a blob value to an SQL statement variable. */ SQLITE_API int sqlite3_bind_blob( - sqlite3_stmt *pStmt, - int i, - const void *zData, - int nData, + sqlite3_stmt *pStmt, + int i, + const void *zData, + int nData, void (*xDel)(void*) ){ return bindText(pStmt, i, zData, nData, xDel, 0); @@ -52394,21 +62648,21 @@ SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ } return rc; } -SQLITE_API int sqlite3_bind_text( - sqlite3_stmt *pStmt, - int i, - const char *zData, - int nData, +SQLITE_API int sqlite3_bind_text( + sqlite3_stmt *pStmt, + int i, + const char *zData, + int nData, void (*xDel)(void*) ){ return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8); } #ifndef SQLITE_OMIT_UTF16 SQLITE_API int sqlite3_bind_text16( - sqlite3_stmt *pStmt, - int i, - const void *zData, - int nData, + sqlite3_stmt *pStmt, + int i, + const void *zData, + int nData, void (*xDel)(void*) ){ return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE); @@ -52458,7 +62712,7 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ /* ** Return the number of wildcards that can be potentially bound to. -** This routine is added to support DBD::SQLite. +** This routine is added to support DBD::SQLite. */ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; @@ -52466,32 +62720,6 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ } /* -** Create a mapping from variable numbers to variable names -** in the Vdbe.azVar[] array, if such a mapping does not already -** exist. -*/ -static void createVarMap(Vdbe *p){ - if( !p->okVar ){ - int j; - Op *pOp; - sqlite3_mutex_enter(p->db->mutex); - /* The race condition here is harmless. If two threads call this - ** routine on the same Vdbe at the same time, they both might end - ** up initializing the Vdbe.azVar[] array. That is a little extra - ** work but it results in the same answer. - */ - for(j=0, pOp=p->aOp; j<p->nOp; j++, pOp++){ - if( pOp->opcode==OP_Variable ){ - assert( pOp->p1>0 && pOp->p1<=p->nVar ); - p->azVar[pOp->p1-1] = pOp->p4.z; - } - } - p->okVar = 1; - sqlite3_mutex_leave(p->db->mutex); - } -} - -/* ** Return the name of a wildcard parameter. Return NULL if the index ** is out of range or if the wildcard is unnamed. ** @@ -52499,10 +62727,9 @@ static void createVarMap(Vdbe *p){ */ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ Vdbe *p = (Vdbe*)pStmt; - if( p==0 || i<1 || i>p->nVar ){ + if( p==0 || i<1 || i>p->nzVar ){ return 0; } - createVarMap(p); return p->azVar[i-1]; } @@ -52516,9 +62743,8 @@ SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nNa if( p==0 ){ return 0; } - createVarMap(p); if( zName ){ - for(i=0; i<p->nVar; i++){ + for(i=0; i<p->nzVar; i++){ const char *z = p->azVar[i]; if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){ return i+1; @@ -52588,6 +62814,14 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){ } /* +** Return true if the prepared statement is guaranteed to not modify the +** database. +*/ +SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){ + return pStmt ? ((Vdbe*)pStmt)->readOnly : 1; +} + +/* ** Return a pointer to the next prepared statement after pStmt associated ** with database connection pDb. If pStmt is NULL, return the first ** prepared statement for the database connection. Return NULL if there @@ -52661,9 +62895,12 @@ static int findNextHostParameter(const char *zSql, int *pnToken){ } /* -** Return a pointer to a string in memory obtained form sqlite3DbMalloc() which -** holds a copy of zRawSql but with host parameters expanded to their -** current bindings. +** This function returns a pointer to a nul-terminated string in memory +** obtained from sqlite3DbMalloc(). If sqlite3.vdbeExecCnt is 1, then the +** string contains a copy of zRawSql but with host parameters expanded to +** their current bindings. Or, if sqlite3.vdbeExecCnt is greater than 1, +** then the returned string holds a copy of zRawSql with "-- " prepended +** to each line of text. ** ** The calling function is responsible for making sure the memory returned ** is eventually freed. @@ -52691,66 +62928,75 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( char zBase[100]; /* Initial working space */ db = p->db; - sqlite3StrAccumInit(&out, zBase, sizeof(zBase), + sqlite3StrAccumInit(&out, zBase, sizeof(zBase), db->aLimit[SQLITE_LIMIT_LENGTH]); out.db = db; - while( zRawSql[0] ){ - n = findNextHostParameter(zRawSql, &nToken); - assert( n>0 ); - sqlite3StrAccumAppend(&out, zRawSql, n); - zRawSql += n; - assert( zRawSql[0] || nToken==0 ); - if( nToken==0 ) break; - if( zRawSql[0]=='?' ){ - if( nToken>1 ){ - assert( sqlite3Isdigit(zRawSql[1]) ); - sqlite3GetInt32(&zRawSql[1], &idx); + if( db->vdbeExecCnt>1 ){ + while( *zRawSql ){ + const char *zStart = zRawSql; + while( *(zRawSql++)!='\n' && *zRawSql ); + sqlite3StrAccumAppend(&out, "-- ", 3); + sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); + } + }else{ + while( zRawSql[0] ){ + n = findNextHostParameter(zRawSql, &nToken); + assert( n>0 ); + sqlite3StrAccumAppend(&out, zRawSql, n); + zRawSql += n; + assert( zRawSql[0] || nToken==0 ); + if( nToken==0 ) break; + if( zRawSql[0]=='?' ){ + if( nToken>1 ){ + assert( sqlite3Isdigit(zRawSql[1]) ); + sqlite3GetInt32(&zRawSql[1], &idx); + }else{ + idx = nextIndex; + } }else{ - idx = nextIndex; - } - }else{ - assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' ); - testcase( zRawSql[0]==':' ); - testcase( zRawSql[0]=='$' ); - testcase( zRawSql[0]=='@' ); - idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken); - assert( idx>0 ); - } - zRawSql += nToken; - nextIndex = idx + 1; - assert( idx>0 && idx<=p->nVar ); - pVar = &p->aVar[idx-1]; - if( pVar->flags & MEM_Null ){ - sqlite3StrAccumAppend(&out, "NULL", 4); - }else if( pVar->flags & MEM_Int ){ - sqlite3XPrintf(&out, "%lld", pVar->u.i); - }else if( pVar->flags & MEM_Real ){ - sqlite3XPrintf(&out, "%!.15g", pVar->r); - }else if( pVar->flags & MEM_Str ){ + assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' ); + testcase( zRawSql[0]==':' ); + testcase( zRawSql[0]=='$' ); + testcase( zRawSql[0]=='@' ); + idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken); + assert( idx>0 ); + } + zRawSql += nToken; + nextIndex = idx + 1; + assert( idx>0 && idx<=p->nVar ); + pVar = &p->aVar[idx-1]; + if( pVar->flags & MEM_Null ){ + sqlite3StrAccumAppend(&out, "NULL", 4); + }else if( pVar->flags & MEM_Int ){ + sqlite3XPrintf(&out, "%lld", pVar->u.i); + }else if( pVar->flags & MEM_Real ){ + sqlite3XPrintf(&out, "%!.15g", pVar->r); + }else if( pVar->flags & MEM_Str ){ #ifndef SQLITE_OMIT_UTF16 - u8 enc = ENC(db); - if( enc!=SQLITE_UTF8 ){ - Mem utf8; - memset(&utf8, 0, sizeof(utf8)); - utf8.db = db; - sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); - sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8); - sqlite3XPrintf(&out, "'%.*q'", utf8.n, utf8.z); - sqlite3VdbeMemRelease(&utf8); - }else + u8 enc = ENC(db); + if( enc!=SQLITE_UTF8 ){ + Mem utf8; + memset(&utf8, 0, sizeof(utf8)); + utf8.db = db; + sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); + sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8); + sqlite3XPrintf(&out, "'%.*q'", utf8.n, utf8.z); + sqlite3VdbeMemRelease(&utf8); + }else #endif - { - sqlite3XPrintf(&out, "'%.*q'", pVar->n, pVar->z); - } - }else if( pVar->flags & MEM_Zero ){ - sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero); - }else{ - assert( pVar->flags & MEM_Blob ); - sqlite3StrAccumAppend(&out, "x'", 2); - for(i=0; i<pVar->n; i++){ - sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff); + { + sqlite3XPrintf(&out, "'%.*q'", pVar->n, pVar->z); + } + }else if( pVar->flags & MEM_Zero ){ + sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero); + }else{ + assert( pVar->flags & MEM_Blob ); + sqlite3StrAccumAppend(&out, "x'", 2); + for(i=0; i<pVar->n; i++){ + sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff); + } + sqlite3StrAccumAppend(&out, "'", 1); } - sqlite3StrAccumAppend(&out, "'", 1); } } return sqlite3StrAccumFinish(&out); @@ -52771,7 +63017,7 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( ** May you share freely, never taking more than you give. ** ************************************************************************* -** The code in this file implements execution method of the +** The code in this file implements execution method of the ** Virtual Database Engine (VDBE). A separate file ("vdbeaux.c") ** handles housekeeping details such as creating and deleting ** VDBE instances. This file is solely interested in executing @@ -52781,10 +63027,10 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( ** to a VDBE. ** ** The SQL parser generates a program which is then executed by -** the VDBE to do the work of the SQL statement. VDBE programs are +** the VDBE to do the work of the SQL statement. VDBE programs are ** similar in form to assembly language. The program consists of -** a linear sequence of operations. Each operation has an opcode -** and 5 operands. Operands P1, P2, and P3 are integers. Operand P4 +** a linear sequence of operations. Each operation has an opcode +** and 5 operands. Operands P1, P2, and P3 are integers. Operand P4 ** is a null-terminated string. Operand P5 is an unsigned character. ** Few opcodes use all 5 operands. ** @@ -52793,7 +63039,7 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( ** either an integer, a null-terminated string, a floating point ** number, or the SQL "NULL" value. An implicit conversion from one ** type to the other occurs as necessary. -** +** ** Most of the code in this file is taken up by the sqlite3VdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up @@ -52807,6 +63053,17 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( */ /* +** Invoke this macro on memory cells just prior to changing the +** value of the cell. This macro verifies that shallow copies are +** not misused. +*/ +#ifdef SQLITE_DEBUG +# define memAboutToChange(P,M) sqlite3VdbeMemPrepareToChange(P,M) +#else +# define memAboutToChange(P,M) +#endif + +/* ** The following global variable is incremented every time a cursor ** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test ** procedures use this information to make sure that indices are @@ -52906,10 +63163,17 @@ SQLITE_API int sqlite3_found_count = 0; */ #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0) +/* Return true if the cursor was opened using the OP_OpenSorter opcode. */ +#ifdef SQLITE_OMIT_MERGE_SORT +# define isSorter(x) 0 +#else +# define isSorter(x) ((x)->pSorter!=0) +#endif + /* ** Argument pMem points at a register that will be passed to a ** user-defined function or returned to the user as the result of a query. -** This routine sets the pMem->type variable used by the sqlite3_value_*() +** This routine sets the pMem->type variable used by the sqlite3_value_*() ** routines. */ SQLITE_PRIVATE void sqlite3VdbeMemStoreType(Mem *pMem){ @@ -52942,7 +63206,7 @@ static VdbeCursor *allocateCursor( int isBtreeCursor /* True for B-Tree. False for pseudo-table or vtab */ ){ /* Find the memory cell that will be used to store the blob of memory - ** required for this VdbeCursor structure. It is convenient to use a + ** required for this VdbeCursor structure. It is convenient to use a ** vdbe memory cell to manage the memory allocation required for a ** VdbeCursor structure for the following reasons: ** @@ -52963,9 +63227,9 @@ static VdbeCursor *allocateCursor( int nByte; VdbeCursor *pCx = 0; - nByte = - ROUND8(sizeof(VdbeCursor)) + - (isBtreeCursor?sqlite3BtreeCursorSize():0) + + nByte = + ROUND8(sizeof(VdbeCursor)) + + (isBtreeCursor?sqlite3BtreeCursorSize():0) + 2*nField*sizeof(u32); assert( iCur<p->nCursor ); @@ -52998,31 +63262,17 @@ static VdbeCursor *allocateCursor( */ static void applyNumericAffinity(Mem *pRec){ if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){ - int realnum; + double rValue; + i64 iValue; u8 enc = pRec->enc; - sqlite3VdbeMemNulTerminate(pRec); - if( (pRec->flags&MEM_Str) && sqlite3IsNumber(pRec->z, &realnum, enc) ){ - i64 value; - char *zUtf8 = pRec->z; -#ifndef SQLITE_OMIT_UTF16 - if( enc!=SQLITE_UTF8 ){ - assert( pRec->db ); - zUtf8 = sqlite3Utf16to8(pRec->db, pRec->z, pRec->n, enc); - if( !zUtf8 ) return; - } -#endif - if( !realnum && sqlite3Atoi64(zUtf8, &value) ){ - pRec->u.i = value; - MemSetTypeFlag(pRec, MEM_Int); - }else{ - sqlite3AtoF(zUtf8, &pRec->r); - MemSetTypeFlag(pRec, MEM_Real); - } -#ifndef SQLITE_OMIT_UTF16 - if( enc!=SQLITE_UTF8 ){ - sqlite3DbFree(pRec->db, zUtf8); - } -#endif + if( (pRec->flags&MEM_Str)==0 ) return; + if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; + if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ + pRec->u.i = iValue; + pRec->flags |= MEM_Int; + }else{ + pRec->r = rValue; + pRec->flags |= MEM_Real; } } } @@ -53033,7 +63283,7 @@ static void applyNumericAffinity(Mem *pRec){ ** SQLITE_AFF_INTEGER: ** SQLITE_AFF_REAL: ** SQLITE_AFF_NUMERIC: -** Try to convert pRec to an integer representation or a +** Try to convert pRec to an integer representation or a ** 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 @@ -53074,23 +63324,23 @@ static void applyAffinity( ** into a numeric representation. Use either INTEGER or REAL whichever ** is appropriate. But only do the conversion if it is possible without ** loss of information and return the revised type of the argument. -** -** This is an EXPERIMENTAL api and is subject to change or removal. */ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){ Mem *pMem = (Mem*)pVal; - applyNumericAffinity(pMem); - sqlite3VdbeMemStoreType(pMem); + if( pMem->type==SQLITE_TEXT ){ + applyNumericAffinity(pMem); + sqlite3VdbeMemStoreType(pMem); + } return pMem->type; } /* -** Exported version of applyAffinity(). This one works on sqlite3_value*, +** Exported version of applyAffinity(). This one works on sqlite3_value*, ** not the internal Mem* type. */ SQLITE_PRIVATE void sqlite3ValueApplyAffinity( - sqlite3_value *pVal, - u8 affinity, + sqlite3_value *pVal, + u8 affinity, u8 enc ){ applyAffinity((Mem *)pVal, affinity, enc); @@ -53219,8 +63469,8 @@ static void registerTrace(FILE *out, int iReg, Mem *p){ #ifdef VDBE_PROFILE -/* -** hwtime.h contains inline assembler code for implementing +/* +** hwtime.h contains inline assembler code for implementing ** high-performance timing routines. */ /************** Include hwtime.h in the middle of vdbe.c *********************/ @@ -53278,7 +63528,7 @@ static void registerTrace(FILE *out, int iReg, Mem *p){ __asm__ __volatile__ ("rdtsc" : "=A" (val)); return val; } - + #elif (defined(__GNUC__) && defined(__ppc__)) __inline__ sqlite_uint64 sqlite3Hwtime(void){ @@ -53329,30 +63579,14 @@ SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } #define CHECK_FOR_INTERRUPT \ if( db->u1.isInterrupted ) goto abort_due_to_interrupt; -#ifdef SQLITE_DEBUG -static int fileExists(sqlite3 *db, const char *zFile){ - int res = 0; - int rc = SQLITE_OK; -#ifdef SQLITE_TEST - /* If we are currently testing IO errors, then do not call OsAccess() to - ** test for the presence of zFile. This is because any IO error that - ** occurs here will not be reported, causing the test to fail. - */ - extern int sqlite3_io_error_pending; - if( sqlite3_io_error_pending<=0 ) -#endif - rc = sqlite3OsAccess(db->pVfs, zFile, SQLITE_ACCESS_EXISTS, &res); - return (res && rc==SQLITE_OK); -} -#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 +** the number of non-transaction savepoints currently in the ** linked list starting at sqlite3.pSavepoint. -** +** ** Usage: ** ** assert( checkSavepointCount(db) ); @@ -53367,6 +63601,20 @@ static int checkSavepointCount(sqlite3 *db){ #endif /* +** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored +** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored +** in memory obtained from sqlite3DbMalloc). +*/ +static void importVtabErrMsg(Vdbe *p, sqlite3_vtab *pVtab){ + sqlite3 *db = p->db; + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg); + sqlite3_free(pVtab->zErrMsg); + pVtab->zErrMsg = 0; +} + + +/* ** Execute as much of a VDBE program as we can then return. ** ** sqlite3VdbeMakeReady() must be called before this routine in order to @@ -53405,7 +63653,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec( Op *pOp; /* Current operation */ int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ - u8 resetSchemaOnFault = 0; /* Reset schema after an error if true */ + u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ u8 encoding = ENC(db); /* The database encoding */ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK int checkProgress; /* True if progress callbacks are enabled */ @@ -53418,6 +63666,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec( Mem *pOut = 0; /* Output operand */ int iCompare = 0; /* Result of last OP_Compare operation */ int *aPermute = 0; /* Permutation of columns for OP_Compare */ + i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */ #ifdef VDBE_PROFILE u64 start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ @@ -53435,9 +63684,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec( int pcDest; } aa; struct OP_Variable_stack_vars { - int p1; /* Variable to copy from */ - int p2; /* Register to copy to */ - int n; /* Number of values left to copy */ Mem *pVar; /* Value being transferred */ } ab; struct OP_Move_stack_vars { @@ -53468,8 +63714,10 @@ SQLITE_PRIVATE int sqlite3VdbeExec( int n; } ag; struct OP_ShiftRight_stack_vars { - i64 a; - i64 b; + i64 iA; + u64 uA; + i64 iB; + u8 op; } ah; struct OP_Ge_stack_vars { int res; /* Result of the comparison of pIn1 against pIn3 */ @@ -53516,6 +63764,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec( u32 szField; /* Number of bytes in the content of a field */ int szHdr; /* Size of the header size field at start of record */ int avail; /* Number of bytes of available data */ + u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ } am; struct OP_Affinity_stack_vars { @@ -53571,6 +63820,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec( } au; struct OP_VerifyCookie_stack_vars { int iMeta; + int iGen; Btree *pBt; } av; struct OP_OpenWrite_stack_vars { @@ -53586,9 +63836,12 @@ SQLITE_PRIVATE int sqlite3VdbeExec( struct OP_OpenEphemeral_stack_vars { VdbeCursor *pCx; } ax; - struct OP_OpenPseudo_stack_vars { + struct OP_SorterOpen_stack_vars { VdbeCursor *pCx; } ay; + struct OP_OpenPseudo_stack_vars { + VdbeCursor *pCx; + } az; struct OP_SeekGt_stack_vars { int res; int oc; @@ -53596,18 +63849,19 @@ SQLITE_PRIVATE int sqlite3VdbeExec( UnpackedRecord r; int nField; i64 iKey; /* The rowid we are to seek to */ - } az; + } ba; struct OP_Seek_stack_vars { VdbeCursor *pC; - } ba; + } bb; struct OP_Found_stack_vars { int alreadyExists; VdbeCursor *pC; int res; + char *pFree; UnpackedRecord *pIdxKey; UnpackedRecord r; char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; - } bb; + } bc; struct OP_IsUnique_stack_vars { u16 ii; VdbeCursor *pCx; @@ -53616,13 +63870,13 @@ SQLITE_PRIVATE int sqlite3VdbeExec( Mem *aMx; UnpackedRecord r; /* B-Tree index search key */ i64 R; /* Rowid stored in register P3 */ - } bc; + } bd; struct OP_NotExists_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int res; u64 iKey; - } bd; + } be; struct OP_NewRowid_stack_vars { i64 v; /* The new rowid */ VdbeCursor *pC; /* Cursor of table to get the new rowid */ @@ -53630,7 +63884,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec( int cnt; /* Counter to limit the number of searches */ Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ VdbeFrame *pFrame; /* Root frame of VDBE */ - } be; + } bf; struct OP_InsertInt_stack_vars { Mem *pData; /* MEM cell holding data for the record to be inserted */ Mem *pKey; /* MEM cell holding key for the record */ @@ -53641,83 +63895,89 @@ SQLITE_PRIVATE int sqlite3VdbeExec( const char *zDb; /* database name - used by the update hook */ const char *zTbl; /* Table name - used by the opdate hook */ int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ - } bf; + } bg; struct OP_Delete_stack_vars { i64 iKey; VdbeCursor *pC; - } bg; + } bh; + struct OP_SorterCompare_stack_vars { + VdbeCursor *pC; + int res; + } bi; + struct OP_SorterData_stack_vars { + VdbeCursor *pC; + } bj; struct OP_RowData_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; u32 n; i64 n64; - } bh; + } bk; struct OP_Rowid_stack_vars { VdbeCursor *pC; i64 v; sqlite3_vtab *pVtab; const sqlite3_module *pModule; - } bi; + } bl; struct OP_NullRow_stack_vars { VdbeCursor *pC; - } bj; + } bm; struct OP_Last_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int res; - } bk; + } bn; struct OP_Rewind_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int res; - } bl; + } bo; struct OP_Next_stack_vars { VdbeCursor *pC; - BtCursor *pCrsr; int res; - } bm; + } bp; struct OP_IdxInsert_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int nKey; const char *zKey; - } bn; + } bq; struct OP_IdxDelete_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int res; UnpackedRecord r; - } bo; + } br; struct OP_IdxRowid_stack_vars { BtCursor *pCrsr; VdbeCursor *pC; i64 rowid; - } bp; + } bs; struct OP_IdxGE_stack_vars { VdbeCursor *pC; int res; UnpackedRecord r; - } bq; + } bt; struct OP_Destroy_stack_vars { int iMoved; int iCnt; Vdbe *pVdbe; int iDb; - } br; + } bu; struct OP_Clear_stack_vars { int nChange; - } bs; + } bv; struct OP_CreateTable_stack_vars { int pgno; int flags; Db *pDb; - } bt; + } bw; struct OP_ParseSchema_stack_vars { int iDb; const char *zMaster; char *zSql; InitData initData; - } bu; + } bx; struct OP_IntegrityCk_stack_vars { int nRoot; /* Number of tables to check. (Number of root pages.) */ int *aRoot; /* Array of rootpage numbers for tables to be checked */ @@ -53725,14 +63985,14 @@ SQLITE_PRIVATE int sqlite3VdbeExec( int nErr; /* Number of errors reported */ char *z; /* Text of the error report */ Mem *pnErr; /* Register keeping track of errors remaining */ - } bv; + } by; struct OP_RowSetRead_stack_vars { i64 val; - } bw; + } bz; struct OP_RowSetTest_stack_vars { int iSet; int exists; - } bx; + } ca; struct OP_Program_stack_vars { int nMem; /* Number of memory registers for sub-program */ int nByte; /* Bytes of runtime space required for sub-program */ @@ -53742,15 +64002,15 @@ SQLITE_PRIVATE int sqlite3VdbeExec( VdbeFrame *pFrame; /* New vdbe frame to execute in */ SubProgram *pProgram; /* Sub-program to execute */ void *t; /* Token identifying trigger */ - } by; + } cb; struct OP_Param_stack_vars { VdbeFrame *pFrame; Mem *pIn; - } bz; + } cc; struct OP_MemMax_stack_vars { Mem *pIn1; VdbeFrame *pFrame; - } ca; + } cd; struct OP_AggStep_stack_vars { int n; int i; @@ -53758,22 +64018,34 @@ SQLITE_PRIVATE int sqlite3VdbeExec( Mem *pRec; sqlite3_context ctx; sqlite3_value **apVal; - } cb; + } ce; struct OP_AggFinal_stack_vars { Mem *pMem; - } cc; + } cf; + struct OP_Checkpoint_stack_vars { + int i; /* Loop counter */ + int aRes[3]; /* Results */ + Mem *pMem; /* Write results here */ + } cg; + struct OP_JournalMode_stack_vars { + Btree *pBt; /* Btree to change journal mode of */ + Pager *pPager; /* Pager associated with pBt */ + int eNew; /* New journal mode */ + int eOld; /* The old journal mode */ + const char *zFilename; /* Name of database file for pPager */ + } ch; struct OP_IncrVacuum_stack_vars { Btree *pBt; - } cd; + } ci; struct OP_VBegin_stack_vars { VTable *pVTab; - } ce; + } cj; struct OP_VOpen_stack_vars { VdbeCursor *pCur; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; sqlite3_module *pModule; - } cf; + } ck; struct OP_VFilter_stack_vars { int nArg; int iQuery; @@ -53786,23 +64058,23 @@ SQLITE_PRIVATE int sqlite3VdbeExec( int res; int i; Mem **apArg; - } cg; + } cl; struct OP_VColumn_stack_vars { sqlite3_vtab *pVtab; const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; - } ch; + } cm; struct OP_VNext_stack_vars { sqlite3_vtab *pVtab; const sqlite3_module *pModule; int res; VdbeCursor *pCur; - } ci; + } cn; struct OP_VRename_stack_vars { sqlite3_vtab *pVtab; Mem *pName; - } cj; + } co; struct OP_VUpdate_stack_vars { sqlite3_vtab *pVtab; sqlite3_module *pModule; @@ -53811,21 +64083,17 @@ SQLITE_PRIVATE int sqlite3VdbeExec( sqlite_int64 rowid; Mem **apArg; Mem *pX; - } ck; - struct OP_Pagecount_stack_vars { - int p1; - int nPage; - Pager *pPager; - } cl; + } cp; struct OP_Trace_stack_vars { char *zTrace; - } cm; + char *z; + } cq; } u; /* End automatically generated code ********************************************************************/ assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ - sqlite3VdbeMutexArrayEnter(p); + sqlite3VdbeEnter(p); if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or ** sqlite3_column_text16() failed. */ @@ -53843,9 +64111,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec( #endif #ifdef SQLITE_DEBUG sqlite3BeginBenignMalloc(); - if( p->pc==0 - && ((p->db->flags & SQLITE_VdbeListing) || fileExists(db, "vdbe_explain")) - ){ + if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){ int i; printf("VDBE Program Listing:\n"); sqlite3VdbePrintSql(p); @@ -53853,9 +64119,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec( sqlite3VdbePrintOp(stdout, i, &aOp[i]); } } - if( fileExists(db, "vdbe_trace") ){ - p->trace = stdout; - } sqlite3EndBenignMalloc(); #endif for(pc=p->pc; rc==SQLITE_OK; pc++){ @@ -53877,15 +64140,8 @@ SQLITE_PRIVATE int sqlite3VdbeExec( } sqlite3VdbePrintOp(p->trace, pc, pOp); } - if( p->trace==0 && pc==0 ){ - sqlite3BeginBenignMalloc(); - if( fileExists(db, "vdbe_sqltrace") ){ - sqlite3VdbePrintSql(p); - } - sqlite3EndBenignMalloc(); - } #endif - + /* Check to see if we need to simulate an interrupt. This only happens ** if we have a special test build. @@ -53930,7 +64186,8 @@ SQLITE_PRIVATE int sqlite3VdbeExec( assert( pOp->p2>0 ); assert( pOp->p2<=p->nMem ); pOut = &aMem[pOp->p2]; - sqlite3VdbeMemReleaseExternal(pOut); + memAboutToChange(p, pOut); + MemReleaseExt(pOut); pOut->flags = MEM_Int; } @@ -53939,28 +64196,33 @@ SQLITE_PRIVATE int sqlite3VdbeExec( if( (pOp->opflags & OPFLG_IN1)!=0 ){ assert( pOp->p1>0 ); assert( pOp->p1<=p->nMem ); + assert( memIsValid(&aMem[pOp->p1]) ); REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); } if( (pOp->opflags & OPFLG_IN2)!=0 ){ assert( pOp->p2>0 ); assert( pOp->p2<=p->nMem ); + assert( memIsValid(&aMem[pOp->p2]) ); REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); } if( (pOp->opflags & OPFLG_IN3)!=0 ){ assert( pOp->p3>0 ); assert( pOp->p3<=p->nMem ); + assert( memIsValid(&aMem[pOp->p3]) ); REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); } if( (pOp->opflags & OPFLG_OUT2)!=0 ){ assert( pOp->p2>0 ); assert( pOp->p2<=p->nMem ); + memAboutToChange(p, &aMem[pOp->p2]); } if( (pOp->opflags & OPFLG_OUT3)!=0 ){ assert( pOp->p3>0 ); assert( pOp->p3<=p->nMem ); + memAboutToChange(p, &aMem[pOp->p3]); } #endif - + switch( pOp->opcode ){ /***************************************************************************** @@ -54001,7 +64263,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec( /* Opcode: Goto * P2 * * * ** ** An unconditional jump to address P2. -** The next instruction executed will be +** The next instruction executed will be ** the one at index P2 from the beginning of ** the program. */ @@ -54019,6 +64281,7 @@ case OP_Goto: { /* jump */ case OP_Gosub: { /* jump, in1 */ pIn1 = &aMem[pOp->p1]; assert( (pIn1->flags & MEM_Dyn)==0 ); + memAboutToChange(p, pIn1); pIn1->flags = MEM_Int; pIn1->u.i = pc; REGISTER_TRACE(pOp->p1, pIn1); @@ -54057,7 +64320,7 @@ case OP_Yield: { /* in1 */ /* Opcode: HaltIfNull P1 P2 P3 P4 * ** -** Check the value in register P3. If is is NULL then Halt using +** Check the value in register P3. If it is NULL then Halt using ** parameter P1, P2, and P4 as if this were a Halt instruction. If the ** value in register P3 is not NULL, then this routine is a no-op. */ @@ -54078,7 +64341,7 @@ case OP_HaltIfNull: { /* in3 */ ** whether or not to rollback the current transaction. Do not rollback ** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort, ** then back out all changes that have occurred during this execution of the -** VDBE, but do not rollback the transaction. +** VDBE, but do not rollback the transaction. ** ** If P4 is not null then it is an error message string. ** @@ -54094,8 +64357,9 @@ case OP_Halt: { p->nFrame--; sqlite3VdbeSetChanges(db, p->nChange); pc = sqlite3VdbeFrameRestore(pFrame); + lastRowid = db->lastRowid; if( pOp->p2==OE_Ignore ){ - /* Instruction pc is the OP_Program that invoked the sub-program + /* Instruction pc is the OP_Program that invoked the sub-program ** currently being halted. If the p2 instruction of this OP_Halt ** instruction is set to OE_Ignore, then the sub-program is throwing ** an IGNORE exception. In this case jump to the address specified @@ -54167,7 +64431,7 @@ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */ /* Opcode: String8 * P2 * P4 * ** -** P4 points to a nul terminated UTF-8 string. This opcode is transformed +** P4 points to a nul terminated UTF-8 string. This opcode is transformed ** into an OP_String before it is executed for the first time. */ case OP_String8: { /* same as TK_STRING, out2-prerelease */ @@ -54198,7 +64462,7 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */ } /* Fall through to the next case, OP_String */ } - + /* Opcode: String P1 P2 * P4 * ** ** The string value P4 of length P1 (bytes) is stored in register P2. @@ -54226,11 +64490,7 @@ case OP_Null: { /* out2-prerelease */ /* Opcode: Blob P1 P2 * P4 ** ** P4 points to a blob of data P1 bytes long. Store this -** blob in register P2. This instruction is not coded directly -** by the compiler. Instead, the compiler layer specifies -** an OP_HexBlob opcode, with the hex string representation of -** the blob as P4. This opcode is transformed to an OP_Blob -** the first time it is executed. +** blob in register P2. */ case OP_Blob: { /* out2-prerelease */ assert( pOp->p1 <= SQLITE_MAX_LENGTH ); @@ -54240,40 +64500,26 @@ case OP_Blob: { /* out2-prerelease */ break; } -/* Opcode: Variable P1 P2 P3 P4 * +/* Opcode: Variable P1 P2 * P4 * ** -** Transfer the values of bound parameters P1..P1+P3-1 into registers -** P2..P2+P3-1. +** Transfer the values of bound parameter P1 into register P2 ** ** If the parameter is named, then its name appears in P4 and P3==1. ** The P4 value is used by sqlite3_bind_parameter_name(). */ -case OP_Variable: { +case OP_Variable: { /* out2-prerelease */ #if 0 /* local variables moved into u.ab */ - int p1; /* Variable to copy from */ - int p2; /* Register to copy to */ - int n; /* Number of values left to copy */ Mem *pVar; /* Value being transferred */ #endif /* local variables moved into u.ab */ - u.ab.p1 = pOp->p1 - 1; - u.ab.p2 = pOp->p2; - u.ab.n = pOp->p3; - assert( u.ab.p1>=0 && u.ab.p1+u.ab.n<=p->nVar ); - assert( u.ab.p2>=1 && u.ab.p2+u.ab.n-1<=p->nMem ); - assert( pOp->p4.z==0 || pOp->p3==1 || pOp->p3==0 ); - - while( u.ab.n-- > 0 ){ - u.ab.pVar = &p->aVar[u.ab.p1++]; - if( sqlite3VdbeMemTooBig(u.ab.pVar) ){ - goto too_big; - } - pOut = &aMem[u.ab.p2++]; - sqlite3VdbeMemReleaseExternal(pOut); - pOut->flags = MEM_Null; - sqlite3VdbeMemShallowCopy(pOut, u.ab.pVar, MEM_Static); - UPDATE_MAX_BLOBSIZE(pOut); + assert( pOp->p1>0 && pOp->p1<=p->nVar ); + assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] ); + u.ab.pVar = &p->aVar[pOp->p1 - 1]; + if( sqlite3VdbeMemTooBig(u.ab.pVar) ){ + goto too_big; } + sqlite3VdbeMemShallowCopy(pOut, u.ab.pVar, MEM_Static); + UPDATE_MAX_BLOBSIZE(pOut); break; } @@ -54303,9 +64549,16 @@ case OP_Move: { while( u.ac.n-- ){ assert( pOut<=&aMem[p->nMem] ); assert( pIn1<=&aMem[p->nMem] ); + assert( memIsValid(pIn1) ); + memAboutToChange(p, pOut); u.ac.zMalloc = pOut->zMalloc; pOut->zMalloc = 0; sqlite3VdbeMemMove(pOut, pIn1); +#ifdef SQLITE_DEBUG + if( pOut->pScopyFrom>=&aMem[u.ac.p1] && pOut->pScopyFrom<&aMem[u.ac.p1+pOp->p3] ){ + pOut->pScopyFrom += u.ac.p1 - pOp->p2; + } +#endif pIn1->zMalloc = u.ac.zMalloc; REGISTER_TRACE(u.ac.p2++, pOut); pIn1++; @@ -54348,6 +64601,9 @@ case OP_SCopy: { /* in1, out2 */ pOut = &aMem[pOp->p2]; assert( pOut!=pIn1 ); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); +#ifdef SQLITE_DEBUG + if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1; +#endif REGISTER_TRACE(pOp->p2, pOut); break; } @@ -54408,6 +64664,10 @@ case OP_ResultRow: { */ u.ad.pMem = p->pResultSet = &aMem[pOp->p1]; for(u.ad.i=0; u.ad.i<pOp->p2; u.ad.i++){ + assert( memIsValid(&u.ad.pMem[u.ad.i]) ); + Deephemeralize(&u.ad.pMem[u.ad.i]); + assert( (u.ad.pMem[u.ad.i].flags & MEM_Ephem)==0 + || (u.ad.pMem[u.ad.i].flags & (MEM_Str|MEM_Blob))==0 ); sqlite3VdbeMemNulTerminate(&u.ad.pMem[u.ad.i]); sqlite3VdbeMemStoreType(&u.ad.pMem[u.ad.i]); REGISTER_TRACE(pOp->p1+u.ad.i, &u.ad.pMem[u.ad.i]); @@ -54492,14 +64752,14 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ /* Opcode: Divide P1 P2 P3 * * ** ** Divide the value in register P1 by the value in register P2 -** and store the result in register P3 (P3=P2/P1). If the value in -** register P1 is zero, then the result is NULL. If either input is +** and store the result in register P3 (P3=P2/P1). If the value in +** register P1 is zero, then the result is NULL. If either input is ** NULL, the result is NULL. */ /* Opcode: Remainder P1 P2 P3 * * ** ** Compute the remainder after integer division of the value in -** register P1 by the value in register P2 and store the result in P3. +** register P1 by the value in register P2 and store the result in P3. ** If the value in register P2 is zero the result is NULL. ** If either operand is NULL, the result is NULL. */ @@ -54527,19 +64787,12 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ u.af.iA = pIn1->u.i; u.af.iB = pIn2->u.i; switch( pOp->opcode ){ - case OP_Add: u.af.iB += u.af.iA; break; - case OP_Subtract: u.af.iB -= u.af.iA; break; - case OP_Multiply: u.af.iB *= u.af.iA; break; + case OP_Add: if( sqlite3AddInt64(&u.af.iB,u.af.iA) ) goto fp_math; break; + case OP_Subtract: if( sqlite3SubInt64(&u.af.iB,u.af.iA) ) goto fp_math; break; + case OP_Multiply: if( sqlite3MulInt64(&u.af.iB,u.af.iA) ) goto fp_math; break; case OP_Divide: { if( u.af.iA==0 ) goto arithmetic_result_is_null; - /* Dividing the largest possible negative 64-bit integer (1<<63) by - ** -1 returns an integer too large to store in a 64-bit data-type. On - ** some architectures, the value overflows to (1<<63). On others, - ** a SIGFPE is issued. The following statement normalizes this - ** behavior so that all architectures behave as if integer - ** overflow occurred. - */ - if( u.af.iA==-1 && u.af.iB==SMALLEST_INT64 ) u.af.iA = 1; + if( u.af.iA==-1 && u.af.iB==SMALLEST_INT64 ) goto fp_math; u.af.iB /= u.af.iA; break; } @@ -54553,6 +64806,7 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ pOut->u.i = u.af.iB; MemSetTypeFlag(pOut, MEM_Int); }else{ +fp_math: u.af.rA = sqlite3VdbeRealValue(pIn1); u.af.rB = sqlite3VdbeRealValue(pIn2); switch( pOp->opcode ){ @@ -54618,7 +64872,7 @@ case OP_CollSeq: { ** successors. The result of the function is stored in register P3. ** Register P3 must not be one of the function inputs. ** -** P1 is a 32-bit bitmask indicating whether or not each argument to the +** P1 is a 32-bit bitmask indicating whether or not each argument to the ** function was determined to be constant at compile time. If the first ** argument was constant then bit 0 of P1 is set. This is used to determine ** whether meta data associated with a user function argument using the @@ -54639,14 +64893,19 @@ case OP_Function: { u.ag.n = pOp->p5; u.ag.apVal = p->apArg; assert( u.ag.apVal || u.ag.n==0 ); + assert( pOp->p3>0 && pOp->p3<=p->nMem ); + pOut = &aMem[pOp->p3]; + memAboutToChange(p, pOut); assert( u.ag.n==0 || (pOp->p2>0 && pOp->p2+u.ag.n<=p->nMem+1) ); assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ag.n ); u.ag.pArg = &aMem[pOp->p2]; for(u.ag.i=0; u.ag.i<u.ag.n; u.ag.i++, u.ag.pArg++){ + assert( memIsValid(u.ag.pArg) ); u.ag.apVal[u.ag.i] = u.ag.pArg; + Deephemeralize(u.ag.pArg); sqlite3VdbeMemStoreType(u.ag.pArg); - REGISTER_TRACE(pOp->p2, u.ag.pArg); + REGISTER_TRACE(pOp->p2+u.ag.i, u.ag.pArg); } assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC ); @@ -54658,8 +64917,6 @@ case OP_Function: { u.ag.ctx.pFunc = u.ag.ctx.pVdbeFunc->pFunc; } - assert( pOp->p3>0 && pOp->p3<=p->nMem ); - pOut = &aMem[pOp->p3]; u.ag.ctx.s.flags = MEM_Null; u.ag.ctx.s.db = db; u.ag.ctx.s.xDel = 0; @@ -54679,16 +64936,9 @@ case OP_Function: { assert( pOp[-1].opcode==OP_CollSeq ); u.ag.ctx.pColl = pOp[-1].p4.pColl; } - (*u.ag.ctx.pFunc->xFunc)(&u.ag.ctx, u.ag.n, u.ag.apVal); - if( db->mallocFailed ){ - /* Even though a malloc() has failed, the implementation of the - ** user function may have called an sqlite3_result_XXX() function - ** to return a value. The following call releases any resources - ** associated with such a value. - */ - sqlite3VdbeMemRelease(&u.ag.ctx.s); - goto no_mem; - } + db->lastRowid = lastRowid; + (*u.ag.ctx.pFunc->xFunc)(&u.ag.ctx, u.ag.n, u.ag.apVal); /* IMP: R-24505-23230 */ + lastRowid = db->lastRowid; /* If any auxiliary data functions have been called by this user function, ** immediately call the destructor for any non-static values. @@ -54699,6 +64949,16 @@ case OP_Function: { pOp->p4type = P4_VDBEFUNC; } + if( db->mallocFailed ){ + /* Even though a malloc() has failed, the implementation of the + ** user function may have called an sqlite3_result_XXX() function + ** to return a value. The following call releases any resources + ** associated with such a value. + */ + sqlite3VdbeMemRelease(&u.ag.ctx.s); + goto no_mem; + } + /* If the function returned an error, throw an exception */ if( u.ag.ctx.isError ){ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ag.ctx.s)); @@ -54711,6 +64971,15 @@ case OP_Function: { if( sqlite3VdbeMemTooBig(pOut) ){ goto too_big; } + +#if 0 + /* The app-defined function has done something that as caused this + ** statement to expire. (Perhaps the function called sqlite3_exec() + ** with a CREATE TABLE statement.) + */ + if( p->expired ) rc = SQLITE_ABORT; +#endif + REGISTER_TRACE(pOp->p3, pOut); UPDATE_MAX_BLOBSIZE(pOut); break; @@ -54731,7 +65000,7 @@ case OP_Function: { /* Opcode: ShiftLeft P1 P2 P3 * * ** ** Shift the integer value in register P2 to the left by the -** number of bits specified by the integer in regiser P1. +** number of bits specified by the integer in register P1. ** Store the result in register P3. ** If either input is NULL, the result is NULL. */ @@ -54747,8 +65016,10 @@ case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */ case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ #if 0 /* local variables moved into u.ah */ - i64 a; - i64 b; + i64 iA; + u64 uA; + i64 iB; + u8 op; #endif /* local variables moved into u.ah */ pIn1 = &aMem[pOp->p1]; @@ -54758,22 +65029,44 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ sqlite3VdbeMemSetNull(pOut); break; } - u.ah.a = sqlite3VdbeIntValue(pIn2); - u.ah.b = sqlite3VdbeIntValue(pIn1); - switch( pOp->opcode ){ - case OP_BitAnd: u.ah.a &= u.ah.b; break; - case OP_BitOr: u.ah.a |= u.ah.b; break; - case OP_ShiftLeft: u.ah.a <<= u.ah.b; break; - default: assert( pOp->opcode==OP_ShiftRight ); - u.ah.a >>= u.ah.b; break; + u.ah.iA = sqlite3VdbeIntValue(pIn2); + u.ah.iB = sqlite3VdbeIntValue(pIn1); + u.ah.op = pOp->opcode; + if( u.ah.op==OP_BitAnd ){ + u.ah.iA &= u.ah.iB; + }else if( u.ah.op==OP_BitOr ){ + u.ah.iA |= u.ah.iB; + }else if( u.ah.iB!=0 ){ + assert( u.ah.op==OP_ShiftRight || u.ah.op==OP_ShiftLeft ); + + /* If shifting by a negative amount, shift in the other direction */ + if( u.ah.iB<0 ){ + assert( OP_ShiftRight==OP_ShiftLeft+1 ); + u.ah.op = 2*OP_ShiftLeft + 1 - u.ah.op; + u.ah.iB = u.ah.iB>(-64) ? -u.ah.iB : 64; + } + + if( u.ah.iB>=64 ){ + u.ah.iA = (u.ah.iA>=0 || u.ah.op==OP_ShiftLeft) ? 0 : -1; + }else{ + memcpy(&u.ah.uA, &u.ah.iA, sizeof(u.ah.uA)); + if( u.ah.op==OP_ShiftLeft ){ + u.ah.uA <<= u.ah.iB; + }else{ + u.ah.uA >>= u.ah.iB; + /* Sign-extend on a right shift of a negative number */ + if( u.ah.iA<0 ) u.ah.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.ah.iB); + } + memcpy(&u.ah.iA, &u.ah.uA, sizeof(u.ah.iA)); + } } - pOut->u.i = u.ah.a; + pOut->u.i = u.ah.iA; MemSetTypeFlag(pOut, MEM_Int); break; } /* Opcode: AddImm P1 P2 * * * -** +** ** Add the constant P2 to the value in register P1. ** The result is always an integer. ** @@ -54781,13 +65074,14 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ */ case OP_AddImm: { /* in1 */ pIn1 = &aMem[pOp->p1]; + memAboutToChange(p, pIn1); sqlite3VdbeMemIntegerify(pIn1); pIn1->u.i += pOp->p2; break; } /* Opcode: MustBeInt P1 P2 * * * -** +** ** Force the value in register P1 to be an integer. If the value ** in P1 is not an integer and cannot be converted into an integer ** without data loss, then jump immediately to P2, or if P2==0 @@ -54840,6 +65134,7 @@ case OP_RealAffinity: { /* in1 */ */ case OP_ToText: { /* same as TK_TO_TEXT, in1 */ pIn1 = &aMem[pOp->p1]; + memAboutToChange(p, pIn1); if( pIn1->flags & MEM_Null ) break; assert( MEM_Str==(MEM_Blob>>3) ); pIn1->flags |= (pIn1->flags&MEM_Blob)>>3; @@ -54879,23 +65174,21 @@ case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */ ** Force the value in register P1 to be numeric (either an ** integer or a floating-point number.) ** If the value is text or blob, try to convert it to an using the -** equivalent of atoi() or atof() and store 0 if no such conversion +** equivalent of atoi() or atof() and store 0 if no such conversion ** is possible. ** ** A NULL value is not changed by this routine. It remains NULL. */ case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */ pIn1 = &aMem[pOp->p1]; - if( (pIn1->flags & (MEM_Null|MEM_Int|MEM_Real))==0 ){ - sqlite3VdbeMemNumerify(pIn1); - } + sqlite3VdbeMemNumerify(pIn1); break; } #endif /* SQLITE_OMIT_CAST */ /* Opcode: ToInt P1 * * * * ** -** Force the value in register P1 be an integer. If +** Force the value in register P1 to be an integer. If ** The value is currently a real number, drop its fractional part. ** If the value is text or blob, try to convert it to an integer using the ** equivalent of atoi() and store 0 if no such conversion is possible. @@ -54922,6 +65215,7 @@ case OP_ToInt: { /* same as TK_TO_INT, in1 */ */ case OP_ToReal: { /* same as TK_TO_REAL, in1 */ pIn1 = &aMem[pOp->p1]; + memAboutToChange(p, pIn1); if( (pIn1->flags & MEM_Null)==0 ){ sqlite3VdbeMemRealify(pIn1); } @@ -54932,21 +65226,21 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */ /* Opcode: Lt P1 P2 P3 P4 P5 ** ** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then -** jump to address P2. +** jump to address P2. ** ** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or -** reg(P3) is NULL then take the jump. If the SQLITE_JUMPIFNULL -** bit is clear then fall thru if either operand is NULL. +** reg(P3) is NULL then take the jump. If the SQLITE_JUMPIFNULL +** bit is clear then fall through if either operand is NULL. ** ** The SQLITE_AFF_MASK portion of P5 must be an affinity character - -** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made +** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made ** to coerce both inputs according to this affinity before the ** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric ** affinity is used. Note that the affinity conversions are stored ** back into the input registers P1 and P3. So this opcode can cause ** persistent changes to registers P1 and P3. ** -** Once any conversions have taken place, and neither value is NULL, +** Once any conversions have taken place, and neither value is NULL, ** the values are compared. If both values are blobs then memcmp() is ** used to determine the results of the comparison. If both values ** are text, then the appropriate collating function specified in @@ -54968,7 +65262,7 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */ ** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either ** true or false and is never NULL. If both operands are NULL then the result ** of comparison is false. If either operand is NULL then the result is true. -** If neither operand is NULL the the result is the same as it would be if +** If neither operand is NULL the result is the same as it would be if ** the SQLITE_NULLEQ flag were omitted from P5. */ /* Opcode: Eq P1 P2 P3 P4 P5 @@ -54980,7 +65274,7 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */ ** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either ** true or false and is never NULL. If both operands are NULL then the result ** of comparison is true. If either operand is NULL then the result is false. -** If neither operand is NULL the the result is the same as it would be if +** If neither operand is NULL the result is the same as it would be if ** the SQLITE_NULLEQ flag were omitted from P5. */ /* Opcode: Le P1 P2 P3 P4 P5 @@ -55018,7 +65312,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ pIn3 = &aMem[pOp->p3]; u.ai.flags1 = pIn1->flags; u.ai.flags3 = pIn3->flags; - if( (pIn1->flags | pIn3->flags)&MEM_Null ){ + if( (u.ai.flags1 | u.ai.flags3)&MEM_Null ){ /* One or both operands are NULL */ if( pOp->p5 & SQLITE_NULLEQ ){ /* If SQLITE_NULLEQ is set (which will only happen if the operator is @@ -55026,7 +65320,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ ** or not both operands are null. */ assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); - u.ai.res = (pIn1->flags & pIn3->flags & MEM_Null)==0; + u.ai.res = (u.ai.flags1 & u.ai.flags3 & MEM_Null)==0; }else{ /* SQLITE_NULLEQ is clear and at least one operand is NULL, ** then the result is always NULL. @@ -55066,6 +65360,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &aMem[pOp->p2]; + memAboutToChange(p, pOut); MemSetTypeFlag(pOut, MEM_Int); pOut->u.i = u.ai.res; REGISTER_TRACE(pOp->p2, pOut); @@ -55097,8 +65392,8 @@ case OP_Permutation: { /* Opcode: Compare P1 P2 P3 P4 * ** -** Compare to vectors of registers in reg(P1)..reg(P1+P3-1) (all this -** one "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of +** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this +** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of ** the comparison for use by the next OP_Jump instruct. ** ** P4 is a KeyInfo structure that defines collating sequences and sort @@ -55140,6 +65435,8 @@ case OP_Compare: { #endif /* SQLITE_DEBUG */ for(u.aj.i=0; u.aj.i<u.aj.n; u.aj.i++){ u.aj.idx = aPermute ? aPermute[u.aj.i] : u.aj.i; + assert( memIsValid(&aMem[u.aj.p1+u.aj.idx]) ); + assert( memIsValid(&aMem[u.aj.p2+u.aj.idx]) ); REGISTER_TRACE(u.aj.p1+u.aj.idx, &aMem[u.aj.p1+u.aj.idx]); REGISTER_TRACE(u.aj.p2+u.aj.idx, &aMem[u.aj.p2+u.aj.idx]); assert( u.aj.i<u.aj.pKeyInfo->nField ); @@ -55229,7 +65526,7 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */ /* Opcode: Not P1 P2 * * * ** ** Interpret the value in register P1 as a boolean value. Store the -** boolean complement in register P2. If the value in register P1 is +** boolean complement in register P2. If the value in register P1 is ** NULL, then a NULL is stored in P2. */ case OP_Not: { /* same as TK_NOT, in1, out2 */ @@ -55260,18 +65557,29 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ break; } +/* Opcode: Once P1 P2 * * * +** +** Jump to P2 if the value in register P1 is a not null or zero. If +** the value is NULL or zero, fall through and change the P1 register +** to an integer 1. +** +** When P1 is not used otherwise in a program, this opcode falls through +** once and jumps on all subsequent invocations. It is the equivalent +** of "OP_If P1 P2", followed by "OP_Integer 1 P1". +*/ /* Opcode: If P1 P2 P3 * * ** -** Jump to P2 if the value in register P1 is true. The value is +** Jump to P2 if the value in register P1 is true. The value ** is considered true if it is numeric and non-zero. If the value ** in P1 is NULL then take the jump if P3 is true. */ /* Opcode: IfNot P1 P2 P3 * * ** -** Jump to P2 if the value in register P1 is False. The value is +** Jump to P2 if the value in register P1 is False. The value ** is considered true if it has a numeric value of zero. If the value ** in P1 is NULL then take the jump if P3 is true. */ +case OP_Once: /* jump, in1 */ case OP_If: /* jump, in1 */ case OP_IfNot: { /* jump, in1 */ #if 0 /* local variables moved into u.al */ @@ -55290,6 +65598,12 @@ case OP_IfNot: { /* jump, in1 */ } if( u.al.c ){ pc = pOp->p2-1; + }else if( pOp->opcode==OP_Once ){ + assert( (pIn1->flags & (MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))==0 ); + memAboutToChange(p, pIn1); + pIn1->flags = MEM_Int; + pIn1->u.i = 1; + REGISTER_TRACE(pOp->p1, pIn1); } break; } @@ -55308,7 +65622,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ /* Opcode: NotNull P1 P2 * * * ** -** Jump to P2 if the value in register P1 is not NULL. +** Jump to P2 if the value in register P1 is not NULL. */ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ pIn1 = &aMem[pOp->p1]; @@ -55323,7 +65637,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ ** 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 that (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. @@ -55360,6 +65674,7 @@ case OP_Column: { u32 szField; /* Number of bytes in the content of a field */ int szHdr; /* Size of the header size field at start of record */ int avail; /* Number of bytes of available data */ + u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ #endif /* local variables moved into u.am */ @@ -55371,7 +65686,7 @@ case OP_Column: { assert( u.am.p1<p->nCursor ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); u.am.pDest = &aMem[pOp->p3]; - MemSetTypeFlag(u.am.pDest, MEM_Null); + memAboutToChange(p, u.am.pDest); u.am.zRec = 0; /* This block sets the variable u.am.payloadSize to be the total number of @@ -55415,9 +65730,10 @@ case OP_Column: { rc = sqlite3BtreeDataSize(u.am.pCrsr, &u.am.payloadSize); assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ } - }else if( u.am.pC->pseudoTableReg>0 ){ + }else if( ALWAYS(u.am.pC->pseudoTableReg>0) ){ u.am.pReg = &aMem[u.am.pC->pseudoTableReg]; assert( u.am.pReg->flags & MEM_Blob ); + assert( memIsValid(u.am.pReg) ); u.am.payloadSize = u.am.pReg->n; u.am.zRec = u.am.pReg->z; u.am.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr; @@ -55427,9 +65743,10 @@ case OP_Column: { u.am.payloadSize = 0; } - /* If u.am.payloadSize is 0, then just store a NULL */ + /* If u.am.payloadSize is 0, then just store a NULL. This can happen because of + ** nullRow or because of a corrupt database. */ if( u.am.payloadSize==0 ){ - assert( u.am.pDest->flags&MEM_Null ); + MemSetTypeFlag(u.am.pDest, MEM_Null); goto op_column_out; } assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 ); @@ -55536,8 +65853,14 @@ case OP_Column: { for(u.am.i=0; u.am.i<u.am.nField; u.am.i++){ if( u.am.zIdx<u.am.zEndHdr ){ u.am.aOffset[u.am.i] = u.am.offset; - u.am.zIdx += getVarint32(u.am.zIdx, u.am.aType[u.am.i]); - u.am.szField = sqlite3VdbeSerialTypeLen(u.am.aType[u.am.i]); + if( u.am.zIdx[0]<0x80 ){ + u.am.t = u.am.zIdx[0]; + u.am.zIdx++; + }else{ + u.am.zIdx += sqlite3GetVarint32(u.am.zIdx, &u.am.t); + } + u.am.aType[u.am.i] = u.am.t; + u.am.szField = sqlite3VdbeSerialTypeLen(u.am.t); u.am.offset += u.am.szField; if( u.am.offset<u.am.szField ){ /* True if u.am.offset overflows */ u.am.zIdx = &u.am.zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */ @@ -55578,7 +65901,7 @@ case OP_Column: { if( u.am.aOffset[u.am.p2] ){ assert( rc==SQLITE_OK ); if( u.am.zRec ){ - sqlite3VdbeMemReleaseExternal(u.am.pDest); + MemReleaseExt(u.am.pDest); sqlite3VdbeSerialGet((u8 *)&u.am.zRec[u.am.aOffset[u.am.p2]], u.am.aType[u.am.p2], u.am.pDest); }else{ u.am.len = sqlite3VdbeSerialTypeLen(u.am.aType[u.am.p2]); @@ -55595,7 +65918,7 @@ case OP_Column: { if( pOp->p4type==P4_MEM ){ sqlite3VdbeMemShallowCopy(u.am.pDest, pOp->p4.pMem, MEM_Static); }else{ - assert( u.am.pDest->flags&MEM_Null ); + MemSetTypeFlag(u.am.pDest, MEM_Null); } } @@ -55642,6 +65965,7 @@ case OP_Affinity: { pIn1 = &aMem[pOp->p1]; while( (u.an.cAff = *(u.an.zAffinity++))!=0 ){ assert( pIn1 <= &p->aMem[p->nMem] ); + assert( memIsValid(pIn1) ); ExpandBlob(pIn1); applyAffinity(pIn1, u.an.cAff, encoding); pIn1++; @@ -55651,12 +65975,9 @@ case OP_Affinity: { /* Opcode: MakeRecord P1 P2 P3 P4 * ** -** Convert P2 registers beginning with P1 into a single entry -** suitable for use as a data record in a database table or as a key -** in an index. The details of the format are irrelevant as long as -** the OP_Column opcode can decode the record later. -** Refer to source code comments for the details of the record -** format. +** Convert P2 registers beginning with P1 into the [record format] +** use as a data record in a database table or as a key +** in an index. The OP_Column opcode can decode the record later. ** ** P4 may be a string that is P2 characters long. The nth character of the ** string indicates the column affinity that should be used for the nth @@ -55703,7 +66024,6 @@ case OP_MakeRecord: { */ u.ao.nData = 0; /* Number of bytes of data space */ u.ao.nHdr = 0; /* Number of bytes of header space */ - u.ao.nByte = 0; /* Data space required for this record */ u.ao.nZero = 0; /* Number of zero bytes at the end of the record */ u.ao.nField = pOp->p1; u.ao.zAffinity = pOp->p4.z; @@ -55713,10 +66033,16 @@ case OP_MakeRecord: { u.ao.pLast = &u.ao.pData0[u.ao.nField-1]; u.ao.file_format = p->minWriteFileFormat; + /* Identify the output register */ + assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 ); + pOut = &aMem[pOp->p3]; + memAboutToChange(p, pOut); + /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){ + assert( memIsValid(u.ao.pRec) ); if( u.ao.zAffinity ){ applyAffinity(u.ao.pRec, u.ao.zAffinity[u.ao.pRec-u.ao.pData0], encoding); } @@ -55751,8 +66077,6 @@ case OP_MakeRecord: { ** be one of the input registers (because the following call to ** sqlite3VdbeMemGrow() could clobber the value before it is used). */ - assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 ); - pOut = &aMem[pOp->p3]; if( sqlite3VdbeMemGrow(pOut, (int)u.ao.nByte, 0) ){ goto no_mem; } @@ -55785,7 +66109,7 @@ case OP_MakeRecord: { /* Opcode: Count P1 P2 * * * ** -** Store the number of entries (an integer value) in the table or index +** Store the number of entries (an integer value) in the table or index ** opened by cursor P1 in register P2 */ #ifndef SQLITE_OMIT_BTREECOUNT @@ -55796,7 +66120,7 @@ case OP_Count: { /* out2-prerelease */ #endif /* local variables moved into u.ap */ u.ap.pCrsr = p->apCsr[pOp->p1]->pCursor; - if( u.ap.pCrsr ){ + if( ALWAYS(u.ap.pCrsr) ){ rc = sqlite3BtreeCount(u.ap.pCrsr, &u.ap.nEntry); }else{ u.ap.nEntry = 0; @@ -55846,6 +66170,17 @@ case OP_Savepoint: { }else{ u.aq.nName = sqlite3Strlen30(u.aq.zName); +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* This call is Ok even if this savepoint is actually a transaction + ** savepoint (and therefore should not prompt xSavepoint()) callbacks. + ** If this is a transaction savepoint being opened, it is guaranteed + ** that the db->aVTrans[] array is empty. */ + assert( db->autoCommit==0 || db->nVTrans==0 ); + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, + db->nStatement+db->nSavepoint); + if( rc!=SQLITE_OK ) goto abort_due_to_error; +#endif + /* Create a new savepoint structure. */ u.aq.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.aq.nName+1); if( u.aq.pNew ){ @@ -55924,7 +66259,8 @@ case OP_Savepoint: { } if( u.aq.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ sqlite3ExpirePreparedStatements(db); - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); + db->flags = (db->flags | SQLITE_InternChanges); } } @@ -55951,6 +66287,11 @@ case OP_Savepoint: { }else{ db->nDeferredCons = u.aq.pSavepoint->nDeferredCons; } + + if( !isTransaction ){ + rc = sqlite3VtabSavepoint(db, u.aq.p1, u.aq.iSavepoint); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + } } } @@ -56067,7 +66408,7 @@ case OP_Transaction: { #endif /* local variables moved into u.as */ assert( pOp->p1>=0 && pOp->p1<db->nDb ); - assert( (p->btreeMask & (1<<pOp->p1))!=0 ); + assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); u.as.pBt = db->aDb[pOp->p1].pBt; if( u.as.pBt ){ @@ -56090,7 +66431,11 @@ case OP_Transaction: { db->nStatement++; p->iStatement = db->nSavepoint + db->nStatement; } - rc = sqlite3BtreeBeginStmt(u.as.pBt, p->iStatement); + + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeBeginStmt(u.as.pBt, p->iStatement); + } /* Store the current value of the database handles deferred constraint ** counter. If the statement transaction needs to be rolled back, @@ -56125,7 +66470,7 @@ case OP_ReadCookie: { /* out2-prerelease */ assert( pOp->p3<SQLITE_N_BTREE_META ); assert( u.at.iDb>=0 && u.at.iDb<db->nDb ); assert( db->aDb[u.at.iDb].pBt!=0 ); - assert( (p->btreeMask & (1<<u.at.iDb))!=0 ); + assert( (p->btreeMask & (((yDbMask)1)<<u.at.iDb))!=0 ); sqlite3BtreeGetMeta(db->aDb[u.at.iDb].pBt, u.at.iCookie, (u32 *)&u.at.iMeta); pOut->u.i = u.at.iMeta; @@ -56135,9 +66480,9 @@ case OP_ReadCookie: { /* out2-prerelease */ /* Opcode: SetCookie P1 P2 P3 * * ** ** Write the content of register P3 (interpreted as an integer) -** into cookie number P2 of database P1. P2==1 is the schema version. -** P2==2 is the database format. P2==3 is the recommended pager cache -** size, and so forth. P1==0 is the main database file and P1==1 is the +** into cookie number P2 of database P1. P2==1 is the schema version. +** P2==2 is the database format. P2==3 is the recommended pager cache +** size, and so forth. P1==0 is the main database file and P1==1 is the ** database file used to store temporary tables. ** ** A transaction must be started before executing this opcode. @@ -56148,9 +66493,10 @@ case OP_SetCookie: { /* in3 */ #endif /* local variables moved into u.au */ assert( pOp->p2<SQLITE_N_BTREE_META ); assert( pOp->p1>=0 && pOp->p1<db->nDb ); - assert( (p->btreeMask & (1<<pOp->p1))!=0 ); + assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); u.au.pDb = &db->aDb[pOp->p1]; assert( u.au.pDb->pBt!=0 ); + assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); pIn3 = &aMem[pOp->p3]; sqlite3VdbeMemIntegerify(pIn3); /* See note about index shifting on OP_ReadCookie */ @@ -56172,10 +66518,12 @@ case OP_SetCookie: { /* in3 */ break; } -/* Opcode: VerifyCookie P1 P2 * +/* Opcode: VerifyCookie P1 P2 P3 * * ** ** Check the value of global database parameter number 0 (the -** schema version) and make sure it is equal to P2. +** schema version) and make sure it is equal to P2 and that the +** generation counter on the local schema parse equals P3. +** ** P1 is the database number which is 0 for the main database file ** and 1 for the file holding temporary tables and some higher number ** for auxiliary databases. @@ -56191,17 +66539,21 @@ case OP_SetCookie: { /* in3 */ case OP_VerifyCookie: { #if 0 /* local variables moved into u.av */ int iMeta; + int iGen; Btree *pBt; #endif /* local variables moved into u.av */ + assert( pOp->p1>=0 && pOp->p1<db->nDb ); - assert( (p->btreeMask & (1<<pOp->p1))!=0 ); + assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); + assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); u.av.pBt = db->aDb[pOp->p1].pBt; if( u.av.pBt ){ sqlite3BtreeGetMeta(u.av.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.av.iMeta); + u.av.iGen = db->aDb[pOp->p1].pSchema->iGeneration; }else{ - u.av.iMeta = 0; + u.av.iGen = u.av.iMeta = 0; } - if( u.av.iMeta!=pOp->p2 ){ + if( u.av.iMeta!=pOp->p2 || u.av.iGen!=pOp->p3 ){ sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); /* If the schema-cookie from the database file matches the cookie @@ -56221,7 +66573,7 @@ case OP_VerifyCookie: { sqlite3ResetInternalSchema(db, pOp->p1); } - sqlite3ExpirePreparedStatements(db); + p->expired = 1; rc = SQLITE_SCHEMA; } break; @@ -56230,8 +66582,8 @@ case OP_VerifyCookie: { /* Opcode: OpenRead P1 P2 P3 P4 P5 ** ** Open a read-only cursor for the database table whose root page is -** P2 in a database file. The database file is determined by P3. -** P3==0 means the main database, P3==1 means the database used for +** P2 in a database file. The database file is determined by P3. +** P3==0 means the main database, P3==1 means the database used for ** temporary tables, and P3>1 means used the corresponding attached ** database. Give the new cursor an identifier of P1. The P1 ** values need not be contiguous but all P1 values should be small integers. @@ -56250,9 +66602,9 @@ case OP_VerifyCookie: { ** SQLITE_BUSY error code. ** ** The P4 value may be either an integer (P4_INT32) or a pointer to -** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo -** structure, then said structure defines the content and collating -** sequence of the index being opened. Otherwise, if P4 is an integer +** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo +** structure, then said structure defines the content and collating +** sequence of the index being opened. Otherwise, if P4 is an integer ** value, it is set to the number of columns in the table. ** ** See also OpenWrite. @@ -56264,9 +66616,9 @@ case OP_VerifyCookie: { ** root page. ** ** The P4 value may be either an integer (P4_INT32) or a pointer to -** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo -** structure, then said structure defines the content and collating -** sequence of the index being opened. Otherwise, if P4 is an integer +** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo +** structure, then said structure defines the content and collating +** sequence of the index being opened. Otherwise, if P4 is an integer ** value, it is set to the number of columns in the table, or to the ** largest index of any column of the table that is actually used. ** @@ -56299,12 +66651,13 @@ case OP_OpenWrite: { u.aw.p2 = pOp->p2; u.aw.iDb = pOp->p3; assert( u.aw.iDb>=0 && u.aw.iDb<db->nDb ); - assert( (p->btreeMask & (1<<u.aw.iDb))!=0 ); + assert( (p->btreeMask & (((yDbMask)1)<<u.aw.iDb))!=0 ); u.aw.pDb = &db->aDb[u.aw.iDb]; u.aw.pX = u.aw.pDb->pBt; assert( u.aw.pX!=0 ); if( pOp->opcode==OP_OpenWrite ){ u.aw.wrFlag = 1; + assert( sqlite3SchemaMutexHeld(db, u.aw.iDb, 0) ); if( u.aw.pDb->pSchema->file_format < p->minWriteFileFormat ){ p->minWriteFileFormat = u.aw.pDb->pSchema->file_format; } @@ -56315,6 +66668,8 @@ case OP_OpenWrite: { assert( u.aw.p2>0 ); assert( u.aw.p2<=p->nMem ); pIn2 = &aMem[u.aw.p2]; + assert( memIsValid(pIn2) ); + assert( (pIn2->flags & MEM_Int)!=0 ); sqlite3VdbeMemIntegerify(pIn2); u.aw.p2 = (int)pIn2->u.i; /* The u.aw.p2 value always comes from a prior OP_CreateTable opcode and @@ -56337,18 +66692,13 @@ case OP_OpenWrite: { u.aw.pCur = allocateCursor(p, pOp->p1, u.aw.nField, u.aw.iDb, 1); if( u.aw.pCur==0 ) goto no_mem; u.aw.pCur->nullRow = 1; + u.aw.pCur->isOrdered = 1; rc = sqlite3BtreeCursor(u.aw.pX, u.aw.p2, u.aw.wrFlag, u.aw.pKeyInfo, u.aw.pCur->pCursor); u.aw.pCur->pKeyInfo = u.aw.pKeyInfo; - /* Since it performs no memory allocation or IO, the only values that - ** sqlite3BtreeCursor() may return are SQLITE_EMPTY and SQLITE_OK. - ** SQLITE_EMPTY is only returned when attempting to open the table - ** rooted at page 1 of a zero-byte database. */ - assert( rc==SQLITE_EMPTY || rc==SQLITE_OK ); - if( rc==SQLITE_EMPTY ){ - u.aw.pCur->pCursor = 0; - rc = SQLITE_OK; - } + /* Since it performs no memory allocation or IO, the only value that + ** sqlite3BtreeCursor() may return is SQLITE_OK. */ + assert( rc==SQLITE_OK ); /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of ** SQLite used to check if the root-page flags were sane at this point @@ -56359,14 +66709,14 @@ case OP_OpenWrite: { break; } -/* Opcode: OpenEphemeral P1 P2 * P4 * +/* Opcode: OpenEphemeral P1 P2 * P4 P5 ** ** Open a new cursor P1 to a transient table. -** The cursor is always opened read/write even if -** the main database is read-only. The transient or virtual +** The cursor is always opened read/write even if +** the main database is read-only. The ephemeral ** table is deleted automatically when the cursor is closed. ** -** P2 is the number of columns in the virtual table. +** P2 is the number of columns in the ephemeral table. ** The cursor points to a BTree table if P4==0 and to a BTree index ** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure ** that defines the format of keys in the index. @@ -56376,12 +66726,25 @@ case OP_OpenWrite: { ** to a TEMP table at the SQL level, or to a table opened by ** this opcode. Then this opcode was call OpenVirtual. But ** that created confusion with the whole virtual-table idea. +** +** The P5 parameter can be a mask of the BTREE_* flags defined +** in btree.h. These flags control aspects of the operation of +** the btree. The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are +** added automatically. */ +/* Opcode: OpenAutoindex P1 P2 * P4 * +** +** 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: case OP_OpenEphemeral: { #if 0 /* local variables moved into u.ax */ VdbeCursor *pCx; #endif /* local variables moved into u.ax */ - static const int openFlags = + static const int vfsFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | @@ -56392,21 +66755,21 @@ case OP_OpenEphemeral: { u.ax.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); if( u.ax.pCx==0 ) goto no_mem; u.ax.pCx->nullRow = 1; - rc = sqlite3BtreeFactory(db, 0, 1, SQLITE_DEFAULT_TEMP_CACHE_SIZE, openFlags, - &u.ax.pCx->pBt); + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.ax.pCx->pBt, + BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); if( rc==SQLITE_OK ){ rc = sqlite3BtreeBeginTrans(u.ax.pCx->pBt, 1); } if( rc==SQLITE_OK ){ /* If a transient index is required, create it by calling - ** sqlite3BtreeCreateTable() with the BTREE_ZERODATA flag before + ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before ** opening it. If a transient table is required, just use the - ** automatically created table with root-page 1 (an INTKEY table). + ** automatically created table with root-page 1 (an BLOB_INTKEY table). */ if( pOp->p4.pKeyInfo ){ int pgno; assert( pOp->p4type==P4_KEYINFO ); - rc = sqlite3BtreeCreateTable(u.ax.pCx->pBt, &pgno, BTREE_ZERODATA); + rc = sqlite3BtreeCreateTable(u.ax.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5); if( rc==SQLITE_OK ){ assert( pgno==MASTER_ROOT+1 ); rc = sqlite3BtreeCursor(u.ax.pCx->pBt, pgno, 1, @@ -56420,15 +66783,40 @@ case OP_OpenEphemeral: { u.ax.pCx->isTable = 1; } } + u.ax.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); u.ax.pCx->isIndex = !u.ax.pCx->isTable; break; } +/* Opcode: OpenSorter P1 P2 * P4 * +** +** This opcode works like OP_OpenEphemeral except that it opens +** a transient index that is specifically designed to sort large +** tables using an external merge-sort algorithm. +*/ +case OP_SorterOpen: { +#if 0 /* local variables moved into u.ay */ + VdbeCursor *pCx; +#endif /* local variables moved into u.ay */ +#ifndef SQLITE_OMIT_MERGE_SORT + u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); + if( u.ay.pCx==0 ) goto no_mem; + u.ay.pCx->pKeyInfo = pOp->p4.pKeyInfo; + u.ay.pCx->pKeyInfo->enc = ENC(p->db); + u.ay.pCx->isSorter = 1; + rc = sqlite3VdbeSorterInit(db, u.ay.pCx); +#else + pOp->opcode = OP_OpenEphemeral; + pc--; +#endif + break; +} + /* Opcode: OpenPseudo P1 P2 P3 * * ** ** Open a new cursor that points to a fake table that contains a single ** row of data. The content of that one row in the content of memory -** register P2. In other words, cursor P1 becomes an alias for the +** register P2. In other words, cursor P1 becomes an alias for the ** MEM_Blob content contained in register P2. ** ** A pseudo-table created by this opcode is used to hold a single @@ -56440,17 +66828,17 @@ case OP_OpenEphemeral: { ** the pseudo-table. */ case OP_OpenPseudo: { -#if 0 /* local variables moved into u.ay */ +#if 0 /* local variables moved into u.az */ VdbeCursor *pCx; -#endif /* local variables moved into u.ay */ +#endif /* local variables moved into u.az */ assert( pOp->p1>=0 ); - u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); - if( u.ay.pCx==0 ) goto no_mem; - u.ay.pCx->nullRow = 1; - u.ay.pCx->pseudoTableReg = pOp->p2; - u.ay.pCx->isTable = 1; - u.ay.pCx->isIndex = 0; + u.az.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); + if( u.az.pCx==0 ) goto no_mem; + u.az.pCx->nullRow = 1; + u.az.pCx->pseudoTableReg = pOp->p2; + u.az.pCx->isTable = 1; + u.az.pCx->isIndex = 0; break; } @@ -56468,52 +66856,52 @@ case OP_Close: { /* Opcode: SeekGe P1 P2 P3 P4 * ** -** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the value in register P3 as the key. If cursor P1 refers -** to an SQL index, then P3 is the first in an array of P4 registers -** that are used as an unpacked index key. +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as the key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. ** -** Reposition cursor P1 so that it points to the smallest entry that -** is greater than or equal to the key value. If there are no records +** Reposition cursor P1 so that it points to the smallest entry that +** is greater than or equal to the key value. If there are no records ** greater than or equal to the key and P2 is not zero, then jump to P2. ** ** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe */ /* Opcode: SeekGt P1 P2 P3 P4 * ** -** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the value in register P3 as a key. If cursor P1 refers -** to an SQL index, then P3 is the first in an array of P4 registers -** that are used as an unpacked index key. +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. ** -** Reposition cursor P1 so that it points to the smallest entry that -** is greater than the key value. If there are no records greater than +** Reposition cursor P1 so that it points to the smallest entry that +** is greater than the key value. If there are no records greater than ** the key and P2 is not zero, then jump to P2. ** ** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe */ -/* Opcode: SeekLt P1 P2 P3 P4 * +/* Opcode: SeekLt P1 P2 P3 P4 * ** -** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the value in register P3 as a key. If cursor P1 refers -** to an SQL index, then P3 is the first in an array of P4 registers -** that are used as an unpacked index key. +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. ** -** Reposition cursor P1 so that it points to the largest entry that -** is less than the key value. If there are no records less than +** Reposition cursor P1 so that it points to the largest entry that +** is less than the key value. If there are no records less than ** the key and P2 is not zero, then jump to P2. ** ** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe */ /* Opcode: SeekLe P1 P2 P3 P4 * ** -** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the value in register P3 as a key. If cursor P1 refers -** to an SQL index, then P3 is the first in an array of P4 registers -** that are used as an unpacked index key. +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. ** -** Reposition cursor P1 so that it points to the largest entry that -** is less than or equal to the key value. If there are no records +** Reposition cursor P1 so that it points to the largest entry that +** is less than or equal to the key value. If there are no records ** less than or equal to the key and P2 is not zero, then jump to P2. ** ** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt @@ -56522,34 +66910,35 @@ case OP_SeekLt: /* jump, in3 */ case OP_SeekLe: /* jump, in3 */ case OP_SeekGe: /* jump, in3 */ case OP_SeekGt: { /* jump, in3 */ -#if 0 /* local variables moved into u.az */ +#if 0 /* local variables moved into u.ba */ int res; int oc; VdbeCursor *pC; UnpackedRecord r; int nField; i64 iKey; /* The rowid we are to seek to */ -#endif /* local variables moved into u.az */ +#endif /* local variables moved into u.ba */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p2!=0 ); - u.az.pC = p->apCsr[pOp->p1]; - assert( u.az.pC!=0 ); - assert( u.az.pC->pseudoTableReg==0 ); + u.ba.pC = p->apCsr[pOp->p1]; + assert( u.ba.pC!=0 ); + assert( u.ba.pC->pseudoTableReg==0 ); assert( OP_SeekLe == OP_SeekLt+1 ); assert( OP_SeekGe == OP_SeekLt+2 ); assert( OP_SeekGt == OP_SeekLt+3 ); - if( u.az.pC->pCursor!=0 ){ - u.az.oc = pOp->opcode; - u.az.pC->nullRow = 0; - if( u.az.pC->isTable ){ + assert( u.ba.pC->isOrdered ); + if( ALWAYS(u.ba.pC->pCursor!=0) ){ + u.ba.oc = pOp->opcode; + u.ba.pC->nullRow = 0; + if( u.ba.pC->isTable ){ /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do ** the seek, so covert it. */ pIn3 = &aMem[pOp->p3]; applyNumericAffinity(pIn3); - u.az.iKey = sqlite3VdbeIntValue(pIn3); - u.az.pC->rowidIsValid = 0; + u.ba.iKey = sqlite3VdbeIntValue(pIn3); + u.ba.pC->rowidIsValid = 0; /* If the P3 value could not be converted into an integer without ** loss of information, then special processing is required... */ @@ -56564,98 +66953,101 @@ case OP_SeekGt: { /* jump, in3 */ ** point number. */ assert( (pIn3->flags & MEM_Real)!=0 ); - if( u.az.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.az.iKey || pIn3->r>0) ){ + if( u.ba.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.ba.iKey || pIn3->r>0) ){ /* The P3 value is too large in magnitude to be expressed as an ** integer. */ - u.az.res = 1; + u.ba.res = 1; if( pIn3->r<0 ){ - if( u.az.oc>=OP_SeekGe ){ assert( u.az.oc==OP_SeekGe || u.az.oc==OP_SeekGt ); - rc = sqlite3BtreeFirst(u.az.pC->pCursor, &u.az.res); + if( u.ba.oc>=OP_SeekGe ){ assert( u.ba.oc==OP_SeekGe || u.ba.oc==OP_SeekGt ); + rc = sqlite3BtreeFirst(u.ba.pC->pCursor, &u.ba.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; } }else{ - if( u.az.oc<=OP_SeekLe ){ assert( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekLe ); - rc = sqlite3BtreeLast(u.az.pC->pCursor, &u.az.res); + if( u.ba.oc<=OP_SeekLe ){ assert( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekLe ); + rc = sqlite3BtreeLast(u.ba.pC->pCursor, &u.ba.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; } } - if( u.az.res ){ + if( u.ba.res ){ pc = pOp->p2 - 1; } break; - }else if( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekGe ){ + }else if( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekGe ){ /* Use the ceiling() function to convert real->int */ - if( pIn3->r > (double)u.az.iKey ) u.az.iKey++; + if( pIn3->r > (double)u.ba.iKey ) u.ba.iKey++; }else{ /* Use the floor() function to convert real->int */ - assert( u.az.oc==OP_SeekLe || u.az.oc==OP_SeekGt ); - if( pIn3->r < (double)u.az.iKey ) u.az.iKey--; + assert( u.ba.oc==OP_SeekLe || u.ba.oc==OP_SeekGt ); + if( pIn3->r < (double)u.ba.iKey ) u.ba.iKey--; } } - rc = sqlite3BtreeMovetoUnpacked(u.az.pC->pCursor, 0, (u64)u.az.iKey, 0, &u.az.res); + rc = sqlite3BtreeMovetoUnpacked(u.ba.pC->pCursor, 0, (u64)u.ba.iKey, 0, &u.ba.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - if( u.az.res==0 ){ - u.az.pC->rowidIsValid = 1; - u.az.pC->lastRowid = u.az.iKey; + if( u.ba.res==0 ){ + u.ba.pC->rowidIsValid = 1; + u.ba.pC->lastRowid = u.ba.iKey; } }else{ - u.az.nField = pOp->p4.i; + u.ba.nField = pOp->p4.i; assert( pOp->p4type==P4_INT32 ); - assert( u.az.nField>0 ); - u.az.r.pKeyInfo = u.az.pC->pKeyInfo; - u.az.r.nField = (u16)u.az.nField; + assert( u.ba.nField>0 ); + u.ba.r.pKeyInfo = u.ba.pC->pKeyInfo; + u.ba.r.nField = (u16)u.ba.nField; /* The next line of code computes as follows, only faster: - ** if( u.az.oc==OP_SeekGt || u.az.oc==OP_SeekLe ){ - ** u.az.r.flags = UNPACKED_INCRKEY; + ** if( u.ba.oc==OP_SeekGt || u.ba.oc==OP_SeekLe ){ + ** u.ba.r.flags = UNPACKED_INCRKEY; ** }else{ - ** u.az.r.flags = 0; + ** u.ba.r.flags = 0; ** } */ - u.az.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.az.oc - OP_SeekLt))); - assert( u.az.oc!=OP_SeekGt || u.az.r.flags==UNPACKED_INCRKEY ); - assert( u.az.oc!=OP_SeekLe || u.az.r.flags==UNPACKED_INCRKEY ); - assert( u.az.oc!=OP_SeekGe || u.az.r.flags==0 ); - assert( u.az.oc!=OP_SeekLt || u.az.r.flags==0 ); - - u.az.r.aMem = &aMem[pOp->p3]; - ExpandBlob(u.az.r.aMem); - rc = sqlite3BtreeMovetoUnpacked(u.az.pC->pCursor, &u.az.r, 0, 0, &u.az.res); + u.ba.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.ba.oc - OP_SeekLt))); + assert( u.ba.oc!=OP_SeekGt || u.ba.r.flags==UNPACKED_INCRKEY ); + assert( u.ba.oc!=OP_SeekLe || u.ba.r.flags==UNPACKED_INCRKEY ); + assert( u.ba.oc!=OP_SeekGe || u.ba.r.flags==0 ); + assert( u.ba.oc!=OP_SeekLt || u.ba.r.flags==0 ); + + u.ba.r.aMem = &aMem[pOp->p3]; +#ifdef SQLITE_DEBUG + { int i; for(i=0; i<u.ba.r.nField; i++) assert( memIsValid(&u.ba.r.aMem[i]) ); } +#endif + ExpandBlob(u.ba.r.aMem); + rc = sqlite3BtreeMovetoUnpacked(u.ba.pC->pCursor, &u.ba.r, 0, 0, &u.ba.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - u.az.pC->rowidIsValid = 0; + u.ba.pC->rowidIsValid = 0; } - u.az.pC->deferredMoveto = 0; - u.az.pC->cacheStatus = CACHE_STALE; + u.ba.pC->deferredMoveto = 0; + u.ba.pC->cacheStatus = CACHE_STALE; #ifdef SQLITE_TEST sqlite3_search_count++; #endif - if( u.az.oc>=OP_SeekGe ){ assert( u.az.oc==OP_SeekGe || u.az.oc==OP_SeekGt ); - if( u.az.res<0 || (u.az.res==0 && u.az.oc==OP_SeekGt) ){ - rc = sqlite3BtreeNext(u.az.pC->pCursor, &u.az.res); + if( u.ba.oc>=OP_SeekGe ){ assert( u.ba.oc==OP_SeekGe || u.ba.oc==OP_SeekGt ); + if( u.ba.res<0 || (u.ba.res==0 && u.ba.oc==OP_SeekGt) ){ + rc = sqlite3BtreeNext(u.ba.pC->pCursor, &u.ba.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; - u.az.pC->rowidIsValid = 0; + u.ba.pC->rowidIsValid = 0; }else{ - u.az.res = 0; + u.ba.res = 0; } }else{ - assert( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekLe ); - if( u.az.res>0 || (u.az.res==0 && u.az.oc==OP_SeekLt) ){ - rc = sqlite3BtreePrevious(u.az.pC->pCursor, &u.az.res); + assert( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekLe ); + if( u.ba.res>0 || (u.ba.res==0 && u.ba.oc==OP_SeekLt) ){ + rc = sqlite3BtreePrevious(u.ba.pC->pCursor, &u.ba.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; - u.az.pC->rowidIsValid = 0; + u.ba.pC->rowidIsValid = 0; }else{ - /* u.az.res might be negative because the table is empty. Check to + /* u.ba.res might be negative because the table is empty. Check to ** see if this is the case. */ - u.az.res = sqlite3BtreeEof(u.az.pC->pCursor); + u.ba.res = sqlite3BtreeEof(u.ba.pC->pCursor); } } assert( pOp->p2>0 ); - if( u.az.res ){ + if( u.ba.res ){ pc = pOp->p2 - 1; } }else{ @@ -56678,24 +67070,24 @@ case OP_SeekGt: { /* jump, in3 */ ** occur, no unnecessary I/O happens. */ case OP_Seek: { /* in2 */ -#if 0 /* local variables moved into u.ba */ +#if 0 /* local variables moved into u.bb */ VdbeCursor *pC; -#endif /* local variables moved into u.ba */ +#endif /* local variables moved into u.bb */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.ba.pC = p->apCsr[pOp->p1]; - assert( u.ba.pC!=0 ); - if( ALWAYS(u.ba.pC->pCursor!=0) ){ - assert( u.ba.pC->isTable ); - u.ba.pC->nullRow = 0; + u.bb.pC = p->apCsr[pOp->p1]; + assert( u.bb.pC!=0 ); + if( ALWAYS(u.bb.pC->pCursor!=0) ){ + assert( u.bb.pC->isTable ); + u.bb.pC->nullRow = 0; pIn2 = &aMem[pOp->p2]; - u.ba.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); - u.ba.pC->rowidIsValid = 0; - u.ba.pC->deferredMoveto = 1; + u.bb.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); + u.bb.pC->rowidIsValid = 0; + u.bb.pC->deferredMoveto = 1; } break; } - + /* Opcode: Found P1 P2 P3 P4 * ** @@ -56712,9 +67104,9 @@ case OP_Seek: { /* in2 */ ** If P4==0 then register P3 holds a blob constructed by MakeRecord. If ** P4>0 then register P3 is the first of P4 registers that form an unpacked ** record. -** +** ** Cursor P1 is on an index btree. If the record identified by P3 and P4 -** is not the prefix of any entry in P1 then a jump is made to P2. If P1 +** is not the prefix of any entry in P1 then a jump is made to P2. If P1 ** does contain an entry whose prefix matches the P3/P4 record then control ** falls through to the next instruction and P1 is left pointing at the ** matching entry. @@ -56723,59 +67115,63 @@ case OP_Seek: { /* in2 */ */ case OP_NotFound: /* jump, in3 */ case OP_Found: { /* jump, in3 */ -#if 0 /* local variables moved into u.bb */ +#if 0 /* local variables moved into u.bc */ int alreadyExists; VdbeCursor *pC; int res; + char *pFree; UnpackedRecord *pIdxKey; UnpackedRecord r; char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; -#endif /* local variables moved into u.bb */ +#endif /* local variables moved into u.bc */ #ifdef SQLITE_TEST sqlite3_found_count++; #endif - u.bb.alreadyExists = 0; + u.bc.alreadyExists = 0; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p4type==P4_INT32 ); - u.bb.pC = p->apCsr[pOp->p1]; - assert( u.bb.pC!=0 ); + u.bc.pC = p->apCsr[pOp->p1]; + assert( u.bc.pC!=0 ); pIn3 = &aMem[pOp->p3]; - if( ALWAYS(u.bb.pC->pCursor!=0) ){ + if( ALWAYS(u.bc.pC->pCursor!=0) ){ - assert( u.bb.pC->isTable==0 ); + assert( u.bc.pC->isTable==0 ); if( pOp->p4.i>0 ){ - u.bb.r.pKeyInfo = u.bb.pC->pKeyInfo; - u.bb.r.nField = (u16)pOp->p4.i; - u.bb.r.aMem = pIn3; - u.bb.r.flags = UNPACKED_PREFIX_MATCH; - u.bb.pIdxKey = &u.bb.r; + u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo; + u.bc.r.nField = (u16)pOp->p4.i; + u.bc.r.aMem = pIn3; +#ifdef SQLITE_DEBUG + { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); } +#endif + u.bc.r.flags = UNPACKED_PREFIX_MATCH; + u.bc.pIdxKey = &u.bc.r; }else{ + u.bc.pIdxKey = sqlite3VdbeAllocUnpackedRecord( + u.bc.pC->pKeyInfo, u.bc.aTempRec, sizeof(u.bc.aTempRec), &u.bc.pFree + ); + if( u.bc.pIdxKey==0 ) goto no_mem; assert( pIn3->flags & MEM_Blob ); - ExpandBlob(pIn3); - u.bb.pIdxKey = sqlite3VdbeRecordUnpack(u.bb.pC->pKeyInfo, pIn3->n, pIn3->z, - u.bb.aTempRec, sizeof(u.bb.aTempRec)); - if( u.bb.pIdxKey==0 ){ - goto no_mem; - } - u.bb.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; + assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */ + sqlite3VdbeRecordUnpack(u.bc.pC->pKeyInfo, pIn3->n, pIn3->z, u.bc.pIdxKey); + u.bc.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; } - rc = sqlite3BtreeMovetoUnpacked(u.bb.pC->pCursor, u.bb.pIdxKey, 0, 0, &u.bb.res); + rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, u.bc.pIdxKey, 0, 0, &u.bc.res); if( pOp->p4.i==0 ){ - sqlite3VdbeDeleteUnpackedRecord(u.bb.pIdxKey); + sqlite3DbFree(db, u.bc.pFree); } if( rc!=SQLITE_OK ){ break; } - u.bb.alreadyExists = (u.bb.res==0); - u.bb.pC->deferredMoveto = 0; - u.bb.pC->cacheStatus = CACHE_STALE; + u.bc.alreadyExists = (u.bc.res==0); + u.bc.pC->deferredMoveto = 0; + u.bc.pC->cacheStatus = CACHE_STALE; } if( pOp->opcode==OP_Found ){ - if( u.bb.alreadyExists ) pc = pOp->p2 - 1; + if( u.bc.alreadyExists ) pc = pOp->p2 - 1; }else{ - if( !u.bb.alreadyExists ) pc = pOp->p2 - 1; + if( !u.bc.alreadyExists ) pc = pOp->p2 - 1; } break; } @@ -56787,7 +67183,7 @@ case OP_Found: { /* jump, in3 */ ** the list field being the integer ROWID of the entry that the index ** entry refers to. ** -** The P3 register contains an integer record number. Call this record +** The P3 register contains an integer record number. Call this record ** number R. Register P4 is the first in a set of N contiguous registers ** that make up an unpacked index key that can be used with cursor P1. ** The value of N can be inferred from the cursor. N includes the rowid @@ -56807,7 +67203,7 @@ case OP_Found: { /* jump, in3 */ ** See also: NotFound, NotExists, Found */ case OP_IsUnique: { /* jump, in3 */ -#if 0 /* local variables moved into u.bc */ +#if 0 /* local variables moved into u.bd */ u16 ii; VdbeCursor *pCx; BtCursor *pCrsr; @@ -56815,52 +67211,55 @@ case OP_IsUnique: { /* jump, in3 */ Mem *aMx; UnpackedRecord r; /* B-Tree index search key */ i64 R; /* Rowid stored in register P3 */ -#endif /* local variables moved into u.bc */ +#endif /* local variables moved into u.bd */ pIn3 = &aMem[pOp->p3]; - u.bc.aMx = &aMem[pOp->p4.i]; + u.bd.aMx = &aMem[pOp->p4.i]; /* Assert that the values of parameters P1 and P4 are in range. */ assert( pOp->p4type==P4_INT32 ); assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); /* Find the index cursor. */ - u.bc.pCx = p->apCsr[pOp->p1]; - assert( u.bc.pCx->deferredMoveto==0 ); - u.bc.pCx->seekResult = 0; - u.bc.pCx->cacheStatus = CACHE_STALE; - u.bc.pCrsr = u.bc.pCx->pCursor; + u.bd.pCx = p->apCsr[pOp->p1]; + assert( u.bd.pCx->deferredMoveto==0 ); + u.bd.pCx->seekResult = 0; + u.bd.pCx->cacheStatus = CACHE_STALE; + u.bd.pCrsr = u.bd.pCx->pCursor; /* If any of the values are NULL, take the jump. */ - u.bc.nField = u.bc.pCx->pKeyInfo->nField; - for(u.bc.ii=0; u.bc.ii<u.bc.nField; u.bc.ii++){ - if( u.bc.aMx[u.bc.ii].flags & MEM_Null ){ + u.bd.nField = u.bd.pCx->pKeyInfo->nField; + for(u.bd.ii=0; u.bd.ii<u.bd.nField; u.bd.ii++){ + if( u.bd.aMx[u.bd.ii].flags & MEM_Null ){ pc = pOp->p2 - 1; - u.bc.pCrsr = 0; + u.bd.pCrsr = 0; break; } } - assert( (u.bc.aMx[u.bc.nField].flags & MEM_Null)==0 ); + assert( (u.bd.aMx[u.bd.nField].flags & MEM_Null)==0 ); - if( u.bc.pCrsr!=0 ){ + if( u.bd.pCrsr!=0 ){ /* Populate the index search key. */ - u.bc.r.pKeyInfo = u.bc.pCx->pKeyInfo; - u.bc.r.nField = u.bc.nField + 1; - u.bc.r.flags = UNPACKED_PREFIX_SEARCH; - u.bc.r.aMem = u.bc.aMx; + u.bd.r.pKeyInfo = u.bd.pCx->pKeyInfo; + u.bd.r.nField = u.bd.nField + 1; + u.bd.r.flags = UNPACKED_PREFIX_SEARCH; + u.bd.r.aMem = u.bd.aMx; +#ifdef SQLITE_DEBUG + { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); } +#endif - /* Extract the value of u.bc.R from register P3. */ + /* Extract the value of u.bd.R from register P3. */ sqlite3VdbeMemIntegerify(pIn3); - u.bc.R = pIn3->u.i; + u.bd.R = pIn3->u.i; /* Search the B-Tree index. If no conflicting record is found, jump ** to P2. Otherwise, copy the rowid of the conflicting record to ** register P3 and fall through to the next instruction. */ - rc = sqlite3BtreeMovetoUnpacked(u.bc.pCrsr, &u.bc.r, 0, 0, &u.bc.pCx->seekResult); - if( (u.bc.r.flags & UNPACKED_PREFIX_SEARCH) || u.bc.r.rowid==u.bc.R ){ + rc = sqlite3BtreeMovetoUnpacked(u.bd.pCrsr, &u.bd.r, 0, 0, &u.bd.pCx->seekResult); + if( (u.bd.r.flags & UNPACKED_PREFIX_SEARCH) || u.bd.r.rowid==u.bd.R ){ pc = pOp->p2 - 1; }else{ - pIn3->u.i = u.bc.r.rowid; + pIn3->u.i = u.bd.r.rowid; } } break; @@ -56868,9 +67267,9 @@ case OP_IsUnique: { /* jump, in3 */ /* Opcode: NotExists P1 P2 P3 * * ** -** Use the content of register P3 as a integer key. If a record -** with that key does not exist in table of P1, then jump to P2. -** If the record does exist, then fall thru. The cursor is left +** Use the content of register P3 as an integer key. If a record +** with that key does not exist in table of P1, then jump to P2. +** If the record does exist, then fall through. The cursor is left ** pointing to the record if it exists. ** ** The difference between this operation and NotFound is that this @@ -56881,42 +67280,42 @@ case OP_IsUnique: { /* jump, in3 */ ** See also: Found, NotFound, IsUnique */ case OP_NotExists: { /* jump, in3 */ -#if 0 /* local variables moved into u.bd */ +#if 0 /* local variables moved into u.be */ VdbeCursor *pC; BtCursor *pCrsr; int res; u64 iKey; -#endif /* local variables moved into u.bd */ +#endif /* local variables moved into u.be */ pIn3 = &aMem[pOp->p3]; assert( pIn3->flags & MEM_Int ); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bd.pC = p->apCsr[pOp->p1]; - assert( u.bd.pC!=0 ); - assert( u.bd.pC->isTable ); - assert( u.bd.pC->pseudoTableReg==0 ); - u.bd.pCrsr = u.bd.pC->pCursor; - if( u.bd.pCrsr!=0 ){ - u.bd.res = 0; - u.bd.iKey = pIn3->u.i; - rc = sqlite3BtreeMovetoUnpacked(u.bd.pCrsr, 0, u.bd.iKey, 0, &u.bd.res); - u.bd.pC->lastRowid = pIn3->u.i; - u.bd.pC->rowidIsValid = u.bd.res==0 ?1:0; - u.bd.pC->nullRow = 0; - u.bd.pC->cacheStatus = CACHE_STALE; - u.bd.pC->deferredMoveto = 0; - if( u.bd.res!=0 ){ + u.be.pC = p->apCsr[pOp->p1]; + assert( u.be.pC!=0 ); + assert( u.be.pC->isTable ); + assert( u.be.pC->pseudoTableReg==0 ); + u.be.pCrsr = u.be.pC->pCursor; + if( ALWAYS(u.be.pCrsr!=0) ){ + u.be.res = 0; + u.be.iKey = pIn3->u.i; + rc = sqlite3BtreeMovetoUnpacked(u.be.pCrsr, 0, u.be.iKey, 0, &u.be.res); + u.be.pC->lastRowid = pIn3->u.i; + u.be.pC->rowidIsValid = u.be.res==0 ?1:0; + u.be.pC->nullRow = 0; + u.be.pC->cacheStatus = CACHE_STALE; + u.be.pC->deferredMoveto = 0; + if( u.be.res!=0 ){ pc = pOp->p2 - 1; - assert( u.bd.pC->rowidIsValid==0 ); + assert( u.be.pC->rowidIsValid==0 ); } - u.bd.pC->seekResult = u.bd.res; + u.be.pC->seekResult = u.be.res; }else{ /* This happens when an attempt to open a read cursor on the ** sqlite_master table returns SQLITE_EMPTY. */ pc = pOp->p2 - 1; - assert( u.bd.pC->rowidIsValid==0 ); - u.bd.pC->seekResult = 0; + assert( u.be.pC->rowidIsValid==0 ); + u.be.pC->seekResult = 0; } break; } @@ -56926,7 +67325,7 @@ case OP_NotExists: { /* jump, in3 */ ** Find the next available sequence number for cursor P1. ** Write the sequence number into register P2. ** The sequence number on the cursor is incremented after this -** instruction. +** instruction. */ case OP_Sequence: { /* out2-prerelease */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); @@ -56943,29 +67342,29 @@ case OP_Sequence: { /* out2-prerelease */ ** table that cursor P1 points to. The new record number is written ** written to register P2. ** -** If P3>0 then P3 is a register in the root frame of this VDBE that holds +** If P3>0 then P3 is a register in the root frame of this VDBE that holds ** the largest previously generated record number. No new record numbers are -** allowed to be less than this value. When this value reaches its maximum, -** a SQLITE_FULL error is generated. The P3 register is updated with the ' +** allowed to be less than this value. When this value reaches its maximum, +** an SQLITE_FULL error is generated. The P3 register is updated with the ' ** generated record number. This P3 mechanism is used to help implement the ** AUTOINCREMENT feature. */ case OP_NewRowid: { /* out2-prerelease */ -#if 0 /* local variables moved into u.be */ +#if 0 /* local variables moved into u.bf */ i64 v; /* The new rowid */ VdbeCursor *pC; /* Cursor of table to get the new rowid */ int res; /* Result of an sqlite3BtreeLast() */ int cnt; /* Counter to limit the number of searches */ Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ VdbeFrame *pFrame; /* Root frame of VDBE */ -#endif /* local variables moved into u.be */ +#endif /* local variables moved into u.bf */ - u.be.v = 0; - u.be.res = 0; + u.bf.v = 0; + u.bf.res = 0; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.be.pC = p->apCsr[pOp->p1]; - assert( u.be.pC!=0 ); - if( NEVER(u.be.pC->pCursor==0) ){ + u.bf.pC = p->apCsr[pOp->p1]; + assert( u.bf.pC!=0 ); + if( NEVER(u.bf.pC->pCursor==0) ){ /* The zero initialization above is all that is needed */ }else{ /* The next rowid or record number (different terms for the same @@ -56981,8 +67380,7 @@ case OP_NewRowid: { /* out2-prerelease */ ** succeeded. If the random rowid does exist, we select a new one ** and try again, up to 100 times. */ - assert( u.be.pC->isTable ); - u.be.cnt = 0; + assert( u.bf.pC->isTable ); #ifdef SQLITE_32BIT_ROWID # define MAX_ROWID 0x7fffffff @@ -56994,23 +67392,23 @@ case OP_NewRowid: { /* out2-prerelease */ # define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) #endif - if( !u.be.pC->useRandomRowid ){ - u.be.v = sqlite3BtreeGetCachedRowid(u.be.pC->pCursor); - if( u.be.v==0 ){ - rc = sqlite3BtreeLast(u.be.pC->pCursor, &u.be.res); + if( !u.bf.pC->useRandomRowid ){ + u.bf.v = sqlite3BtreeGetCachedRowid(u.bf.pC->pCursor); + if( u.bf.v==0 ){ + rc = sqlite3BtreeLast(u.bf.pC->pCursor, &u.bf.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - if( u.be.res ){ - u.be.v = 1; /* IMP: R-61914-48074 */ + if( u.bf.res ){ + u.bf.v = 1; /* IMP: R-61914-48074 */ }else{ - assert( sqlite3BtreeCursorIsValid(u.be.pC->pCursor) ); - rc = sqlite3BtreeKeySize(u.be.pC->pCursor, &u.be.v); + assert( sqlite3BtreeCursorIsValid(u.bf.pC->pCursor) ); + rc = sqlite3BtreeKeySize(u.bf.pC->pCursor, &u.bf.v); assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ - if( u.be.v==MAX_ROWID ){ - u.be.pC->useRandomRowid = 1; + if( u.bf.v==MAX_ROWID ){ + u.bf.pC->useRandomRowid = 1; }else{ - u.be.v++; /* IMP: R-29538-34987 */ + u.bf.v++; /* IMP: R-29538-34987 */ } } } @@ -57020,62 +67418,71 @@ case OP_NewRowid: { /* out2-prerelease */ /* Assert that P3 is a valid memory cell. */ assert( pOp->p3>0 ); if( p->pFrame ){ - for(u.be.pFrame=p->pFrame; u.be.pFrame->pParent; u.be.pFrame=u.be.pFrame->pParent); + for(u.bf.pFrame=p->pFrame; u.bf.pFrame->pParent; u.bf.pFrame=u.bf.pFrame->pParent); /* Assert that P3 is a valid memory cell. */ - assert( pOp->p3<=u.be.pFrame->nMem ); - u.be.pMem = &u.be.pFrame->aMem[pOp->p3]; + assert( pOp->p3<=u.bf.pFrame->nMem ); + u.bf.pMem = &u.bf.pFrame->aMem[pOp->p3]; }else{ /* Assert that P3 is a valid memory cell. */ assert( pOp->p3<=p->nMem ); - u.be.pMem = &aMem[pOp->p3]; + u.bf.pMem = &aMem[pOp->p3]; + memAboutToChange(p, u.bf.pMem); } + assert( memIsValid(u.bf.pMem) ); - REGISTER_TRACE(pOp->p3, u.be.pMem); - sqlite3VdbeMemIntegerify(u.be.pMem); - assert( (u.be.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ - if( u.be.pMem->u.i==MAX_ROWID || u.be.pC->useRandomRowid ){ + REGISTER_TRACE(pOp->p3, u.bf.pMem); + sqlite3VdbeMemIntegerify(u.bf.pMem); + assert( (u.bf.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ + if( u.bf.pMem->u.i==MAX_ROWID || u.bf.pC->useRandomRowid ){ rc = SQLITE_FULL; /* IMP: R-12275-61338 */ goto abort_due_to_error; } - if( u.be.v<u.be.pMem->u.i+1 ){ - u.be.v = u.be.pMem->u.i + 1; + if( u.bf.v<u.bf.pMem->u.i+1 ){ + u.bf.v = u.bf.pMem->u.i + 1; } - u.be.pMem->u.i = u.be.v; + u.bf.pMem->u.i = u.bf.v; } #endif - sqlite3BtreeSetCachedRowid(u.be.pC->pCursor, u.be.v<MAX_ROWID ? u.be.v+1 : 0); + sqlite3BtreeSetCachedRowid(u.bf.pC->pCursor, u.bf.v<MAX_ROWID ? u.bf.v+1 : 0); } - if( u.be.pC->useRandomRowid ){ - /* IMPLEMENTATION-OF: R-48598-02938 If the largest ROWID is equal to the + if( u.bf.pC->useRandomRowid ){ + /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the ** largest possible integer (9223372036854775807) then the database - ** engine starts picking candidate ROWIDs at random until it finds one - ** that is not previously used. - */ + ** engine starts picking positive candidate ROWIDs at random until + ** it finds one that is not previously used. */ assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is ** an AUTOINCREMENT table. */ - u.be.v = db->lastRowid; - u.be.cnt = 0; - do{ - if( u.be.cnt==0 && (u.be.v&0xffffff)==u.be.v ){ - u.be.v++; + /* on the first attempt, simply do one more than previous */ + u.bf.v = lastRowid; + u.bf.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ + u.bf.v++; /* ensure non-zero */ + u.bf.cnt = 0; + while( ((rc = sqlite3BtreeMovetoUnpacked(u.bf.pC->pCursor, 0, (u64)u.bf.v, + 0, &u.bf.res))==SQLITE_OK) + && (u.bf.res==0) + && (++u.bf.cnt<100)){ + /* collision - try another random rowid */ + sqlite3_randomness(sizeof(u.bf.v), &u.bf.v); + if( u.bf.cnt<5 ){ + /* try "small" random rowids for the initial attempts */ + u.bf.v &= 0xffffff; }else{ - sqlite3_randomness(sizeof(u.be.v), &u.be.v); - if( u.be.cnt<5 ) u.be.v &= 0xffffff; + u.bf.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ } - rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, 0, (u64)u.be.v, 0, &u.be.res); - u.be.cnt++; - }while( u.be.cnt<100 && rc==SQLITE_OK && u.be.res==0 ); - if( rc==SQLITE_OK && u.be.res==0 ){ + u.bf.v++; /* ensure non-zero */ + } + if( rc==SQLITE_OK && u.bf.res==0 ){ rc = SQLITE_FULL; /* IMP: R-38219-53002 */ goto abort_due_to_error; } + assert( u.bf.v>0 ); /* EV: R-40812-03570 */ } - u.be.pC->rowidIsValid = 0; - u.be.pC->deferredMoveto = 0; - u.be.pC->cacheStatus = CACHE_STALE; + u.bf.pC->rowidIsValid = 0; + u.bf.pC->deferredMoveto = 0; + u.bf.pC->cacheStatus = CACHE_STALE; } - pOut->u.i = u.be.v; + pOut->u.i = u.bf.v; break; } @@ -57106,7 +67513,7 @@ case OP_NewRowid: { /* out2-prerelease */ ** the update hook. ** ** Parameter P4 may point to a string containing the table-name, or -** may be NULL. If it is not NULL, then the update-hook +** may be NULL. If it is not NULL, then the update-hook ** (sqlite3.xUpdateCallback) is invoked following a successful insert. ** ** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically @@ -57123,9 +67530,9 @@ case OP_NewRowid: { /* out2-prerelease */ ** This works exactly like OP_Insert except that the key is the ** integer value P3, not the value of the integer stored in register P3. */ -case OP_Insert: +case OP_Insert: case OP_InsertInt: { -#if 0 /* local variables moved into u.bf */ +#if 0 /* local variables moved into u.bg */ Mem *pData; /* MEM cell holding data for the record to be inserted */ Mem *pKey; /* MEM cell holding key for the record */ i64 iKey; /* The integer ROWID or key for the record to be inserted */ @@ -57135,58 +67542,60 @@ case OP_InsertInt: { const char *zDb; /* database name - used by the update hook */ const char *zTbl; /* Table name - used by the opdate hook */ int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ -#endif /* local variables moved into u.bf */ +#endif /* local variables moved into u.bg */ - u.bf.pData = &aMem[pOp->p2]; + u.bg.pData = &aMem[pOp->p2]; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bf.pC = p->apCsr[pOp->p1]; - assert( u.bf.pC!=0 ); - assert( u.bf.pC->pCursor!=0 ); - assert( u.bf.pC->pseudoTableReg==0 ); - assert( u.bf.pC->isTable ); - REGISTER_TRACE(pOp->p2, u.bf.pData); + assert( memIsValid(u.bg.pData) ); + u.bg.pC = p->apCsr[pOp->p1]; + assert( u.bg.pC!=0 ); + assert( u.bg.pC->pCursor!=0 ); + assert( u.bg.pC->pseudoTableReg==0 ); + assert( u.bg.pC->isTable ); + REGISTER_TRACE(pOp->p2, u.bg.pData); if( pOp->opcode==OP_Insert ){ - u.bf.pKey = &aMem[pOp->p3]; - assert( u.bf.pKey->flags & MEM_Int ); - REGISTER_TRACE(pOp->p3, u.bf.pKey); - u.bf.iKey = u.bf.pKey->u.i; + u.bg.pKey = &aMem[pOp->p3]; + assert( u.bg.pKey->flags & MEM_Int ); + assert( memIsValid(u.bg.pKey) ); + REGISTER_TRACE(pOp->p3, u.bg.pKey); + u.bg.iKey = u.bg.pKey->u.i; }else{ assert( pOp->opcode==OP_InsertInt ); - u.bf.iKey = pOp->p3; + u.bg.iKey = pOp->p3; } if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; - if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = u.bf.iKey; - if( u.bf.pData->flags & MEM_Null ){ - u.bf.pData->z = 0; - u.bf.pData->n = 0; + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bg.iKey; + if( u.bg.pData->flags & MEM_Null ){ + u.bg.pData->z = 0; + u.bg.pData->n = 0; }else{ - assert( u.bf.pData->flags & (MEM_Blob|MEM_Str) ); + assert( u.bg.pData->flags & (MEM_Blob|MEM_Str) ); } - u.bf.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bf.pC->seekResult : 0); - if( u.bf.pData->flags & MEM_Zero ){ - u.bf.nZero = u.bf.pData->u.nZero; + u.bg.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bg.pC->seekResult : 0); + if( u.bg.pData->flags & MEM_Zero ){ + u.bg.nZero = u.bg.pData->u.nZero; }else{ - u.bf.nZero = 0; + u.bg.nZero = 0; } - sqlite3BtreeSetCachedRowid(u.bf.pC->pCursor, 0); - rc = sqlite3BtreeInsert(u.bf.pC->pCursor, 0, u.bf.iKey, - u.bf.pData->z, u.bf.pData->n, u.bf.nZero, - pOp->p5 & OPFLAG_APPEND, u.bf.seekResult + sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, 0); + rc = sqlite3BtreeInsert(u.bg.pC->pCursor, 0, u.bg.iKey, + u.bg.pData->z, u.bg.pData->n, u.bg.nZero, + pOp->p5 & OPFLAG_APPEND, u.bg.seekResult ); - u.bf.pC->rowidIsValid = 0; - u.bf.pC->deferredMoveto = 0; - u.bf.pC->cacheStatus = CACHE_STALE; + u.bg.pC->rowidIsValid = 0; + u.bg.pC->deferredMoveto = 0; + u.bg.pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ - u.bf.zDb = db->aDb[u.bf.pC->iDb].zName; - u.bf.zTbl = pOp->p4.z; - u.bf.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); - assert( u.bf.pC->isTable ); - db->xUpdateCallback(db->pUpdateArg, u.bf.op, u.bf.zDb, u.bf.zTbl, u.bf.iKey); - assert( u.bf.pC->iDb>=0 ); + u.bg.zDb = db->aDb[u.bg.pC->iDb].zName; + u.bg.zTbl = pOp->p4.z; + u.bg.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); + assert( u.bg.pC->isTable ); + db->xUpdateCallback(db->pUpdateArg, u.bg.op, u.bg.zDb, u.bg.zTbl, u.bg.iKey); + assert( u.bg.pC->iDb>=0 ); } break; } @@ -57212,47 +67621,47 @@ case OP_InsertInt: { ** using OP_NotFound prior to invoking this opcode. */ case OP_Delete: { -#if 0 /* local variables moved into u.bg */ +#if 0 /* local variables moved into u.bh */ i64 iKey; VdbeCursor *pC; -#endif /* local variables moved into u.bg */ +#endif /* local variables moved into u.bh */ - u.bg.iKey = 0; + u.bh.iKey = 0; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bg.pC = p->apCsr[pOp->p1]; - assert( u.bg.pC!=0 ); - assert( u.bg.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ + u.bh.pC = p->apCsr[pOp->p1]; + assert( u.bh.pC!=0 ); + assert( u.bh.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ - /* If the update-hook will be invoked, set u.bg.iKey to the rowid of the + /* If the update-hook will be invoked, set u.bh.iKey to the rowid of the ** row being deleted. */ if( db->xUpdateCallback && pOp->p4.z ){ - assert( u.bg.pC->isTable ); - assert( u.bg.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ - u.bg.iKey = u.bg.pC->lastRowid; + assert( u.bh.pC->isTable ); + assert( u.bh.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ + u.bh.iKey = u.bh.pC->lastRowid; } /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or ** OP_Column on the same table without any intervening operations that - ** might move or invalidate the cursor. Hence cursor u.bg.pC is always pointing + ** might move or invalidate the cursor. Hence cursor u.bh.pC is always pointing ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation ** below is always a no-op and cannot fail. We will run it anyhow, though, ** to guard against future changes to the code generator. **/ - assert( u.bg.pC->deferredMoveto==0 ); - rc = sqlite3VdbeCursorMoveto(u.bg.pC); + assert( u.bh.pC->deferredMoveto==0 ); + rc = sqlite3VdbeCursorMoveto(u.bh.pC); if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; - sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, 0); - rc = sqlite3BtreeDelete(u.bg.pC->pCursor); - u.bg.pC->cacheStatus = CACHE_STALE; + sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, 0); + rc = sqlite3BtreeDelete(u.bh.pC->pCursor); + u.bh.pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ - const char *zDb = db->aDb[u.bg.pC->iDb].zName; + const char *zDb = db->aDb[u.bh.pC->iDb].zName; const char *zTbl = pOp->p4.z; - db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bg.iKey); - assert( u.bg.pC->iDb>=0 ); + db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bh.iKey); + assert( u.bh.pC->iDb>=0 ); } if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; break; @@ -57270,11 +67679,54 @@ case OP_ResetCount: { break; } +/* Opcode: SorterCompare P1 P2 P3 +** +** P1 is a sorter cursor. This instruction compares the record blob in +** register P3 with the entry that the sorter cursor currently points to. +** If, excluding the rowid fields at the end, the two records are a match, +** fall through to the next instruction. Otherwise, jump to instruction P2. +*/ +case OP_SorterCompare: { +#if 0 /* local variables moved into u.bi */ + VdbeCursor *pC; + int res; +#endif /* local variables moved into u.bi */ + + u.bi.pC = p->apCsr[pOp->p1]; + assert( isSorter(u.bi.pC) ); + pIn3 = &aMem[pOp->p3]; + rc = sqlite3VdbeSorterCompare(u.bi.pC, pIn3, &u.bi.res); + if( u.bi.res ){ + pc = pOp->p2-1; + } + break; +}; + +/* Opcode: SorterData P1 P2 * * * +** +** Write into register P2 the current sorter data for sorter cursor P1. +*/ +case OP_SorterData: { +#if 0 /* local variables moved into u.bj */ + VdbeCursor *pC; +#endif /* local variables moved into u.bj */ +#ifndef SQLITE_OMIT_MERGE_SORT + pOut = &aMem[pOp->p2]; + u.bj.pC = p->apCsr[pOp->p1]; + assert( u.bj.pC->isSorter ); + rc = sqlite3VdbeSorterRowkey(u.bj.pC, pOut); +#else + pOp->opcode = OP_RowKey; + pc--; +#endif + break; +} + /* Opcode: RowData P1 P2 * * * ** ** Write into register P2 the complete row data for cursor P1. -** There is no interpretation of the data. -** It is just copied onto the P2 register exactly as +** There is no interpretation of the data. +** It is just copied onto the P2 register exactly as ** it is found in the database file. ** ** If the P1 cursor must be pointing to a valid row (not a NULL row) @@ -57283,8 +67735,8 @@ case OP_ResetCount: { /* Opcode: RowKey P1 P2 * * * ** ** Write into register P2 the complete row key for cursor P1. -** There is no interpretation of the data. -** The key is copied onto the P3 register exactly as +** There is no interpretation of the data. +** The key is copied onto the P3 register exactly as ** it is found in the database file. ** ** If the P1 cursor must be pointing to a valid row (not a NULL row) @@ -57292,60 +67744,63 @@ case OP_ResetCount: { */ case OP_RowKey: case OP_RowData: { -#if 0 /* local variables moved into u.bh */ +#if 0 /* local variables moved into u.bk */ VdbeCursor *pC; BtCursor *pCrsr; u32 n; i64 n64; -#endif /* local variables moved into u.bh */ +#endif /* local variables moved into u.bk */ pOut = &aMem[pOp->p2]; + memAboutToChange(p, pOut); /* Note that RowKey and RowData are really exactly the same instruction */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bh.pC = p->apCsr[pOp->p1]; - assert( u.bh.pC->isTable || pOp->opcode==OP_RowKey ); - assert( u.bh.pC->isIndex || pOp->opcode==OP_RowData ); - assert( u.bh.pC!=0 ); - assert( u.bh.pC->nullRow==0 ); - assert( u.bh.pC->pseudoTableReg==0 ); - assert( u.bh.pC->pCursor!=0 ); - u.bh.pCrsr = u.bh.pC->pCursor; - assert( sqlite3BtreeCursorIsValid(u.bh.pCrsr) ); + u.bk.pC = p->apCsr[pOp->p1]; + assert( u.bk.pC->isSorter==0 ); + assert( u.bk.pC->isTable || pOp->opcode!=OP_RowData ); + assert( u.bk.pC->isIndex || pOp->opcode==OP_RowData ); + assert( u.bk.pC!=0 ); + assert( u.bk.pC->nullRow==0 ); + assert( u.bk.pC->pseudoTableReg==0 ); + assert( !u.bk.pC->isSorter ); + assert( u.bk.pC->pCursor!=0 ); + u.bk.pCrsr = u.bk.pC->pCursor; + assert( sqlite3BtreeCursorIsValid(u.bk.pCrsr) ); /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or ** OP_Rewind/Op_Next with no intervening instructions that might invalidate ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always ** a no-op and can never fail. But we leave it in place as a safety. */ - assert( u.bh.pC->deferredMoveto==0 ); - rc = sqlite3VdbeCursorMoveto(u.bh.pC); + assert( u.bk.pC->deferredMoveto==0 ); + rc = sqlite3VdbeCursorMoveto(u.bk.pC); if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; - if( u.bh.pC->isIndex ){ - assert( !u.bh.pC->isTable ); - rc = sqlite3BtreeKeySize(u.bh.pCrsr, &u.bh.n64); + if( u.bk.pC->isIndex ){ + assert( !u.bk.pC->isTable ); + rc = sqlite3BtreeKeySize(u.bk.pCrsr, &u.bk.n64); assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ - if( u.bh.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + if( u.bk.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } - u.bh.n = (u32)u.bh.n64; + u.bk.n = (u32)u.bk.n64; }else{ - rc = sqlite3BtreeDataSize(u.bh.pCrsr, &u.bh.n); + rc = sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n); assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ - if( u.bh.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + if( u.bk.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } } - if( sqlite3VdbeMemGrow(pOut, u.bh.n, 0) ){ + if( sqlite3VdbeMemGrow(pOut, u.bk.n, 0) ){ goto no_mem; } - pOut->n = u.bh.n; + pOut->n = u.bk.n; MemSetTypeFlag(pOut, MEM_Blob); - if( u.bh.pC->isIndex ){ - rc = sqlite3BtreeKey(u.bh.pCrsr, 0, u.bh.n, pOut->z); + if( u.bk.pC->isIndex ){ + rc = sqlite3BtreeKey(u.bk.pCrsr, 0, u.bk.n, pOut->z); }else{ - rc = sqlite3BtreeData(u.bh.pCrsr, 0, u.bh.n, pOut->z); + rc = sqlite3BtreeData(u.bk.pCrsr, 0, u.bk.n, pOut->z); } pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ UPDATE_MAX_BLOBSIZE(pOut); @@ -57362,44 +67817,42 @@ case OP_RowData: { ** one opcode now works for both table types. */ case OP_Rowid: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bi */ +#if 0 /* local variables moved into u.bl */ VdbeCursor *pC; i64 v; sqlite3_vtab *pVtab; const sqlite3_module *pModule; -#endif /* local variables moved into u.bi */ +#endif /* local variables moved into u.bl */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bi.pC = p->apCsr[pOp->p1]; - assert( u.bi.pC!=0 ); - assert( u.bi.pC->pseudoTableReg==0 ); - if( u.bi.pC->nullRow ){ + u.bl.pC = p->apCsr[pOp->p1]; + assert( u.bl.pC!=0 ); + assert( u.bl.pC->pseudoTableReg==0 ); + if( u.bl.pC->nullRow ){ pOut->flags = MEM_Null; break; - }else if( u.bi.pC->deferredMoveto ){ - u.bi.v = u.bi.pC->movetoTarget; + }else if( u.bl.pC->deferredMoveto ){ + u.bl.v = u.bl.pC->movetoTarget; #ifndef SQLITE_OMIT_VIRTUALTABLE - }else if( u.bi.pC->pVtabCursor ){ - u.bi.pVtab = u.bi.pC->pVtabCursor->pVtab; - u.bi.pModule = u.bi.pVtab->pModule; - assert( u.bi.pModule->xRowid ); - rc = u.bi.pModule->xRowid(u.bi.pC->pVtabCursor, &u.bi.v); - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.bi.pVtab->zErrMsg; - u.bi.pVtab->zErrMsg = 0; + }else if( u.bl.pC->pVtabCursor ){ + u.bl.pVtab = u.bl.pC->pVtabCursor->pVtab; + u.bl.pModule = u.bl.pVtab->pModule; + assert( u.bl.pModule->xRowid ); + rc = u.bl.pModule->xRowid(u.bl.pC->pVtabCursor, &u.bl.v); + importVtabErrMsg(p, u.bl.pVtab); #endif /* SQLITE_OMIT_VIRTUALTABLE */ }else{ - assert( u.bi.pC->pCursor!=0 ); - rc = sqlite3VdbeCursorMoveto(u.bi.pC); + assert( u.bl.pC->pCursor!=0 ); + rc = sqlite3VdbeCursorMoveto(u.bl.pC); if( rc ) goto abort_due_to_error; - if( u.bi.pC->rowidIsValid ){ - u.bi.v = u.bi.pC->lastRowid; + if( u.bl.pC->rowidIsValid ){ + u.bl.v = u.bl.pC->lastRowid; }else{ - rc = sqlite3BtreeKeySize(u.bi.pC->pCursor, &u.bi.v); + rc = sqlite3BtreeKeySize(u.bl.pC->pCursor, &u.bl.v); assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */ } } - pOut->u.i = u.bi.v; + pOut->u.i = u.bl.v; break; } @@ -57410,50 +67863,51 @@ case OP_Rowid: { /* out2-prerelease */ ** write a NULL. */ case OP_NullRow: { -#if 0 /* local variables moved into u.bj */ +#if 0 /* local variables moved into u.bm */ VdbeCursor *pC; -#endif /* local variables moved into u.bj */ +#endif /* local variables moved into u.bm */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bj.pC = p->apCsr[pOp->p1]; - assert( u.bj.pC!=0 ); - u.bj.pC->nullRow = 1; - u.bj.pC->rowidIsValid = 0; - if( u.bj.pC->pCursor ){ - sqlite3BtreeClearCursor(u.bj.pC->pCursor); + u.bm.pC = p->apCsr[pOp->p1]; + assert( u.bm.pC!=0 ); + u.bm.pC->nullRow = 1; + u.bm.pC->rowidIsValid = 0; + assert( u.bm.pC->pCursor || u.bm.pC->pVtabCursor ); + if( u.bm.pC->pCursor ){ + sqlite3BtreeClearCursor(u.bm.pC->pCursor); } break; } /* Opcode: Last P1 P2 * * * ** -** The next use of the Rowid or Column or Next instruction for P1 +** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the last entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. */ case OP_Last: { /* jump */ -#if 0 /* local variables moved into u.bk */ +#if 0 /* local variables moved into u.bn */ VdbeCursor *pC; BtCursor *pCrsr; int res; -#endif /* local variables moved into u.bk */ +#endif /* local variables moved into u.bn */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bk.pC = p->apCsr[pOp->p1]; - assert( u.bk.pC!=0 ); - u.bk.pCrsr = u.bk.pC->pCursor; - if( u.bk.pCrsr==0 ){ - u.bk.res = 1; + u.bn.pC = p->apCsr[pOp->p1]; + assert( u.bn.pC!=0 ); + u.bn.pCrsr = u.bn.pC->pCursor; + if( NEVER(u.bn.pCrsr==0) ){ + u.bn.res = 1; }else{ - rc = sqlite3BtreeLast(u.bk.pCrsr, &u.bk.res); + rc = sqlite3BtreeLast(u.bn.pCrsr, &u.bn.res); } - u.bk.pC->nullRow = (u8)u.bk.res; - u.bk.pC->deferredMoveto = 0; - u.bk.pC->rowidIsValid = 0; - u.bk.pC->cacheStatus = CACHE_STALE; - if( pOp->p2>0 && u.bk.res ){ + u.bn.pC->nullRow = (u8)u.bn.res; + u.bn.pC->deferredMoveto = 0; + u.bn.pC->rowidIsValid = 0; + u.bn.pC->cacheStatus = CACHE_STALE; + if( pOp->p2>0 && u.bn.res ){ pc = pOp->p2 - 1; } break; @@ -57472,6 +67926,10 @@ case OP_Last: { /* jump */ ** regression tests can determine whether or not the optimizer is ** correctly optimizing out sorts. */ +case OP_SorterSort: /* jump */ +#ifdef SQLITE_OMIT_MERGE_SORT + pOp->opcode = OP_Sort; +#endif case OP_Sort: { /* jump */ #ifdef SQLITE_TEST sqlite3_sort_count++; @@ -57482,40 +67940,44 @@ case OP_Sort: { /* jump */ } /* Opcode: Rewind P1 P2 * * * ** -** The next use of the Rowid or Column or Next instruction for P1 +** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the first entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. */ case OP_Rewind: { /* jump */ -#if 0 /* local variables moved into u.bl */ +#if 0 /* local variables moved into u.bo */ VdbeCursor *pC; BtCursor *pCrsr; int res; -#endif /* local variables moved into u.bl */ +#endif /* local variables moved into u.bo */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bl.pC = p->apCsr[pOp->p1]; - assert( u.bl.pC!=0 ); - if( (u.bl.pCrsr = u.bl.pC->pCursor)!=0 ){ - rc = sqlite3BtreeFirst(u.bl.pCrsr, &u.bl.res); - u.bl.pC->atFirst = u.bl.res==0 ?1:0; - u.bl.pC->deferredMoveto = 0; - u.bl.pC->cacheStatus = CACHE_STALE; - u.bl.pC->rowidIsValid = 0; + u.bo.pC = p->apCsr[pOp->p1]; + assert( u.bo.pC!=0 ); + assert( u.bo.pC->isSorter==(pOp->opcode==OP_SorterSort) ); + u.bo.res = 1; + if( isSorter(u.bo.pC) ){ + rc = sqlite3VdbeSorterRewind(db, u.bo.pC, &u.bo.res); }else{ - u.bl.res = 1; + u.bo.pCrsr = u.bo.pC->pCursor; + assert( u.bo.pCrsr ); + rc = sqlite3BtreeFirst(u.bo.pCrsr, &u.bo.res); + u.bo.pC->atFirst = u.bo.res==0 ?1:0; + u.bo.pC->deferredMoveto = 0; + u.bo.pC->cacheStatus = CACHE_STALE; + u.bo.pC->rowidIsValid = 0; } - u.bl.pC->nullRow = (u8)u.bl.res; + u.bo.pC->nullRow = (u8)u.bo.res; assert( pOp->p2>0 && pOp->p2<p->nOp ); - if( u.bl.res ){ + if( u.bo.res ){ pc = pOp->p2 - 1; } break; } -/* Opcode: Next P1 P2 * * * +/* Opcode: Next P1 P2 * P4 P5 ** ** Advance cursor P1 so that it points to the next key/data pair in its ** table or index. If there are no more key/value pairs then fall through @@ -57524,9 +67986,15 @@ case OP_Rewind: { /* jump */ ** ** The P1 cursor must be for a real table, not a pseudo-table. ** +** P4 is always of type P4_ADVANCE. The function pointer points to +** sqlite3BtreeNext(). +** +** If P5 is positive and the jump is taken, then event counter +** number P5-1 in the prepared statement is incremented. +** ** See also: Prev */ -/* Opcode: Prev P1 P2 * * * +/* Opcode: Prev P1 P2 * * P5 ** ** Back up cursor P1 so that it points to the previous key/data pair in its ** table or index. If there is no previous key/value pairs then fall through @@ -57534,46 +68002,59 @@ case OP_Rewind: { /* jump */ ** jump immediately to P2. ** ** The P1 cursor must be for a real table, not a pseudo-table. +** +** P4 is always of type P4_ADVANCE. The function pointer points to +** sqlite3BtreePrevious(). +** +** If P5 is positive and the jump is taken, then event counter +** number P5-1 in the prepared statement is incremented. */ +case OP_SorterNext: /* jump */ +#ifdef SQLITE_OMIT_MERGE_SORT + pOp->opcode = OP_Next; +#endif case OP_Prev: /* jump */ case OP_Next: { /* jump */ -#if 0 /* local variables moved into u.bm */ +#if 0 /* local variables moved into u.bp */ VdbeCursor *pC; - BtCursor *pCrsr; int res; -#endif /* local variables moved into u.bm */ +#endif /* local variables moved into u.bp */ CHECK_FOR_INTERRUPT; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bm.pC = p->apCsr[pOp->p1]; - if( u.bm.pC==0 ){ + assert( pOp->p5<=ArraySize(p->aCounter) ); + u.bp.pC = p->apCsr[pOp->p1]; + if( u.bp.pC==0 ){ break; /* See ticket #2273 */ } - u.bm.pCrsr = u.bm.pC->pCursor; - if( u.bm.pCrsr==0 ){ - u.bm.pC->nullRow = 1; - break; - } - u.bm.res = 1; - assert( u.bm.pC->deferredMoveto==0 ); - rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(u.bm.pCrsr, &u.bm.res) : - sqlite3BtreePrevious(u.bm.pCrsr, &u.bm.res); - u.bm.pC->nullRow = (u8)u.bm.res; - u.bm.pC->cacheStatus = CACHE_STALE; - if( u.bm.res==0 ){ + assert( u.bp.pC->isSorter==(pOp->opcode==OP_SorterNext) ); + if( isSorter(u.bp.pC) ){ + assert( pOp->opcode==OP_SorterNext ); + rc = sqlite3VdbeSorterNext(db, u.bp.pC, &u.bp.res); + }else{ + u.bp.res = 1; + assert( u.bp.pC->deferredMoveto==0 ); + assert( u.bp.pC->pCursor ); + assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); + assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); + rc = pOp->p4.xAdvance(u.bp.pC->pCursor, &u.bp.res); + } + u.bp.pC->nullRow = (u8)u.bp.res; + u.bp.pC->cacheStatus = CACHE_STALE; + if( u.bp.res==0 ){ pc = pOp->p2 - 1; if( pOp->p5 ) p->aCounter[pOp->p5-1]++; #ifdef SQLITE_TEST sqlite3_search_count++; #endif } - u.bm.pC->rowidIsValid = 0; + u.bp.pC->rowidIsValid = 0; break; } /* Opcode: IdxInsert P1 P2 P3 * P5 ** -** Register P2 holds a SQL index key made using the +** Register P2 holds an SQL index key made using the ** MakeRecord instructions. This opcode writes that key ** into the index P1. Data for the entry is nil. ** @@ -57583,31 +68064,40 @@ case OP_Next: { /* jump */ ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. */ +case OP_SorterInsert: /* in2 */ +#ifdef SQLITE_OMIT_MERGE_SORT + pOp->opcode = OP_IdxInsert; +#endif case OP_IdxInsert: { /* in2 */ -#if 0 /* local variables moved into u.bn */ +#if 0 /* local variables moved into u.bq */ VdbeCursor *pC; BtCursor *pCrsr; int nKey; const char *zKey; -#endif /* local variables moved into u.bn */ +#endif /* local variables moved into u.bq */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bn.pC = p->apCsr[pOp->p1]; - assert( u.bn.pC!=0 ); + u.bq.pC = p->apCsr[pOp->p1]; + assert( u.bq.pC!=0 ); + assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterInsert) ); pIn2 = &aMem[pOp->p2]; assert( pIn2->flags & MEM_Blob ); - u.bn.pCrsr = u.bn.pC->pCursor; - if( ALWAYS(u.bn.pCrsr!=0) ){ - assert( u.bn.pC->isTable==0 ); + u.bq.pCrsr = u.bq.pC->pCursor; + if( ALWAYS(u.bq.pCrsr!=0) ){ + assert( u.bq.pC->isTable==0 ); rc = ExpandBlob(pIn2); if( rc==SQLITE_OK ){ - u.bn.nKey = pIn2->n; - u.bn.zKey = pIn2->z; - rc = sqlite3BtreeInsert(u.bn.pCrsr, u.bn.zKey, u.bn.nKey, "", 0, 0, pOp->p3, - ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bn.pC->seekResult : 0) - ); - assert( u.bn.pC->deferredMoveto==0 ); - u.bn.pC->cacheStatus = CACHE_STALE; + if( isSorter(u.bq.pC) ){ + rc = sqlite3VdbeSorterWrite(db, u.bq.pC, pIn2); + }else{ + u.bq.nKey = pIn2->n; + u.bq.zKey = pIn2->z; + rc = sqlite3BtreeInsert(u.bq.pCrsr, u.bq.zKey, u.bq.nKey, "", 0, 0, pOp->p3, + ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bq.pC->seekResult : 0) + ); + assert( u.bq.pC->deferredMoveto==0 ); + u.bq.pC->cacheStatus = CACHE_STALE; + } } } break; @@ -57616,34 +68106,37 @@ case OP_IdxInsert: { /* in2 */ /* Opcode: IdxDelete P1 P2 P3 * * ** ** The content of P3 registers starting at register P2 form -** an unpacked index key. This opcode removes that entry from the +** an unpacked index key. This opcode removes that entry from the ** index opened by cursor P1. */ case OP_IdxDelete: { -#if 0 /* local variables moved into u.bo */ +#if 0 /* local variables moved into u.br */ VdbeCursor *pC; BtCursor *pCrsr; int res; UnpackedRecord r; -#endif /* local variables moved into u.bo */ +#endif /* local variables moved into u.br */ assert( pOp->p3>0 ); assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bo.pC = p->apCsr[pOp->p1]; - assert( u.bo.pC!=0 ); - u.bo.pCrsr = u.bo.pC->pCursor; - if( ALWAYS(u.bo.pCrsr!=0) ){ - u.bo.r.pKeyInfo = u.bo.pC->pKeyInfo; - u.bo.r.nField = (u16)pOp->p3; - u.bo.r.flags = 0; - u.bo.r.aMem = &aMem[pOp->p2]; - rc = sqlite3BtreeMovetoUnpacked(u.bo.pCrsr, &u.bo.r, 0, 0, &u.bo.res); - if( rc==SQLITE_OK && u.bo.res==0 ){ - rc = sqlite3BtreeDelete(u.bo.pCrsr); - } - assert( u.bo.pC->deferredMoveto==0 ); - u.bo.pC->cacheStatus = CACHE_STALE; + u.br.pC = p->apCsr[pOp->p1]; + assert( u.br.pC!=0 ); + u.br.pCrsr = u.br.pC->pCursor; + if( ALWAYS(u.br.pCrsr!=0) ){ + u.br.r.pKeyInfo = u.br.pC->pKeyInfo; + u.br.r.nField = (u16)pOp->p3; + u.br.r.flags = 0; + u.br.r.aMem = &aMem[pOp->p2]; +#ifdef SQLITE_DEBUG + { int i; for(i=0; i<u.br.r.nField; i++) assert( memIsValid(&u.br.r.aMem[i]) ); } +#endif + rc = sqlite3BtreeMovetoUnpacked(u.br.pCrsr, &u.br.r, 0, 0, &u.br.res); + if( rc==SQLITE_OK && u.br.res==0 ){ + rc = sqlite3BtreeDelete(u.br.pCrsr); + } + assert( u.br.pC->deferredMoveto==0 ); + u.br.pC->cacheStatus = CACHE_STALE; } break; } @@ -57657,28 +68150,28 @@ case OP_IdxDelete: { ** See also: Rowid, MakeRecord. */ case OP_IdxRowid: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bp */ +#if 0 /* local variables moved into u.bs */ BtCursor *pCrsr; VdbeCursor *pC; i64 rowid; -#endif /* local variables moved into u.bp */ +#endif /* local variables moved into u.bs */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bp.pC = p->apCsr[pOp->p1]; - assert( u.bp.pC!=0 ); - u.bp.pCrsr = u.bp.pC->pCursor; + u.bs.pC = p->apCsr[pOp->p1]; + assert( u.bs.pC!=0 ); + u.bs.pCrsr = u.bs.pC->pCursor; pOut->flags = MEM_Null; - if( ALWAYS(u.bp.pCrsr!=0) ){ - rc = sqlite3VdbeCursorMoveto(u.bp.pC); + if( ALWAYS(u.bs.pCrsr!=0) ){ + rc = sqlite3VdbeCursorMoveto(u.bs.pC); if( NEVER(rc) ) goto abort_due_to_error; - assert( u.bp.pC->deferredMoveto==0 ); - assert( u.bp.pC->isTable==0 ); - if( !u.bp.pC->nullRow ){ - rc = sqlite3VdbeIdxRowid(db, u.bp.pCrsr, &u.bp.rowid); + assert( u.bs.pC->deferredMoveto==0 ); + assert( u.bs.pC->isTable==0 ); + if( !u.bs.pC->nullRow ){ + rc = sqlite3VdbeIdxRowid(db, u.bs.pCrsr, &u.bs.rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - pOut->u.i = u.bp.rowid; + pOut->u.i = u.bs.rowid; pOut->flags = MEM_Int; } } @@ -57687,61 +68180,65 @@ case OP_IdxRowid: { /* out2-prerelease */ /* Opcode: IdxGE P1 P2 P3 P4 P5 ** -** The P4 register values beginning with P3 form an unpacked index -** key that omits the ROWID. Compare this key value against the index +** The P4 register values beginning with P3 form an unpacked index +** key that omits the ROWID. Compare this key value against the index ** that P1 is currently pointing to, ignoring the ROWID on the P1 index. ** ** If the P1 index entry is greater than or equal to the key value ** then jump to P2. Otherwise fall through to the next instruction. ** -** If P5 is non-zero then the key value is increased by an epsilon +** If P5 is non-zero then the key value is increased by an epsilon ** prior to the comparison. This make the opcode work like IdxGT except ** that if the key from register P3 is a prefix of the key in the cursor, ** the result is false whereas it would be true with IdxGT. */ -/* Opcode: IdxLT P1 P2 P3 * P5 +/* Opcode: IdxLT P1 P2 P3 P4 P5 ** -** The P4 register values beginning with P3 form an unpacked index -** key that omits the ROWID. Compare this key value against the index +** The P4 register values beginning with P3 form an unpacked index +** key that omits the ROWID. Compare this key value against the index ** that P1 is currently pointing to, ignoring the ROWID on the P1 index. ** ** If the P1 index entry is less than the key value then jump to P2. ** Otherwise fall through to the next instruction. ** -** If P5 is non-zero then the key value is increased by an epsilon prior +** If P5 is non-zero then the key value is increased by an epsilon prior ** to the comparison. This makes the opcode work like IdxLE. */ case OP_IdxLT: /* jump */ case OP_IdxGE: { /* jump */ -#if 0 /* local variables moved into u.bq */ +#if 0 /* local variables moved into u.bt */ VdbeCursor *pC; int res; UnpackedRecord r; -#endif /* local variables moved into u.bq */ +#endif /* local variables moved into u.bt */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bq.pC = p->apCsr[pOp->p1]; - assert( u.bq.pC!=0 ); - if( ALWAYS(u.bq.pC->pCursor!=0) ){ - assert( u.bq.pC->deferredMoveto==0 ); + u.bt.pC = p->apCsr[pOp->p1]; + assert( u.bt.pC!=0 ); + assert( u.bt.pC->isOrdered ); + if( ALWAYS(u.bt.pC->pCursor!=0) ){ + assert( u.bt.pC->deferredMoveto==0 ); assert( pOp->p5==0 || pOp->p5==1 ); assert( pOp->p4type==P4_INT32 ); - u.bq.r.pKeyInfo = u.bq.pC->pKeyInfo; - u.bq.r.nField = (u16)pOp->p4.i; + u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo; + u.bt.r.nField = (u16)pOp->p4.i; if( pOp->p5 ){ - u.bq.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; + u.bt.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; }else{ - u.bq.r.flags = UNPACKED_IGNORE_ROWID; + u.bt.r.flags = UNPACKED_IGNORE_ROWID; } - u.bq.r.aMem = &aMem[pOp->p3]; - rc = sqlite3VdbeIdxKeyCompare(u.bq.pC, &u.bq.r, &u.bq.res); + u.bt.r.aMem = &aMem[pOp->p3]; +#ifdef SQLITE_DEBUG + { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); } +#endif + rc = sqlite3VdbeIdxKeyCompare(u.bt.pC, &u.bt.r, &u.bt.res); if( pOp->opcode==OP_IdxLT ){ - u.bq.res = -u.bq.res; + u.bt.res = -u.bt.res; }else{ assert( pOp->opcode==OP_IdxGE ); - u.bq.res++; + u.bt.res++; } - if( u.bq.res>0 ){ + if( u.bt.res>0 ){ pc = pOp->p2 - 1 ; } } @@ -57761,45 +68258,47 @@ case OP_IdxGE: { /* jump */ ** might be moved into the newly deleted root page in order to keep all ** root pages contiguous at the beginning of the database. The former ** value of the root page that moved - its value before the move occurred - -** is stored in register P2. If no page -** movement was required (because the table being dropped was already +** is stored in register P2. If no page +** movement was required (because the table being dropped was already ** the last one in the database) then a zero is stored in register P2. ** If AUTOVACUUM is disabled then a zero is stored in register P2. ** ** See also: Clear */ case OP_Destroy: { /* out2-prerelease */ -#if 0 /* local variables moved into u.br */ +#if 0 /* local variables moved into u.bu */ int iMoved; int iCnt; Vdbe *pVdbe; int iDb; -#endif /* local variables moved into u.br */ +#endif /* local variables moved into u.bu */ #ifndef SQLITE_OMIT_VIRTUALTABLE - u.br.iCnt = 0; - for(u.br.pVdbe=db->pVdbe; u.br.pVdbe; u.br.pVdbe = u.br.pVdbe->pNext){ - if( u.br.pVdbe->magic==VDBE_MAGIC_RUN && u.br.pVdbe->inVtabMethod<2 && u.br.pVdbe->pc>=0 ){ - u.br.iCnt++; + u.bu.iCnt = 0; + for(u.bu.pVdbe=db->pVdbe; u.bu.pVdbe; u.bu.pVdbe = u.bu.pVdbe->pNext){ + if( u.bu.pVdbe->magic==VDBE_MAGIC_RUN && u.bu.pVdbe->inVtabMethod<2 && u.bu.pVdbe->pc>=0 ){ + u.bu.iCnt++; } } #else - u.br.iCnt = db->activeVdbeCnt; + u.bu.iCnt = db->activeVdbeCnt; #endif pOut->flags = MEM_Null; - if( u.br.iCnt>1 ){ + if( u.bu.iCnt>1 ){ rc = SQLITE_LOCKED; p->errorAction = OE_Abort; }else{ - u.br.iDb = pOp->p3; - assert( u.br.iCnt==1 ); - assert( (p->btreeMask & (1<<u.br.iDb))!=0 ); - rc = sqlite3BtreeDropTable(db->aDb[u.br.iDb].pBt, pOp->p1, &u.br.iMoved); + u.bu.iDb = pOp->p3; + assert( u.bu.iCnt==1 ); + assert( (p->btreeMask & (((yDbMask)1)<<u.bu.iDb))!=0 ); + rc = sqlite3BtreeDropTable(db->aDb[u.bu.iDb].pBt, pOp->p1, &u.bu.iMoved); pOut->flags = MEM_Int; - pOut->u.i = u.br.iMoved; + pOut->u.i = u.bu.iMoved; #ifndef SQLITE_OMIT_AUTOVACUUM - if( rc==SQLITE_OK && u.br.iMoved!=0 ){ - sqlite3RootPageMoved(&db->aDb[u.br.iDb], u.br.iMoved, pOp->p1); - resetSchemaOnFault = 1; + if( rc==SQLITE_OK && u.bu.iMoved!=0 ){ + sqlite3RootPageMoved(db, u.bu.iDb, u.bu.iMoved, pOp->p1); + /* All OP_Destroy operations occur on the same btree */ + assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bu.iDb+1 ); + resetSchemaOnFault = u.bu.iDb+1; } #endif } @@ -57817,27 +68316,29 @@ case OP_Destroy: { /* out2-prerelease */ ** that is used to store tables create using CREATE TEMPORARY TABLE. ** ** If the P3 value is non-zero, then the table referred to must be an -** intkey table (an SQL table, not an index). In this case the row change -** count is incremented by the number of rows in the table being cleared. +** intkey table (an SQL table, not an index). In this case the row change +** count is incremented by the number of rows in the table being cleared. ** If P3 is greater than zero, then the value stored in register P3 is ** also incremented by the number of rows in the table being cleared. ** ** See also: Destroy */ case OP_Clear: { -#if 0 /* local variables moved into u.bs */ +#if 0 /* local variables moved into u.bv */ int nChange; -#endif /* local variables moved into u.bs */ +#endif /* local variables moved into u.bv */ - u.bs.nChange = 0; - assert( (p->btreeMask & (1<<pOp->p2))!=0 ); + u.bv.nChange = 0; + assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); rc = sqlite3BtreeClearTable( - db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bs.nChange : 0) + db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bv.nChange : 0) ); if( pOp->p3 ){ - p->nChange += u.bs.nChange; + p->nChange += u.bv.nChange; if( pOp->p3>0 ){ - aMem[pOp->p3].u.i += u.bs.nChange; + assert( memIsValid(&aMem[pOp->p3]) ); + memAboutToChange(p, &aMem[pOp->p3]); + aMem[pOp->p3].u.i += u.bv.nChange; } } break; @@ -57867,96 +68368,78 @@ case OP_Clear: { */ case OP_CreateIndex: /* out2-prerelease */ case OP_CreateTable: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bt */ +#if 0 /* local variables moved into u.bw */ int pgno; int flags; Db *pDb; -#endif /* local variables moved into u.bt */ +#endif /* local variables moved into u.bw */ - u.bt.pgno = 0; + u.bw.pgno = 0; assert( pOp->p1>=0 && pOp->p1<db->nDb ); - assert( (p->btreeMask & (1<<pOp->p1))!=0 ); - u.bt.pDb = &db->aDb[pOp->p1]; - assert( u.bt.pDb->pBt!=0 ); + assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); + u.bw.pDb = &db->aDb[pOp->p1]; + assert( u.bw.pDb->pBt!=0 ); if( pOp->opcode==OP_CreateTable ){ - /* u.bt.flags = BTREE_INTKEY; */ - u.bt.flags = BTREE_LEAFDATA|BTREE_INTKEY; + /* u.bw.flags = BTREE_INTKEY; */ + u.bw.flags = BTREE_INTKEY; }else{ - u.bt.flags = BTREE_ZERODATA; + u.bw.flags = BTREE_BLOBKEY; } - rc = sqlite3BtreeCreateTable(u.bt.pDb->pBt, &u.bt.pgno, u.bt.flags); - pOut->u.i = u.bt.pgno; + rc = sqlite3BtreeCreateTable(u.bw.pDb->pBt, &u.bw.pgno, u.bw.flags); + pOut->u.i = u.bw.pgno; break; } -/* Opcode: ParseSchema P1 P2 * P4 * +/* Opcode: ParseSchema P1 * * P4 * ** ** Read and parse all entries from the SQLITE_MASTER table of database P1 -** that match the WHERE clause P4. P2 is the "force" flag. Always do -** the parsing if P2 is true. If P2 is false, then this routine is a -** no-op if the schema is not currently loaded. In other words, if P2 -** is false, the SQLITE_MASTER table is only parsed if the rest of the -** schema is already loaded into the symbol table. +** that match the WHERE clause P4. ** ** This opcode invokes the parser to create a new virtual machine, ** then runs the new virtual machine. It is thus a re-entrant opcode. */ case OP_ParseSchema: { -#if 0 /* local variables moved into u.bu */ +#if 0 /* local variables moved into u.bx */ int iDb; const char *zMaster; char *zSql; InitData initData; -#endif /* local variables moved into u.bu */ +#endif /* local variables moved into u.bx */ - u.bu.iDb = pOp->p1; - assert( u.bu.iDb>=0 && u.bu.iDb<db->nDb ); + /* Any prepared statement that invokes this opcode will hold mutexes + ** on every btree. This is a prerequisite for invoking + ** sqlite3InitCallback(). + */ +#ifdef SQLITE_DEBUG + for(u.bx.iDb=0; u.bx.iDb<db->nDb; u.bx.iDb++){ + assert( u.bx.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.bx.iDb].pBt) ); + } +#endif - /* If pOp->p2 is 0, then this opcode is being executed to read a - ** single row, for example the row corresponding to a new index - ** created by this VDBE, from the sqlite_master table. It only - ** does this if the corresponding in-memory schema is currently - ** loaded. Otherwise, the new index definition can be loaded along - ** with the rest of the schema when it is required. - ** - ** Although the mutex on the BtShared object that corresponds to - ** database u.bu.iDb (the database containing the sqlite_master table - ** read by this instruction) is currently held, it is necessary to - ** obtain the mutexes on all attached databases before checking if - ** the schema of u.bu.iDb is loaded. This is because, at the start of - ** the sqlite3_exec() call below, SQLite will invoke - ** sqlite3BtreeEnterAll(). If all mutexes are not already held, the - ** u.bu.iDb mutex may be temporarily released to avoid deadlock. If - ** this happens, then some other thread may delete the in-memory - ** schema of database u.bu.iDb before the SQL statement runs. The schema - ** will not be reloaded becuase the db->init.busy flag is set. This - ** can result in a "no such table: sqlite_master" or "malformed - ** database schema" error being returned to the user. - */ - assert( sqlite3BtreeHoldsMutex(db->aDb[u.bu.iDb].pBt) ); - sqlite3BtreeEnterAll(db); - if( pOp->p2 || DbHasProperty(db, u.bu.iDb, DB_SchemaLoaded) ){ - u.bu.zMaster = SCHEMA_TABLE(u.bu.iDb); - u.bu.initData.db = db; - u.bu.initData.iDb = pOp->p1; - u.bu.initData.pzErrMsg = &p->zErrMsg; - u.bu.zSql = sqlite3MPrintf(db, + u.bx.iDb = pOp->p1; + assert( u.bx.iDb>=0 && u.bx.iDb<db->nDb ); + assert( DbHasProperty(db, u.bx.iDb, DB_SchemaLoaded) ); + /* Used to be a conditional */ { + u.bx.zMaster = SCHEMA_TABLE(u.bx.iDb); + u.bx.initData.db = db; + u.bx.initData.iDb = pOp->p1; + u.bx.initData.pzErrMsg = &p->zErrMsg; + u.bx.zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", - db->aDb[u.bu.iDb].zName, u.bu.zMaster, pOp->p4.z); - if( u.bu.zSql==0 ){ + db->aDb[u.bx.iDb].zName, u.bx.zMaster, pOp->p4.z); + if( u.bx.zSql==0 ){ rc = SQLITE_NOMEM; }else{ assert( db->init.busy==0 ); db->init.busy = 1; - u.bu.initData.rc = SQLITE_OK; + u.bx.initData.rc = SQLITE_OK; assert( !db->mallocFailed ); - rc = sqlite3_exec(db, u.bu.zSql, sqlite3InitCallback, &u.bu.initData, 0); - if( rc==SQLITE_OK ) rc = u.bu.initData.rc; - sqlite3DbFree(db, u.bu.zSql); + rc = sqlite3_exec(db, u.bx.zSql, sqlite3InitCallback, &u.bx.initData, 0); + if( rc==SQLITE_OK ) rc = u.bx.initData.rc; + sqlite3DbFree(db, u.bx.zSql); db->init.busy = 0; } } - sqlite3BtreeLeaveAll(db); if( rc==SQLITE_NOMEM ){ goto no_mem; } @@ -57973,7 +68456,7 @@ case OP_ParseSchema: { case OP_LoadAnalysis: { assert( pOp->p1>=0 && pOp->p1<db->nDb ); rc = sqlite3AnalysisLoad(db, pOp->p1); - break; + break; } #endif /* !defined(SQLITE_OMIT_ANALYZE) */ @@ -58023,7 +68506,7 @@ case OP_DropTrigger: { ** ** The register P3 contains the maximum number of allowed errors. ** At most reg(P3) errors will be reported. -** In other words, the analysis stops as soon as reg(P1) errors are +** In other words, the analysis stops as soon as reg(P1) errors are ** seen. Reg(P1) is updated with the number of errors remaining. ** ** The root page numbers of all tables in the database are integer @@ -58036,41 +68519,41 @@ case OP_DropTrigger: { ** This opcode is used to implement the integrity_check pragma. */ case OP_IntegrityCk: { -#if 0 /* local variables moved into u.bv */ +#if 0 /* local variables moved into u.by */ int nRoot; /* Number of tables to check. (Number of root pages.) */ int *aRoot; /* Array of rootpage numbers for tables to be checked */ int j; /* Loop counter */ int nErr; /* Number of errors reported */ char *z; /* Text of the error report */ Mem *pnErr; /* Register keeping track of errors remaining */ -#endif /* local variables moved into u.bv */ +#endif /* local variables moved into u.by */ - u.bv.nRoot = pOp->p2; - assert( u.bv.nRoot>0 ); - u.bv.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.bv.nRoot+1) ); - if( u.bv.aRoot==0 ) goto no_mem; + u.by.nRoot = pOp->p2; + assert( u.by.nRoot>0 ); + u.by.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.by.nRoot+1) ); + if( u.by.aRoot==0 ) goto no_mem; assert( pOp->p3>0 && pOp->p3<=p->nMem ); - u.bv.pnErr = &aMem[pOp->p3]; - assert( (u.bv.pnErr->flags & MEM_Int)!=0 ); - assert( (u.bv.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); + u.by.pnErr = &aMem[pOp->p3]; + assert( (u.by.pnErr->flags & MEM_Int)!=0 ); + assert( (u.by.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); pIn1 = &aMem[pOp->p1]; - for(u.bv.j=0; u.bv.j<u.bv.nRoot; u.bv.j++){ - u.bv.aRoot[u.bv.j] = (int)sqlite3VdbeIntValue(&pIn1[u.bv.j]); + for(u.by.j=0; u.by.j<u.by.nRoot; u.by.j++){ + u.by.aRoot[u.by.j] = (int)sqlite3VdbeIntValue(&pIn1[u.by.j]); } - u.bv.aRoot[u.bv.j] = 0; + u.by.aRoot[u.by.j] = 0; assert( pOp->p5<db->nDb ); - assert( (p->btreeMask & (1<<pOp->p5))!=0 ); - u.bv.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.bv.aRoot, u.bv.nRoot, - (int)u.bv.pnErr->u.i, &u.bv.nErr); - sqlite3DbFree(db, u.bv.aRoot); - u.bv.pnErr->u.i -= u.bv.nErr; + assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); + u.by.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.by.aRoot, u.by.nRoot, + (int)u.by.pnErr->u.i, &u.by.nErr); + sqlite3DbFree(db, u.by.aRoot); + u.by.pnErr->u.i -= u.by.nErr; sqlite3VdbeMemSetNull(pIn1); - if( u.bv.nErr==0 ){ - assert( u.bv.z==0 ); - }else if( u.bv.z==0 ){ + if( u.by.nErr==0 ){ + assert( u.by.z==0 ); + }else if( u.by.z==0 ){ goto no_mem; }else{ - sqlite3VdbeMemSetStr(pIn1, u.bv.z, -1, SQLITE_UTF8, sqlite3_free); + sqlite3VdbeMemSetStr(pIn1, u.by.z, -1, SQLITE_UTF8, sqlite3_free); } UPDATE_MAX_BLOBSIZE(pIn1); sqlite3VdbeChangeEncoding(pIn1, encoding); @@ -58104,20 +68587,20 @@ case OP_RowSetAdd: { /* in1, in2 */ ** unchanged and jump to instruction P2. */ case OP_RowSetRead: { /* jump, in1, out3 */ -#if 0 /* local variables moved into u.bw */ +#if 0 /* local variables moved into u.bz */ i64 val; -#endif /* local variables moved into u.bw */ +#endif /* local variables moved into u.bz */ CHECK_FOR_INTERRUPT; pIn1 = &aMem[pOp->p1]; if( (pIn1->flags & MEM_RowSet)==0 - || sqlite3RowSetNext(pIn1->u.pRowSet, &u.bw.val)==0 + || sqlite3RowSetNext(pIn1->u.pRowSet, &u.bz.val)==0 ){ /* The boolean index is empty */ sqlite3VdbeMemSetNull(pIn1); pc = pOp->p2 - 1; }else{ /* A value was pulled from the index */ - sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.bw.val); + sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.bz.val); } break; } @@ -58146,14 +68629,14 @@ case OP_RowSetRead: { /* jump, in1, out3 */ ** inserted as part of some other set). */ case OP_RowSetTest: { /* jump, in1, in3 */ -#if 0 /* local variables moved into u.bx */ +#if 0 /* local variables moved into u.ca */ int iSet; int exists; -#endif /* local variables moved into u.bx */ +#endif /* local variables moved into u.ca */ pIn1 = &aMem[pOp->p1]; pIn3 = &aMem[pOp->p3]; - u.bx.iSet = pOp->p4.i; + u.ca.iSet = pOp->p4.i; assert( pIn3->flags&MEM_Int ); /* If there is anything other than a rowset object in memory cell P1, @@ -58165,17 +68648,17 @@ case OP_RowSetTest: { /* jump, in1, in3 */ } assert( pOp->p4type==P4_INT32 ); - assert( u.bx.iSet==-1 || u.bx.iSet>=0 ); - if( u.bx.iSet ){ - u.bx.exists = sqlite3RowSetTest(pIn1->u.pRowSet, - (u8)(u.bx.iSet>=0 ? u.bx.iSet & 0xf : 0xff), + assert( u.ca.iSet==-1 || u.ca.iSet>=0 ); + if( u.ca.iSet ){ + u.ca.exists = sqlite3RowSetTest(pIn1->u.pRowSet, + (u8)(u.ca.iSet>=0 ? u.ca.iSet & 0xf : 0xff), pIn3->u.i); - if( u.bx.exists ){ + if( u.ca.exists ){ pc = pOp->p2 - 1; break; } } - if( u.bx.iSet>=0 ){ + if( u.ca.iSet>=0 ){ sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); } break; @@ -58186,19 +68669,19 @@ case OP_RowSetTest: { /* jump, in1, in3 */ /* Opcode: Program P1 P2 P3 P4 * ** -** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). +** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). ** -** P1 contains the address of the memory cell that contains the first memory -** cell in an array of values used as arguments to the sub-program. P2 -** contains the address to jump to if the sub-program throws an IGNORE -** exception using the RAISE() function. Register P3 contains the address -** of a memory cell in this (the parent) VM that is used to allocate the +** P1 contains the address of the memory cell that contains the first memory +** cell in an array of values used as arguments to the sub-program. P2 +** contains the address to jump to if the sub-program throws an IGNORE +** exception using the RAISE() function. Register P3 contains the address +** of a memory cell in this (the parent) VM that is used to allocate the ** memory required by the sub-vdbe at runtime. ** ** P4 is a pointer to the VM containing the trigger program. */ case OP_Program: { /* jump */ -#if 0 /* local variables moved into u.by */ +#if 0 /* local variables moved into u.cb */ int nMem; /* Number of memory registers for sub-program */ int nByte; /* Bytes of runtime space required for sub-program */ Mem *pRt; /* Register to allocate runtime space */ @@ -58207,11 +68690,12 @@ case OP_Program: { /* jump */ VdbeFrame *pFrame; /* New vdbe frame to execute in */ SubProgram *pProgram; /* Sub-program to execute */ void *t; /* Token identifying trigger */ -#endif /* local variables moved into u.by */ +#endif /* local variables moved into u.cb */ - u.by.pProgram = pOp->p4.pProgram; - u.by.pRt = &aMem[pOp->p3]; - assert( u.by.pProgram->nOp>0 ); + u.cb.pProgram = pOp->p4.pProgram; + u.cb.pRt = &aMem[pOp->p3]; + assert( memIsValid(u.cb.pRt) ); + assert( u.cb.pProgram->nOp>0 ); /* If the p5 flag is clear, then recursive invocation of triggers is ** disabled for backwards compatibility (p5 is set if this sub-program @@ -58225,9 +68709,9 @@ case OP_Program: { /* jump */ ** single trigger all have the same value for the SubProgram.token ** variable. */ if( pOp->p5 ){ - u.by.t = u.by.pProgram->token; - for(u.by.pFrame=p->pFrame; u.by.pFrame && u.by.pFrame->token!=u.by.t; u.by.pFrame=u.by.pFrame->pParent); - if( u.by.pFrame ) break; + u.cb.t = u.cb.pProgram->token; + for(u.cb.pFrame=p->pFrame; u.cb.pFrame && u.cb.pFrame->token!=u.cb.t; u.cb.pFrame=u.cb.pFrame->pParent); + if( u.cb.pFrame ) break; } if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ @@ -58236,64 +68720,64 @@ case OP_Program: { /* jump */ break; } - /* Register u.by.pRt is used to store the memory required to save the state + /* Register u.cb.pRt is used to store the memory required to save the state ** of the current program, and the memory required at runtime to execute - ** the trigger program. If this trigger has been fired before, then u.by.pRt + ** the trigger program. If this trigger has been fired before, then u.cb.pRt ** is already allocated. Otherwise, it must be initialized. */ - if( (u.by.pRt->flags&MEM_Frame)==0 ){ + if( (u.cb.pRt->flags&MEM_Frame)==0 ){ /* SubProgram.nMem is set to the number of memory cells used by the ** program stored in SubProgram.aOp. As well as these, one memory ** cell is required for each cursor used by the program. Set local - ** variable u.by.nMem (and later, VdbeFrame.nChildMem) to this value. + ** variable u.cb.nMem (and later, VdbeFrame.nChildMem) to this value. */ - u.by.nMem = u.by.pProgram->nMem + u.by.pProgram->nCsr; - u.by.nByte = ROUND8(sizeof(VdbeFrame)) - + u.by.nMem * sizeof(Mem) - + u.by.pProgram->nCsr * sizeof(VdbeCursor *); - u.by.pFrame = sqlite3DbMallocZero(db, u.by.nByte); - if( !u.by.pFrame ){ + u.cb.nMem = u.cb.pProgram->nMem + u.cb.pProgram->nCsr; + u.cb.nByte = ROUND8(sizeof(VdbeFrame)) + + u.cb.nMem * sizeof(Mem) + + u.cb.pProgram->nCsr * sizeof(VdbeCursor *); + u.cb.pFrame = sqlite3DbMallocZero(db, u.cb.nByte); + if( !u.cb.pFrame ){ goto no_mem; } - sqlite3VdbeMemRelease(u.by.pRt); - u.by.pRt->flags = MEM_Frame; - u.by.pRt->u.pFrame = u.by.pFrame; - - u.by.pFrame->v = p; - u.by.pFrame->nChildMem = u.by.nMem; - u.by.pFrame->nChildCsr = u.by.pProgram->nCsr; - u.by.pFrame->pc = pc; - u.by.pFrame->aMem = p->aMem; - u.by.pFrame->nMem = p->nMem; - u.by.pFrame->apCsr = p->apCsr; - u.by.pFrame->nCursor = p->nCursor; - u.by.pFrame->aOp = p->aOp; - u.by.pFrame->nOp = p->nOp; - u.by.pFrame->token = u.by.pProgram->token; - - u.by.pEnd = &VdbeFrameMem(u.by.pFrame)[u.by.pFrame->nChildMem]; - for(u.by.pMem=VdbeFrameMem(u.by.pFrame); u.by.pMem!=u.by.pEnd; u.by.pMem++){ - u.by.pMem->flags = MEM_Null; - u.by.pMem->db = db; + sqlite3VdbeMemRelease(u.cb.pRt); + u.cb.pRt->flags = MEM_Frame; + u.cb.pRt->u.pFrame = u.cb.pFrame; + + u.cb.pFrame->v = p; + u.cb.pFrame->nChildMem = u.cb.nMem; + u.cb.pFrame->nChildCsr = u.cb.pProgram->nCsr; + u.cb.pFrame->pc = pc; + u.cb.pFrame->aMem = p->aMem; + u.cb.pFrame->nMem = p->nMem; + u.cb.pFrame->apCsr = p->apCsr; + u.cb.pFrame->nCursor = p->nCursor; + u.cb.pFrame->aOp = p->aOp; + u.cb.pFrame->nOp = p->nOp; + u.cb.pFrame->token = u.cb.pProgram->token; + + u.cb.pEnd = &VdbeFrameMem(u.cb.pFrame)[u.cb.pFrame->nChildMem]; + for(u.cb.pMem=VdbeFrameMem(u.cb.pFrame); u.cb.pMem!=u.cb.pEnd; u.cb.pMem++){ + u.cb.pMem->flags = MEM_Null; + u.cb.pMem->db = db; } }else{ - u.by.pFrame = u.by.pRt->u.pFrame; - assert( u.by.pProgram->nMem+u.by.pProgram->nCsr==u.by.pFrame->nChildMem ); - assert( u.by.pProgram->nCsr==u.by.pFrame->nChildCsr ); - assert( pc==u.by.pFrame->pc ); + u.cb.pFrame = u.cb.pRt->u.pFrame; + assert( u.cb.pProgram->nMem+u.cb.pProgram->nCsr==u.cb.pFrame->nChildMem ); + assert( u.cb.pProgram->nCsr==u.cb.pFrame->nChildCsr ); + assert( pc==u.cb.pFrame->pc ); } p->nFrame++; - u.by.pFrame->pParent = p->pFrame; - u.by.pFrame->lastRowid = db->lastRowid; - u.by.pFrame->nChange = p->nChange; + u.cb.pFrame->pParent = p->pFrame; + u.cb.pFrame->lastRowid = lastRowid; + u.cb.pFrame->nChange = p->nChange; p->nChange = 0; - p->pFrame = u.by.pFrame; - p->aMem = aMem = &VdbeFrameMem(u.by.pFrame)[-1]; - p->nMem = u.by.pFrame->nChildMem; - p->nCursor = (u16)u.by.pFrame->nChildCsr; + p->pFrame = u.cb.pFrame; + p->aMem = aMem = &VdbeFrameMem(u.cb.pFrame)[-1]; + p->nMem = u.cb.pFrame->nChildMem; + p->nCursor = (u16)u.cb.pFrame->nChildCsr; p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; - p->aOp = aOp = u.by.pProgram->aOp; - p->nOp = u.by.pProgram->nOp; + p->aOp = aOp = u.cb.pProgram->aOp; + p->nOp = u.cb.pProgram->nOp; pc = -1; break; @@ -58301,10 +68785,10 @@ case OP_Program: { /* jump */ /* Opcode: Param P1 P2 * * * ** -** This opcode is only ever present in sub-programs called via the -** OP_Program instruction. Copy a value currently stored in a memory -** cell of the calling (parent) frame to cell P2 in the current frames -** address space. This is used by trigger programs to access the new.* +** This opcode is only ever present in sub-programs called via the +** OP_Program instruction. Copy a value currently stored in a memory +** cell of the calling (parent) frame to cell P2 in the current frames +** address space. This is used by trigger programs to access the new.* ** and old.* values. ** ** The address of the cell in the parent frame is determined by adding @@ -58312,13 +68796,13 @@ case OP_Program: { /* jump */ ** calling OP_Program instruction. */ case OP_Param: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bz */ +#if 0 /* local variables moved into u.cc */ VdbeFrame *pFrame; Mem *pIn; -#endif /* local variables moved into u.bz */ - u.bz.pFrame = p->pFrame; - u.bz.pIn = &u.bz.pFrame->aMem[pOp->p1 + u.bz.pFrame->aOp[u.bz.pFrame->pc].p1]; - sqlite3VdbeMemShallowCopy(pOut, u.bz.pIn, MEM_Ephem); +#endif /* local variables moved into u.cc */ + u.cc.pFrame = p->pFrame; + u.cc.pIn = &u.cc.pFrame->aMem[pOp->p1 + u.cc.pFrame->aOp[u.cc.pFrame->pc].p1]; + sqlite3VdbeMemShallowCopy(pOut, u.cc.pIn, MEM_Ephem); break; } @@ -58328,8 +68812,8 @@ case OP_Param: { /* out2-prerelease */ /* Opcode: FkCounter P1 P2 * * * ** ** Increment a "constraint counter" by P2 (P2 may be negative or positive). -** If P1 is non-zero, the database constraint counter is incremented -** (deferred foreign key constraints). Otherwise, if P1 is zero, the +** If P1 is non-zero, the database constraint counter is incremented +** (deferred foreign key constraints). Otherwise, if P1 is zero, the ** statement counter is incremented (immediate foreign key constraints). */ case OP_FkCounter: { @@ -58344,7 +68828,7 @@ case OP_FkCounter: { /* Opcode: FkIfZero P1 P2 * * * ** ** This opcode tests if a foreign key constraint-counter is currently zero. -** If so, jump to instruction P2. Otherwise, fall through to the next +** If so, jump to instruction P2. Otherwise, fall through to the next ** instruction. ** ** If P1 is non-zero, then the jump is taken if the database constraint-counter @@ -58367,28 +68851,29 @@ case OP_FkIfZero: { /* jump */ ** ** P1 is a register in the root frame of this VM (the root frame is ** different from the current frame if this instruction is being executed -** within a sub-program). Set the value of register P1 to the maximum of +** within a sub-program). Set the value of register P1 to the maximum of ** its current value and the value in register P2. ** ** This instruction throws an error if the memory cell is not initially ** an integer. */ case OP_MemMax: { /* in2 */ -#if 0 /* local variables moved into u.ca */ +#if 0 /* local variables moved into u.cd */ Mem *pIn1; VdbeFrame *pFrame; -#endif /* local variables moved into u.ca */ +#endif /* local variables moved into u.cd */ if( p->pFrame ){ - for(u.ca.pFrame=p->pFrame; u.ca.pFrame->pParent; u.ca.pFrame=u.ca.pFrame->pParent); - u.ca.pIn1 = &u.ca.pFrame->aMem[pOp->p1]; + for(u.cd.pFrame=p->pFrame; u.cd.pFrame->pParent; u.cd.pFrame=u.cd.pFrame->pParent); + u.cd.pIn1 = &u.cd.pFrame->aMem[pOp->p1]; }else{ - u.ca.pIn1 = &aMem[pOp->p1]; + u.cd.pIn1 = &aMem[pOp->p1]; } - sqlite3VdbeMemIntegerify(u.ca.pIn1); + assert( memIsValid(u.cd.pIn1) ); + sqlite3VdbeMemIntegerify(u.cd.pIn1); pIn2 = &aMem[pOp->p2]; sqlite3VdbeMemIntegerify(pIn2); - if( u.ca.pIn1->u.i<pIn2->u.i){ - u.ca.pIn1->u.i = pIn2->u.i; + if( u.cd.pIn1->u.i<pIn2->u.i){ + u.cd.pIn1->u.i = pIn2->u.i; } break; } @@ -58412,7 +68897,7 @@ case OP_IfPos: { /* jump, in1 */ /* Opcode: IfNeg P1 P2 * * * ** -** If the value of register P1 is less than zero, jump to P2. +** If the value of register P1 is less than zero, jump to P2. ** ** It is illegal to use this instruction on a register that does ** not contain an integer. An assertion fault will result if you try. @@ -58429,7 +68914,7 @@ case OP_IfNeg: { /* jump, in1 */ /* Opcode: IfZero P1 P2 P3 * * ** ** The register P1 must contain an integer. Add literal P3 to the -** value in register P1. If the result is exactly 0, jump to P2. +** value in register P1. If the result is exactly 0, jump to P2. ** ** It is illegal to use this instruction on a register that does ** not contain an integer. An assertion fault will result if you try. @@ -58455,47 +68940,51 @@ case OP_IfZero: { /* jump, in1 */ ** successors. */ case OP_AggStep: { -#if 0 /* local variables moved into u.cb */ +#if 0 /* local variables moved into u.ce */ int n; int i; Mem *pMem; Mem *pRec; sqlite3_context ctx; sqlite3_value **apVal; -#endif /* local variables moved into u.cb */ +#endif /* local variables moved into u.ce */ - u.cb.n = pOp->p5; - assert( u.cb.n>=0 ); - u.cb.pRec = &aMem[pOp->p2]; - u.cb.apVal = p->apArg; - assert( u.cb.apVal || u.cb.n==0 ); - for(u.cb.i=0; u.cb.i<u.cb.n; u.cb.i++, u.cb.pRec++){ - u.cb.apVal[u.cb.i] = u.cb.pRec; - sqlite3VdbeMemStoreType(u.cb.pRec); - } - u.cb.ctx.pFunc = pOp->p4.pFunc; + u.ce.n = pOp->p5; + assert( u.ce.n>=0 ); + u.ce.pRec = &aMem[pOp->p2]; + u.ce.apVal = p->apArg; + assert( u.ce.apVal || u.ce.n==0 ); + for(u.ce.i=0; u.ce.i<u.ce.n; u.ce.i++, u.ce.pRec++){ + assert( memIsValid(u.ce.pRec) ); + u.ce.apVal[u.ce.i] = u.ce.pRec; + memAboutToChange(p, u.ce.pRec); + sqlite3VdbeMemStoreType(u.ce.pRec); + } + u.ce.ctx.pFunc = pOp->p4.pFunc; assert( pOp->p3>0 && pOp->p3<=p->nMem ); - u.cb.ctx.pMem = u.cb.pMem = &aMem[pOp->p3]; - u.cb.pMem->n++; - u.cb.ctx.s.flags = MEM_Null; - u.cb.ctx.s.z = 0; - u.cb.ctx.s.zMalloc = 0; - u.cb.ctx.s.xDel = 0; - u.cb.ctx.s.db = db; - u.cb.ctx.isError = 0; - u.cb.ctx.pColl = 0; - if( u.cb.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ + u.ce.ctx.pMem = u.ce.pMem = &aMem[pOp->p3]; + u.ce.pMem->n++; + u.ce.ctx.s.flags = MEM_Null; + u.ce.ctx.s.z = 0; + u.ce.ctx.s.zMalloc = 0; + u.ce.ctx.s.xDel = 0; + u.ce.ctx.s.db = db; + u.ce.ctx.isError = 0; + u.ce.ctx.pColl = 0; + if( u.ce.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ assert( pOp>p->aOp ); assert( pOp[-1].p4type==P4_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); - u.cb.ctx.pColl = pOp[-1].p4.pColl; + u.ce.ctx.pColl = pOp[-1].p4.pColl; } - (u.cb.ctx.pFunc->xStep)(&u.cb.ctx, u.cb.n, u.cb.apVal); - if( u.cb.ctx.isError ){ - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cb.ctx.s)); - rc = u.cb.ctx.isError; + (u.ce.ctx.pFunc->xStep)(&u.ce.ctx, u.ce.n, u.ce.apVal); /* IMP: R-24505-23230 */ + if( u.ce.ctx.isError ){ + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ce.ctx.s)); + rc = u.ce.ctx.isError; } - sqlite3VdbeMemRelease(&u.cb.ctx.s); + + sqlite3VdbeMemRelease(&u.ce.ctx.s); + break; } @@ -58512,24 +69001,165 @@ case OP_AggStep: { ** the step function was not previously called. */ case OP_AggFinal: { -#if 0 /* local variables moved into u.cc */ +#if 0 /* local variables moved into u.cf */ Mem *pMem; -#endif /* local variables moved into u.cc */ +#endif /* local variables moved into u.cf */ assert( pOp->p1>0 && pOp->p1<=p->nMem ); - u.cc.pMem = &aMem[pOp->p1]; - assert( (u.cc.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); - rc = sqlite3VdbeMemFinalize(u.cc.pMem, pOp->p4.pFunc); + u.cf.pMem = &aMem[pOp->p1]; + assert( (u.cf.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); + rc = sqlite3VdbeMemFinalize(u.cf.pMem, pOp->p4.pFunc); if( rc ){ - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cc.pMem)); + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cf.pMem)); } - sqlite3VdbeChangeEncoding(u.cc.pMem, encoding); - UPDATE_MAX_BLOBSIZE(u.cc.pMem); - if( sqlite3VdbeMemTooBig(u.cc.pMem) ){ + sqlite3VdbeChangeEncoding(u.cf.pMem, encoding); + UPDATE_MAX_BLOBSIZE(u.cf.pMem); + if( sqlite3VdbeMemTooBig(u.cf.pMem) ){ goto too_big; } break; } +#ifndef SQLITE_OMIT_WAL +/* Opcode: Checkpoint P1 P2 P3 * * +** +** Checkpoint database P1. This is a no-op if P1 is not currently in +** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL +** or RESTART. Write 1 or 0 into mem[P3] if the checkpoint returns +** SQLITE_BUSY or not, respectively. Write the number of pages in the +** WAL after the checkpoint into mem[P3+1] and the number of pages +** in the WAL that have been checkpointed after the checkpoint +** completes into mem[P3+2]. However on an error, mem[P3+1] and +** mem[P3+2] are initialized to -1. +*/ +case OP_Checkpoint: { +#if 0 /* local variables moved into u.cg */ + int i; /* Loop counter */ + int aRes[3]; /* Results */ + Mem *pMem; /* Write results here */ +#endif /* local variables moved into u.cg */ + + u.cg.aRes[0] = 0; + u.cg.aRes[1] = u.cg.aRes[2] = -1; + assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE + || pOp->p2==SQLITE_CHECKPOINT_FULL + || pOp->p2==SQLITE_CHECKPOINT_RESTART + ); + rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.cg.aRes[1], &u.cg.aRes[2]); + if( rc==SQLITE_BUSY ){ + rc = SQLITE_OK; + u.cg.aRes[0] = 1; + } + for(u.cg.i=0, u.cg.pMem = &aMem[pOp->p3]; u.cg.i<3; u.cg.i++, u.cg.pMem++){ + sqlite3VdbeMemSetInt64(u.cg.pMem, (i64)u.cg.aRes[u.cg.i]); + } + break; +}; +#endif + +#ifndef SQLITE_OMIT_PRAGMA +/* Opcode: JournalMode P1 P2 P3 * P5 +** +** Change the journal mode of database P1 to P3. P3 must be one of the +** PAGER_JOURNALMODE_XXX values. If changing between the various rollback +** modes (delete, truncate, persist, off and memory), this is a simple +** operation. No IO is required. +** +** If changing into or out of WAL mode the procedure is more complicated. +** +** Write a string containing the final journal-mode to register P2. +*/ +case OP_JournalMode: { /* out2-prerelease */ +#if 0 /* local variables moved into u.ch */ + Btree *pBt; /* Btree to change journal mode of */ + Pager *pPager; /* Pager associated with pBt */ + int eNew; /* New journal mode */ + int eOld; /* The old journal mode */ + const char *zFilename; /* Name of database file for pPager */ +#endif /* local variables moved into u.ch */ + + u.ch.eNew = pOp->p3; + assert( u.ch.eNew==PAGER_JOURNALMODE_DELETE + || u.ch.eNew==PAGER_JOURNALMODE_TRUNCATE + || u.ch.eNew==PAGER_JOURNALMODE_PERSIST + || u.ch.eNew==PAGER_JOURNALMODE_OFF + || u.ch.eNew==PAGER_JOURNALMODE_MEMORY + || u.ch.eNew==PAGER_JOURNALMODE_WAL + || u.ch.eNew==PAGER_JOURNALMODE_QUERY + ); + assert( pOp->p1>=0 && pOp->p1<db->nDb ); + + u.ch.pBt = db->aDb[pOp->p1].pBt; + u.ch.pPager = sqlite3BtreePager(u.ch.pBt); + u.ch.eOld = sqlite3PagerGetJournalMode(u.ch.pPager); + if( u.ch.eNew==PAGER_JOURNALMODE_QUERY ) u.ch.eNew = u.ch.eOld; + if( !sqlite3PagerOkToChangeJournalMode(u.ch.pPager) ) u.ch.eNew = u.ch.eOld; + +#ifndef SQLITE_OMIT_WAL + u.ch.zFilename = sqlite3PagerFilename(u.ch.pPager); + + /* Do not allow a transition to journal_mode=WAL for a database + ** in temporary storage or if the VFS does not support shared memory + */ + if( u.ch.eNew==PAGER_JOURNALMODE_WAL + && (u.ch.zFilename[0]==0 /* Temp file */ + || !sqlite3PagerWalSupported(u.ch.pPager)) /* No shared-memory support */ + ){ + u.ch.eNew = u.ch.eOld; + } + + if( (u.ch.eNew!=u.ch.eOld) + && (u.ch.eOld==PAGER_JOURNALMODE_WAL || u.ch.eNew==PAGER_JOURNALMODE_WAL) + ){ + if( !db->autoCommit || db->activeVdbeCnt>1 ){ + rc = SQLITE_ERROR; + sqlite3SetString(&p->zErrMsg, db, + "cannot change %s wal mode from within a transaction", + (u.ch.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") + ); + break; + }else{ + + if( u.ch.eOld==PAGER_JOURNALMODE_WAL ){ + /* If leaving WAL mode, close the log file. If successful, the call + ** to PagerCloseWal() checkpoints and deletes the write-ahead-log + ** file. An EXCLUSIVE lock may still be held on the database file + ** after a successful return. + */ + rc = sqlite3PagerCloseWal(u.ch.pPager); + if( rc==SQLITE_OK ){ + sqlite3PagerSetJournalMode(u.ch.pPager, u.ch.eNew); + } + }else if( u.ch.eOld==PAGER_JOURNALMODE_MEMORY ){ + /* Cannot transition directly from MEMORY to WAL. Use mode OFF + ** as an intermediate */ + sqlite3PagerSetJournalMode(u.ch.pPager, PAGER_JOURNALMODE_OFF); + } + + /* Open a transaction on the database file. Regardless of the journal + ** mode, this transaction always uses a rollback journal. + */ + assert( sqlite3BtreeIsInTrans(u.ch.pBt)==0 ); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeSetVersion(u.ch.pBt, (u.ch.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); + } + } + } +#endif /* ifndef SQLITE_OMIT_WAL */ + + if( rc ){ + u.ch.eNew = u.ch.eOld; + } + u.ch.eNew = sqlite3PagerSetJournalMode(u.ch.pPager, u.ch.eNew); + + pOut = &aMem[pOp->p2]; + pOut->flags = MEM_Str|MEM_Static|MEM_Term; + pOut->z = (char *)sqlite3JournalModename(u.ch.eNew); + pOut->n = sqlite3Strlen30(pOut->z); + pOut->enc = SQLITE_UTF8; + sqlite3VdbeChangeEncoding(pOut, encoding); + break; +}; +#endif /* SQLITE_OMIT_PRAGMA */ #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) /* Opcode: Vacuum * * * * * @@ -58552,14 +69182,14 @@ case OP_Vacuum: { ** P2. Otherwise, fall through to the next instruction. */ case OP_IncrVacuum: { /* jump */ -#if 0 /* local variables moved into u.cd */ +#if 0 /* local variables moved into u.ci */ Btree *pBt; -#endif /* local variables moved into u.cd */ +#endif /* local variables moved into u.ci */ assert( pOp->p1>=0 && pOp->p1<db->nDb ); - assert( (p->btreeMask & (1<<pOp->p1))!=0 ); - u.cd.pBt = db->aDb[pOp->p1].pBt; - rc = sqlite3BtreeIncrVacuum(u.cd.pBt); + assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); + u.ci.pBt = db->aDb[pOp->p1].pBt; + rc = sqlite3BtreeIncrVacuum(u.ci.pBt); if( rc==SQLITE_DONE ){ pc = pOp->p2 - 1; rc = SQLITE_OK; @@ -58571,11 +69201,11 @@ case OP_IncrVacuum: { /* jump */ /* Opcode: Expire P1 * * * * ** ** Cause precompiled statements to become expired. An expired statement -** fails with an error code of SQLITE_SCHEMA if it is ever executed +** fails with an error code of SQLITE_SCHEMA if it is ever executed ** (via sqlite3_step()). -** +** ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, -** then only the currently executing statement is affected. +** then only the currently executing statement is affected. */ case OP_Expire: { if( !pOp->p1 ){ @@ -58590,7 +69220,7 @@ case OP_Expire: { /* Opcode: TableLock P1 P2 P3 P4 * ** ** Obtain a lock on a particular table. This instruction is only used when -** the shared-cache feature is enabled. +** the shared-cache feature is enabled. ** ** P1 is the index of the database in sqlite3.aDb[] of the database ** on which the lock is acquired. A readlock is obtained if P3==0 or @@ -58604,9 +69234,9 @@ case OP_Expire: { case OP_TableLock: { u8 isWriteLock = (u8)pOp->p3; if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ - int p1 = pOp->p1; + int p1 = pOp->p1; assert( p1>=0 && p1<db->nDb ); - assert( (p->btreeMask & (1<<p1))!=0 ); + assert( (p->btreeMask & (((yDbMask)1)<<p1))!=0 ); assert( isWriteLock==0 || isWriteLock==1 ); rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); if( (rc&0xFF)==SQLITE_LOCKED ){ @@ -58621,7 +69251,7 @@ case OP_TableLock: { #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VBegin * * * P4 * ** -** P4 may be a pointer to an sqlite3_vtab structure. If so, call the +** P4 may be a pointer to an sqlite3_vtab structure. If so, call the ** xBegin method for that table. ** ** Also, whether or not P4 is set, check that this is not being called from @@ -58629,16 +69259,12 @@ case OP_TableLock: { ** code will be set to SQLITE_LOCKED. */ case OP_VBegin: { -#if 0 /* local variables moved into u.ce */ +#if 0 /* local variables moved into u.cj */ VTable *pVTab; -#endif /* local variables moved into u.ce */ - u.ce.pVTab = pOp->p4.pVtab; - rc = sqlite3VtabBegin(db, u.ce.pVTab); - if( u.ce.pVTab ){ - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.ce.pVTab->pVtab->zErrMsg; - u.ce.pVTab->pVtab->zErrMsg = 0; - } +#endif /* local variables moved into u.cj */ + u.cj.pVTab = pOp->p4.pVtab; + rc = sqlite3VtabBegin(db, u.cj.pVTab); + if( u.cj.pVTab ) importVtabErrMsg(p, u.cj.pVTab->pVtab); break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -58677,34 +69303,32 @@ case OP_VDestroy: { ** table and stores that cursor in P1. */ case OP_VOpen: { -#if 0 /* local variables moved into u.cf */ +#if 0 /* local variables moved into u.ck */ VdbeCursor *pCur; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; sqlite3_module *pModule; -#endif /* local variables moved into u.cf */ +#endif /* local variables moved into u.ck */ - u.cf.pCur = 0; - u.cf.pVtabCursor = 0; - u.cf.pVtab = pOp->p4.pVtab->pVtab; - u.cf.pModule = (sqlite3_module *)u.cf.pVtab->pModule; - assert(u.cf.pVtab && u.cf.pModule); - rc = u.cf.pModule->xOpen(u.cf.pVtab, &u.cf.pVtabCursor); - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.cf.pVtab->zErrMsg; - u.cf.pVtab->zErrMsg = 0; + u.ck.pCur = 0; + u.ck.pVtabCursor = 0; + u.ck.pVtab = pOp->p4.pVtab->pVtab; + u.ck.pModule = (sqlite3_module *)u.ck.pVtab->pModule; + assert(u.ck.pVtab && u.ck.pModule); + rc = u.ck.pModule->xOpen(u.ck.pVtab, &u.ck.pVtabCursor); + importVtabErrMsg(p, u.ck.pVtab); if( SQLITE_OK==rc ){ /* Initialize sqlite3_vtab_cursor base class */ - u.cf.pVtabCursor->pVtab = u.cf.pVtab; + u.ck.pVtabCursor->pVtab = u.ck.pVtab; /* Initialise vdbe cursor object */ - u.cf.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); - if( u.cf.pCur ){ - u.cf.pCur->pVtabCursor = u.cf.pVtabCursor; - u.cf.pCur->pModule = u.cf.pVtabCursor->pVtab->pModule; + u.ck.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); + if( u.ck.pCur ){ + u.ck.pCur->pVtabCursor = u.ck.pVtabCursor; + u.ck.pCur->pModule = u.ck.pVtabCursor->pVtab->pModule; }else{ db->mallocFailed = 1; - u.cf.pModule->xClose(u.cf.pVtabCursor); + u.ck.pModule->xClose(u.ck.pVtabCursor); } } break; @@ -58731,7 +69355,7 @@ case OP_VOpen: { ** A jump is made to P2 if the result set after filtering would be empty. */ case OP_VFilter: { /* jump */ -#if 0 /* local variables moved into u.cg */ +#if 0 /* local variables moved into u.cl */ int nArg; int iQuery; const sqlite3_module *pModule; @@ -58743,46 +69367,45 @@ case OP_VFilter: { /* jump */ int res; int i; Mem **apArg; -#endif /* local variables moved into u.cg */ +#endif /* local variables moved into u.cl */ - u.cg.pQuery = &aMem[pOp->p3]; - u.cg.pArgc = &u.cg.pQuery[1]; - u.cg.pCur = p->apCsr[pOp->p1]; - REGISTER_TRACE(pOp->p3, u.cg.pQuery); - assert( u.cg.pCur->pVtabCursor ); - u.cg.pVtabCursor = u.cg.pCur->pVtabCursor; - u.cg.pVtab = u.cg.pVtabCursor->pVtab; - u.cg.pModule = u.cg.pVtab->pModule; + u.cl.pQuery = &aMem[pOp->p3]; + u.cl.pArgc = &u.cl.pQuery[1]; + u.cl.pCur = p->apCsr[pOp->p1]; + assert( memIsValid(u.cl.pQuery) ); + REGISTER_TRACE(pOp->p3, u.cl.pQuery); + assert( u.cl.pCur->pVtabCursor ); + u.cl.pVtabCursor = u.cl.pCur->pVtabCursor; + u.cl.pVtab = u.cl.pVtabCursor->pVtab; + u.cl.pModule = u.cl.pVtab->pModule; /* Grab the index number and argc parameters */ - assert( (u.cg.pQuery->flags&MEM_Int)!=0 && u.cg.pArgc->flags==MEM_Int ); - u.cg.nArg = (int)u.cg.pArgc->u.i; - u.cg.iQuery = (int)u.cg.pQuery->u.i; + assert( (u.cl.pQuery->flags&MEM_Int)!=0 && u.cl.pArgc->flags==MEM_Int ); + u.cl.nArg = (int)u.cl.pArgc->u.i; + u.cl.iQuery = (int)u.cl.pQuery->u.i; /* Invoke the xFilter method */ { - u.cg.res = 0; - u.cg.apArg = p->apArg; - for(u.cg.i = 0; u.cg.i<u.cg.nArg; u.cg.i++){ - u.cg.apArg[u.cg.i] = &u.cg.pArgc[u.cg.i+1]; - sqlite3VdbeMemStoreType(u.cg.apArg[u.cg.i]); + u.cl.res = 0; + u.cl.apArg = p->apArg; + for(u.cl.i = 0; u.cl.i<u.cl.nArg; u.cl.i++){ + u.cl.apArg[u.cl.i] = &u.cl.pArgc[u.cl.i+1]; + sqlite3VdbeMemStoreType(u.cl.apArg[u.cl.i]); } p->inVtabMethod = 1; - rc = u.cg.pModule->xFilter(u.cg.pVtabCursor, u.cg.iQuery, pOp->p4.z, u.cg.nArg, u.cg.apArg); + rc = u.cl.pModule->xFilter(u.cl.pVtabCursor, u.cl.iQuery, pOp->p4.z, u.cl.nArg, u.cl.apArg); p->inVtabMethod = 0; - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.cg.pVtab->zErrMsg; - u.cg.pVtab->zErrMsg = 0; + importVtabErrMsg(p, u.cl.pVtab); if( rc==SQLITE_OK ){ - u.cg.res = u.cg.pModule->xEof(u.cg.pVtabCursor); + u.cl.res = u.cl.pModule->xEof(u.cl.pVtabCursor); } - if( u.cg.res ){ + if( u.cl.res ){ pc = pOp->p2 - 1; } } - u.cg.pCur->nullRow = 0; + u.cl.pCur->nullRow = 0; break; } @@ -58792,56 +69415,55 @@ case OP_VFilter: { /* jump */ /* Opcode: VColumn P1 P2 P3 * * ** ** Store the value of the P2-th column of -** the row of the virtual-table that the +** the row of the virtual-table that the ** P1 cursor is pointing to into register P3. */ case OP_VColumn: { -#if 0 /* local variables moved into u.ch */ +#if 0 /* local variables moved into u.cm */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; -#endif /* local variables moved into u.ch */ +#endif /* local variables moved into u.cm */ VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); - u.ch.pDest = &aMem[pOp->p3]; + u.cm.pDest = &aMem[pOp->p3]; + memAboutToChange(p, u.cm.pDest); if( pCur->nullRow ){ - sqlite3VdbeMemSetNull(u.ch.pDest); + sqlite3VdbeMemSetNull(u.cm.pDest); break; } - u.ch.pVtab = pCur->pVtabCursor->pVtab; - u.ch.pModule = u.ch.pVtab->pModule; - assert( u.ch.pModule->xColumn ); - memset(&u.ch.sContext, 0, sizeof(u.ch.sContext)); + u.cm.pVtab = pCur->pVtabCursor->pVtab; + u.cm.pModule = u.cm.pVtab->pModule; + assert( u.cm.pModule->xColumn ); + memset(&u.cm.sContext, 0, sizeof(u.cm.sContext)); /* The output cell may already have a buffer allocated. Move - ** the current contents to u.ch.sContext.s so in case the user-function + ** the current contents to u.cm.sContext.s so in case the user-function ** can use the already allocated buffer instead of allocating a ** new one. */ - sqlite3VdbeMemMove(&u.ch.sContext.s, u.ch.pDest); - MemSetTypeFlag(&u.ch.sContext.s, MEM_Null); + sqlite3VdbeMemMove(&u.cm.sContext.s, u.cm.pDest); + MemSetTypeFlag(&u.cm.sContext.s, MEM_Null); - rc = u.ch.pModule->xColumn(pCur->pVtabCursor, &u.ch.sContext, pOp->p2); - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.ch.pVtab->zErrMsg; - u.ch.pVtab->zErrMsg = 0; - if( u.ch.sContext.isError ){ - rc = u.ch.sContext.isError; + rc = u.cm.pModule->xColumn(pCur->pVtabCursor, &u.cm.sContext, pOp->p2); + importVtabErrMsg(p, u.cm.pVtab); + if( u.cm.sContext.isError ){ + rc = u.cm.sContext.isError; } /* Copy the result of the function to the P3 register. We ** do this regardless of whether or not an error occurred to ensure any - ** dynamic allocation in u.ch.sContext.s (a Mem struct) is released. + ** dynamic allocation in u.cm.sContext.s (a Mem struct) is released. */ - sqlite3VdbeChangeEncoding(&u.ch.sContext.s, encoding); - sqlite3VdbeMemMove(u.ch.pDest, &u.ch.sContext.s); - REGISTER_TRACE(pOp->p3, u.ch.pDest); - UPDATE_MAX_BLOBSIZE(u.ch.pDest); + sqlite3VdbeChangeEncoding(&u.cm.sContext.s, encoding); + sqlite3VdbeMemMove(u.cm.pDest, &u.cm.sContext.s); + REGISTER_TRACE(pOp->p3, u.cm.pDest); + UPDATE_MAX_BLOBSIZE(u.cm.pDest); - if( sqlite3VdbeMemTooBig(u.ch.pDest) ){ + if( sqlite3VdbeMemTooBig(u.cm.pDest) ){ goto too_big; } break; @@ -58856,22 +69478,22 @@ case OP_VColumn: { ** the end of its result set, then fall through to the next instruction. */ case OP_VNext: { /* jump */ -#if 0 /* local variables moved into u.ci */ +#if 0 /* local variables moved into u.cn */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; int res; VdbeCursor *pCur; -#endif /* local variables moved into u.ci */ +#endif /* local variables moved into u.cn */ - u.ci.res = 0; - u.ci.pCur = p->apCsr[pOp->p1]; - assert( u.ci.pCur->pVtabCursor ); - if( u.ci.pCur->nullRow ){ + u.cn.res = 0; + u.cn.pCur = p->apCsr[pOp->p1]; + assert( u.cn.pCur->pVtabCursor ); + if( u.cn.pCur->nullRow ){ break; } - u.ci.pVtab = u.ci.pCur->pVtabCursor->pVtab; - u.ci.pModule = u.ci.pVtab->pModule; - assert( u.ci.pModule->xNext ); + u.cn.pVtab = u.cn.pCur->pVtabCursor->pVtab; + u.cn.pModule = u.cn.pVtab->pModule; + assert( u.cn.pModule->xNext ); /* Invoke the xNext() method of the module. There is no way for the ** underlying implementation to return an error if one occurs during @@ -58880,16 +69502,14 @@ case OP_VNext: { /* jump */ ** some other method is next invoked on the save virtual table cursor. */ p->inVtabMethod = 1; - rc = u.ci.pModule->xNext(u.ci.pCur->pVtabCursor); + rc = u.cn.pModule->xNext(u.cn.pCur->pVtabCursor); p->inVtabMethod = 0; - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.ci.pVtab->zErrMsg; - u.ci.pVtab->zErrMsg = 0; + importVtabErrMsg(p, u.cn.pVtab); if( rc==SQLITE_OK ){ - u.ci.res = u.ci.pModule->xEof(u.ci.pCur->pVtabCursor); + u.cn.res = u.cn.pModule->xEof(u.cn.pCur->pVtabCursor); } - if( !u.ci.res ){ + if( !u.cn.res ){ /* If there is data, jump to P2 */ pc = pOp->p2 - 1; } @@ -58905,20 +69525,20 @@ case OP_VNext: { /* jump */ ** in register P1 is passed as the zName argument to the xRename method. */ case OP_VRename: { -#if 0 /* local variables moved into u.cj */ +#if 0 /* local variables moved into u.co */ sqlite3_vtab *pVtab; Mem *pName; -#endif /* local variables moved into u.cj */ - - u.cj.pVtab = pOp->p4.pVtab->pVtab; - u.cj.pName = &aMem[pOp->p1]; - assert( u.cj.pVtab->pModule->xRename ); - REGISTER_TRACE(pOp->p1, u.cj.pName); - assert( u.cj.pName->flags & MEM_Str ); - rc = u.cj.pVtab->pModule->xRename(u.cj.pVtab, u.cj.pName->z); - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.cj.pVtab->zErrMsg; - u.cj.pVtab->zErrMsg = 0; +#endif /* local variables moved into u.co */ + + u.co.pVtab = pOp->p4.pVtab->pVtab; + u.co.pName = &aMem[pOp->p1]; + assert( u.co.pVtab->pModule->xRename ); + assert( memIsValid(u.co.pName) ); + REGISTER_TRACE(pOp->p1, u.co.pName); + assert( u.co.pName->flags & MEM_Str ); + rc = u.co.pVtab->pModule->xRename(u.co.pVtab, u.co.pName->z); + importVtabErrMsg(p, u.co.pVtab); + p->expired = 0; break; } @@ -58929,27 +69549,27 @@ case OP_VRename: { ** ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. ** This opcode invokes the corresponding xUpdate method. P2 values -** are contiguous memory cells starting at P3 to pass to the xUpdate -** invocation. The value in register (P3+P2-1) corresponds to the +** are contiguous memory cells starting at P3 to pass to the xUpdate +** invocation. The value in register (P3+P2-1) corresponds to the ** p2th element of the argv array passed to xUpdate. ** ** The xUpdate method will do a DELETE or an INSERT or both. ** The argv[0] element (which corresponds to memory cell P3) -** is the rowid of a row to delete. If argv[0] is NULL then no -** deletion occurs. The argv[1] element is the rowid of the new -** row. This can be NULL to have the virtual table select the new -** rowid for itself. The subsequent elements in the array are +** is the rowid of a row to delete. If argv[0] is NULL then no +** deletion occurs. The argv[1] element is the rowid of the new +** row. This can be NULL to have the virtual table select the new +** rowid for itself. The subsequent elements in the array are ** the values of columns in the new row. ** ** If P2==1 then no insert is performed. argv[0] is the rowid of ** a row to delete. ** ** P1 is a boolean flag. If it is set to true and the xUpdate call -** is successful, then the value returned by sqlite3_last_insert_rowid() +** is successful, then the value returned by sqlite3_last_insert_rowid() ** is set to the value of the rowid for the row just inserted. */ case OP_VUpdate: { -#if 0 /* local variables moved into u.ck */ +#if 0 /* local variables moved into u.cp */ sqlite3_vtab *pVtab; sqlite3_module *pModule; int nArg; @@ -58957,29 +69577,43 @@ case OP_VUpdate: { sqlite_int64 rowid; Mem **apArg; Mem *pX; -#endif /* local variables moved into u.ck */ +#endif /* local variables moved into u.cp */ - u.ck.pVtab = pOp->p4.pVtab->pVtab; - u.ck.pModule = (sqlite3_module *)u.ck.pVtab->pModule; - u.ck.nArg = pOp->p2; + assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback + || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace + ); + u.cp.pVtab = pOp->p4.pVtab->pVtab; + u.cp.pModule = (sqlite3_module *)u.cp.pVtab->pModule; + u.cp.nArg = pOp->p2; assert( pOp->p4type==P4_VTAB ); - if( ALWAYS(u.ck.pModule->xUpdate) ){ - u.ck.apArg = p->apArg; - u.ck.pX = &aMem[pOp->p3]; - for(u.ck.i=0; u.ck.i<u.ck.nArg; u.ck.i++){ - sqlite3VdbeMemStoreType(u.ck.pX); - u.ck.apArg[u.ck.i] = u.ck.pX; - u.ck.pX++; - } - rc = u.ck.pModule->xUpdate(u.ck.pVtab, u.ck.nArg, u.ck.apArg, &u.ck.rowid); - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.ck.pVtab->zErrMsg; - u.ck.pVtab->zErrMsg = 0; + if( ALWAYS(u.cp.pModule->xUpdate) ){ + u8 vtabOnConflict = db->vtabOnConflict; + u.cp.apArg = p->apArg; + u.cp.pX = &aMem[pOp->p3]; + for(u.cp.i=0; u.cp.i<u.cp.nArg; u.cp.i++){ + assert( memIsValid(u.cp.pX) ); + memAboutToChange(p, u.cp.pX); + sqlite3VdbeMemStoreType(u.cp.pX); + u.cp.apArg[u.cp.i] = u.cp.pX; + u.cp.pX++; + } + db->vtabOnConflict = pOp->p5; + rc = u.cp.pModule->xUpdate(u.cp.pVtab, u.cp.nArg, u.cp.apArg, &u.cp.rowid); + db->vtabOnConflict = vtabOnConflict; + importVtabErrMsg(p, u.cp.pVtab); if( rc==SQLITE_OK && pOp->p1 ){ - assert( u.ck.nArg>1 && u.ck.apArg[0] && (u.ck.apArg[0]->flags&MEM_Null) ); - db->lastRowid = u.ck.rowid; + assert( u.cp.nArg>1 && u.cp.apArg[0] && (u.cp.apArg[0]->flags&MEM_Null) ); + db->lastRowid = lastRowid = u.cp.rowid; + } + if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ + if( pOp->p5==OE_Ignore ){ + rc = SQLITE_OK; + }else{ + p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5); + } + }else{ + p->nChange++; } - p->nChange++; } break; } @@ -58991,25 +69625,37 @@ case OP_VUpdate: { ** Write the current number of pages in database P1 to memory cell P2. */ case OP_Pagecount: { /* out2-prerelease */ -#if 0 /* local variables moved into u.cl */ - int p1; - int nPage; - Pager *pPager; -#endif /* local variables moved into u.cl */ + pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt); + break; +} +#endif + - u.cl.p1 = pOp->p1; - u.cl.pPager = sqlite3BtreePager(db->aDb[u.cl.p1].pBt); - rc = sqlite3PagerPagecount(u.cl.pPager, &u.cl.nPage); - /* OP_Pagecount is always called from within a read transaction. The - ** page count has already been successfully read and cached. So the - ** sqlite3PagerPagecount() call above cannot fail. */ - if( ALWAYS(rc==SQLITE_OK) ){ - pOut->u.i = u.cl.nPage; +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* Opcode: MaxPgcnt P1 P2 P3 * * +** +** Try to set the maximum page count for database P1 to the value in P3. +** Do not let the maximum page count fall below the current page count and +** do not change the maximum page count value if P3==0. +** +** Store the maximum page count after the change in register P2. +*/ +case OP_MaxPgcnt: { /* out2-prerelease */ + unsigned int newMax; + Btree *pBt; + + pBt = db->aDb[pOp->p1].pBt; + newMax = 0; + if( pOp->p3 ){ + newMax = sqlite3BtreeLastPage(pBt); + if( newMax < (unsigned)pOp->p3 ) newMax = (unsigned)pOp->p3; } + pOut->u.i = sqlite3BtreeMaxPageCount(pBt, newMax); break; } #endif + #ifndef SQLITE_OMIT_TRACE /* Opcode: Trace * * * P4 * ** @@ -59017,23 +69663,23 @@ case OP_Pagecount: { /* out2-prerelease */ ** the UTF-8 string contained in P4 is emitted on the trace callback. */ case OP_Trace: { -#if 0 /* local variables moved into u.cm */ +#if 0 /* local variables moved into u.cq */ char *zTrace; -#endif /* local variables moved into u.cm */ + char *z; +#endif /* local variables moved into u.cq */ - u.cm.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); - if( u.cm.zTrace ){ - if( db->xTrace ){ - char *z = sqlite3VdbeExpandSql(p, u.cm.zTrace); - db->xTrace(db->pTraceArg, z); - sqlite3DbFree(db, z); - } + if( db->xTrace && (u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ + u.cq.z = sqlite3VdbeExpandSql(p, u.cq.zTrace); + db->xTrace(db->pTraceArg, u.cq.z); + sqlite3DbFree(db, u.cq.z); + } #ifdef SQLITE_DEBUG - if( (db->flags & SQLITE_SqlTrace)!=0 ){ - sqlite3DebugPrintf("SQL-trace: %s\n", u.cm.zTrace); - } -#endif /* SQLITE_DEBUG */ + if( (db->flags & SQLITE_SqlTrace)!=0 + && (u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 + ){ + sqlite3DebugPrintf("SQL-trace: %s\n", u.cq.zTrace); } +#endif /* SQLITE_DEBUG */ break; } #endif @@ -59104,18 +69750,21 @@ vdbe_error_halt: assert( rc ); p->rc = rc; testcase( sqlite3GlobalConfig.xLog!=0 ); - sqlite3_log(rc, "statement aborts at %d: [%s] %s", + sqlite3_log(rc, "statement aborts at %d: [%s] %s", pc, p->zSql, p->zErrMsg); sqlite3VdbeHalt(p); if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1; rc = SQLITE_ERROR; - if( resetSchemaOnFault ) sqlite3ResetInternalSchema(db, 0); + if( resetSchemaOnFault>0 ){ + sqlite3ResetInternalSchema(db, resetSchemaOnFault-1); + } /* 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: - sqlite3BtreeMutexArrayLeave(&p->aMutex); + db->lastRowid = lastRowid; + sqlite3VdbeLeave(p); return rc; /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH @@ -59184,11 +69833,82 @@ struct Incrblob { int flags; /* Copy of "flags" passed to sqlite3_blob_open() */ int nByte; /* Size of open blob, in bytes */ int iOffset; /* Byte offset of blob in cursor data */ + int iCol; /* Table column this handle is open on */ BtCursor *pCsr; /* Cursor pointing at blob row */ sqlite3_stmt *pStmt; /* Statement holding cursor open */ sqlite3 *db; /* The associated database */ }; + +/* +** This function is used by both blob_open() and blob_reopen(). It seeks +** the b-tree cursor associated with blob handle p to point to row iRow. +** If successful, SQLITE_OK is returned and subsequent calls to +** sqlite3_blob_read() or sqlite3_blob_write() access the specified row. +** +** If an error occurs, or if the specified row does not exist or does not +** contain a value of type TEXT or BLOB in the column nominated when the +** blob handle was opened, then an error code is returned and *pzErr may +** be set to point to a buffer containing an error message. It is the +** responsibility of the caller to free the error message buffer using +** sqlite3DbFree(). +** +** If an error does occur, then the b-tree cursor is closed. All subsequent +** calls to sqlite3_blob_read(), blob_write() or blob_reopen() will +** immediately return SQLITE_ABORT. +*/ +static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ + int rc; /* Error code */ + char *zErr = 0; /* Error message */ + Vdbe *v = (Vdbe *)p->pStmt; + + /* Set the value of the SQL statements only variable to integer iRow. + ** This is done directly instead of using sqlite3_bind_int64() to avoid + ** triggering asserts related to mutexes. + */ + assert( v->aVar[0].flags&MEM_Int ); + v->aVar[0].u.i = iRow; + + rc = sqlite3_step(p->pStmt); + if( rc==SQLITE_ROW ){ + u32 type = v->apCsr[0]->aType[p->iCol]; + if( type<12 ){ + zErr = sqlite3MPrintf(p->db, "cannot open value of type %s", + type==0?"null": type==7?"real": "integer" + ); + rc = SQLITE_ERROR; + sqlite3_finalize(p->pStmt); + p->pStmt = 0; + }else{ + p->iOffset = v->apCsr[0]->aOffset[p->iCol]; + p->nByte = sqlite3VdbeSerialTypeLen(type); + p->pCsr = v->apCsr[0]->pCursor; + sqlite3BtreeEnterCursor(p->pCsr); + sqlite3BtreeCacheOverflow(p->pCsr); + sqlite3BtreeLeaveCursor(p->pCsr); + } + } + + if( rc==SQLITE_ROW ){ + rc = SQLITE_OK; + }else if( p->pStmt ){ + rc = sqlite3_finalize(p->pStmt); + p->pStmt = 0; + if( rc==SQLITE_OK ){ + zErr = sqlite3MPrintf(p->db, "no such rowid: %lld", iRow); + rc = SQLITE_ERROR; + }else{ + zErr = sqlite3MPrintf(p->db, "%s", sqlite3_errmsg(p->db)); + } + } + + assert( rc!=SQLITE_OK || zErr==0 ); + assert( rc!=SQLITE_ROW && rc!=SQLITE_DONE ); + + *pzErr = zErr; + return rc; +} + /* ** Open a blob handle. */ @@ -59204,7 +69924,7 @@ SQLITE_API int sqlite3_blob_open( int nAttempt = 0; int iCol; /* Index of zColumn in row-record */ - /* This VDBE program seeks a btree cursor to the identified + /* This VDBE program seeks a btree cursor to the identified ** db/table/row entry. The reason for using a vdbe program instead ** of writing code to use the b-tree layer directly is that the ** vdbe program will take advantage of the various transaction, @@ -59212,11 +69932,11 @@ SQLITE_API int sqlite3_blob_open( ** ** After seeking the cursor, the vdbe executes an OP_ResultRow. ** Code external to the Vdbe then "borrows" the b-tree cursor and - ** uses it to implement the blob_read(), blob_write() and + ** uses it to implement the blob_read(), blob_write() and ** blob_bytes() functions. ** ** The sqlite3_blob_close() function finalizes the vdbe program, - ** which closes the b-tree cursor and (possibly) commits the + ** which closes the b-tree cursor and (possibly) commits the ** transaction. */ static const VdbeOpList openBlob[] = { @@ -59229,29 +69949,35 @@ SQLITE_API int sqlite3_blob_open( {OP_OpenWrite, 0, 0, 0}, /* 4: Open cursor 0 for read/write */ {OP_Variable, 1, 1, 1}, /* 5: Push the rowid to the stack */ - {OP_NotExists, 0, 9, 1}, /* 6: Seek the cursor */ + {OP_NotExists, 0, 10, 1}, /* 6: Seek the cursor */ {OP_Column, 0, 0, 1}, /* 7 */ {OP_ResultRow, 1, 0, 0}, /* 8 */ - {OP_Close, 0, 0, 0}, /* 9 */ - {OP_Halt, 0, 0, 0}, /* 10 */ + {OP_Goto, 0, 5, 0}, /* 9 */ + {OP_Close, 0, 0, 0}, /* 10 */ + {OP_Halt, 0, 0, 0}, /* 11 */ }; - Vdbe *v = 0; int rc = SQLITE_OK; char *zErr = 0; Table *pTab; - Parse *pParse; + Parse *pParse = 0; + Incrblob *pBlob = 0; + flags = !!flags; /* flags = (flags ? 1 : 0); */ *ppBlob = 0; + sqlite3_mutex_enter(db->mutex); + + pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); + if( !pBlob ) goto blob_open_out; pParse = sqlite3StackAllocRaw(db, sizeof(*pParse)); - if( pParse==0 ){ - rc = SQLITE_NOMEM; - goto blob_open_out; - } + if( !pParse ) goto blob_open_out; + do { memset(pParse, 0, sizeof(Parse)); pParse->db = db; + sqlite3DbFree(db, zErr); + zErr = 0; sqlite3BtreeEnterAll(db); pTab = sqlite3LocateTable(pParse, 0, zTable, zDb); @@ -59277,7 +70003,7 @@ SQLITE_API int sqlite3_blob_open( } /* Now search pTab for the exact column. */ - for(iCol=0; iCol < pTab->nCol; iCol++) { + for(iCol=0; iCol<pTab->nCol; iCol++) { if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){ break; } @@ -59291,7 +70017,7 @@ SQLITE_API int sqlite3_blob_open( } /* If the value is being opened for writing, check that the - ** column is not indexed, and that it is not part of a foreign key. + ** column is not indexed, and that it is not part of a foreign key. ** It is against the rules to open a column to which either of these ** descriptions applies for writing. */ if( flags ){ @@ -59301,7 +70027,7 @@ SQLITE_API int sqlite3_blob_open( if( db->flags&SQLITE_ForeignKeys ){ /* Check that the column is not part of an FK child key definition. It ** is not necessary to check if it is part of a parent key, as parent - ** key columns must be indexed. The check below will pick up this + ** key columns must be indexed. The check below will pick up this ** case. */ FKey *pFKey; for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ @@ -59331,11 +70057,14 @@ SQLITE_API int sqlite3_blob_open( } } - v = sqlite3VdbeCreate(db); - if( v ){ + pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(db); + assert( pBlob->pStmt || db->mallocFailed ); + if( pBlob->pStmt ){ + Vdbe *v = (Vdbe *)pBlob->pStmt; int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob); - flags = !!flags; /* flags = (flags ? 1 : 0); */ + /* Configure the OP_Transaction */ sqlite3VdbeChangeP1(v, 0, iDb); @@ -59344,19 +70073,24 @@ SQLITE_API int sqlite3_blob_open( /* Configure the OP_VerifyCookie */ sqlite3VdbeChangeP1(v, 1, iDb); sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie); + sqlite3VdbeChangeP3(v, 1, pTab->pSchema->iGeneration); /* Make sure a mutex is held on the table to be accessed */ - sqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeUsesBtree(v, iDb); /* Configure the OP_TableLock instruction */ +#ifdef SQLITE_OMIT_SHARED_CACHE + sqlite3VdbeChangeToNoop(v, 2); +#else sqlite3VdbeChangeP1(v, 2, iDb); sqlite3VdbeChangeP2(v, 2, pTab->tnum); sqlite3VdbeChangeP3(v, 2, flags); sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT); +#endif - /* Remove either the OP_OpenWrite or OpenRead. Set the P2 + /* Remove either the OP_OpenWrite or OpenRead. Set the P2 ** parameter of the other to pTab->tnum. */ - sqlite3VdbeChangeToNoop(v, 4 - flags, 1); + sqlite3VdbeChangeToNoop(v, 4 - flags); sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum); sqlite3VdbeChangeP3(v, 3 + flags, iDb); @@ -59364,75 +70098,38 @@ SQLITE_API int sqlite3_blob_open( ** think that the table has one more column than it really ** does. An OP_Column to retrieve this imaginary column will ** always return an SQL NULL. This is useful because it means - ** we can invoke OP_Column to fill in the vdbe cursors type + ** we can invoke OP_Column to fill in the vdbe cursors type ** and offset cache without causing any IO. */ sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); sqlite3VdbeChangeP2(v, 7, pTab->nCol); if( !db->mallocFailed ){ - sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0); + pParse->nVar = 1; + pParse->nMem = 1; + pParse->nTab = 1; + sqlite3VdbeMakeReady(v, pParse); } } - + + pBlob->flags = flags; + pBlob->iCol = iCol; + pBlob->db = db; sqlite3BtreeLeaveAll(db); if( db->mallocFailed ){ goto blob_open_out; } - - sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow); - rc = sqlite3_step((sqlite3_stmt *)v); - if( rc!=SQLITE_ROW ){ - nAttempt++; - rc = sqlite3_finalize((sqlite3_stmt *)v); - sqlite3DbFree(db, zErr); - zErr = sqlite3MPrintf(db, sqlite3_errmsg(db)); - v = 0; - } - } while( nAttempt<5 && rc==SQLITE_SCHEMA ); - - if( rc==SQLITE_ROW ){ - /* The row-record has been opened successfully. Check that the - ** column in question contains text or a blob. If it contains - ** text, it is up to the caller to get the encoding right. - */ - Incrblob *pBlob; - u32 type = v->apCsr[0]->aType[iCol]; - - if( type<12 ){ - sqlite3DbFree(db, zErr); - zErr = sqlite3MPrintf(db, "cannot open value of type %s", - type==0?"null": type==7?"real": "integer" - ); - rc = SQLITE_ERROR; - goto blob_open_out; - } - pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); - if( db->mallocFailed ){ - sqlite3DbFree(db, pBlob); - goto blob_open_out; - } - pBlob->flags = flags; - pBlob->pCsr = v->apCsr[0]->pCursor; - sqlite3BtreeEnterCursor(pBlob->pCsr); - sqlite3BtreeCacheOverflow(pBlob->pCsr); - sqlite3BtreeLeaveCursor(pBlob->pCsr); - pBlob->pStmt = (sqlite3_stmt *)v; - pBlob->iOffset = v->apCsr[0]->aOffset[iCol]; - pBlob->nByte = sqlite3VdbeSerialTypeLen(type); - pBlob->db = db; - *ppBlob = (sqlite3_blob *)pBlob; - rc = SQLITE_OK; - }else if( rc==SQLITE_OK ){ - sqlite3DbFree(db, zErr); - zErr = sqlite3MPrintf(db, "no such rowid: %lld", iRow); - rc = SQLITE_ERROR; - } + sqlite3_bind_int64(pBlob->pStmt, 1, iRow); + rc = blobSeekToRow(pBlob, iRow, &zErr); + } while( (++nAttempt)<5 && rc==SQLITE_SCHEMA ); blob_open_out: - if( v && (rc!=SQLITE_OK || db->mallocFailed) ){ - sqlite3VdbeFinalize(v); + if( rc==SQLITE_OK && db->mallocFailed==0 ){ + *ppBlob = (sqlite3_blob *)pBlob; + }else{ + if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); + sqlite3DbFree(db, pBlob); } - sqlite3Error(db, rc, zErr); + sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr); sqlite3DbFree(db, zErr); sqlite3StackFree(db, pParse); rc = sqlite3ApiExit(db, rc); @@ -59465,10 +70162,10 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){ ** Perform a read or write operation on a blob */ static int blobReadWrite( - sqlite3_blob *pBlob, - void *z, - int n, - int iOffset, + sqlite3_blob *pBlob, + void *z, + int n, + int iOffset, int (*xCall)(BtCursor*, u32, u32, void*) ){ int rc; @@ -59485,7 +70182,7 @@ static int blobReadWrite( /* Request is out of range. Return a transient error. */ rc = SQLITE_ERROR; sqlite3Error(db, SQLITE_ERROR, 0); - } else if( v==0 ){ + }else if( v==0 ){ /* If there is no statement handle, then the blob-handle has ** already been invalidated. Return SQLITE_ABORT in this case. */ @@ -59533,12 +70230,935 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int */ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){ Incrblob *p = (Incrblob *)pBlob; - return p ? p->nByte : 0; + return (p && p->pStmt) ? p->nByte : 0; +} + +/* +** Move an existing blob handle to point to a different row of the same +** database table. +** +** If an error occurs, or if the specified row does not exist or does not +** contain a blob or text value, then an error code is returned and the +** database handle error code and message set. If this happens, then all +** subsequent calls to sqlite3_blob_xxx() functions (except blob_close()) +** immediately return SQLITE_ABORT. +*/ +SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ + int rc; + Incrblob *p = (Incrblob *)pBlob; + sqlite3 *db; + + if( p==0 ) return SQLITE_MISUSE_BKPT; + db = p->db; + sqlite3_mutex_enter(db->mutex); + + if( p->pStmt==0 ){ + /* If there is no statement handle, then the blob-handle has + ** already been invalidated. Return SQLITE_ABORT in this case. + */ + rc = SQLITE_ABORT; + }else{ + char *zErr; + rc = blobSeekToRow(p, iRow, &zErr); + if( rc!=SQLITE_OK ){ + sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr); + sqlite3DbFree(db, zErr); + } + assert( rc!=SQLITE_SCHEMA ); + } + + rc = sqlite3ApiExit(db, rc); + assert( rc==SQLITE_OK || p->pStmt==0 ); + sqlite3_mutex_leave(db->mutex); + return rc; } #endif /* #ifndef SQLITE_OMIT_INCRBLOB */ /************** End of vdbeblob.c ********************************************/ +/************** Begin file vdbesort.c ****************************************/ +/* +** 2011 July 9 +** +** 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 code for the VdbeSorter object, used in concert with +** a VdbeCursor to sort large numbers of keys (as may be required, for +** example, by CREATE INDEX statements on tables too large to fit in main +** memory). +*/ + + +#ifndef SQLITE_OMIT_MERGE_SORT + +typedef struct VdbeSorterIter VdbeSorterIter; +typedef struct SorterRecord SorterRecord; + +/* +** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES: +** +** As keys are added to the sorter, they are written to disk in a series +** of sorted packed-memory-arrays (PMAs). The size of each PMA is roughly +** the same as the cache-size allowed for temporary databases. In order +** to allow the caller to extract keys from the sorter in sorted order, +** all PMAs currently stored on disk must be merged together. This comment +** describes the data structure used to do so. The structure supports +** merging any number of arrays in a single pass with no redundant comparison +** operations. +** +** The aIter[] array contains an iterator for each of the PMAs being merged. +** An aIter[] iterator either points to a valid key or else is at EOF. For +** the purposes of the paragraphs below, we assume that the array is actually +** N elements in size, where N is the smallest power of 2 greater to or equal +** to the number of iterators being merged. The extra aIter[] elements are +** treated as if they are empty (always at EOF). +** +** The aTree[] array is also N elements in size. The value of N is stored in +** the VdbeSorter.nTree variable. +** +** The final (N/2) elements of aTree[] contain the results of comparing +** pairs of iterator keys together. Element i contains the result of +** comparing aIter[2*i-N] and aIter[2*i-N+1]. Whichever key is smaller, the +** aTree element is set to the index of it. +** +** For the purposes of this comparison, EOF is considered greater than any +** other key value. If the keys are equal (only possible with two EOF +** values), it doesn't matter which index is stored. +** +** The (N/4) elements of aTree[] that preceed the final (N/2) described +** above contains the index of the smallest of each block of 4 iterators. +** And so on. So that aTree[1] contains the index of the iterator that +** currently points to the smallest key value. aTree[0] is unused. +** +** Example: +** +** aIter[0] -> Banana +** aIter[1] -> Feijoa +** aIter[2] -> Elderberry +** aIter[3] -> Currant +** aIter[4] -> Grapefruit +** aIter[5] -> Apple +** aIter[6] -> Durian +** aIter[7] -> EOF +** +** aTree[] = { X, 5 0, 5 0, 3, 5, 6 } +** +** The current element is "Apple" (the value of the key indicated by +** iterator 5). When the Next() operation is invoked, iterator 5 will +** be advanced to the next key in its segment. Say the next key is +** "Eggplant": +** +** aIter[5] -> Eggplant +** +** The contents of aTree[] are updated first by comparing the new iterator +** 5 key to the current key of iterator 4 (still "Grapefruit"). The iterator +** 5 value is still smaller, so aTree[6] is set to 5. And so on up the tree. +** The value of iterator 6 - "Durian" - is now smaller than that of iterator +** 5, so aTree[3] is set to 6. Key 0 is smaller than key 6 (Banana<Durian), +** so the value written into element 1 of the array is 0. As follows: +** +** aTree[] = { X, 0 0, 6 0, 3, 5, 6 } +** +** In other words, each time we advance to the next sorter element, log2(N) +** key comparison operations are required, where N is the number of segments +** being merged (rounded up to the next power of 2). +*/ +struct VdbeSorter { + int nInMemory; /* Current size of pRecord list as PMA */ + int nTree; /* Used size of aTree/aIter (power of 2) */ + VdbeSorterIter *aIter; /* Array of iterators to merge */ + int *aTree; /* Current state of incremental merge */ + i64 iWriteOff; /* Current write offset within file pTemp1 */ + i64 iReadOff; /* Current read offset within file pTemp1 */ + sqlite3_file *pTemp1; /* PMA file 1 */ + int nPMA; /* Number of PMAs stored in pTemp1 */ + SorterRecord *pRecord; /* Head of in-memory record list */ + int mnPmaSize; /* Minimum PMA size, in bytes */ + int mxPmaSize; /* Maximum PMA size, in bytes. 0==no limit */ + UnpackedRecord *pUnpacked; /* Used to unpack keys */ +}; + +/* +** The following type is an iterator for a PMA. It caches the current key in +** variables nKey/aKey. If the iterator is at EOF, pFile==0. +*/ +struct VdbeSorterIter { + i64 iReadOff; /* Current read offset */ + i64 iEof; /* 1 byte past EOF for this iterator */ + sqlite3_file *pFile; /* File iterator is reading from */ + int nAlloc; /* Bytes of space at aAlloc */ + u8 *aAlloc; /* Allocated space */ + int nKey; /* Number of bytes in key */ + u8 *aKey; /* Pointer to current key */ +}; + +/* +** A structure to store a single record. All in-memory records are connected +** together into a linked list headed at VdbeSorter.pRecord using the +** SorterRecord.pNext pointer. +*/ +struct SorterRecord { + void *pVal; + int nVal; + SorterRecord *pNext; +}; + +/* Minimum allowable value for the VdbeSorter.nWorking variable */ +#define SORTER_MIN_WORKING 10 + +/* Maximum number of segments to merge in a single pass. */ +#define SORTER_MAX_MERGE_COUNT 16 + +/* +** Free all memory belonging to the VdbeSorterIter object passed as the second +** argument. All structure fields are set to zero before returning. +*/ +static void vdbeSorterIterZero(sqlite3 *db, VdbeSorterIter *pIter){ + sqlite3DbFree(db, pIter->aAlloc); + memset(pIter, 0, sizeof(VdbeSorterIter)); +} + +/* +** Advance iterator pIter to the next key in its PMA. Return SQLITE_OK if +** no error occurs, or an SQLite error code if one does. +*/ +static int vdbeSorterIterNext( + sqlite3 *db, /* Database handle (for sqlite3DbMalloc() ) */ + VdbeSorterIter *pIter /* Iterator to advance */ +){ + int rc; /* Return Code */ + int nRead; /* Number of bytes read */ + int nRec = 0; /* Size of record in bytes */ + int iOff = 0; /* Size of serialized size varint in bytes */ + + assert( pIter->iEof>=pIter->iReadOff ); + if( pIter->iEof-pIter->iReadOff>5 ){ + nRead = 5; + }else{ + nRead = (int)(pIter->iEof - pIter->iReadOff); + } + if( nRead<=0 ){ + /* This is an EOF condition */ + vdbeSorterIterZero(db, pIter); + return SQLITE_OK; + } + + rc = sqlite3OsRead(pIter->pFile, pIter->aAlloc, nRead, pIter->iReadOff); + if( rc==SQLITE_OK ){ + iOff = getVarint32(pIter->aAlloc, nRec); + if( (iOff+nRec)>nRead ){ + int nRead2; /* Number of extra bytes to read */ + if( (iOff+nRec)>pIter->nAlloc ){ + int nNew = pIter->nAlloc*2; + while( (iOff+nRec)>nNew ) nNew = nNew*2; + pIter->aAlloc = sqlite3DbReallocOrFree(db, pIter->aAlloc, nNew); + if( !pIter->aAlloc ) return SQLITE_NOMEM; + pIter->nAlloc = nNew; + } + + nRead2 = iOff + nRec - nRead; + rc = sqlite3OsRead( + pIter->pFile, &pIter->aAlloc[nRead], nRead2, pIter->iReadOff+nRead + ); + } + } + + assert( rc!=SQLITE_OK || nRec>0 ); + pIter->iReadOff += iOff+nRec; + pIter->nKey = nRec; + pIter->aKey = &pIter->aAlloc[iOff]; + return rc; +} + +/* +** Write a single varint, value iVal, to file-descriptor pFile. Return +** SQLITE_OK if successful, or an SQLite error code if some error occurs. +** +** The value of *piOffset when this function is called is used as the byte +** offset in file pFile to write to. Before returning, *piOffset is +** incremented by the number of bytes written. +*/ +static int vdbeSorterWriteVarint( + sqlite3_file *pFile, /* File to write to */ + i64 iVal, /* Value to write as a varint */ + i64 *piOffset /* IN/OUT: Write offset in file pFile */ +){ + u8 aVarint[9]; /* Buffer large enough for a varint */ + int nVarint; /* Number of used bytes in varint */ + int rc; /* Result of write() call */ + + nVarint = sqlite3PutVarint(aVarint, iVal); + rc = sqlite3OsWrite(pFile, aVarint, nVarint, *piOffset); + *piOffset += nVarint; + + return rc; +} + +/* +** Read a single varint from file-descriptor pFile. Return SQLITE_OK if +** successful, or an SQLite error code if some error occurs. +** +** The value of *piOffset when this function is called is used as the +** byte offset in file pFile from whence to read the varint. If successful +** (i.e. if no IO error occurs), then *piOffset is set to the offset of +** the first byte past the end of the varint before returning. *piVal is +** set to the integer value read. If an error occurs, the final values of +** both *piOffset and *piVal are undefined. +*/ +static int vdbeSorterReadVarint( + sqlite3_file *pFile, /* File to read from */ + i64 *piOffset, /* IN/OUT: Read offset in pFile */ + i64 *piVal /* OUT: Value read from file */ +){ + u8 aVarint[9]; /* Buffer large enough for a varint */ + i64 iOff = *piOffset; /* Offset in file to read from */ + int rc; /* Return code */ + + rc = sqlite3OsRead(pFile, aVarint, 9, iOff); + if( rc==SQLITE_OK ){ + *piOffset += getVarint(aVarint, (u64 *)piVal); + } + + return rc; +} + +/* +** Initialize iterator pIter to scan through the PMA stored in file pFile +** starting at offset iStart and ending at offset iEof-1. This function +** leaves the iterator pointing to the first key in the PMA (or EOF if the +** PMA is empty). +*/ +static int vdbeSorterIterInit( + sqlite3 *db, /* Database handle */ + VdbeSorter *pSorter, /* Sorter object */ + i64 iStart, /* Start offset in pFile */ + VdbeSorterIter *pIter, /* Iterator to populate */ + i64 *pnByte /* IN/OUT: Increment this value by PMA size */ +){ + int rc; + + assert( pSorter->iWriteOff>iStart ); + assert( pIter->aAlloc==0 ); + pIter->pFile = pSorter->pTemp1; + pIter->iReadOff = iStart; + pIter->nAlloc = 128; + pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc); + if( !pIter->aAlloc ){ + rc = SQLITE_NOMEM; + }else{ + i64 nByte; /* Total size of PMA in bytes */ + rc = vdbeSorterReadVarint(pSorter->pTemp1, &pIter->iReadOff, &nByte); + *pnByte += nByte; + pIter->iEof = pIter->iReadOff + nByte; + } + if( rc==SQLITE_OK ){ + rc = vdbeSorterIterNext(db, pIter); + } + return rc; +} + + +/* +** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, +** size nKey2 bytes). Argument pKeyInfo supplies the collation functions +** used by the comparison. If an error occurs, return an SQLite error code. +** Otherwise, return SQLITE_OK and set *pRes to a negative, zero or positive +** value, depending on whether key1 is smaller, equal to or larger than key2. +** +** If the bOmitRowid argument is non-zero, assume both keys end in a rowid +** field. For the purposes of the comparison, ignore it. Also, if bOmitRowid +** is true and key1 contains even a single NULL value, it is considered to +** be less than key2. Even if key2 also contains NULL values. +** +** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace +** has been allocated and contains an unpacked record that is used as key2. +*/ +static void vdbeSorterCompare( + VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ + int bOmitRowid, /* Ignore rowid field at end of keys */ + void *pKey1, int nKey1, /* Left side of comparison */ + void *pKey2, int nKey2, /* Right side of comparison */ + int *pRes /* OUT: Result of comparison */ +){ + KeyInfo *pKeyInfo = pCsr->pKeyInfo; + VdbeSorter *pSorter = pCsr->pSorter; + UnpackedRecord *r2 = pSorter->pUnpacked; + int i; + + if( pKey2 ){ + sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2); + } + + if( bOmitRowid ){ + r2->nField = pKeyInfo->nField; + assert( r2->nField>0 ); + for(i=0; i<r2->nField; i++){ + if( r2->aMem[i].flags & MEM_Null ){ + *pRes = -1; + return; + } + } + r2->flags |= UNPACKED_PREFIX_MATCH; + } + + *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2); +} + +/* +** This function is called to compare two iterator keys when merging +** multiple b-tree segments. Parameter iOut is the index of the aTree[] +** value to recalculate. +*/ +static int vdbeSorterDoCompare(VdbeCursor *pCsr, int iOut){ + VdbeSorter *pSorter = pCsr->pSorter; + int i1; + int i2; + int iRes; + VdbeSorterIter *p1; + VdbeSorterIter *p2; + + assert( iOut<pSorter->nTree && iOut>0 ); + + if( iOut>=(pSorter->nTree/2) ){ + i1 = (iOut - pSorter->nTree/2) * 2; + i2 = i1 + 1; + }else{ + i1 = pSorter->aTree[iOut*2]; + i2 = pSorter->aTree[iOut*2+1]; + } + + p1 = &pSorter->aIter[i1]; + p2 = &pSorter->aIter[i2]; + + if( p1->pFile==0 ){ + iRes = i2; + }else if( p2->pFile==0 ){ + iRes = i1; + }else{ + int res; + assert( pCsr->pSorter->pUnpacked!=0 ); /* allocated in vdbeSorterMerge() */ + vdbeSorterCompare( + pCsr, 0, p1->aKey, p1->nKey, p2->aKey, p2->nKey, &res + ); + if( res<=0 ){ + iRes = i1; + }else{ + iRes = i2; + } + } + + pSorter->aTree[iOut] = iRes; + return SQLITE_OK; +} + +/* +** Initialize the temporary index cursor just opened as a sorter cursor. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *db, VdbeCursor *pCsr){ + int pgsz; /* Page size of main database */ + int mxCache; /* Cache size */ + VdbeSorter *pSorter; /* The new sorter */ + char *d; /* Dummy */ + + assert( pCsr->pKeyInfo && pCsr->pBt==0 ); + pCsr->pSorter = pSorter = sqlite3DbMallocZero(db, sizeof(VdbeSorter)); + if( pSorter==0 ){ + return SQLITE_NOMEM; + } + + pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pCsr->pKeyInfo, 0, 0, &d); + if( pSorter->pUnpacked==0 ) return SQLITE_NOMEM; + assert( pSorter->pUnpacked==(UnpackedRecord *)d ); + + if( !sqlite3TempInMemory(db) ){ + pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); + pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz; + mxCache = db->aDb[0].pSchema->cache_size; + if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING; + pSorter->mxPmaSize = mxCache * pgsz; + } + + return SQLITE_OK; +} + +/* +** Free the list of sorted records starting at pRecord. +*/ +static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){ + SorterRecord *p; + SorterRecord *pNext; + for(p=pRecord; p; p=pNext){ + pNext = p->pNext; + sqlite3DbFree(db, p); + } +} + +/* +** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. +*/ +SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ + VdbeSorter *pSorter = pCsr->pSorter; + if( pSorter ){ + if( pSorter->aIter ){ + int i; + for(i=0; i<pSorter->nTree; i++){ + vdbeSorterIterZero(db, &pSorter->aIter[i]); + } + sqlite3DbFree(db, pSorter->aIter); + } + if( pSorter->pTemp1 ){ + sqlite3OsCloseFree(pSorter->pTemp1); + } + vdbeSorterRecordFree(db, pSorter->pRecord); + sqlite3DbFree(db, pSorter->pUnpacked); + sqlite3DbFree(db, pSorter); + pCsr->pSorter = 0; + } +} + +/* +** Allocate space for a file-handle and open a temporary file. If successful, +** set *ppFile to point to the malloc'd file-handle and return SQLITE_OK. +** Otherwise, set *ppFile to 0 and return an SQLite error code. +*/ +static int vdbeSorterOpenTempFile(sqlite3 *db, sqlite3_file **ppFile){ + int dummy; + return sqlite3OsOpenMalloc(db->pVfs, 0, ppFile, + SQLITE_OPEN_TEMP_JOURNAL | + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &dummy + ); +} + +/* +** Merge the two sorted lists p1 and p2 into a single list. +** Set *ppOut to the head of the new list. +*/ +static void vdbeSorterMerge( + VdbeCursor *pCsr, /* For pKeyInfo */ + SorterRecord *p1, /* First list to merge */ + SorterRecord *p2, /* Second list to merge */ + SorterRecord **ppOut /* OUT: Head of merged list */ +){ + SorterRecord *pFinal = 0; + SorterRecord **pp = &pFinal; + void *pVal2 = p2 ? p2->pVal : 0; + + while( p1 && p2 ){ + int res; + vdbeSorterCompare(pCsr, 0, p1->pVal, p1->nVal, pVal2, p2->nVal, &res); + if( res<=0 ){ + *pp = p1; + pp = &p1->pNext; + p1 = p1->pNext; + pVal2 = 0; + }else{ + *pp = p2; + pp = &p2->pNext; + p2 = p2->pNext; + if( p2==0 ) break; + pVal2 = p2->pVal; + } + } + *pp = p1 ? p1 : p2; + *ppOut = pFinal; +} + +/* +** Sort the linked list of records headed at pCsr->pRecord. Return SQLITE_OK +** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error +** occurs. +*/ +static int vdbeSorterSort(VdbeCursor *pCsr){ + int i; + SorterRecord **aSlot; + SorterRecord *p; + VdbeSorter *pSorter = pCsr->pSorter; + + aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *)); + if( !aSlot ){ + return SQLITE_NOMEM; + } + + p = pSorter->pRecord; + while( p ){ + SorterRecord *pNext = p->pNext; + p->pNext = 0; + for(i=0; aSlot[i]; i++){ + vdbeSorterMerge(pCsr, p, aSlot[i], &p); + aSlot[i] = 0; + } + aSlot[i] = p; + p = pNext; + } + + p = 0; + for(i=0; i<64; i++){ + vdbeSorterMerge(pCsr, p, aSlot[i], &p); + } + pSorter->pRecord = p; + + sqlite3_free(aSlot); + return SQLITE_OK; +} + + +/* +** Write the current contents of the in-memory linked-list to a PMA. Return +** SQLITE_OK if successful, or an SQLite error code otherwise. +** +** The format of a PMA is: +** +** * A varint. This varint contains the total number of bytes of content +** in the PMA (not including the varint itself). +** +** * One or more records packed end-to-end in order of ascending keys. +** Each record consists of a varint followed by a blob of data (the +** key). The varint is the number of bytes in the blob of data. +*/ +static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){ + int rc = SQLITE_OK; /* Return code */ + VdbeSorter *pSorter = pCsr->pSorter; + + if( pSorter->nInMemory==0 ){ + assert( pSorter->pRecord==0 ); + return rc; + } + + rc = vdbeSorterSort(pCsr); + + /* If the first temporary PMA file has not been opened, open it now. */ + if( rc==SQLITE_OK && pSorter->pTemp1==0 ){ + rc = vdbeSorterOpenTempFile(db, &pSorter->pTemp1); + assert( rc!=SQLITE_OK || pSorter->pTemp1 ); + assert( pSorter->iWriteOff==0 ); + assert( pSorter->nPMA==0 ); + } + + if( rc==SQLITE_OK ){ + i64 iOff = pSorter->iWriteOff; + SorterRecord *p; + SorterRecord *pNext = 0; + static const char eightZeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + pSorter->nPMA++; + rc = vdbeSorterWriteVarint(pSorter->pTemp1, pSorter->nInMemory, &iOff); + for(p=pSorter->pRecord; rc==SQLITE_OK && p; p=pNext){ + pNext = p->pNext; + rc = vdbeSorterWriteVarint(pSorter->pTemp1, p->nVal, &iOff); + + if( rc==SQLITE_OK ){ + rc = sqlite3OsWrite(pSorter->pTemp1, p->pVal, p->nVal, iOff); + iOff += p->nVal; + } + + sqlite3DbFree(db, p); + } + + /* This assert verifies that unless an error has occurred, the size of + ** the PMA on disk is the same as the expected size stored in + ** pSorter->nInMemory. */ + assert( rc!=SQLITE_OK || pSorter->nInMemory==( + iOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nInMemory) + )); + + pSorter->iWriteOff = iOff; + if( rc==SQLITE_OK ){ + /* Terminate each file with 8 extra bytes so that from any offset + ** in the file we can always read 9 bytes without a SHORT_READ error */ + rc = sqlite3OsWrite(pSorter->pTemp1, eightZeros, 8, iOff); + } + pSorter->pRecord = p; + } + + return rc; +} + +/* +** Add a record to the sorter. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterWrite( + sqlite3 *db, /* Database handle */ + VdbeCursor *pCsr, /* Sorter cursor */ + Mem *pVal /* Memory cell containing record */ +){ + VdbeSorter *pSorter = pCsr->pSorter; + int rc = SQLITE_OK; /* Return Code */ + SorterRecord *pNew; /* New list element */ + + assert( pSorter ); + pSorter->nInMemory += sqlite3VarintLen(pVal->n) + pVal->n; + + pNew = (SorterRecord *)sqlite3DbMallocRaw(db, pVal->n + sizeof(SorterRecord)); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + pNew->pVal = (void *)&pNew[1]; + memcpy(pNew->pVal, pVal->z, pVal->n); + pNew->nVal = pVal->n; + pNew->pNext = pSorter->pRecord; + pSorter->pRecord = pNew; + } + + /* See if the contents of the sorter should now be written out. They + ** are written out when either of the following are true: + ** + ** * The total memory allocated for the in-memory list is greater + ** than (page-size * cache-size), or + ** + ** * The total memory allocated for the in-memory list is greater + ** than (page-size * 10) and sqlite3HeapNearlyFull() returns true. + */ + if( rc==SQLITE_OK && pSorter->mxPmaSize>0 && ( + (pSorter->nInMemory>pSorter->mxPmaSize) + || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull()) + )){ + rc = vdbeSorterListToPMA(db, pCsr); + pSorter->nInMemory = 0; + } + + return rc; +} + +/* +** Helper function for sqlite3VdbeSorterRewind(). +*/ +static int vdbeSorterInitMerge( + sqlite3 *db, /* Database handle */ + VdbeCursor *pCsr, /* Cursor handle for this sorter */ + i64 *pnByte /* Sum of bytes in all opened PMAs */ +){ + VdbeSorter *pSorter = pCsr->pSorter; + int rc = SQLITE_OK; /* Return code */ + int i; /* Used to iterator through aIter[] */ + i64 nByte = 0; /* Total bytes in all opened PMAs */ + + /* Initialize the iterators. */ + for(i=0; i<SORTER_MAX_MERGE_COUNT; i++){ + VdbeSorterIter *pIter = &pSorter->aIter[i]; + rc = vdbeSorterIterInit(db, pSorter, pSorter->iReadOff, pIter, &nByte); + pSorter->iReadOff = pIter->iEof; + assert( rc!=SQLITE_OK || pSorter->iReadOff<=pSorter->iWriteOff ); + if( rc!=SQLITE_OK || pSorter->iReadOff>=pSorter->iWriteOff ) break; + } + + /* Initialize the aTree[] array. */ + for(i=pSorter->nTree-1; rc==SQLITE_OK && i>0; i--){ + rc = vdbeSorterDoCompare(pCsr, i); + } + + *pnByte = nByte; + return rc; +} + +/* +** Once the sorter has been populated, this function is called to prepare +** for iterating through its contents in sorted order. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ + VdbeSorter *pSorter = pCsr->pSorter; + int rc; /* Return code */ + sqlite3_file *pTemp2 = 0; /* Second temp file to use */ + i64 iWrite2 = 0; /* Write offset for pTemp2 */ + int nIter; /* Number of iterators used */ + int nByte; /* Bytes of space required for aIter/aTree */ + int N = 2; /* Power of 2 >= nIter */ + + assert( pSorter ); + + /* If no data has been written to disk, then do not do so now. Instead, + ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly + ** from the in-memory list. */ + if( pSorter->nPMA==0 ){ + *pbEof = !pSorter->pRecord; + assert( pSorter->aTree==0 ); + return vdbeSorterSort(pCsr); + } + + /* Write the current b-tree to a PMA. Close the b-tree cursor. */ + rc = vdbeSorterListToPMA(db, pCsr); + if( rc!=SQLITE_OK ) return rc; + + /* Allocate space for aIter[] and aTree[]. */ + nIter = pSorter->nPMA; + if( nIter>SORTER_MAX_MERGE_COUNT ) nIter = SORTER_MAX_MERGE_COUNT; + assert( nIter>0 ); + while( N<nIter ) N += N; + nByte = N * (sizeof(int) + sizeof(VdbeSorterIter)); + pSorter->aIter = (VdbeSorterIter *)sqlite3DbMallocZero(db, nByte); + if( !pSorter->aIter ) return SQLITE_NOMEM; + pSorter->aTree = (int *)&pSorter->aIter[N]; + pSorter->nTree = N; + + do { + int iNew; /* Index of new, merged, PMA */ + + for(iNew=0; + rc==SQLITE_OK && iNew*SORTER_MAX_MERGE_COUNT<pSorter->nPMA; + iNew++ + ){ + i64 nWrite; /* Number of bytes in new PMA */ + + /* If there are SORTER_MAX_MERGE_COUNT or less PMAs in file pTemp1, + ** initialize an iterator for each of them and break out of the loop. + ** These iterators will be incrementally merged as the VDBE layer calls + ** sqlite3VdbeSorterNext(). + ** + ** Otherwise, if pTemp1 contains more than SORTER_MAX_MERGE_COUNT PMAs, + ** initialize interators for SORTER_MAX_MERGE_COUNT of them. These PMAs + ** are merged into a single PMA that is written to file pTemp2. + */ + rc = vdbeSorterInitMerge(db, pCsr, &nWrite); + assert( rc!=SQLITE_OK || pSorter->aIter[ pSorter->aTree[1] ].pFile ); + if( rc!=SQLITE_OK || pSorter->nPMA<=SORTER_MAX_MERGE_COUNT ){ + break; + } + + /* Open the second temp file, if it is not already open. */ + if( pTemp2==0 ){ + assert( iWrite2==0 ); + rc = vdbeSorterOpenTempFile(db, &pTemp2); + } + + if( rc==SQLITE_OK ){ + rc = vdbeSorterWriteVarint(pTemp2, nWrite, &iWrite2); + } + + if( rc==SQLITE_OK ){ + int bEof = 0; + while( rc==SQLITE_OK && bEof==0 ){ + int nToWrite; + VdbeSorterIter *pIter = &pSorter->aIter[ pSorter->aTree[1] ]; + assert( pIter->pFile ); + nToWrite = pIter->nKey + sqlite3VarintLen(pIter->nKey); + rc = sqlite3OsWrite(pTemp2, pIter->aAlloc, nToWrite, iWrite2); + iWrite2 += nToWrite; + if( rc==SQLITE_OK ){ + rc = sqlite3VdbeSorterNext(db, pCsr, &bEof); + } + } + } + } + + if( pSorter->nPMA<=SORTER_MAX_MERGE_COUNT ){ + break; + }else{ + sqlite3_file *pTmp = pSorter->pTemp1; + pSorter->nPMA = iNew; + pSorter->pTemp1 = pTemp2; + pTemp2 = pTmp; + pSorter->iWriteOff = iWrite2; + pSorter->iReadOff = 0; + iWrite2 = 0; + } + }while( rc==SQLITE_OK ); + + if( pTemp2 ){ + sqlite3OsCloseFree(pTemp2); + } + *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); + return rc; +} + +/* +** Advance to the next element in the sorter. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ + VdbeSorter *pSorter = pCsr->pSorter; + int rc; /* Return code */ + + if( pSorter->aTree ){ + int iPrev = pSorter->aTree[1];/* Index of iterator to advance */ + int i; /* Index of aTree[] to recalculate */ + + rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]); + for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){ + rc = vdbeSorterDoCompare(pCsr, i); + } + + *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); + }else{ + SorterRecord *pFree = pSorter->pRecord; + pSorter->pRecord = pFree->pNext; + pFree->pNext = 0; + vdbeSorterRecordFree(db, pFree); + *pbEof = !pSorter->pRecord; + rc = SQLITE_OK; + } + return rc; +} + +/* +** Return a pointer to a buffer owned by the sorter that contains the +** current key. +*/ +static void *vdbeSorterRowkey( + VdbeSorter *pSorter, /* Sorter object */ + int *pnKey /* OUT: Size of current key in bytes */ +){ + void *pKey; + if( pSorter->aTree ){ + VdbeSorterIter *pIter; + pIter = &pSorter->aIter[ pSorter->aTree[1] ]; + *pnKey = pIter->nKey; + pKey = pIter->aKey; + }else{ + *pnKey = pSorter->pRecord->nVal; + pKey = pSorter->pRecord->pVal; + } + return pKey; +} + +/* +** Copy the current sorter key into the memory cell pOut. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){ + VdbeSorter *pSorter = pCsr->pSorter; + void *pKey; int nKey; /* Sorter key to copy into pOut */ + + pKey = vdbeSorterRowkey(pSorter, &nKey); + if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){ + return SQLITE_NOMEM; + } + pOut->n = nKey; + MemSetTypeFlag(pOut, MEM_Blob); + memcpy(pOut->z, pKey, nKey); + + return SQLITE_OK; +} + +/* +** Compare the key in memory cell pVal with the key that the sorter cursor +** passed as the first argument currently points to. For the purposes of +** the comparison, ignore the rowid field at the end of each record. +** +** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM). +** Otherwise, set *pRes to a negative, zero or positive value if the +** key in pVal is smaller than, equal to or larger than the current sorter +** key. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterCompare( + VdbeCursor *pCsr, /* Sorter cursor */ + Mem *pVal, /* Value to compare to current sorter key */ + int *pRes /* OUT: Result of comparison */ +){ + VdbeSorter *pSorter = pCsr->pSorter; + void *pKey; int nKey; /* Sorter key to compare pVal with */ + + pKey = vdbeSorterRowkey(pSorter, &nKey); + vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes); + return SQLITE_OK; +} + +#endif /* #ifndef SQLITE_OMIT_MERGE_SORT */ + +/************** End of vdbesort.c ********************************************/ /************** Begin file journal.c *****************************************/ /* ** 2007 August 22 @@ -59562,7 +71182,7 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){ ** be used to service read() and write() requests. The actual file ** on disk is not created or populated until either: ** -** 1) The in-memory representation grows too large for the allocated +** 1) The in-memory representation grows too large for the allocated ** buffer, or ** 2) The sqlite3JournalCreate() function is called. */ @@ -59586,7 +71206,7 @@ struct JournalFile { typedef struct JournalFile JournalFile; /* -** If it does not already exists, create and populate the on-disk file +** If it does not already exists, create and populate the on-disk file ** for JournalFile p. */ static int createFile(JournalFile *p){ @@ -59723,10 +71343,14 @@ static struct sqlite3_io_methods JournalFileMethods = { 0, /* xCheckReservedLock */ 0, /* xFileControl */ 0, /* xSectorSize */ - 0 /* xDeviceCharacteristics */ + 0, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0 /* xShmUnmap */ }; -/* +/* ** Open a journal file. */ SQLITE_PRIVATE int sqlite3JournalOpen( @@ -59765,7 +71389,7 @@ SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){ return createFile((JournalFile *)p); } -/* +/* ** Return the number of bytes required to store a JournalFile that uses vfs ** pVfs to create the underlying on-disk files. */ @@ -59863,7 +71487,7 @@ static int memjrnlRead( if( p->readpoint.iOffset!=iOfst || iOfst==0 ){ sqlite3_int64 iOff = 0; - for(pChunk=p->pFirst; + for(pChunk=p->pFirst; ALWAYS(pChunk) && (iOff+JOURNAL_CHUNKSIZE)<=iOfst; pChunk=pChunk->pNext ){ @@ -59973,11 +71597,10 @@ static int memjrnlClose(sqlite3_file *pJfd){ ** exists purely as a contingency, in case some malfunction in some other ** part of SQLite causes Sync to be called by mistake. */ -static int memjrnlSync(sqlite3_file *NotUsed, int NotUsed2){ /*NO_TEST*/ - UNUSED_PARAMETER2(NotUsed, NotUsed2); /*NO_TEST*/ - assert( 0 ); /*NO_TEST*/ - return SQLITE_OK; /*NO_TEST*/ -} /*NO_TEST*/ +static int memjrnlSync(sqlite3_file *NotUsed, int NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return SQLITE_OK; +} /* ** Query the size of the file in bytes. @@ -59991,7 +71614,7 @@ static int memjrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){ /* ** Table of methods for MemJournal sqlite3_file object. */ -static struct sqlite3_io_methods MemJournalMethods = { +static const struct sqlite3_io_methods MemJournalMethods = { 1, /* iVersion */ memjrnlClose, /* xClose */ memjrnlRead, /* xRead */ @@ -60004,30 +71627,33 @@ static struct sqlite3_io_methods MemJournalMethods = { 0, /* xCheckReservedLock */ 0, /* xFileControl */ 0, /* xSectorSize */ - 0 /* xDeviceCharacteristics */ + 0, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0 /* xShmUnlock */ }; -/* +/* ** Open a journal file. */ SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *pJfd){ MemJournal *p = (MemJournal *)pJfd; assert( EIGHT_BYTE_ALIGNMENT(p) ); memset(p, 0, sqlite3MemJournalSize()); - p->pMethod = &MemJournalMethods; + p->pMethod = (sqlite3_io_methods*)&MemJournalMethods; } /* -** Return true if the file-handle passed as an argument is -** an in-memory journal +** Return true if the file-handle passed as an argument is +** an in-memory journal */ SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *pJfd){ return pJfd->pMethods==&MemJournalMethods; } -/* -** Return the number of bytes required to store a MemJournal that uses vfs -** pVfs to create the underlying on-disk files. +/* +** Return the number of bytes required to store a MemJournal file descriptor. */ SQLITE_PRIVATE int sqlite3MemJournalSize(void){ return sizeof(MemJournal); @@ -60049,6 +71675,8 @@ SQLITE_PRIVATE int sqlite3MemJournalSize(void){ ** This file contains routines used for walking the parser tree for ** an SQL statement. */ +/* #include <stdlib.h> */ +/* #include <string.h> */ /* @@ -60125,7 +71753,7 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ ** Walk the parse trees associated with all subqueries in the ** FROM clause of SELECT statement p. Do not invoke the select ** callback on p, but do invoke it on each FROM clause subquery -** and on any subqueries further down in the tree. Return +** and on any subqueries further down in the tree. Return ** WRC_Abort or WRC_Continue; */ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ @@ -60142,7 +71770,7 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ } } return WRC_Continue; -} +} /* ** Call sqlite3WalkExpr() for every expression in Select statement p. @@ -60187,6 +71815,8 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ ** resolve all identifiers by associating them with a particular ** table and column. */ +/* #include <stdlib.h> */ +/* #include <string.h> */ /* ** Turn the pExpr expression into an alias for the iCol-th column of the @@ -60200,7 +71830,7 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ ** ** The reason for suppressing the TK_AS term when the expression is a simple ** column reference is so that the column reference will be recognized as -** usable by indices within the WHERE clause processing logic. +** usable by indices within the WHERE clause processing logic. ** ** Hack: The TK_AS operator is inhibited if zType[0]=='G'. This means ** that in a GROUP BY clause, the expression is evaluated twice. Hence: @@ -60258,7 +71888,7 @@ static void resolveAlias( pDup->flags |= EP_ExpCollate; } - /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This + /* 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. */ @@ -60270,7 +71900,7 @@ static void resolveAlias( /* ** 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 +** 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: ** @@ -60332,7 +71962,7 @@ static int lookupName( Table *pTab; int iDb; Column *pCol; - + pTab = pItem->pTab; assert( pTab!=0 && pTab->zName!=0 ); iDb = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -60394,7 +72024,7 @@ static int lookupName( } #ifndef SQLITE_OMIT_TRIGGER - /* If we have not already resolved the name, then maybe + /* If we have not already resolved the name, then maybe ** it is a new.* or old.* trigger argument reference */ if( zDb==0 && zTab!=0 && cnt==0 && pParse->pTriggerTab!=0 ){ @@ -60409,7 +72039,7 @@ static int lookupName( pTab = pParse->pTriggerTab; } - if( pTab ){ + if( pTab ){ int iCol; pSchema = pTab->pSchema; cntTab++; @@ -60486,7 +72116,7 @@ static int lookupName( assert( zTab==0 && zDb==0 ); goto lookupname_end; } - } + } } /* Advance to the next name context. The loop will exit when either @@ -60527,6 +72157,7 @@ static int lookupName( }else{ sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); } + pParse->checkSchema = 1; pTopNC->nErr++; } @@ -60573,7 +72204,7 @@ lookupname_end: /* ** Allocate and return a pointer to an expression to load the column iCol -** from datasource iSrc datasource in SrcList pSrc. +** from datasource iSrc in SrcList pSrc. */ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); @@ -60585,6 +72216,8 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr p->iColumn = -1; }else{ p->iColumn = (ynVar)iCol; + testcase( iCol==BMS ); + testcase( iCol==BMS-1 ); pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); } ExprSetProperty(p, EP_Resolved); @@ -60634,7 +72267,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ SrcList *pSrcList = pNC->pSrcList; struct SrcList_item *pItem; assert( pSrcList && pSrcList->nSrc==1 ); - pItem = pSrcList->a; + pItem = pSrcList->a; pExpr->op = TK_COLUMN; pExpr->pTab = pItem->pTab; pExpr->iTable = pItem->iCursor; @@ -60649,7 +72282,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ case TK_ID: { return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr); } - + /* A table name and column name: ID.ID ** Or a database, table and column: ID.ID.ID */ @@ -60738,7 +72371,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ sqlite3WalkExprList(pWalker, pList); if( is_agg ) pNC->allowAgg = 1; /* FIX ME: Compute pExpr->affinity based on the expected return - ** type of the function + ** type of the function */ return WRC_Prune; } @@ -60879,7 +72512,7 @@ static void resolveOutOfRangeError( int i, /* The index (1-based) of the term out of range */ int mx /* Largest permissible value of i */ ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "%r %s BY term out of range - should be " "between 1 and %d", i, zType, mx); } @@ -61100,7 +72733,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ExprList *pGroupBy; /* The GROUP BY clause */ Select *pLeftmost; /* Left-most of SELECT of a compound */ sqlite3 *db; /* Database connection */ - + assert( p!=0 ); if( p->selFlags & SF_Resolved ){ @@ -61140,14 +72773,14 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ sqlite3ResolveExprNames(&sNC, p->pOffset) ){ return WRC_Abort; } - + /* Set up the local name-context to pass to sqlite3ResolveExprNames() to ** resolve the result-set expression list. */ sNC.allowAgg = 1; sNC.pSrcList = p->pSrc; sNC.pNext = pOuterNC; - + /* Resolve names in the result set. */ pEList = p->pEList; assert( pEList!=0 ); @@ -61157,21 +72790,35 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ return WRC_Abort; } } - + /* Recursively resolve names in all subqueries */ for(i=0; i<p->pSrc->nSrc; i++){ struct SrcList_item *pItem = &p->pSrc->a[i]; if( pItem->pSelect ){ + NameContext *pNC; /* Used to iterate name contexts */ + int nRef = 0; /* Refcount for pOuterNC and outer contexts */ const char *zSavedContext = pParse->zAuthContext; + + /* Count the total number of references to pOuterNC and all of its + ** parent contexts. After resolving references to expressions in + ** pItem->pSelect, check if this value has changed. If so, then + ** SELECT statement pItem->pSelect must be correlated. Set the + ** pItem->isCorrelated flag if this is the case. */ + for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef; + if( pItem->zName ) pParse->zAuthContext = pItem->zName; sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); pParse->zAuthContext = zSavedContext; if( pParse->nErr || db->mallocFailed ) return WRC_Abort; + + for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef; + assert( pItem->isCorrelated==0 && nRef<=0 ); + pItem->isCorrelated = (nRef!=0); } } - - /* If there are no aggregate functions in the result-set, and no GROUP BY + + /* If there are no aggregate functions in the result-set, and no GROUP BY ** expression, do not allow aggregates in any of the other expressions. */ assert( (p->selFlags & SF_Aggregate)==0 ); @@ -61181,14 +72828,14 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ }else{ sNC.allowAgg = 0; } - + /* If a HAVING clause is present, then there must be a GROUP BY clause. */ if( p->pHaving && !pGroupBy ){ sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); return WRC_Abort; } - + /* Add the expression list to the name-context before parsing the ** other expressions in the SELECT statement. This is so that ** expressions in the WHERE clause (etc.) can refer to expressions by @@ -61205,7 +72852,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } /* The ORDER BY and GROUP BY clauses may not refer to terms in - ** outer queries + ** outer queries */ sNC.pNext = 0; sNC.allowAgg = 1; @@ -61221,13 +72868,13 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ if( db->mallocFailed ){ return WRC_Abort; } - - /* Resolve the GROUP BY clause. At the same time, make sure + + /* Resolve the GROUP BY clause. At the same time, make sure ** the GROUP BY clause does not contain aggregate functions. */ if( pGroupBy ){ struct ExprList_item *pItem; - + if( resolveOrderGroupBy(&sNC, p, pGroupBy, "GROUP") || db->mallocFailed ){ return WRC_Abort; } @@ -61262,7 +72909,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** checking on function usage and set a flag if any aggregate functions ** are seen. ** -** To resolve table columns references we look for nodes (or subtrees) of the +** To resolve table columns references we look for nodes (or subtrees) of the ** form X.Y.Z or Y.Z or just Z where ** ** X: The name of a database. Ex: "main" or "temp" or @@ -61294,7 +72941,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** ** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b; ** -** Function calls are checked to make sure that the function is +** Function calls are checked to make sure that the function is ** defined and that the correct number of arguments are specified. ** If the function is an aggregate function, then the pNC->hasAgg is ** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION. @@ -61304,7 +72951,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** An error message is left in pParse if anything is amiss. The number ** if errors is returned. */ -SQLITE_PRIVATE int sqlite3ResolveExprNames( +SQLITE_PRIVATE int sqlite3ResolveExprNames( NameContext *pNC, /* Namespace to resolve expressions in. */ Expr *pExpr /* The expression to be analyzed. */ ){ @@ -61391,7 +73038,7 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames( ** Return the 'affinity' of the expression pExpr if any. ** ** If pExpr is a column, a reference to a column via an 'AS' alias, -** or a sub-select with a column as the return value, then the +** or a sub-select with a column as the return value, then the ** affinity of that column is returned. Otherwise, 0x00 is returned, ** indicating no affinity for the expression. ** @@ -61415,7 +73062,7 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){ return sqlite3AffinityType(pExpr->u.zToken); } #endif - if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER) + if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER) && pExpr->pTab!=0 ){ /* op==TK_REGISTER && pExpr->pTab!=0 happens when pExpr was originally @@ -61429,24 +73076,31 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){ } /* +** Set the explicit collating sequence for an expression to the +** collating sequence supplied in the second argument. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr *pExpr, CollSeq *pColl){ + if( pExpr && pColl ){ + pExpr->pColl = pColl; + pExpr->flags |= EP_ExpCollate; + } + return pExpr; +} + +/* ** Set the collating sequence for expression pExpr to be the collating ** sequence named by pToken. Return a pointer to the revised expression. ** The collating sequence is marked as "explicit" using the EP_ExpCollate ** flag. An explicit collating sequence will override implicit ** collating sequences. */ -SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pCollName){ +SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr *pExpr, Token *pCollName){ char *zColl = 0; /* Dequoted name of collation sequence */ CollSeq *pColl; sqlite3 *db = pParse->db; zColl = sqlite3NameFromToken(db, pCollName); - if( pExpr && zColl ){ - pColl = sqlite3LocateCollSeq(pParse, zColl); - if( pColl ){ - pExpr->pColl = pColl; - pExpr->flags |= EP_ExpCollate; - } - } + pColl = sqlite3LocateCollSeq(pParse, zColl); + sqlite3ExprSetColl(pExpr, pColl); sqlite3DbFree(db, zColl); return pExpr; } @@ -61458,7 +73112,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pColl SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ CollSeq *pColl = 0; Expr *p = pExpr; - while( ALWAYS(p) ){ + while( p ){ int op; pColl = p->pColl; if( pColl ) break; @@ -61483,7 +73137,7 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ } p = p->pLeft; } - if( sqlite3CheckCollSeq(pParse, pColl) ){ + if( sqlite3CheckCollSeq(pParse, pColl) ){ pColl = 0; } return pColl; @@ -61579,8 +73233,8 @@ static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){ ** it is not considered. */ SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq( - Parse *pParse, - Expr *pLeft, + Parse *pParse, + Expr *pLeft, Expr *pRight ){ CollSeq *pColl; @@ -61634,7 +73288,7 @@ SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse *pParse, int nHeight){ int rc = SQLITE_OK; int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH]; if( nHeight>mxHeight ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "Expression tree is too large (maximum depth %d)", mxHeight ); rc = SQLITE_ERROR; @@ -61680,10 +73334,10 @@ static void heightOfSelect(Select *p, int *pnHeight){ } /* -** Set the Expr.nHeight variable in the structure passed as an -** argument. An expression with no children, Expr.pList or +** Set the Expr.nHeight variable in the structure passed as an +** argument. An expression with no children, Expr.pList or ** Expr.pSelect member has a height of 1. Any other expression -** has a height equal to the maximum height of any other +** has a height equal to the maximum height of any other ** referenced Expr plus one. */ static void exprSetHeight(Expr *p){ @@ -61755,6 +73409,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc( if( op!=TK_INTEGER || pToken->z==0 || sqlite3GetInt32(pToken->z, &iValue)==0 ){ nExtra = pToken->n+1; + assert( iValue>=0 ); } } pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra); @@ -61770,7 +73425,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc( pNew->u.zToken = (char*)&pNew[1]; memcpy(pNew->u.zToken, pToken->z, pToken->n); pNew->u.zToken[pToken->n] = 0; - if( dequote && nExtra>=3 + if( dequote && nExtra>=3 && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){ sqlite3Dequote(pNew->u.zToken); if( c=='"' ) pNew->flags |= EP_DblQuoted; @@ -61779,7 +73434,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc( } #if SQLITE_MAX_EXPR_DEPTH>0 pNew->nHeight = 1; -#endif +#endif } return pNew; } @@ -61850,6 +73505,9 @@ SQLITE_PRIVATE Expr *sqlite3PExpr( ){ Expr *p = sqlite3ExprAlloc(pParse->db, op, pToken, 1); sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); + if( p ) { + sqlite3ExprCheckHeight(pParse, p->nHeight); + } return p; } @@ -61890,7 +73548,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token * /* ** Assign a variable number to an expression that encodes a wildcard -** in the original SQL statement. +** in the original SQL statement. ** ** Wildcards consisting of a single "?" are assigned the next sequential ** variable number. @@ -61917,55 +73575,56 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ /* Wildcard of the form "?". Assign the next variable number */ assert( z[0]=='?' ); pExpr->iColumn = (ynVar)(++pParse->nVar); - }else if( z[0]=='?' ){ - /* Wildcard of the form "?nnn". Convert "nnn" to an integer and - ** use it as the variable number */ - int i = atoi((char*)&z[1]); - pExpr->iColumn = (ynVar)i; - testcase( i==0 ); - testcase( i==1 ); - testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); - testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); - if( i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ - sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", - db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); - } - if( i>pParse->nVar ){ - pParse->nVar = i; - } }else{ - /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable - ** number as the prior appearance of the same name, or if the name - ** has never appeared before, reuse the same variable number - */ - int i; - u32 n; - n = sqlite3Strlen30(z); - for(i=0; i<pParse->nVarExpr; i++){ - Expr *pE = pParse->apVarExpr[i]; - assert( pE!=0 ); - if( memcmp(pE->u.zToken, z, n)==0 && pE->u.zToken[n]==0 ){ - pExpr->iColumn = pE->iColumn; - break; + ynVar x = 0; + u32 n = sqlite3Strlen30(z); + if( z[0]=='?' ){ + /* Wildcard of the form "?nnn". Convert "nnn" to an integer and + ** use it as the variable number */ + i64 i; + int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); + pExpr->iColumn = x = (ynVar)i; + testcase( i==0 ); + testcase( i==1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); + if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ + sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", + db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); + x = 0; + } + if( i>pParse->nVar ){ + pParse->nVar = (int)i; + } + }else{ + /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable + ** number as the prior appearance of the same name, or if the name + ** has never appeared before, reuse the same variable number + */ + ynVar i; + for(i=0; i<pParse->nzVar; i++){ + if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){ + pExpr->iColumn = x = (ynVar)i+1; + break; + } } + if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar); } - if( i>=pParse->nVarExpr ){ - pExpr->iColumn = (ynVar)(++pParse->nVar); - if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){ - pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10; - pParse->apVarExpr = - sqlite3DbReallocOrFree( - db, - pParse->apVarExpr, - pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) - ); + if( x>0 ){ + if( x>pParse->nzVar ){ + char **a; + a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); + if( a==0 ) return; /* Error reported through db->mallocFailed */ + pParse->azVar = a; + memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); + pParse->nzVar = x; } - if( !db->mallocFailed ){ - assert( pParse->apVarExpr!=0 ); - pParse->apVarExpr[pParse->nVarExpr++] = pExpr; + if( z[0]!='?' || pParse->azVar[x-1]==0 ){ + sqlite3DbFree(db, pParse->azVar[x-1]); + pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); } } - } + } if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "too many SQL variables"); } @@ -61976,6 +73635,8 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ */ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ if( p==0 ) return; + /* Sanity check: Assert that the IntValue is non-negative if it exists */ + assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); if( !ExprHasAnyProperty(p, EP_TokenOnly) ){ sqlite3ExprDelete(db, p->pLeft); sqlite3ExprDelete(db, p->pRight); @@ -61994,7 +73655,7 @@ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ } /* -** Return the number of bytes allocated for the expression structure +** Return the number of bytes allocated for the expression structure ** passed as the first argument. This is always one of EXPR_FULLSIZE, ** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE. */ @@ -62009,14 +73670,14 @@ static int exprStructSize(Expr *p){ ** to store a copy of an expression or expression tree. They differ in ** how much of the tree is measured. ** -** dupedExprStructSize() Size of only the Expr structure +** dupedExprStructSize() Size of only the Expr structure ** dupedExprNodeSize() Size of Expr + space for token ** dupedExprSize() Expr + token + subtree components ** *************************************************************************** ** -** The dupedExprStructSize() function returns two values OR-ed together: -** (1) the space required for a copy of the Expr structure only and +** The dupedExprStructSize() function returns two values OR-ed together: +** (1) the space required for a copy of the Expr structure only and ** (2) the EP_xxx flags that indicate what the structure size should be. ** The return values is always one of: ** @@ -62045,7 +73706,7 @@ static int dupedExprStructSize(Expr *p, int flags){ nSize = EXPR_FULLSIZE; }else{ assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) ); - assert( !ExprHasProperty(p, EP_FromJoin) ); + assert( !ExprHasProperty(p, EP_FromJoin) ); assert( (p->flags2 & EP2_MallocedToken)==0 ); assert( (p->flags2 & EP2_Irreducible)==0 ); if( p->pLeft || p->pRight || p->pColl || p->x.pList ){ @@ -62058,7 +73719,7 @@ static int dupedExprStructSize(Expr *p, int flags){ } /* -** This function returns the space in bytes required to store the copy +** This function returns the space in bytes required to store the copy ** of the Expr structure and a copy of the Expr.u.zToken string (if that ** string is defined.) */ @@ -62071,16 +73732,16 @@ static int dupedExprNodeSize(Expr *p, int flags){ } /* -** Return the number of bytes required to create a duplicate of the +** Return the number of bytes required to create a duplicate of the ** expression passed as the first argument. The second argument is a ** mask containing EXPRDUP_XXX flags. ** ** The value returned includes space to create a copy of the Expr struct ** itself and the buffer referred to by Expr.u.zToken, if any. ** -** If the EXPRDUP_REDUCE flag is set, then the return value includes -** space to duplicate all Expr nodes in the tree formed by Expr.pLeft -** and Expr.pRight variables (but not for any structures pointed to or +** If the EXPRDUP_REDUCE flag is set, then the return value includes +** space to duplicate all Expr nodes in the tree formed by Expr.pLeft +** and Expr.pRight variables (but not for any structures pointed to or ** descended from the Expr.x.pList or Expr.x.pSelect variables). */ static int dupedExprSize(Expr *p, int flags){ @@ -62095,8 +73756,8 @@ static int dupedExprSize(Expr *p, int flags){ } /* -** This function is similar to sqlite3ExprDup(), except that if pzBuffer -** is not NULL then *pzBuffer is assumed to point to a buffer large enough +** This function is similar to sqlite3ExprDup(), except that if pzBuffer +** is not NULL then *pzBuffer is assumed to point to a buffer large enough ** to store the copy of expression p, the copies of p->u.zToken ** (if applicable), and the copies of the p->pLeft and p->pRight expressions, ** if any. Before returning, *pzBuffer is set to the first byte passed the @@ -62193,7 +73854,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ ** without effecting the originals. ** ** The expression list, ID, and source lists return by sqlite3ExprListDup(), -** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded +** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded ** by subsequent calls to sqlite*ListAppend() routines. ** ** Any tables that the SrcList might point to are not duplicated. @@ -62219,7 +73880,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags) if( pItem==0 ){ sqlite3DbFree(db, pNew); return 0; - } + } pOldItem = p->a; for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){ Expr *pOldExpr = pOldItem->pExpr; @@ -62236,7 +73897,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags) /* ** If cursors, triggers, views and subqueries are all omitted from -** the build, then none of the following routines, except for +** the build, then none of the following routines, except for ** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes ** called with a NULL argument. */ @@ -62260,7 +73921,9 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); pNewItem->jointype = pOldItem->jointype; pNewItem->iCursor = pOldItem->iCursor; - pNewItem->isPopulated = pOldItem->isPopulated; + pNewItem->addrFillSub = pOldItem->addrFillSub; + pNewItem->regReturn = pOldItem->regReturn; + pNewItem->isCorrelated = pOldItem->isCorrelated; pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex); pNewItem->notIndexed = pOldItem->notIndexed; pNewItem->pIndex = pOldItem->pIndex; @@ -62366,7 +74029,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend( } return pList; -no_mem: +no_mem: /* Avoid leaking memory if malloc has failed. */ sqlite3ExprDelete(db, pExpr); sqlite3ExprListDelete(db, pList); @@ -62560,16 +74223,17 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p){ */ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){ int rc = 0; + + /* If an expression is an integer literal that fits in a signed 32-bit + ** integer, then the EP_IntValue flag will have already been set */ + assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0 + || sqlite3GetInt32(p->u.zToken, &rc)==0 ); + if( p->flags & EP_IntValue ){ *pValue = p->u.iValue; return 1; } switch( p->op ){ - case TK_INTEGER: { - rc = sqlite3GetInt32(p->u.zToken, pValue); - assert( rc==0 ); - break; - } case TK_UPLUS: { rc = sqlite3ExprIsInteger(p->pLeft, pValue); break; @@ -62584,13 +74248,6 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){ } default: break; } - if( rc ){ - assert( ExprHasAnyProperty(p, EP_Reduced|EP_TokenOnly) - || (p->flags2 & EP2_MallocedToken)==0 ); - p->op = TK_INTEGER; - p->flags |= EP_IntValue; - p->u.iValue = *pValue; - } return rc; } @@ -62598,7 +74255,7 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){ ** Return FALSE if there is no chance that the expression can be NULL. ** ** If the expression might be NULL or if the expression is too complex -** to tell return TRUE. +** to tell return TRUE. ** ** This routine is used as an optimization, to skip OP_IsNull opcodes ** when we know that a value cannot be NULL. Hence, a false positive @@ -62626,7 +74283,7 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ /* ** Generate an OP_IsNull instruction that tests register iReg and jumps -** to location iDest if the value in iReg is NULL. The value in iReg +** to location iDest if the value in iReg is NULL. The value in iReg ** was computed by pExpr. If we can look at pExpr at compile-time and ** determine that it can never generate a NULL, then the OP_IsNull operation ** can be omitted. @@ -62741,7 +74398,7 @@ static int isCandidateForInOpt(Select *p){ ** either to test for membership of the (...) set or to iterate through ** its members, skipping duplicates. ** -** The index of the cursor opened on the b-tree (database table, database index +** The index of the cursor opened on the b-tree (database table, database index ** or ephermal table) is stored in pX->iTable before this function returns. ** The returned value of this function indicates the b-tree type, as follows: ** @@ -62761,13 +74418,13 @@ static int isCandidateForInOpt(Select *p){ ** to be unique - either because it is an INTEGER PRIMARY KEY or it ** has a UNIQUE constraint or UNIQUE index. ** -** If the prNotFound parameter is not 0, then the b-tree will be used -** for fast set membership tests. In this case an epheremal table must -** be used unless <column> is an INTEGER PRIMARY KEY or an index can +** If the prNotFound parameter is not 0, then the b-tree will be used +** for fast set membership tests. In this case an epheremal table must +** be used unless <column> is an INTEGER PRIMARY KEY or an index can ** be found with <column> as its left-most column. ** ** When the b-tree is being used for membership tests, the calling function -** needs to know whether or not the structure contains an SQL NULL +** needs to know whether or not the structure contains an SQL NULL ** value in order to correctly evaluate expressions like "X IN (Y, Z)". ** If there is any chance that the (...) might contain a NULL value at ** runtime, then a register is allocated and the register number written @@ -62799,7 +74456,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ assert( pX->op==TK_IN ); /* Check to see if an existing table or index can be used to - ** satisfy the query. This is preferable to generating a new + ** satisfy the query. This is preferable to generating a new ** ephemeral table. */ p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0); @@ -62810,7 +74467,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ Table *pTab = p->pSrc->a[0].pTab; /* Table <table>. */ int iDb; /* Database idx for pTab */ - + /* Code an OP_VerifyCookie and OP_TableLock for <table>. */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3CodeVerifySchema(pParse, iDb); @@ -62825,8 +74482,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ int iMem = ++pParse->nMem; int iAddr; - iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem); - sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); + iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem); sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); eType = IN_INDEX_ROWID; @@ -62840,7 +74496,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ ** to this collation sequence. */ CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pExpr); - /* Check that the affinity that will be used to perform the + /* Check that the affinity that will be used to perform the ** comparison is the same as the affinity of the column. If ** it is not, it is not possible to use any index. */ @@ -62855,11 +74511,10 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ int iMem = ++pParse->nMem; int iAddr; char *pKey; - + pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx); - iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem); - sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); - + iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem); + sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb, pKey,P4_KEYINFO_HANDOFF); VdbeComment((v, "%s", pIdx->zName)); @@ -62878,14 +74533,20 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ /* Could not found an existing table or index to use as the RHS b-tree. ** We will have to generate an ephemeral table to do the job. */ + double savedNQueryLoop = pParse->nQueryLoop; int rMayHaveNull = 0; eType = IN_INDEX_EPH; if( prNotFound ){ *prNotFound = rMayHaveNull = ++pParse->nMem; - }else if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){ - eType = IN_INDEX_ROWID; + }else{ + testcase( pParse->nQueryLoop>(double)1 ); + pParse->nQueryLoop = (double)1; + if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){ + eType = IN_INDEX_ROWID; + } } sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID); + pParse->nQueryLoop = savedNQueryLoop; }else{ pX->iTable = iTab; } @@ -62894,8 +74555,8 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ #endif /* -** Generate code for scalar subqueries used as an expression -** and IN operators. Examples: +** Generate code for scalar subqueries used as a subquery expression, EXISTS, +** or IN operators. Examples: ** ** (SELECT a FROM b) -- subquery ** EXISTS (SELECT a FROM b) -- EXISTS subquery @@ -62933,7 +74594,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( int rMayHaveNull, /* Register that records whether NULLs exist in RHS */ int isRowid /* If true, LHS of IN operator is a rowid */ ){ - int testAddr = 0; /* One-time test address */ + int testAddr = -1; /* One-time test address */ int rReg = 0; /* Register storing resulting */ Vdbe *v = sqlite3GetVdbe(pParse); if( NEVER(v==0) ) return 0; @@ -62951,17 +74612,25 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( */ if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->pTriggerTab ){ int mem = ++pParse->nMem; - sqlite3VdbeAddOp1(v, OP_If, mem); - testAddr = sqlite3VdbeAddOp2(v, OP_Integer, 1, mem); - assert( testAddr>0 || pParse->db->mallocFailed ); + testAddr = sqlite3VdbeAddOp1(v, OP_Once, mem); } +#ifndef SQLITE_OMIT_EXPLAIN + if( pParse->explain==2 ){ + char *zMsg = sqlite3MPrintf( + pParse->db, "EXECUTE %s%s SUBQUERY %d", testAddr>=0?"":"CORRELATED ", + pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId + ); + sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); + } +#endif + switch( pExpr->op ){ case TK_IN: { - char affinity; - KeyInfo keyInfo; - int addr; /* Address of OP_OpenEphemeral instruction */ - Expr *pLeft = pExpr->pLeft; + char affinity; /* Affinity of the LHS of the IN */ + KeyInfo keyInfo; /* Keyinfo for the generated table */ + int addr; /* Address of OP_OpenEphemeral instruction */ + Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */ if( rMayHaveNull ){ sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull); @@ -62970,7 +74639,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( affinity = sqlite3ExprAffinity(pLeft); /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)' - ** expression it is handled the same way. An ephemeral table is + ** expression it is handled the same way. An ephemeral table is ** filled with single-field index keys representing the results ** from the SELECT or the <exprlist>. ** @@ -62984,6 +74653,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( */ pExpr->iTable = pParse->nTab++; addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid); + if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED); memset(&keyInfo, 0, sizeof(keyInfo)); keyInfo.nField = 1; @@ -63000,15 +74670,16 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); dest.affinity = (u8)affinity; assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); + pExpr->x.pSelect->iLimit = 0; if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){ return 0; } pEList = pExpr->x.pSelect->pEList; - if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){ + if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){ keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pEList->a[0].pExpr); } - }else if( pExpr->x.pList!=0 ){ + }else if( ALWAYS(pExpr->x.pList!=0) ){ /* Case 2: expr IN (exprlist) ** ** For each expression, build an index key from the evaluation and @@ -63039,9 +74710,9 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( ** this code only executes once. Because for a non-constant ** expression we need to rerun this code each time. */ - if( testAddr && !sqlite3ExprIsConstant(pE2) ){ - sqlite3VdbeChangeToNoop(v, testAddr-1, 2); - testAddr = 0; + if( testAddr>=0 && !sqlite3ExprIsConstant(pE2) ){ + sqlite3VdbeChangeToNoop(v, testAddr); + testAddr = -1; } /* Evaluate the expression and insert it into the temp table */ @@ -63078,7 +74749,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( ** an integer 0 (not exists) or 1 (exists) into a memory cell ** and record that memory cell in iColumn. */ - static const Token one = { "1", 1 }; /* Token for literal value 1 */ Select *pSel; /* SELECT statement to encode */ SelectDest dest; /* How to deal with SELECt result */ @@ -63099,7 +74769,9 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( VdbeComment((v, "Init EXISTS result")); } sqlite3ExprDelete(pParse->db, pSel->pLimit); - pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &one); + pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, + &sqlite3IntTokens[1]); + pSel->iLimit = 0; if( sqlite3Select(pParse, pSel, &dest) ){ return 0; } @@ -63109,8 +74781,8 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( } } - if( testAddr ){ - sqlite3VdbeJumpHere(v, testAddr-1); + if( testAddr>=0 ){ + sqlite3VdbeJumpHere(v, testAddr); } sqlite3ExprCachePop(pParse, 1); @@ -63131,7 +74803,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( ** if the LHS is NULL or if the LHS is not contained within the RHS and the ** RHS contains one or more NULL values. ** -** This routine generates code will jump to destIfFalse if the LHS is not +** This routine generates code will jump to destIfFalse if the LHS is not ** contained within the RHS. If due to NULLs we cannot determine if the LHS ** is contained in the RHS then jump to destIfNull. If the LHS is contained ** within the RHS then fall through. @@ -63167,8 +74839,20 @@ static void sqlite3ExprCodeIN( sqlite3ExprCachePush(pParse); r1 = sqlite3GetTempReg(pParse); sqlite3ExprCode(pParse, pExpr->pLeft, r1); - sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); + /* If the LHS is NULL, then the result is either false or NULL depending + ** on whether the RHS is empty or not, respectively. + */ + if( destIfNull==destIfFalse ){ + /* Shortcut for the common case where the false and NULL outcomes are + ** the same. */ + sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); + }else{ + int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); + sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); + sqlite3VdbeJumpHere(v, addr1); + } if( eType==IN_INDEX_ROWID ){ /* In this case, the RHS is the ROWID of table b-tree @@ -63180,9 +74864,9 @@ static void sqlite3ExprCodeIN( */ sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1); - /* If the set membership test fails, then the result of the + /* If the set membership test fails, then the result of the ** "x IN (...)" expression must be either 0 or NULL. If the set - ** contains no NULL values, then the result is 0. If the set + ** contains no NULL values, then the result is 0. If the set ** contains one or more NULL values, then the result of the ** expression is also NULL. */ @@ -63228,7 +74912,7 @@ static void sqlite3ExprCodeIN( sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull); sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); - /* The OP_Found at the top of this branch jumps here when true, + /* The OP_Found at the top of this branch jumps here when true, ** causing the overall IN expression evaluation to fall through. */ sqlite3VdbeJumpHere(v, j1); @@ -63256,7 +74940,7 @@ static char *dup8bytes(Vdbe *v, const char *in){ ** Generate an instruction that will put the floating point ** value described by z[0..n-1] into register iMem. ** -** The z[] string will probably not be zero-terminated. But the +** The z[] string will probably not be zero-terminated. But the ** z[n] character is guaranteed to be something that does not look ** like the continuation of the number. */ @@ -63264,7 +74948,7 @@ static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ if( ALWAYS(z!=0) ){ double value; char *zV; - sqlite3AtoF(z, &value); + sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ if( negateFlag ) value = -value; zV = dup8bytes(v, (char*)&value); @@ -63278,24 +74962,24 @@ static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ ** Generate an instruction that will put the integer describe by ** text z[0..n-1] into register iMem. ** -** The z[] string will probably not be zero-terminated. But the -** z[n] character is guaranteed to be something that does not look -** like the continuation of the number. +** Expr.u.zToken is always UTF8 and zero-terminated. */ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ Vdbe *v = pParse->pVdbe; if( pExpr->flags & EP_IntValue ){ int i = pExpr->u.iValue; + assert( i>=0 ); if( negFlag ) i = -i; sqlite3VdbeAddOp2(v, OP_Integer, i, iMem); }else{ + int c; + i64 value; const char *z = pExpr->u.zToken; assert( z!=0 ); - if( sqlite3FitsIn64Bits(z, negFlag) ){ - i64 value; + c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); + if( c==0 || (c==2 && negFlag) ){ char *zV; - sqlite3Atoi64(z, &value); - if( negFlag ) value = -value; + if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } zV = dup8bytes(v, (char*)&value); sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); }else{ @@ -63456,6 +75140,27 @@ static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){ } /* +** Generate code to extract the value of the iCol-th column of a table. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable( + Vdbe *v, /* The VDBE under construction */ + Table *pTab, /* The table containing the value */ + int iTabCur, /* The cursor for this table */ + int iCol, /* Index of the column to extract */ + int regOut /* Extract the valud into this register */ +){ + if( iCol<0 || iCol==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); + }else{ + int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; + sqlite3VdbeAddOp3(v, op, iTabCur, iCol, regOut); + } + if( iCol>=0 ){ + sqlite3ColumnDefault(v, pTab, iCol, regOut); + } +} + +/* ** Generate code that will extract the iColumn-th column from ** table pTab and store the column value in a register. An effort ** is made to store the column value in register iReg, but this is @@ -63481,15 +75186,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn( sqlite3ExprCachePinRegister(pParse, p->iReg); return p->iReg; } - } + } assert( v!=0 ); - if( iColumn<0 ){ - sqlite3VdbeAddOp2(v, OP_Rowid, iTable, iReg); - }else if( ALWAYS(pTab!=0) ){ - int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; - sqlite3VdbeAddOp3(v, op, iTable, iColumn, iReg); - sqlite3ColumnDefault(v, pTab, iColumn, iReg); - } + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg); sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg); return iReg; } @@ -63566,73 +75265,6 @@ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){ #endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */ /* -** If the last instruction coded is an ephemeral copy of any of -** the registers in the nReg registers beginning with iReg, then -** convert the last instruction from OP_SCopy to OP_Copy. -*/ -SQLITE_PRIVATE void sqlite3ExprHardCopy(Parse *pParse, int iReg, int nReg){ - VdbeOp *pOp; - Vdbe *v; - - assert( pParse->db->mallocFailed==0 ); - v = pParse->pVdbe; - assert( v!=0 ); - pOp = sqlite3VdbeGetOp(v, -1); - assert( pOp!=0 ); - if( pOp->opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1<iReg+nReg ){ - pOp->opcode = OP_Copy; - } -} - -/* -** Generate code to store the value of the iAlias-th alias in register -** target. The first time this is called, pExpr is evaluated to compute -** the value of the alias. The value is stored in an auxiliary register -** and the number of that register is returned. On subsequent calls, -** the register number is returned without generating any code. -** -** Note that in order for this to work, code must be generated in the -** same order that it is executed. -** -** Aliases are numbered starting with 1. So iAlias is in the range -** of 1 to pParse->nAlias inclusive. -** -** pParse->aAlias[iAlias-1] records the register number where the value -** of the iAlias-th alias is stored. If zero, that means that the -** alias has not yet been computed. -*/ -static int codeAlias(Parse *pParse, int iAlias, Expr *pExpr, int target){ -#if 0 - sqlite3 *db = pParse->db; - int iReg; - if( pParse->nAliasAlloc<pParse->nAlias ){ - pParse->aAlias = sqlite3DbReallocOrFree(db, pParse->aAlias, - sizeof(pParse->aAlias[0])*pParse->nAlias ); - testcase( db->mallocFailed && pParse->nAliasAlloc>0 ); - if( db->mallocFailed ) return 0; - memset(&pParse->aAlias[pParse->nAliasAlloc], 0, - (pParse->nAlias-pParse->nAliasAlloc)*sizeof(pParse->aAlias[0])); - pParse->nAliasAlloc = pParse->nAlias; - } - assert( iAlias>0 && iAlias<=pParse->nAlias ); - iReg = pParse->aAlias[iAlias-1]; - if( iReg==0 ){ - if( pParse->iCacheLevel>0 ){ - iReg = sqlite3ExprCodeTarget(pParse, pExpr, target); - }else{ - iReg = ++pParse->nMem; - sqlite3ExprCode(pParse, pExpr, iReg); - pParse->aAlias[iAlias-1] = iReg; - } - } - return iReg; -#else - UNUSED_PARAMETER(iAlias); - return sqlite3ExprCodeTarget(pParse, pExpr, target); -#endif -} - -/* ** 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. @@ -63672,7 +75304,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) inReg = pCol->iMem; break; }else if( pAggInfo->useSortingIdx ){ - sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdx, + sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, pCol->iSorterColumn, target); break; } @@ -63726,27 +75358,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) } #endif case TK_VARIABLE: { - VdbeOp *pOp; assert( !ExprHasProperty(pExpr, EP_IntValue) ); assert( pExpr->u.zToken!=0 ); assert( pExpr->u.zToken[0]!=0 ); - if( pExpr->u.zToken[1]==0 - && (pOp = sqlite3VdbeGetOp(v, -1))->opcode==OP_Variable - && pOp->p1+pOp->p3==pExpr->iColumn - && pOp->p2+pOp->p3==target - && pOp->p4.z==0 - ){ - /* If the previous instruction was a copy of the previous unnamed - ** parameter into the previous register, then simply increment the - ** repeat count on the prior instruction rather than making a new - ** instruction. - */ - pOp->p3++; - }else{ - sqlite3VdbeAddOp3(v, OP_Variable, pExpr->iColumn, target, 1); - if( pExpr->u.zToken[1]!=0 ){ - sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, 0); - } + sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); + if( pExpr->u.zToken[1]!=0 ){ + assert( pExpr->u.zToken[0]=='?' + || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 ); + sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC); } break; } @@ -63755,7 +75374,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) break; } case TK_AS: { - inReg = codeAlias(pParse, pExpr->iTable, pExpr->pLeft, target); + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); break; } #ifndef SQLITE_OMIT_CAST @@ -63835,7 +75454,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) case TK_BITOR: case TK_SLASH: case TK_LSHIFT: - case TK_RSHIFT: + case TK_RSHIFT: case TK_CONCAT: { assert( TK_AND==OP_And ); assert( TK_OR==OP_Or ); @@ -63990,7 +75609,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) ** see if it is a column in a virtual table. This is done because ** the left operand of infix functions (the operand we want to ** control overloading) ends up as the second argument to the - ** function. The expression "A glob B" is equivalent to + ** function. The expression "A glob B" is equivalent to ** "glob(B,A). We want to use the A in "A glob B" to test ** for function overloading. But we use the B term in "glob(B,A)". */ @@ -64009,7 +75628,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) } } if( pDef->flags & SQLITE_FUNC_NEEDCOLL ){ - if( !pColl ) pColl = db->pDfltColl; + if( !pColl ) pColl = db->pDfltColl; sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); } sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target, @@ -64092,7 +75711,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) ** ** The expression is implemented using an OP_Param opcode. The p1 ** parameter is set to 0 for an old.rowid reference, or to (i+1) - ** to reference another column of the old.* pseudo-table, where + ** to reference another column of the old.* pseudo-table, where ** i is the index of the column. For a new.rowid reference, p1 is ** set to (n+1), where n is the number of columns in each pseudo-table. ** For a reference to any other column in the new.* pseudo-table, p1 @@ -64106,7 +75725,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) ** ** p1==0 -> old.rowid p1==3 -> new.rowid ** p1==1 -> old.a p1==4 -> new.a - ** p1==2 -> old.b p1==5 -> new.b + ** p1==2 -> old.b p1==5 -> new.b */ Table *pTab = pExpr->pTab; int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn; @@ -64126,7 +75745,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) #ifndef SQLITE_OMIT_FLOATING_POINT /* If the column has REAL affinity, it may currently be stored as an ** integer. Use OP_RealAffinity to make sure it is really real. */ - if( pExpr->iColumn>=0 + if( pExpr->iColumn>=0 && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL ){ sqlite3VdbeAddOp1(v, OP_RealAffinity, target); @@ -64187,6 +75806,11 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) opCompare.op = TK_EQ; opCompare.pLeft = &cacheX; pTest = &opCompare; + /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001: + ** The value in regFree1 might get SCopy-ed into the file result. + ** So make sure that the regFree1 register is not reused for other + ** purposes and possibly overwritten. */ + regFree1 = 0; } for(i=0; i<nExpr; i=i+2){ sqlite3ExprCachePush(pParse); @@ -64213,14 +75837,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, target); } - assert( db->mallocFailed || pParse->nErr>0 + assert( db->mallocFailed || pParse->nErr>0 || pParse->iCacheLevel==iCacheLevel ); sqlite3VdbeResolveLabel(v, endLabel); break; } #ifndef SQLITE_OMIT_TRIGGER case TK_RAISE: { - assert( pExpr->affinity==OE_Rollback + assert( pExpr->affinity==OE_Rollback || pExpr->affinity==OE_Abort || pExpr->affinity==OE_Fail || pExpr->affinity==OE_Ignore @@ -64280,10 +75904,14 @@ SQLITE_PRIVATE int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ int inReg; assert( target>0 && target<=pParse->nMem ); - inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); - assert( pParse->pVdbe || pParse->db->mallocFailed ); - if( inReg!=target && pParse->pVdbe ){ - sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target); + if( pExpr && pExpr->op==TK_REGISTER ){ + sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target); + }else{ + inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); + assert( pParse->pVdbe || pParse->db->mallocFailed ); + if( inReg!=target && pParse->pVdbe ){ + sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target); + } } return target; } @@ -64296,7 +75924,7 @@ SQLITE_PRIVATE int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ ** and modify the expression so that the next time it is evaluated, ** the result is a copy of the cache register. ** -** This routine is used for expressions that are used multiple +** This routine is used for expressions that are used multiple ** times. They are evaluated once and the results of the expression ** are reused. */ @@ -64311,7 +75939,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int targe ** no way for a TK_REGISTER to exist here. But it seems prudent to ** keep the ALWAYS() in case the conditions above change with future ** modifications or enhancements. */ - if( ALWAYS(pExpr->op!=TK_REGISTER) ){ + if( ALWAYS(pExpr->op!=TK_REGISTER) ){ int iMem; iMem = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem); @@ -64328,12 +75956,12 @@ SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int targe ** ** * Any expression that evaluates to two or more opcodes. ** -** * Any OP_Integer, OP_Real, OP_String, OP_Blob, OP_Null, -** or OP_Variable that does not need to be placed in a +** * Any OP_Integer, OP_Real, OP_String, OP_Blob, OP_Null, +** or OP_Variable that does not need to be placed in a ** specific register. ** ** There is no point in factoring out single-instruction constant -** expressions that need to be placed in a particular register. +** expressions that need to be placed in a particular register. ** We could factor them out, but then we would end up adding an ** OP_SCopy instruction to move the value into the correct register ** later. We might as well just use the original instruction and @@ -64399,7 +76027,7 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){ case TK_CONST_FUNC: { /* The arguments to a function have a fixed destination. ** Mark them this way to avoid generated unneeded OP_SCopy - ** instructions. + ** instructions. */ ExprList *pList = pExpr->x.pList; assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); @@ -64430,9 +76058,22 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){ ** Preevaluate constant subexpressions within pExpr and store the ** results in registers. Modify pExpr so that the constant subexpresions ** are TK_REGISTER opcodes that refer to the precomputed values. +** +** This routine is a no-op if the jump to the cookie-check code has +** already occur. Since the cookie-check jump is generated prior to +** any other serious processing, this check ensures that there is no +** way to accidently bypass the constant initializations. +** +** This routine is also a no-op if the SQLITE_FactorOutConst optimization +** is disabled via the sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) +** interface. This allows test logic to verify that the same answer is +** obtained for queries regardless of whether or not constants are +** precomputed into registers or if they are inserted in-line. */ SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){ Walker w; + if( pParse->cookieGoto ) return; + if( (pParse->db->flags & SQLITE_FactorOutConst)!=0 ) return; w.xExprCallback = evalConstExpr; w.xSelectCallback = 0; w.pParse = pParse; @@ -64456,19 +76097,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList( int i, n; assert( pList!=0 ); assert( target>0 ); + assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */ n = pList->nExpr; for(pItem=pList->a, i=0; i<n; i++, pItem++){ - if( pItem->iAlias ){ - int iReg = codeAlias(pParse, pItem->iAlias, pItem->pExpr, target+i); - Vdbe *v = sqlite3GetVdbe(pParse); - if( iReg!=target+i ){ - sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target+i); - } - }else{ - sqlite3ExprCode(pParse, pItem->pExpr, target+i); - } - if( doHardCopy && !pParse->db->mallocFailed ){ - sqlite3ExprHardCopy(pParse, target, n); + Expr *pExpr = pItem->pExpr; + int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); + if( inReg!=target+i ){ + sqlite3VdbeAddOp2(pParse->pVdbe, doHardCopy ? OP_Copy : OP_SCopy, + inReg, target+i); } } return n; @@ -64479,7 +76115,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList( ** ** x BETWEEN y AND z ** -** The above is equivalent to +** The above is equivalent to ** ** x>=y AND x<=z ** @@ -64633,6 +76269,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int exprCodeBetween(pParse, pExpr, dest, 1, jumpIfNull); break; } +#ifndef SQLITE_OMIT_SUBQUERY case TK_IN: { int destIfFalse = sqlite3VdbeMakeLabel(v); int destIfNull = jumpIfNull ? dest : destIfFalse; @@ -64641,6 +76278,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int sqlite3VdbeResolveLabel(v, destIfFalse); break; } +#endif default: { r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0); @@ -64650,7 +76288,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int } } sqlite3ReleaseTempReg(pParse, regFree1); - sqlite3ReleaseTempReg(pParse, regFree2); + sqlite3ReleaseTempReg(pParse, regFree2); } /* @@ -64774,6 +76412,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int exprCodeBetween(pParse, pExpr, dest, 0, jumpIfNull); break; } +#ifndef SQLITE_OMIT_SUBQUERY case TK_IN: { if( jumpIfNull ){ sqlite3ExprCodeIN(pParse, pExpr, dest, dest); @@ -64784,6 +76423,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int } break; } +#endif default: { r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0); @@ -64813,7 +76453,6 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int ** an incorrect 0 or 1 could lead to a malfunction. */ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){ - int i; if( pA==0||pB==0 ){ return pB==pA ? 0 : 2; } @@ -64826,18 +76465,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){ if( pA->op!=pB->op ) return 2; if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2; if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2; - - if( pA->x.pList && pB->x.pList ){ - if( pA->x.pList->nExpr!=pB->x.pList->nExpr ) return 2; - for(i=0; i<pA->x.pList->nExpr; i++){ - Expr *pExprA = pA->x.pList->a[i].pExpr; - Expr *pExprB = pB->x.pList->a[i].pExpr; - if( sqlite3ExprCompare(pExprA, pExprB) ) return 2; - } - }else if( pA->x.pList || pB->x.pList ){ - return 2; - } - + if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2; if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2; if( ExprHasProperty(pA, EP_IntValue) ){ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ @@ -64854,6 +76482,31 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){ return 0; } +/* +** Compare two ExprList objects. Return 0 if they are identical and +** non-zero if they differ in any way. +** +** This routine might return non-zero for equivalent ExprLists. The +** only consequence will be disabled optimizations. But this routine +** must never return 0 if the two ExprList objects are different, or +** a malfunction will result. +** +** Two NULL pointers are considered to be the same. But a NULL pointer +** always differs from a non-NULL pointer. +*/ +SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){ + int i; + if( pA==0 && pB==0 ) return 0; + if( pA==0 || pB==0 ) return 1; + if( pA->nExpr!=pB->nExpr ) return 1; + for(i=0; i<pA->nExpr; i++){ + Expr *pExprA = pA->a[i].pExpr; + Expr *pExprB = pB->a[i].pExpr; + if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1; + if( sqlite3ExprCompare(pExprA, pExprB) ) return 1; + } + return 0; +} /* ** Add a new element to the pAggInfo->aCol[] array. Return the index of @@ -64871,7 +76524,7 @@ static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ &i ); return i; -} +} /* ** Add a new element to the pAggInfo->aFunc[] array. Return the index of @@ -64880,7 +76533,7 @@ static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){ int i; pInfo->aFunc = sqlite3ArrayAllocate( - db, + db, pInfo->aFunc, sizeof(pInfo->aFunc[0]), 3, @@ -64889,7 +76542,7 @@ static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){ &i ); return i; -} +} /* ** This is the xExprCallback for a tree walker. It is used to @@ -64917,7 +76570,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); if( pExpr->iTable==pItem->iCursor ){ /* If we reach this point, it means that pExpr refers to a table - ** that is in the FROM clause of the aggregate query. + ** 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. @@ -64931,7 +76584,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ } } if( (k>=pAggInfo->nColumn) - && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 + && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 ){ pCol = &pAggInfo->aCol[k]; pCol->pTab = pExpr->pTab; @@ -64977,7 +76630,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ /* The pNC->nDepth==0 test causes aggregate functions in subqueries ** to be ignored */ if( pNC->nDepth==0 ){ - /* Check to see if pExpr is a duplicate of another aggregate + /* Check to see if pExpr is a duplicate of another aggregate ** function that is already in the pAggInfo structure */ struct AggInfo_func *pItem = pAggInfo->aFunc; @@ -65146,9 +76799,9 @@ SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ /* -** This function is used by SQL generated to implement the +** This function is used by SQL generated to implement the ** ALTER TABLE command. The first argument is the text of a CREATE TABLE or -** CREATE INDEX command. The second is a table name. The table name in +** CREATE INDEX command. The second is a table name. The table name in ** the CREATE TABLE or CREATE INDEX statement is replaced with the third ** argument and the result returned. Examples: ** @@ -65176,7 +76829,7 @@ static void renameTableFunc( UNUSED_PARAMETER(NotUsed); - /* The principle used to locate the table name in the CREATE TABLE + /* The principle used to locate the table name in the CREATE TABLE ** statement is that the table name is the first non-space token that ** is immediately followed by a TK_LP or TK_USING token. */ @@ -65201,7 +76854,7 @@ static void renameTableFunc( assert( len>0 ); } while( token!=TK_LP && token!=TK_USING ); - zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, + zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, zTableName, tname.z+tname.n); sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); } @@ -65210,7 +76863,7 @@ static void renameTableFunc( /* ** This C function implements an SQL user function that is used by SQL code ** generated by the ALTER TABLE ... RENAME command to modify the definition -** of any foreign key constraints that use the table being renamed as the +** of any foreign key constraints that use the table being renamed as the ** parent table. It is passed three arguments: ** ** 1) The complete text of the CREATE TABLE statement being modified, @@ -65253,7 +76906,7 @@ static void renameParentFunc( if( zParent==0 ) break; sqlite3Dequote(zParent); if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){ - char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", + char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", (zOutput?zOutput:""), z-zInput, zInput, (const char *)zNew ); sqlite3DbFree(db, zOutput); @@ -65264,7 +76917,7 @@ static void renameParentFunc( } } - zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), + zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC); sqlite3DbFree(db, zOutput); } @@ -65272,9 +76925,9 @@ static void renameParentFunc( #ifndef SQLITE_OMIT_TRIGGER /* This function is used by SQL generated to implement the -** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER -** statement. The second is a table name. The table name in the CREATE -** TRIGGER statement is replaced with the third argument and the result +** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER +** statement. The second is a table name. The table name in the CREATE +** TRIGGER statement is replaced with the third argument and the result ** returned. This is analagous to renameTableFunc() above, except for CREATE ** TRIGGER, not CREATE INDEX and CREATE TABLE. */ @@ -65296,7 +76949,7 @@ static void renameTriggerFunc( UNUSED_PARAMETER(NotUsed); - /* The principle used to locate the table name in the CREATE TRIGGER + /* The principle used to locate the table name in the CREATE TRIGGER ** statement is that the table name is the first token that is immediatedly ** preceded by either TK_ON or TK_DOT and immediatedly followed by one ** of TK_WHEN, TK_BEGIN or TK_FOR. @@ -65323,12 +76976,12 @@ static void renameTriggerFunc( assert( len>0 ); /* Variable 'dist' stores the number of tokens read since the most - ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN + ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN ** token is read and 'dist' equals 2, the condition stated above ** to be met. ** ** Note that ON cannot be a database, table or column name, so - ** there is no need to worry about syntax like + ** there is no need to worry about syntax like ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc. */ dist++; @@ -65340,7 +76993,7 @@ static void renameTriggerFunc( /* Variable tname now contains the token that is the old table-name ** in the CREATE TRIGGER statement. */ - zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, + zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, zTableName, tname.z+tname.n); sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); } @@ -65350,17 +77003,23 @@ static void renameTriggerFunc( /* ** Register built-in functions used to help implement ALTER TABLE */ -SQLITE_PRIVATE void sqlite3AlterFunctions(sqlite3 *db){ - sqlite3CreateFunc(db, "sqlite_rename_table", 2, SQLITE_UTF8, 0, - renameTableFunc, 0, 0); +SQLITE_PRIVATE void sqlite3AlterFunctions(void){ + static SQLITE_WSD FuncDef aAlterTableFuncs[] = { + FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc), #ifndef SQLITE_OMIT_TRIGGER - sqlite3CreateFunc(db, "sqlite_rename_trigger", 2, SQLITE_UTF8, 0, - renameTriggerFunc, 0, 0); + FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc), #endif #ifndef SQLITE_OMIT_FOREIGN_KEY - sqlite3CreateFunc(db, "sqlite_rename_parent", 3, SQLITE_UTF8, 0, - renameParentFunc, 0, 0); + FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc), #endif + }; + int i; + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); + FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAlterTableFuncs); + + for(i=0; i<ArraySize(aAlterTableFuncs); i++){ + sqlite3FuncDefInsert(pHash, &aFunc[i]); + } } /* @@ -65368,16 +77027,16 @@ SQLITE_PRIVATE void sqlite3AlterFunctions(sqlite3 *db){ ** ** name=<constant1> OR name=<constant2> OR ... ** -** If argument zWhere is NULL, then a pointer string containing the text +** If argument zWhere is NULL, then a pointer string containing the text ** "name=<constant>" is returned, where <constant> is the quoted version ** of the string passed as argument zConstant. The returned buffer is ** allocated using sqlite3DbMalloc(). It is the responsibility of the ** caller to ensure that it is eventually freed. ** -** If argument zWhere is not NULL, then the string returned is +** If argument zWhere is not NULL, then the string returned is ** "<where> OR name=<constant>", where <where> is the contents of zWhere. ** In this case zWhere is passed to sqlite3DbFree() before returning. -** +** */ static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){ char *zNew; @@ -65410,7 +77069,7 @@ static char *whereForeignKeys(Parse *pParse, Table *pTab){ /* ** Generate the text of a WHERE expression which can be used to select all ** temporary triggers on table pTab from the sqlite_temp_master table. If -** table pTab has no temporary triggers, or is itself stored in the +** table pTab has no temporary triggers, or is itself stored in the ** temporary database, NULL is returned. */ static char *whereTempTriggers(Parse *pParse, Table *pTab){ @@ -65418,9 +77077,9 @@ static char *whereTempTriggers(Parse *pParse, Table *pTab){ char *zWhere = 0; const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */ - /* If the table is not located in the temp-db (in which case NULL is + /* If the table is not located in the temp-db (in which case NULL is ** returned, loop through the tables list of triggers. For each trigger - ** that is not part of the temp-db schema, add a clause to the WHERE + ** that is not part of the temp-db schema, add a clause to the WHERE ** expression being built up in zWhere. */ if( pTab->pSchema!=pTempSchema ){ @@ -65431,6 +77090,11 @@ static char *whereTempTriggers(Parse *pParse, Table *pTab){ } } } + if( zWhere ){ + char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere); + sqlite3DbFree(pParse->db, zWhere); + zWhere = zNew; + } return zWhere; } @@ -65439,7 +77103,7 @@ static char *whereTempTriggers(Parse *pParse, Table *pTab){ ** pTab from the database, including triggers and temporary triggers. ** Argument zName is the name of the table in the database schema at ** the time the generated code is executed. This can be different from -** pTab->zName if this function is being called to code part of an +** pTab->zName if this function is being called to code part of an ** "ALTER TABLE RENAME TO" statement. */ static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){ @@ -65471,21 +77135,37 @@ static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){ /* Reload the table, index and permanent trigger schemas. */ zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName); if( !zWhere ) return; - sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); + sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); #ifndef SQLITE_OMIT_TRIGGER - /* Now, if the table is not stored in the temp database, reload any temp - ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. + /* Now, if the table is not stored in the temp database, reload any temp + ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. */ if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ - sqlite3VdbeAddOp4(v, OP_ParseSchema, 1, 0, 0, zWhere, P4_DYNAMIC); + sqlite3VdbeAddParseSchemaOp(v, 1, zWhere); } #endif } /* -** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" -** command. +** Parameter zName is the name of a table that is about to be altered +** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN). +** If the table is a system table, this function leaves an error message +** in pParse->zErr (system tables may not be altered) and returns non-zero. +** +** Or, if zName is not a system table, zero is returned. +*/ +static int isSystemTable(Parse *pParse, const char *zName){ + if( sqlite3Strlen30(zName)>6 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ + sqlite3ErrorMsg(pParse, "table %s may not be altered", zName); + return 1; + } + return 0; +} + +/* +** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" +** command. */ SQLITE_PRIVATE void sqlite3AlterRenameTable( Parse *pParse, /* Parser context. */ @@ -65495,7 +77175,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( int iDb; /* Database that contains the table */ char *zDb; /* Name of database iDb */ Table *pTab; /* Table being renamed */ - char *zName = 0; /* NULL-terminated version of pName */ + char *zName = 0; /* NULL-terminated version of pName */ sqlite3 *db = pParse->db; /* Database connection */ int nTabName; /* Number of UTF-8 characters in zTabName */ const char *zTabName; /* Original name of the table */ @@ -65504,7 +77184,9 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( char *zWhere = 0; /* Where clause to locate temp triggers */ #endif VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */ + int savedDbFlags; /* Saved value of db->flags */ + savedDbFlags = db->flags; if( NEVER(db->mallocFailed) ) goto exit_rename_table; assert( pSrc->nSrc==1 ); assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); @@ -65513,6 +77195,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( if( !pTab ) goto exit_rename_table; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); zDb = db->aDb[iDb].zName; + db->flags |= SQLITE_PreferBuiltin; /* Get a NULL terminated version of the new table name. */ zName = sqlite3NameFromToken(db, pName); @@ -65522,7 +77205,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( ** in database iDb. If so, this is an error. */ if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "there is already another table or index with this name: %s", zName); goto exit_rename_table; } @@ -65530,14 +77213,11 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( /* Make sure it is not a system table being altered, or a reserved name ** that the table is being renamed to. */ - if( sqlite3Strlen30(pTab->zName)>6 - && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) - ){ - sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName); + if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){ goto exit_rename_table; } - if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ - goto exit_rename_table; + if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto + exit_rename_table; } #ifndef SQLITE_OMIT_VIEW @@ -65566,7 +77246,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( } #endif - /* Begin a transaction and code the VerifyCookie for database iDb. + /* Begin a transaction and code the VerifyCookie for database iDb. ** Then modify the schema cookie (since the ALTER TABLE modifies the ** schema). Open a statement transaction if the table is a virtual ** table. @@ -65598,11 +77278,11 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) if( db->flags&SQLITE_ForeignKeys ){ - /* If foreign-key support is enabled, rewrite the CREATE TABLE + /* If foreign-key support is enabled, rewrite the CREATE TABLE ** statements corresponding to all child tables of foreign key constraints ** for which the renamed table is the parent table. */ if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){ - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE \"%w\".%s SET " "sql = sqlite_rename_parent(sql, %Q, %Q) " "WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere); @@ -65628,8 +77308,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( "'sqlite_autoindex_' || %Q || substr(name,%d+18) " "ELSE name END " "WHERE tbl_name=%Q AND " - "(type='table' OR type='index' OR type='trigger');", - zDb, SCHEMA_TABLE(iDb), zName, zName, zName, + "(type='table' OR type='index' OR type='trigger');", + zDb, SCHEMA_TABLE(iDb), zName, zName, zName, #ifndef SQLITE_OMIT_TRIGGER zName, #endif @@ -65637,7 +77317,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( ); #ifndef SQLITE_OMIT_AUTOINCREMENT - /* If the sqlite_sequence table exists in this database, then update + /* If the sqlite_sequence table exists in this database, then update ** it with the new table name. */ if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ @@ -65653,7 +77333,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( ** the temp database. */ if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE sqlite_temp_master SET " "sql = sqlite_rename_trigger(sql, %Q), " "tbl_name = %Q " @@ -65680,6 +77360,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( exit_rename_table: sqlite3SrcListDelete(db, pSrc); sqlite3DbFree(db, zName); + db->flags = savedDbFlags; } @@ -65748,7 +77429,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ } #endif - /* If the default value for the new column was specified with a + /* If the default value for the new column was specified with a ** literal NULL, then set pDflt to 0. This simplifies checking ** for an SQL NULL default below. */ @@ -65769,12 +77450,12 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ return; } if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "Cannot add a REFERENCES column with non-NULL default value"); return; } if( pCol->notNull && !pDflt ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "Cannot add a NOT NULL column with default value NULL"); return; } @@ -65799,17 +77480,20 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); if( zCol ){ char *zEnd = &zCol[pColDef->n-1]; + int savedDbFlags = db->flags; while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){ *zEnd-- = '\0'; } - sqlite3NestedParse(pParse, + db->flags |= SQLITE_PreferBuiltin; + sqlite3NestedParse(pParse, "UPDATE \"%w\".%s SET " "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " - "WHERE type = 'table' AND name = %Q", + "WHERE type = 'table' AND name = %Q", zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1, zTab ); sqlite3DbFree(db, zCol); + db->flags = savedDbFlags; } /* If the default value of the new column is NULL, then set the file @@ -65824,14 +77508,14 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ /* ** This function is called by the parser after the table-name in -** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument +** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument ** pSrc is the full-name of the table being altered. ** ** This routine makes a (partial) copy of the Table structure ** for the table being altered and sets Parse.pNewTable to point ** to it. Routines called by the parser as the column definition -** is parsed (i.e. sqlite3AddColumn()) add the new Column data to -** the copy. The copy of the Table structure is deleted by tokenize.c +** is parsed (i.e. sqlite3AddColumn()) add the new Column data to +** the copy. The copy of the Table structure is deleted by tokenize.c ** after parsing is finished. ** ** Routine sqlite3AlterFinishAddColumn() will be called to complete @@ -65865,6 +77549,9 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); goto exit_begin_add_column; } + if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){ + goto exit_begin_add_column; + } assert( pTab->addColOffset>0 ); iDb = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -65880,7 +77567,6 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ if( !pNew ) goto exit_begin_add_column; pParse->pNewTable = pNew; pNew->nRef = 1; - pNew->dbMem = pTab->dbMem; pNew->nCol = pTab->nCol; assert( pNew->nCol>0 ); nAlloc = (((pNew->nCol-1)/8)*8)+8; @@ -65941,7 +77627,7 @@ exit_begin_add_column: ** ** If the sqlite_stat1 tables does not previously exist, it is created. ** Similarly, if the sqlite_stat2 table does not exist and the library -** is compiled with SQLITE_ENABLE_STAT2 defined, it is created. +** is compiled with SQLITE_ENABLE_STAT2 defined, it is created. ** ** Argument zWhere may be a pointer to a buffer containing a table name, ** or it may be a NULL pointer. If it is not NULL, then all entries in @@ -65953,9 +77639,10 @@ static void openStatTable( Parse *pParse, /* Parsing context */ int iDb, /* The database we are looking in */ int iStatCur, /* Open the sqlite_stat1 table on this cursor */ - const char *zWhere /* Delete entries associated with this table */ + const char *zWhere, /* Delete entries for this table or index */ + const char *zWhereType /* Either "tbl" or "idx" */ ){ - static struct { + static const struct { const char *zName; const char *zCols; } aTable[] = { @@ -65981,9 +77668,9 @@ static void openStatTable( const char *zTab = aTable[i].zName; Table *pStat; if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){ - /* The sqlite_stat[12] table does not exist. Create it. Note that a - ** side-effect of the CREATE TABLE statement is to leave the rootpage - ** of the new table in register pParse->regRoot. This is important + /* The sqlite_stat[12] table does not exist. Create it. Note that a + ** side-effect of the CREATE TABLE statement is to leave the rootpage + ** of the new table in register pParse->regRoot. This is important ** because the OpenWrite opcode below will be needing it. */ sqlite3NestedParse(pParse, "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols @@ -65991,14 +77678,14 @@ static void openStatTable( aRoot[i] = pParse->regRoot; aCreateTbl[i] = 1; }else{ - /* The table already exists. If zWhere is not NULL, delete all entries + /* The table already exists. If zWhere is not NULL, delete all entries ** associated with the table zWhere. If zWhere is NULL, delete the ** entire contents of the table. */ aRoot[i] = pStat->tnum; sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); if( zWhere ){ sqlite3NestedParse(pParse, - "DELETE FROM %Q.%s WHERE tbl=%Q", pDb->zName, zTab, zWhere + "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere ); }else{ /* The sqlite_stat[12] table already exists. Delete all rows. */ @@ -66022,6 +77709,7 @@ static void openStatTable( static void analyzeOneTable( Parse *pParse, /* Parser context */ Table *pTab, /* Table whose indices are to be analyzed */ + Index *pOnlyIdx, /* If not NULL, only analyze this one index */ int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ int iMem /* Available memory locations begin here */ ){ @@ -66032,7 +77720,7 @@ static void analyzeOneTable( int i; /* Loop counter */ int topOfLoop; /* The top of the loop */ int endOfLoop; /* The end of the loop */ - int addr; /* The address of an instruction */ + int jZeroRows = -1; /* Jump from here if number of rows is zero */ int iDb; /* Index of database containing pTab */ int regTabname = iMem++; /* Register containing table name */ int regIdxname = iMem++; /* Register containing index name */ @@ -66043,6 +77731,7 @@ static void analyzeOneTable( int regRowid = iMem++; /* Rowid for the inserted record */ #ifdef SQLITE_ENABLE_STAT2 + int addr = 0; /* Instruction address */ int regTemp2 = iMem++; /* Temporary use register */ int regSamplerecno = iMem++; /* Index of next sample to record */ int regRecno = iMem++; /* Current sample index */ @@ -66051,13 +77740,21 @@ static void analyzeOneTable( #endif v = sqlite3GetVdbe(pParse); - if( v==0 || NEVER(pTab==0) || pTab->pIndex==0 ){ - /* Do no analysis for tables that have no indices */ + if( v==0 || NEVER(pTab==0) ){ + return; + } + if( pTab->tnum==0 ){ + /* Do not gather statistics on views or virtual tables */ + return; + } + if( memcmp(pTab->zName, "sqlite_", 7)==0 ){ + /* Do not gather statistics on system tables */ return; } assert( sqlite3BtreeHoldsAllMutexes(db) ); iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, db->aDb[iDb].zName ) ){ @@ -66069,10 +77766,14 @@ static void analyzeOneTable( sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); iIdxCur = pParse->nTab++; + sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - int nCol = pIdx->nColumn; - KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); + int nCol; + KeyInfo *pKey; + if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; + nCol = pIdx->nColumn; + pKey = sqlite3IndexKeyinfo(pParse, pIdx); if( iMem+1+(nCol*2)>pParse->nMem ){ pParse->nMem = iMem+1+(nCol*2); } @@ -66083,10 +77784,7 @@ static void analyzeOneTable( (char *)pKey, P4_KEYINFO_HANDOFF); VdbeComment((v, "%s", pIdx->zName)); - /* Populate the registers containing the table and index names. */ - if( pTab->pIndex==pIdx ){ - sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); - } + /* Populate the register containing the index name. */ sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0); #ifdef SQLITE_ENABLE_STAT2 @@ -66117,18 +77815,18 @@ static void analyzeOneTable( /* The block of memory cells initialized here is used as follows. ** - ** iMem: + ** iMem: ** The total number of rows in the table. ** - ** iMem+1 .. iMem+nCol: - ** Number of distinct entries in index considering the - ** left-most N columns only, where N is between 1 and nCol, + ** iMem+1 .. iMem+nCol: + ** Number of distinct entries in index considering the + ** left-most N columns only, where N is between 1 and nCol, ** inclusive. ** - ** iMem+nCol+1 .. Mem+2*nCol: + ** iMem+nCol+1 .. Mem+2*nCol: ** Previous value of indexed columns, from left to right. ** - ** Cells iMem through iMem+nCol are initialized to 0. The others are + ** Cells iMem through iMem+nCol are initialized to 0. The others are ** initialized to contain an SQL NULL. */ for(i=0; i<=nCol; i++){ @@ -66146,14 +77844,15 @@ static void analyzeOneTable( sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1); for(i=0; i<nCol; i++){ + CollSeq *pColl; sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol); -#ifdef SQLITE_ENABLE_STAT2 if( i==0 ){ +#ifdef SQLITE_ENABLE_STAT2 /* Check if the record that cursor iIdxCur points to contains a ** value that should be stored in the sqlite_stat2 table. If so, ** store it. */ int ne = sqlite3VdbeAddOp3(v, OP_Ne, regRecno, 0, regSamplerecno); - assert( regTabname+1==regIdxname + assert( regTabname+1==regIdxname && regTabname+2==regSampleno && regTabname+3==regCol ); @@ -66177,23 +77876,32 @@ static void analyzeOneTable( sqlite3VdbeJumpHere(v, ne); sqlite3VdbeAddOp2(v, OP_AddImm, regRecno, 1); - } #endif - sqlite3VdbeAddOp3(v, OP_Ne, regCol, 0, iMem+nCol+i+1); - /**** TODO: add collating sequence *****/ - sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); + /* Always record the very first row */ + sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1); + } + assert( pIdx->azColl!=0 ); + assert( pIdx->azColl[i]!=0 ); + pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); + sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1, + (char*)pColl, P4_COLLSEQ); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); } if( db->mallocFailed ){ - /* If a malloc failure has occurred, then the result of the expression - ** passed as the second argument to the call to sqlite3VdbeJumpHere() + /* If a malloc failure has occurred, then the result of the expression + ** passed as the second argument to the call to sqlite3VdbeJumpHere() ** below may be negative. Which causes an assert() to fail (or an ** out-of-bounds write if SQLITE_DEBUG is not defined). */ return; } sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop); for(i=0; i<nCol; i++){ - sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-(nCol*2)); + int addr2 = sqlite3VdbeCurrentAddr(v) - (nCol*2); + if( i==0 ){ + sqlite3VdbeJumpHere(v, addr2-1); /* Set jump dest for the OP_IfNot */ + } + sqlite3VdbeJumpHere(v, addr2); /* Set jump dest for the OP_Ne */ sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1); } @@ -66217,12 +77925,14 @@ static void analyzeOneTable( ** ** I = (K+D-1)/D ** - ** If K==0 then no entry is made into the sqlite_stat1 table. + ** If K==0 then no entry is made into the sqlite_stat1 table. ** If K>0 then it is always the case the D>0 so division by zero ** is never possible. */ - addr = sqlite3VdbeAddOp1(v, OP_IfNot, iMem); sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regSampleno); + if( jZeroRows<0 ){ + jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem); + } for(i=0; i<nCol; i++){ sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0); sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno); @@ -66236,13 +77946,33 @@ static void analyzeOneTable( sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid); sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); - sqlite3VdbeJumpHere(v, addr); } + + /* If the table has no indices, create a single sqlite_stat1 entry + ** containing NULL as the index name and the row count as the content. + */ + if( pTab->pIndex==0 ){ + sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb); + VdbeComment((v, "%s", pTab->zName)); + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regSampleno); + sqlite3VdbeAddOp1(v, OP_Close, iIdxCur); + jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regSampleno); + }else{ + sqlite3VdbeJumpHere(v, jZeroRows); + jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto); + } + sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + if( pParse->nMem<regRec ) pParse->nMem = regRec; + sqlite3VdbeJumpHere(v, jZeroRows); } /* ** Generate code that will cause the most recent index analysis to -** be laoded into internal hash tables where is can be used. +** be loaded into internal hash tables where is can be used. */ static void loadAnalysis(Parse *pParse, int iDb){ Vdbe *v = sqlite3GetVdbe(pParse); @@ -66264,20 +77994,22 @@ static void analyzeDatabase(Parse *pParse, int iDb){ sqlite3BeginWriteOperation(pParse, 0, iDb); iStatCur = pParse->nTab; pParse->nTab += 2; - openStatTable(pParse, iDb, iStatCur, 0); + openStatTable(pParse, iDb, iStatCur, 0, 0); iMem = pParse->nMem+1; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ Table *pTab = (Table*)sqliteHashData(k); - analyzeOneTable(pParse, pTab, iStatCur, iMem); + analyzeOneTable(pParse, pTab, 0, iStatCur, iMem); } loadAnalysis(pParse, iDb); } /* ** Generate code that will do an analysis of a single table in -** a database. +** a database. If pOnlyIdx is not NULL then it is a single index +** in pTab that should be analyzed. */ -static void analyzeTable(Parse *pParse, Table *pTab){ +static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ int iDb; int iStatCur; @@ -66287,8 +78019,12 @@ static void analyzeTable(Parse *pParse, Table *pTab){ sqlite3BeginWriteOperation(pParse, 0, iDb); iStatCur = pParse->nTab; pParse->nTab += 2; - openStatTable(pParse, iDb, iStatCur, pTab->zName); - analyzeOneTable(pParse, pTab, iStatCur, pParse->nMem+1); + if( pOnlyIdx ){ + openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx"); + }else{ + openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); + } + analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1); loadAnalysis(pParse, iDb); } @@ -66310,6 +78046,7 @@ SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ int i; char *z, *zDb; Table *pTab; + Index *pIdx; Token *pTableName; /* Read the database schema. If an error occurs, leave an error message @@ -66334,11 +78071,12 @@ SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ }else{ z = sqlite3NameFromToken(db, pName1); if( z ){ - pTab = sqlite3LocateTable(pParse, 0, z, 0); - sqlite3DbFree(db, z); - if( pTab ){ - analyzeTable(pParse, pTab); + if( (pIdx = sqlite3FindIndex(db, z, 0))!=0 ){ + analyzeTable(pParse, pIdx->pTable, pIdx); + }else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){ + analyzeTable(pParse, pTab, 0); } + sqlite3DbFree(db, z); } } }else{ @@ -66348,13 +78086,14 @@ SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ zDb = db->aDb[iDb].zName; z = sqlite3NameFromToken(db, pTableName); if( z ){ - pTab = sqlite3LocateTable(pParse, 0, z, zDb); - sqlite3DbFree(db, z); - if( pTab ){ - analyzeTable(pParse, pTab); + if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){ + analyzeTable(pParse, pIdx->pTable, pIdx); + }else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){ + analyzeTable(pParse, pTab, 0); } + sqlite3DbFree(db, z); } - } + } } } @@ -66370,37 +78109,54 @@ struct analysisInfo { /* ** This callback is invoked once for each index when reading the -** sqlite_stat1 table. +** sqlite_stat1 table. +** +** argv[0] = name of the table +** argv[1] = name of the index (might be NULL) +** argv[2] = results of analysis - on integer for each column ** -** argv[0] = name of the index -** argv[1] = results of analysis - on integer for each column +** Entries for which argv[1]==NULL simply record the number of rows in +** the table. */ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ analysisInfo *pInfo = (analysisInfo*)pData; Index *pIndex; - int i, c; + Table *pTable; + int i, c, n; unsigned int v; const char *z; - assert( argc==2 ); + assert( argc==3 ); UNUSED_PARAMETER2(NotUsed, argc); - if( argv==0 || argv[0]==0 || argv[1]==0 ){ + if( argv==0 || argv[0]==0 || argv[2]==0 ){ return 0; } - pIndex = sqlite3FindIndex(pInfo->db, argv[0], pInfo->zDatabase); - if( pIndex==0 ){ + pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase); + if( pTable==0 ){ return 0; } - z = argv[1]; - for(i=0; *z && i<=pIndex->nColumn; i++){ + if( argv[1] ){ + pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); + }else{ + pIndex = 0; + } + n = pIndex ? pIndex->nColumn : 0; + z = argv[2]; + for(i=0; *z && i<=n; i++){ v = 0; while( (c=z[0])>='0' && c<='9' ){ v = v*10 + c - '0'; z++; } + if( i==0 ) pTable->nRowEst = v; + if( pIndex==0 ) break; pIndex->aiRowEst[i] = v; if( *z==' ' ) z++; + if( memcmp(z, "unordered", 10)==0 ){ + pIndex->bUnordered = 1; + break; + } } return 0; } @@ -66409,21 +78165,20 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ ** If the Index.aSample variable is not NULL, delete the aSample[] array ** and its contents. */ -SQLITE_PRIVATE void sqlite3DeleteIndexSamples(Index *pIdx){ +SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ #ifdef SQLITE_ENABLE_STAT2 if( pIdx->aSample ){ int j; - sqlite3 *dbMem = pIdx->pTable->dbMem; for(j=0; j<SQLITE_INDEX_SAMPLES; j++){ IndexSample *p = &pIdx->aSample[j]; if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){ - sqlite3DbFree(pIdx->pTable->dbMem, p->u.z); + sqlite3DbFree(db, p->u.z); } } - sqlite3DbFree(dbMem, pIdx->aSample); - pIdx->aSample = 0; + sqlite3DbFree(db, pIdx->aSample); } #else + UNUSED_PARAMETER(db); UNUSED_PARAMETER(pIdx); #endif } @@ -66435,11 +78190,11 @@ SQLITE_PRIVATE void sqlite3DeleteIndexSamples(Index *pIdx){ ** Index.aSample[] arrays. ** ** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR -** is returned. In this case, even if SQLITE_ENABLE_STAT2 was defined -** during compilation and the sqlite_stat2 table is present, no data is +** is returned. In this case, even if SQLITE_ENABLE_STAT2 was defined +** during compilation and the sqlite_stat2 table is present, no data is ** read from it. ** -** If SQLITE_ENABLE_STAT2 was defined during compilation and the +** If SQLITE_ENABLE_STAT2 was defined during compilation and the ** sqlite_stat2 table is not present in the database, SQLITE_ERROR is ** returned. However, in this case, data is read from the sqlite_stat1 ** table (if it is present) before returning. @@ -66456,13 +78211,14 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ assert( iDb>=0 && iDb<db->nDb ); assert( db->aDb[iDb].pBt!=0 ); - assert( sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); /* Clear any prior statistics */ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); sqlite3DefaultRowEst(pIdx); - sqlite3DeleteIndexSamples(pIdx); + sqlite3DeleteIndexSamples(db, pIdx); + pIdx->aSample = 0; } /* Check to make sure the sqlite_stat1 table exists */ @@ -66473,8 +78229,8 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ } /* Load new statistics out of the sqlite_stat1 table */ - zSql = sqlite3MPrintf(db, - "SELECT idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase); + zSql = sqlite3MPrintf(db, + "SELECT tbl, idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase); if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ @@ -66491,7 +78247,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ if( rc==SQLITE_OK ){ sqlite3_stmt *pStmt = 0; - zSql = sqlite3MPrintf(db, + zSql = sqlite3MPrintf(db, "SELECT idx,sampleno,sample FROM %Q.sqlite_stat2", sInfo.zDatabase); if( !zSql ){ rc = SQLITE_NOMEM; @@ -66502,22 +78258,24 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ if( rc==SQLITE_OK ){ while( sqlite3_step(pStmt)==SQLITE_ROW ){ - char *zIndex = (char *)sqlite3_column_text(pStmt, 0); - Index *pIdx = sqlite3FindIndex(db, zIndex, sInfo.zDatabase); + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + + zIndex = (char *)sqlite3_column_text(pStmt, 0); + pIdx = zIndex ? sqlite3FindIndex(db, zIndex, sInfo.zDatabase) : 0; if( pIdx ){ int iSample = sqlite3_column_int(pStmt, 1); - sqlite3 *dbMem = pIdx->pTable->dbMem; - assert( dbMem==db || dbMem==0 ); if( iSample<SQLITE_INDEX_SAMPLES && iSample>=0 ){ int eType = sqlite3_column_type(pStmt, 2); if( pIdx->aSample==0 ){ static const int sz = sizeof(IndexSample)*SQLITE_INDEX_SAMPLES; - pIdx->aSample = (IndexSample *)sqlite3DbMallocZero(dbMem, sz); + pIdx->aSample = (IndexSample *)sqlite3DbMallocRaw(0, sz); if( pIdx->aSample==0 ){ db->mallocFailed = 1; break; } + memset(pIdx->aSample, 0, sz); } assert( pIdx->aSample ); @@ -66537,12 +78295,14 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ n = 24; } pSample->nByte = (u8)n; - pSample->u.z = sqlite3DbMallocRaw(dbMem, n); - if( pSample->u.z ){ - memcpy(pSample->u.z, z, n); + if( n < 1){ + pSample->u.z = 0; }else{ - db->mallocFailed = 1; - break; + pSample->u.z = sqlite3DbStrNDup(0, z, n); + if( pSample->u.z==0 ){ + db->mallocFailed = 1; + break; + } } } } @@ -66636,8 +78396,12 @@ static void attachFunc( sqlite3 *db = sqlite3_context_db_handle(context); const char *zName; const char *zFile; + char *zPath = 0; + char *zErr = 0; + unsigned int flags; Db *aNew; char *zErrDyn = 0; + sqlite3_vfs *pVfs; UNUSED_PARAMETER(NotUsed); @@ -66653,7 +78417,7 @@ static void attachFunc( ** * Specified database name already being used. */ if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){ - zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", + zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", db->aLimit[SQLITE_LIMIT_ATTACHED] ); goto attach_error; @@ -66690,9 +78454,18 @@ static void attachFunc( ** it to obtain the database schema. At this point the schema may ** or may not be initialised. */ - rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE, - db->openFlags | SQLITE_OPEN_MAIN_DB, - &aNew->pBt); + flags = db->openFlags; + rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); + return; + } + assert( pVfs ); + flags |= SQLITE_OPEN_MAIN_DB; + rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags); + sqlite3_free( zPath ); db->nDb++; if( rc==SQLITE_CONSTRAINT ){ rc = SQLITE_ERROR; @@ -66703,13 +78476,12 @@ static void attachFunc( if( !aNew->pSchema ){ rc = SQLITE_NOMEM; }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){ - zErrDyn = sqlite3MPrintf(db, + zErrDyn = sqlite3MPrintf(db, "attached databases must use the same text encoding as main database"); rc = SQLITE_ERROR; } pPager = sqlite3BtreePager(aNew->pBt); sqlite3PagerLockingMode(pPager, db->dfltLockMode); - sqlite3PagerJournalMode(pPager, db->dfltJournalMode); sqlite3BtreeSecureDelete(aNew->pBt, sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); } @@ -66733,7 +78505,7 @@ static void attachFunc( zErrDyn = sqlite3DbStrDup(db, "Invalid key value"); rc = SQLITE_ERROR; break; - + case SQLITE_TEXT: case SQLITE_BLOB: nKey = sqlite3_value_bytes(argv[2]); @@ -66744,14 +78516,16 @@ static void attachFunc( case SQLITE_NULL: /* No key specified. Use the key from the main database */ sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); - rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); + if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){ + rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); + } break; } } #endif /* If the file was opened successfully, read the schema for the new database. - ** If this fails, or if opening the file failed, then close the file and + ** If this fails, or if opening the file failed, then close the file and ** remove the entry from the db->aDb[] array. i.e. put everything back the way ** we found it. */ @@ -66768,7 +78542,7 @@ static void attachFunc( db->aDb[iDb].pBt = 0; db->aDb[iDb].pSchema = 0; } - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); db->nDb = iDb; if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ db->mallocFailed = 1; @@ -66779,7 +78553,7 @@ static void attachFunc( } goto attach_error; } - + return; attach_error: @@ -66840,7 +78614,7 @@ static void detachFunc( sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; pDb->pSchema = 0; - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); return; detach_error: @@ -66854,7 +78628,7 @@ detach_error: static void codeAttach( Parse *pParse, /* The parser context */ int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */ - FuncDef *pFunc, /* FuncDef wrapper for detachFunc() or attachFunc() */ + FuncDef const *pFunc,/* FuncDef wrapper for detachFunc() or attachFunc() */ Expr *pAuthArg, /* Expression to pass to authorization callback */ Expr *pFilename, /* Name of database file */ Expr *pDbname, /* Name of the database to use internally */ @@ -66869,7 +78643,7 @@ static void codeAttach( memset(&sName, 0, sizeof(NameContext)); sName.pParse = pParse; - if( + if( SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) || SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) || SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey)) @@ -66880,9 +78654,11 @@ static void codeAttach( #ifndef SQLITE_OMIT_AUTHORIZATION if( pAuthArg ){ - char *zAuthArg = pAuthArg->u.zToken; - if( NEVER(zAuthArg==0) ){ - goto attach_end; + char *zAuthArg; + if( pAuthArg->op==TK_STRING ){ + zAuthArg = pAuthArg->u.zToken; + }else{ + zAuthArg = 0; } rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); if(rc!=SQLITE_OK ){ @@ -66911,7 +78687,7 @@ static void codeAttach( */ sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH)); } - + attach_end: sqlite3ExprDelete(db, pFilename); sqlite3ExprDelete(db, pDbname); @@ -66924,7 +78700,7 @@ attach_end: ** DETACH pDbname */ SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){ - static FuncDef detach_func = { + static const FuncDef detach_func = { 1, /* nArg */ SQLITE_UTF8, /* iPrefEnc */ 0, /* flags */ @@ -66934,7 +78710,8 @@ SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){ 0, /* xStep */ 0, /* xFinalize */ "sqlite_detach", /* zName */ - 0 /* pHash */ + 0, /* pHash */ + 0 /* pDestructor */ }; codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname); } @@ -66945,7 +78722,7 @@ SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){ ** ATTACH p AS pDbname KEY pKey */ SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ - static FuncDef attach_func = { + static const FuncDef attach_func = { 3, /* nArg */ SQLITE_UTF8, /* iPrefEnc */ 0, /* flags */ @@ -66955,7 +78732,8 @@ SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *p 0, /* xStep */ 0, /* xFinalize */ "sqlite_attach", /* zName */ - 0 /* pHash */ + 0, /* pHash */ + 0 /* pDestructor */ }; codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey); } @@ -67231,10 +79009,10 @@ SQLITE_PRIVATE int sqlite3AuthReadCol( /* ** The pExpr should be a TK_COLUMN expression. The table referred to -** is in pTabList or else it is the NEW or OLD table of a trigger. +** is in pTabList or else it is the NEW or OLD table of a trigger. ** Check to see if it is OK to read this particular column. ** -** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN +** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN ** instruction into a TK_NULL. If the auth function returns SQLITE_DENY, ** then generate an error. */ @@ -67333,7 +79111,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck( */ SQLITE_PRIVATE void sqlite3AuthContextPush( Parse *pParse, - AuthContext *pContext, + AuthContext *pContext, const char *zContext ){ assert( pParse ); @@ -67404,7 +79182,7 @@ struct TableLock { }; /* -** Record the fact that we want to lock a table at run-time. +** Record the fact that we want to lock a table at run-time. ** ** The table to be locked has root page iTab and is found in database iDb. ** A read or a write lock can be taken depending on isWritelock. @@ -67455,7 +79233,7 @@ SQLITE_PRIVATE void sqlite3TableLock( */ static void codeTableLocks(Parse *pParse){ int i; - Vdbe *pVdbe; + Vdbe *pVdbe; pVdbe = sqlite3GetVdbe(pParse); assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */ @@ -67494,7 +79272,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ ** vdbe program */ v = sqlite3GetVdbe(pParse); - assert( !pParse->isMultiWrite + assert( !pParse->isMultiWrite || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ sqlite3VdbeAddOp0(v, OP_Halt); @@ -67506,7 +79284,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ ** on each used database. */ if( pParse->cookieGoto>0 ){ - u32 mask; + yDbMask mask; int iDb; sqlite3VdbeJumpHere(v, pParse->cookieGoto-1); for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ @@ -67514,7 +79292,10 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0); if( db->init.busy==0 ){ - sqlite3VdbeAddOp2(v,OP_VerifyCookie, iDb, pParse->cookieValue[iDb]); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + sqlite3VdbeAddOp3(v, OP_VerifyCookie, + iDb, pParse->cookieValue[iDb], + db->aDb[iDb].pSchema->iGeneration); } } #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -67528,8 +79309,8 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ } #endif - /* Once all the cookies have been verified and transactions opened, - ** obtain the required table-locks. This is a no-op unless the + /* 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); @@ -67555,9 +79336,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ /* A minimum of one cursor is required if autoincrement is used * See ticket [a696379c1f08866] */ if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; - sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem, - pParse->nTab, pParse->nMaxArg, pParse->explain, - pParse->isMultiWrite && pParse->mayAbort); + sqlite3VdbeMakeReady(v, pParse); pParse->rc = SQLITE_DONE; pParse->colNamesSet = 0; }else{ @@ -67627,9 +79406,12 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const cha int nName; assert( zName!=0 ); nName = sqlite3Strlen30(zName); + /* All mutexes are required for schema access. Make sure we hold them. */ + assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); for(i=OMIT_TEMPDB; i<db->nDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, nName); if( p ) break; } @@ -67674,7 +79456,7 @@ SQLITE_PRIVATE Table *sqlite3LocateTable( } /* -** Locate the in-memory structure that describes +** Locate the in-memory structure that describes ** a particular index given the name of that index ** and the name of the database that contains the index. ** Return NULL if not found. @@ -67689,11 +79471,14 @@ SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const cha Index *p = 0; int i; int nName = sqlite3Strlen30(zName); + /* All mutexes are required for schema access. Make sure we hold them. */ + assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); for(i=OMIT_TEMPDB; i<db->nDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ Schema *pSchema = db->aDb[j].pSchema; assert( pSchema ); if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); p = sqlite3HashFind(&pSchema->idxHash, zName, nName); if( p ) break; } @@ -67703,34 +79488,15 @@ SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const cha /* ** Reclaim the memory used by an index */ -static void freeIndex(Index *p){ - sqlite3 *db = p->pTable->dbMem; +static void freeIndex(sqlite3 *db, Index *p){ #ifndef SQLITE_OMIT_ANALYZE - sqlite3DeleteIndexSamples(p); + sqlite3DeleteIndexSamples(db, p); #endif sqlite3DbFree(db, p->zColAff); sqlite3DbFree(db, p); } /* -** Remove the given index from the index hash table, and free -** its memory structures. -** -** The index is removed from the database hash tables but -** it is not unlinked from the Table that it indexes. -** Unlinking from the Table must be done by the calling function. -*/ -static void sqlite3DeleteIndex(Index *p){ - Index *pOld; - const char *zName = p->zName; - - pOld = sqlite3HashInsert(&p->pSchema->idxHash, zName, - sqlite3Strlen30(zName), 0); - assert( pOld==0 || pOld==p ); - freeIndex(p); -} - -/* ** For the index called zIdxName which is found in the database iDb, ** unlike that index from its Table then remove the index from ** the index hash table and free all memory structures associated @@ -67739,11 +79505,13 @@ static void sqlite3DeleteIndex(Index *p){ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){ Index *pIndex; int len; - Hash *pHash = &db->aDb[iDb].pSchema->idxHash; + Hash *pHash; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pHash = &db->aDb[iDb].pSchema->idxHash; len = sqlite3Strlen30(zIdxName); pIndex = sqlite3HashInsert(pHash, zIdxName, len, 0); - if( pIndex ){ + if( ALWAYS(pIndex) ){ if( pIndex->pTable->pIndex==pIndex ){ pIndex->pTable->pIndex = pIndex->pNext; }else{ @@ -67756,7 +79524,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char p->pNext = pIndex->pNext; } } - freeIndex(pIndex); + freeIndex(db, pIndex); } db->flags |= SQLITE_InternChanges; } @@ -67768,26 +79536,42 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char ** if there were schema changes during the transaction or if a ** schema-cookie mismatch occurs. ** -** If iDb==0 then reset the internal schema tables for all database -** files. If iDb>=1 then reset the internal schema for only the +** If iDb<0 then reset the internal schema tables for all database +** files. If iDb>=0 then reset the internal schema for only the ** single file indicated. */ SQLITE_PRIVATE void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ int i, j; - assert( iDb>=0 && iDb<db->nDb ); + assert( iDb<db->nDb ); - if( iDb==0 ){ - sqlite3BtreeEnterAll(db); + if( iDb>=0 ){ + /* Case 1: Reset the single schema identified by iDb */ + Db *pDb = &db->aDb[iDb]; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( pDb->pSchema!=0 ); + sqlite3SchemaClear(pDb->pSchema); + + /* If any database other than TEMP is reset, then also reset TEMP + ** since TEMP might be holding triggers that reference tables in the + ** other database. + */ + if( iDb!=1 ){ + pDb = &db->aDb[1]; + assert( pDb->pSchema!=0 ); + sqlite3SchemaClear(pDb->pSchema); + } + return; } - for(i=iDb; i<db->nDb; i++){ + /* Case 2 (from here to the end): Reset all schemas for all attached + ** databases. */ + assert( iDb<0 ); + sqlite3BtreeEnterAll(db); + for(i=0; i<db->nDb; i++){ Db *pDb = &db->aDb[i]; if( pDb->pSchema ){ - assert(i==1 || (pDb->pBt && sqlite3BtreeHoldsMutex(pDb->pBt))); - sqlite3SchemaFree(pDb->pSchema); + sqlite3SchemaClear(pDb->pSchema); } - if( iDb>0 ) return; } - assert( iDb==0 ); db->flags &= ~SQLITE_InternChanges; sqlite3VtabUnlockList(db); sqlite3BtreeLeaveAll(db); @@ -67827,13 +79611,12 @@ SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){ } /* -** Clear the column names from a table or view. +** Delete memory allocated for the column names of a table or view (the +** Table.aCol[] array). */ -static void sqliteResetColumnNames(Table *pTable){ +static void sqliteDeleteColumnNames(sqlite3 *db, Table *pTable){ int i; Column *pCol; - sqlite3 *db = pTable->dbMem; - testcase( db==0 ); assert( pTable!=0 ); if( (pCol = pTable->aCol)!=0 ){ for(i=0; i<pTable->nCol; i++, pCol++){ @@ -67845,8 +79628,6 @@ static void sqliteResetColumnNames(Table *pTable){ } sqlite3DbFree(db, pTable->aCol); } - pTable->aCol = 0; - pTable->nCol = 0; } /* @@ -67855,45 +79636,48 @@ static void sqliteResetColumnNames(Table *pTable){ ** ** This routine just deletes the data structure. It does not unlink ** the table data structure from the hash table. But it does destroy -** memory structures of the indices and foreign keys associated with +** memory structures of the indices and foreign keys associated with ** the table. */ -SQLITE_PRIVATE void sqlite3DeleteTable(Table *pTable){ +SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ Index *pIndex, *pNext; - sqlite3 *db; - if( pTable==0 ) return; - db = pTable->dbMem; - testcase( db==0 ); + assert( !pTable || pTable->nRef>0 ); /* Do not delete the table until the reference count reaches zero. */ - pTable->nRef--; - if( pTable->nRef>0 ){ - return; - } - assert( pTable->nRef==0 ); + if( !pTable ) return; + if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return; - /* Delete all indices associated with this table - */ + /* Delete all indices associated with this table. */ for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ pNext = pIndex->pNext; assert( pIndex->pSchema==pTable->pSchema ); - sqlite3DeleteIndex(pIndex); + if( !db || db->pnBytesFreed==0 ){ + char *zName = pIndex->zName; + TESTONLY ( Index *pOld = ) sqlite3HashInsert( + &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0 + ); + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + assert( pOld==pIndex || pOld==0 ); + } + freeIndex(db, pIndex); } /* Delete any foreign keys attached to this table. */ - sqlite3FkDelete(pTable); + sqlite3FkDelete(db, pTable); /* Delete the Table structure itself. */ - sqliteResetColumnNames(pTable); + sqliteDeleteColumnNames(db, pTable); sqlite3DbFree(db, pTable->zName); sqlite3DbFree(db, pTable->zColAff); sqlite3SelectDelete(db, pTable->pSelect); #ifndef SQLITE_OMIT_CHECK sqlite3ExprDelete(db, pTable->pCheck); #endif - sqlite3VtabClear(pTable); +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3VtabClear(db, pTable); +#endif sqlite3DbFree(db, pTable); } @@ -67908,11 +79692,12 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char assert( db!=0 ); assert( iDb>=0 && iDb<db->nDb ); assert( zTabName ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */ pDb = &db->aDb[iDb]; p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, sqlite3Strlen30(zTabName),0); - sqlite3DeleteTable(p); + sqlite3DeleteTable(db, p); db->flags |= SQLITE_InternChanges; } @@ -67966,7 +79751,7 @@ SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){ Db *pDb; int n = sqlite3Strlen30(zName); for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ - if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) && + if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) && 0==sqlite3StrICmp(pDb->zName, zName) ){ break; } @@ -67978,7 +79763,7 @@ SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){ /* ** The token *pName contains the name of a database (either "main" or ** "temp" or the name of an attached db). This routine returns the -** index of the named database in db->aDb[], or -1 if the named db +** index of the named database in db->aDb[], or -1 if the named db ** does not exist. */ SQLITE_PRIVATE int sqlite3FindDb(sqlite3 *db, Token *pName){ @@ -67994,7 +79779,7 @@ SQLITE_PRIVATE int sqlite3FindDb(sqlite3 *db, Token *pName){ ** pName1 and pName2. If the table name was fully qualified, for example: ** ** CREATE TABLE xxx.yyy (...); -** +** ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if ** the table name is not fully qualified, i.e.: ** @@ -68044,7 +79829,7 @@ SQLITE_PRIVATE int sqlite3TwoPartName( ** is reserved for internal use. */ SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){ - if( !pParse->db->init.busy && pParse->nested==0 + if( !pParse->db->init.busy && pParse->nested==0 && (pParse->db->flags & SQLITE_WriteSchema)==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); @@ -68089,7 +79874,7 @@ SQLITE_PRIVATE void sqlite3StartTable( ** pName1 and pName2. If the table name was fully qualified, for example: ** ** CREATE TABLE xxx.yyy (...); - ** + ** ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if ** the table name is not fully qualified, i.e.: ** @@ -68104,8 +79889,9 @@ SQLITE_PRIVATE void sqlite3StartTable( */ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); if( iDb<0 ) return; - if( !OMIT_TEMPDB && isTemp && iDb>1 ){ - /* If creating a temp table, the name may not be qualified */ + if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){ + /* If creating a temp table, the name may not be qualified. Unless + ** the database name is "temp" anyway. */ sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); return; } @@ -68153,17 +79939,21 @@ SQLITE_PRIVATE void sqlite3StartTable( ** collisions. */ if( !IN_DECLARE_VTAB ){ + char *zDb = db->aDb[iDb].zName; if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto begin_table_error; } - pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName); + pTable = sqlite3FindTable(db, zName, zDb); if( pTable ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "table %T already exists", pName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); } goto begin_table_error; } - if( sqlite3FindIndex(db, zName, 0)!=0 && (iDb==0 || !db->init.busy) ){ + if( sqlite3FindIndex(db, zName, zDb)!=0 ){ sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); goto begin_table_error; } @@ -68180,7 +79970,7 @@ SQLITE_PRIVATE void sqlite3StartTable( pTable->iPKey = -1; pTable->pSchema = db->aDb[iDb].pSchema; pTable->nRef = 1; - pTable->dbMem = 0; + pTable->nRowEst = 1000000; assert( pParse->pNewTable==0 ); pParse->pNewTable = pTable; @@ -68190,6 +79980,7 @@ SQLITE_PRIVATE void sqlite3StartTable( */ #ifndef SQLITE_OMIT_AUTOINCREMENT if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pTable->pSchema->pSeqTab = pTable; } #endif @@ -68198,7 +79989,7 @@ SQLITE_PRIVATE void sqlite3StartTable( ** the SQLITE_MASTER table. Note in particular that we must go ahead ** and allocate the record number for the table entry now. Before any ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause - ** indices to be created and the table record must come before the + ** indices to be created and the table record must come before the ** indices. Hence, the record number for the table must be allocated ** now. */ @@ -68214,7 +80005,7 @@ SQLITE_PRIVATE void sqlite3StartTable( } #endif - /* If the file format and encoding in the database have not been set, + /* If the file format and encoding in the database have not been set, ** set them now. */ reg1 = pParse->regRowid = ++pParse->nMem; @@ -68320,7 +80111,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName){ pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); pCol->zName = z; - + /* If there is no type specified, columns have the default affinity ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will ** be called next to set pCol->affinity correctly. @@ -68346,11 +80137,11 @@ SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){ ** Scan the column type name zType (length nType) and return the ** associated affinity type. ** -** This routine does a case-independent search of zType for the +** This routine does a case-independent search of zType for the ** substrings in the following table. If one of the substrings is ** found, the corresponding affinity is returned. If zType contains -** more than one of the substrings, entries toward the top of -** the table take priority. For example, if zType is 'BLOBINT', +** more than one of the substrings, entries toward the top of +** the table take priority. For example, if zType is 'BLOBINT', ** SQLITE_AFF_INTEGER is returned. ** ** Substring | Affinity @@ -68375,7 +80166,7 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn){ h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff]; zIn++; if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ - aff = SQLITE_AFF_TEXT; + aff = SQLITE_AFF_TEXT; }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */ aff = SQLITE_AFF_TEXT; }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */ @@ -68411,7 +80202,7 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn){ ** in the sequence. Use this information to construct a string ** that contains the typename of the column and store that string ** in zType. -*/ +*/ SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){ Table *p; Column *pCol; @@ -68460,7 +80251,7 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){ } /* -** Designate the PRIMARY KEY for the table. pList is a list of names +** Designate the PRIMARY KEY for the table. pList is a list of names ** of columns that form the primary key. If pList is NULL, then the ** most recently added column of the table is the primary key. ** @@ -68489,7 +80280,7 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey( int iCol = -1, i; if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit; if( pTab->tabFlags & TF_HasPrimaryKey ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "table \"%s\" has more than one primary key", pTab->zName); goto primary_key_exit; } @@ -68576,7 +80367,7 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){ if( sqlite3LocateCollSeq(pParse, zColl) ){ Index *pIdx; p->aCol[i].zColl = zColl; - + /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>", ** then an index may have been created on this column before the ** collation type was added. Correct this if it is the case. @@ -68650,6 +80441,7 @@ SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){ int r1 = sqlite3GetTempReg(pParse); sqlite3 *db = pParse->db; Vdbe *v = pParse->pVdbe; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, r1); sqlite3ReleaseTempReg(pParse, r1); @@ -68672,13 +80464,13 @@ static int identLength(const char *z){ } /* -** The first parameter is a pointer to an output buffer. The second +** The first parameter is a pointer to an output buffer. The second ** parameter is a pointer to an integer that contains the offset at ** which to write into the output buffer. This function copies the ** nul-terminated string pointed to by the third parameter, zSignedIdent, ** to the specified offset in the buffer and updates *pIdx to refer ** to the first byte after the last byte written before returning. -** +** ** If the string zSignedIdent consists entirely of alpha-numeric ** characters, does not begin with a digit and is not an SQL keyword, ** then it is copied to the output buffer exactly as it is. Otherwise, @@ -68722,7 +80514,7 @@ static char *createTableStmt(sqlite3 *db, Table *p){ n += identLength(pCol->zName) + 5; } n += identLength(p->zName); - if( n<50 ){ + if( n<50 ){ zSep = ""; zSep2 = ","; zEnd = ")"; @@ -68732,7 +80524,7 @@ static char *createTableStmt(sqlite3 *db, Table *p){ zEnd = "\n)"; } n += 35 + 6*p->nCol; - zStmt = sqlite3Malloc( n ); + zStmt = sqlite3DbMallocRaw(0, n); if( zStmt==0 ){ db->mallocFailed = 1; return 0; @@ -68757,16 +80549,16 @@ static char *createTableStmt(sqlite3 *db, Table *p){ zSep = zSep2; identPut(zStmt, &k, pCol->zName); assert( pCol->affinity-SQLITE_AFF_TEXT >= 0 ); - assert( pCol->affinity-SQLITE_AFF_TEXT < sizeof(azType)/sizeof(azType[0]) ); + assert( pCol->affinity-SQLITE_AFF_TEXT < ArraySize(azType) ); testcase( pCol->affinity==SQLITE_AFF_TEXT ); testcase( pCol->affinity==SQLITE_AFF_NONE ); testcase( pCol->affinity==SQLITE_AFF_NUMERIC ); testcase( pCol->affinity==SQLITE_AFF_INTEGER ); testcase( pCol->affinity==SQLITE_AFF_REAL ); - + zType = azType[pCol->affinity - SQLITE_AFF_TEXT]; len = sqlite3Strlen30(zType); - assert( pCol->affinity==SQLITE_AFF_NONE + assert( pCol->affinity==SQLITE_AFF_NONE || pCol->affinity==sqlite3AffinityType(zType) ); memcpy(&zStmt[k], zType, len); k += len; @@ -68792,7 +80584,7 @@ static char *createTableStmt(sqlite3 *db, Table *p){ ** the sqlite_master table. We do not want to create it again. ** ** If the pSelect argument is not NULL, it means that this routine -** was called to create a table generated from a +** was called to create a table generated from a ** "CREATE TABLE ... AS SELECT ..." statement. The column names of ** the new table will match the result set of the SELECT. */ @@ -68866,7 +80658,7 @@ SQLITE_PRIVATE void sqlite3EndTable( sqlite3VdbeAddOp1(v, OP_Close, 0); - /* + /* ** Initialize zType for the new view or table. */ if( p->pSelect==0 ){ @@ -68913,7 +80705,7 @@ SQLITE_PRIVATE void sqlite3EndTable( p->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; - sqlite3DeleteTable(pSelTab); + sqlite3DeleteTable(db, pSelTab); } } @@ -68922,12 +80714,12 @@ SQLITE_PRIVATE void sqlite3EndTable( zStmt = createTableStmt(db, p); }else{ n = (int)(pEnd->z - pParse->sNameToken.z) + 1; - zStmt = sqlite3MPrintf(db, + zStmt = sqlite3MPrintf(db, "CREATE %s %.*s", zType2, n, pParse->sNameToken.z ); } - /* A slot for the record has already been allocated in the + /* A slot for the record has already been allocated in the ** SQLITE_MASTER table. We just need to update that slot with all ** the information we've collected. */ @@ -68952,6 +80744,7 @@ SQLITE_PRIVATE void sqlite3EndTable( */ if( p->tabFlags & TF_Autoincrement ){ Db *pDb = &db->aDb[iDb]; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( pDb->pSchema->pSeqTab==0 ){ sqlite3NestedParse(pParse, "CREATE TABLE %Q.sqlite_sequence(name,seq)", @@ -68962,8 +80755,8 @@ SQLITE_PRIVATE void sqlite3EndTable( #endif /* Reparse everything to update our internal data structures */ - sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, - sqlite3MPrintf(db, "tbl_name='%q'",p->zName), P4_DYNAMIC); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "tbl_name='%q'", p->zName)); } @@ -68972,6 +80765,7 @@ SQLITE_PRIVATE void sqlite3EndTable( if( db->init.busy ){ Table *pOld; Schema *pSchema = p->pSchema; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, sqlite3Strlen30(p->zName),p); if( pOld ){ @@ -69016,7 +80810,7 @@ SQLITE_PRIVATE void sqlite3CreateView( const char *z; Token sEnd; DbFixer sFix; - Token *pName; + Token *pName = 0; int iDb; sqlite3 *db = pParse->db; @@ -69027,12 +80821,10 @@ SQLITE_PRIVATE void sqlite3CreateView( } sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); p = pParse->pNewTable; - if( p==0 ){ + if( p==0 || pParse->nErr ){ sqlite3SelectDelete(db, pSelect); return; } - assert( pParse->nErr==0 ); /* If sqlite3StartTable return non-NULL then - ** there could not have been an error */ sqlite3TwoPartName(pParse, pName1, pName2, &pName); iDb = sqlite3SchemaToIndex(db, p->pSchema); if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName) @@ -69115,7 +80907,7 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ ** Actually, the error above is now caught prior to reaching this point. ** But the following test is still important as it does come up ** in the following: - ** + ** ** CREATE TABLE main.ex1(a); ** CREATE TEMP VIEW ex1 AS SELECT a FROM ex1; ** SELECT * FROM temp.ex1; @@ -69157,7 +80949,8 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ pTable->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; - sqlite3DeleteTable(pSelTab); + sqlite3DeleteTable(db, pSelTab); + assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); pTable->pSchema->flags |= DB_UnresetViews; }else{ pTable->nCol = 0; @@ -69168,7 +80961,7 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ nErr++; } #endif /* SQLITE_OMIT_VIEW */ - return nErr; + return nErr; } #endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ @@ -69178,11 +80971,14 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ */ static void sqliteViewResetAll(sqlite3 *db, int idx){ HashElem *i; + assert( sqlite3SchemaMutexHeld(db, idx, 0) ); if( !DbHasProperty(db, idx, DB_UnresetViews) ) return; for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){ Table *pTab = sqliteHashData(i); if( pTab->pSelect ){ - sqliteResetColumnNames(pTab); + sqliteDeleteColumnNames(db, pTab); + pTab->aCol = 0; + pTab->nCol = 0; } } DbClearProperty(db, idx, DB_UnresetViews); @@ -69201,7 +80997,7 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){ ** on tables and/or indices that are the process of being deleted. ** If you are unlucky, one of those deleted indices or tables might ** have the same rootpage number as the real table or index that is -** being moved. So we cannot stop searching after the first match +** being moved. So we cannot stop searching after the first match ** because the first match might be for one of the deleted indices ** or tables and not the table/index that is actually being moved. ** We must continue looping until all tables and indices with @@ -69209,10 +81005,13 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){ ** in order to be certain that we got the right one. */ #ifndef SQLITE_OMIT_AUTOVACUUM -SQLITE_PRIVATE void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){ +SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iTo){ HashElem *pElem; Hash *pHash; + Db *pDb; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pDb = &db->aDb[iDb]; pHash = &pDb->pSchema->tblHash; for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ Table *pTab = sqliteHashData(pElem); @@ -69235,7 +81034,7 @@ SQLITE_PRIVATE void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){ ** Also write code to modify the sqlite_master table and internal schema ** if a root-page of another table is moved by the btree-layer whilst ** erasing iTable (this can happen with an auto-vacuum database). -*/ +*/ static void destroyRootPage(Parse *pParse, int iTable, int iDb){ Vdbe *v = sqlite3GetVdbe(pParse); int r1 = sqlite3GetTempReg(pParse); @@ -69251,7 +81050,7 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){ ** is in register NNN. See grammar rules associated with the TK_REGISTER ** token for additional information. */ - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d", pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1); #endif @@ -69275,7 +81074,7 @@ static void destroyTable(Parse *pParse, Table *pTab){ #else /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM ** is not defined), then it is important to call OP_Destroy on the - ** table and index root-pages in order, starting with the numerically + ** table and index root-pages in order, starting with the numerically ** largest root-page number. This guarantees that none of the root-pages ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the ** following were coded: @@ -69285,7 +81084,7 @@ static void destroyTable(Parse *pParse, Table *pTab){ ** OP_Destroy 5 0 ** ** and root page 5 happened to be the largest root-page number in the - ** database, then root page 5 would be moved to page 4 by the + ** database, then root page 5 would be moved to page 4 by the ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit ** a free-list page. */ @@ -69318,6 +81117,29 @@ static void destroyTable(Parse *pParse, Table *pTab){ } /* +** Remove entries from the sqlite_stat1 and sqlite_stat2 tables +** after a DROP INDEX or DROP TABLE command. +*/ +static void sqlite3ClearStatTables( + Parse *pParse, /* The parsing context */ + int iDb, /* The database number */ + const char *zType, /* "idx" or "tbl" */ + const char *zName /* Name of index or table */ +){ + static const char *azStatTab[] = { "sqlite_stat1", "sqlite_stat2" }; + int i; + const char *zDbName = pParse->db->aDb[iDb].zName; + for(i=0; i<ArraySize(azStatTab); i++){ + if( sqlite3FindTable(pParse->db, azStatTab[i], zDbName) ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE %s=%Q", + zDbName, azStatTab[i], zType, zName + ); + } + } +} + +/* ** This routine is called to do the work of a DROP TABLE statement. ** pName is the name of the table to be dropped. */ @@ -69333,11 +81155,12 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); if( noErr ) db->suppressErr++; - pTab = sqlite3LocateTable(pParse, isView, + pTab = sqlite3LocateTable(pParse, isView, pName->a[0].zName, pName->a[0].zDatabase); if( noErr ) db->suppressErr--; if( pTab==0 ){ + if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); goto exit_drop_table; } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -69425,7 +81248,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, */ pTrigger = sqlite3TriggerList(pParse, pTab); while( pTrigger ){ - assert( pTrigger->pSchema==pTab->pSchema || + assert( pTrigger->pSchema==pTab->pSchema || pTrigger->pSchema==db->aDb[1].pSchema ); sqlite3DropTriggerPtr(pParse, pTrigger); pTrigger = pTrigger->pNext; @@ -69452,17 +81275,10 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, ** created in the temp database that refers to a table in another ** database. */ - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", pDb->zName, SCHEMA_TABLE(iDb), pTab->zName); - - /* Drop any statistics from the sqlite_stat1 table, if it exists */ - if( sqlite3FindTable(db, "sqlite_stat1", db->aDb[iDb].zName) ){ - sqlite3NestedParse(pParse, - "DELETE FROM %Q.sqlite_stat1 WHERE tbl=%Q", pDb->zName, pTab->zName - ); - } - + sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); if( !isView && !IsVirtual(pTab) ){ destroyTable(pParse, pTab); } @@ -69566,8 +81382,8 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( } } if( j>=p->nCol ){ - sqlite3ErrorMsg(pParse, - "unknown column \"%s\" in foreign key definition", + sqlite3ErrorMsg(pParse, + "unknown column \"%s\" in foreign key definition", pFromCol->a[i].zName); goto fk_end; } @@ -69586,7 +81402,8 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( pFKey->aAction[0] = (u8)(flags & 0xff); /* ON DELETE action */ pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */ - pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, + assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); + pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, pFKey->zTo, sqlite3Strlen30(pFKey->zTo), (void *)pFKey ); if( pNextTo==pFKey ){ @@ -69643,7 +81460,9 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ Table *pTab = pIndex->pTable; /* The table that is indexed */ int iTab = pParse->nTab++; /* Btree cursor used for pTab */ int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ + int iSorter = iTab; /* Cursor opened by OpenSorter (if in use) */ int addr1; /* Address of top of loop */ + int addr2; /* Address to jump to for next iteration */ int tnum; /* Root page of index */ Vdbe *v; /* Generate code into this virtual machine */ KeyInfo *pKey; /* KeyInfo for index */ @@ -69671,15 +81490,46 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); } pKey = sqlite3IndexKeyinfo(pParse, pIndex); - sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, + sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, (char *)pKey, P4_KEYINFO_HANDOFF); if( memRootPage>=0 ){ sqlite3VdbeChangeP5(v, 1); } + +#ifndef SQLITE_OMIT_MERGE_SORT + /* Open the sorter cursor if we are to use one. */ + iSorter = pParse->nTab++; + sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO); +#endif + + /* Open the table. Loop through all rows of the table, inserting index + ** records into the sorter. */ sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); + addr2 = addr1 + 1; regRecord = sqlite3GetTempReg(pParse); regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1); + +#ifndef SQLITE_OMIT_MERGE_SORT + sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); + sqlite3VdbeJumpHere(v, addr1); + addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); + if( pIndex->onError!=OE_None ){ + int j2 = sqlite3VdbeCurrentAddr(v) + 3; + sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); + addr2 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord); + sqlite3HaltConstraint( + pParse, OE_Abort, "indexed columns are not unique", P4_STATIC + ); + }else{ + addr2 = sqlite3VdbeCurrentAddr(v); + } + sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); + sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); +#else if( pIndex->onError!=OE_None ){ const int regRowid = regIdxKey + pIndex->nColumn; const int j2 = sqlite3VdbeCurrentAddr(v) + 2; @@ -69688,7 +81538,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ /* The registers accessed by the OP_IsUnique opcode were allocated ** using sqlite3GetTempRange() inside of the sqlite3GenerateIndexKey() ** call above. Just before that function was freed they were released - ** (made available to the compiler for reuse) using + ** (made available to the compiler for reuse) using ** sqlite3ReleaseTempRange(). So in some ways having the OP_IsUnique ** opcode use the values stored within seems dangerous. However, since ** we can be sure that no other temp registers have been allocated @@ -69698,18 +81548,21 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ sqlite3HaltConstraint( pParse, OE_Abort, "indexed columns are not unique", P4_STATIC); } - sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord); + sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); +#endif sqlite3ReleaseTempReg(pParse, regRecord); - sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); + sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp1(v, OP_Close, iTab); sqlite3VdbeAddOp1(v, OP_Close, iIdx); + sqlite3VdbeAddOp1(v, OP_Close, iSorter); } /* -** Create a new index for an SQL table. pName1.pName2 is the name of the index -** and pTblList is the name of the table that is to be indexed. Both will +** Create a new index for an SQL table. pName1.pName2 is the name of the index +** and pTblList is the name of the table that is to be indexed. Both will ** be NULL for a primary key or an index that is created to satisfy a ** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable ** as the table to be indexed. pParse->pNewTable is a table that is @@ -69717,7 +81570,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ ** ** pList is a list of columns to be indexed. pList will be NULL if this ** is a primary key or unique-constraint on the most recent column added -** to the table currently under construction. +** to the table currently under construction. ** ** If the index is created successfully, return a pointer to the new Index ** structure. This is used by sqlite3AddPrimaryKey() to mark the index @@ -69767,7 +81620,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( */ if( pTblName!=0 ){ - /* Use the two-part index name to determine the database + /* Use the two-part index name to determine the database ** to search for the table. 'Fix' the table name to this db ** before looking up the table. */ @@ -69795,7 +81648,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( ** sqlite3FixSrcList can never fail. */ assert(0); } - pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName, + pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName, pTblName->a[0].zDatabase); if( !pTab || db->mallocFailed ) goto exit_create_index; assert( db->aDb[iDb].pSchema==pTab->pSchema ); @@ -69809,7 +81662,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( assert( pTab!=0 ); assert( pParse->nErr==0 ); - if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 && memcmp(&pTab->zName[7],"altertab_",9)!=0 ){ sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; @@ -69829,7 +81682,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( /* ** Find the name of the index. Make sure there is not already another - ** index or table with the same name. + ** index or table with the same name. ** ** Exception: If we are reading the names of permanent indices from the ** sqlite_master table (because some other process changed the schema) and @@ -69855,6 +81708,9 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){ if( !ifNotExist ){ sqlite3ErrorMsg(pParse, "index %s already exists", zName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); } goto exit_create_index; } @@ -69912,12 +81768,12 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( } } - /* - ** Allocate the index structure. + /* + ** Allocate the index structure. */ nName = sqlite3Strlen30(zName); nCol = pList->nExpr; - pIndex = sqlite3DbMallocZero(db, + pIndex = sqlite3DbMallocZero(db, sizeof(Index) + /* Index structure */ sizeof(int)*nCol + /* Index.aiColumn */ sizeof(int)*(nCol+1) + /* Index.aiRowEst */ @@ -69941,6 +81797,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( pIndex->onError = (u8)onError; pIndex->autoIndex = (u8)(pName==0); pIndex->pSchema = db->aDb[iDb].pSchema; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); /* Check to see if we should honor DESC requests on index columns */ @@ -69957,7 +81814,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( ** TODO: Add a test to make sure that the same column is not named ** more than once within the same index. Only the first instance of ** the column will ever be used by the optimizer. Note that using the - ** same column more than once cannot be an error because that would + ** same column more than once cannot be an error because that would ** break backwards compatibility - it needs to be a warning. */ for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){ @@ -69972,6 +81829,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( if( j>=pTab->nCol ){ sqlite3ErrorMsg(pParse, "table %s has no column named %s", pTab->zName, zColName); + pParse->checkSchema = 1; goto exit_create_index; } pIndex->aiColumn[i] = j; @@ -70046,13 +81904,13 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( if( pIdx->onError!=pIndex->onError ){ /* This constraint creates the same index as a previous ** constraint specified somewhere in the CREATE TABLE statement. - ** However the ON CONFLICT clauses are different. If both this + ** However the ON CONFLICT clauses are different. If both this ** constraint and the previous equivalent constraint have explicit ** ON CONFLICT clauses this is an error. Otherwise, use the ** explicitly specified behaviour for the index. */ if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "conflicting ON CONFLICT clauses specified", 0); } if( pIdx->onError==OE_Default ){ @@ -70065,11 +81923,12 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( } /* Link the new Index structure to its table and to the other - ** in-memory database structures. + ** in-memory database structures. */ if( db->init.busy ){ Index *p; - p = sqlite3HashInsert(&pIndex->pSchema->idxHash, + assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + p = sqlite3HashInsert(&pIndex->pSchema->idxHash, pIndex->zName, sqlite3Strlen30(pIndex->zName), pIndex); if( p ){ @@ -70087,8 +81946,8 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( ** involves writing the index into the master table and filling in the ** index with the current table contents. ** - ** The db->init.busy is 0 when the user first enters a CREATE INDEX - ** command. db->init.busy is 1 when a database is opened and + ** The db->init.busy is 0 when the user first enters a CREATE INDEX + ** command. db->init.busy is 1 when a database is opened and ** CREATE INDEX statements are read out of the master table. In ** the latter case the index already exists on disk, which is why ** we don't want to recreate it. @@ -70120,7 +81979,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( /* A named index with an explicit CREATE INDEX statement */ zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", onError==OE_None ? "" : " UNIQUE", - pEnd->z - pName->z + 1, + (int)(pEnd->z - pName->z) + 1, pName->z); }else{ /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ @@ -70130,7 +81989,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( /* Add an entry in sqlite_master for this index */ - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName, @@ -70146,8 +82005,8 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( if( pTblName ){ sqlite3RefillIndex(pParse, pIndex, iMem); sqlite3ChangeCookie(pParse, iDb); - sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, - sqlite3MPrintf(db, "name='%q'", pIndex->zName), P4_DYNAMIC); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); sqlite3VdbeAddOp1(v, OP_Expire, 0); } } @@ -70156,7 +82015,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( ** sure all indices labeled OE_Replace come after all those labeled ** OE_Ignore. This is necessary for the correct constraint check ** processing (in sqlite3GenerateConstraintChecks()) as part of - ** UPDATE and INSERT statements. + ** UPDATE and INSERT statements. */ if( db->init.busy || pTblName==0 ){ if( onError!=OE_Replace || pTab->pIndex==0 @@ -70178,7 +82037,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( /* Clean up before exiting */ exit_create_index: if( pIndex ){ - sqlite3_free(pIndex->zColAff); + sqlite3DbFree(db, pIndex->zColAff); sqlite3DbFree(db, pIndex); } sqlite3ExprListDelete(db, pList); @@ -70208,14 +82067,14 @@ exit_create_index: SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){ unsigned *a = pIdx->aiRowEst; int i; + unsigned n; assert( a!=0 ); - a[0] = 1000000; - for(i=pIdx->nColumn; i>=5; i--){ - a[i] = 5; - } - while( i>=1 ){ - a[i] = 11 - i; - i--; + a[0] = pIdx->pTable->nRowEst; + if( a[0]<10 ) a[0] = 10; + n = 10; + for(i=1; i<=pIdx->nColumn; i++){ + a[i] = n; + if( n>5 ) n--; } if( pIdx->onError!=OE_None ){ a[pIdx->nColumn] = 1; @@ -70244,6 +82103,8 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists if( pIndex==0 ){ if( !ifExists ){ sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0); + }else{ + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); } pParse->checkSchema = 1; goto exit_drop_index; @@ -70275,16 +82136,10 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists if( v ){ sqlite3BeginWriteOperation(pParse, 1, iDb); sqlite3NestedParse(pParse, - "DELETE FROM %Q.%s WHERE name=%Q", - db->aDb[iDb].zName, SCHEMA_TABLE(iDb), - pIndex->zName + "DELETE FROM %Q.%s WHERE name=%Q AND type='index'", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName ); - if( sqlite3FindTable(db, "sqlite_stat1", db->aDb[iDb].zName) ){ - sqlite3NestedParse(pParse, - "DELETE FROM %Q.sqlite_stat1 WHERE idx=%Q", - db->aDb[iDb].zName, pIndex->zName - ); - } + sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); sqlite3ChangeCookie(pParse, iDb); destroyRootPage(pParse, pIndex->tnum, iDb); sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); @@ -70474,7 +82329,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge( ** database name prefix. Like this: "database.table". The pDatabase ** points to the table name and the pTable points to the database name. ** The SrcList.a[].zName field is filled with the table name which might -** come from pTable (if pDatabase is NULL) or from pDatabase. +** come from pTable (if pDatabase is NULL) or from pDatabase. ** SrcList.a[].zDatabase is filled with the database name from pTable, ** or with NULL if no database is specified. ** @@ -70557,7 +82412,7 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ sqlite3DbFree(db, pItem->zName); sqlite3DbFree(db, pItem->zAlias); sqlite3DbFree(db, pItem->zIndex); - sqlite3DeleteTable(pItem->pTab); + sqlite3DeleteTable(db, pItem->pTab); sqlite3SelectDelete(db, pItem->pSelect); sqlite3ExprDelete(db, pItem->pOn); sqlite3IdListDelete(db, pItem->pUsing); @@ -70594,7 +82449,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( struct SrcList_item *pItem; sqlite3 *db = pParse->db; if( !p && (pOn || pUsing) ){ - sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", + sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", (pOn ? "ON" : "USING") ); goto append_from_error; @@ -70622,7 +82477,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( } /* -** Add an INDEXED BY or NOT INDEXED clause to the most recently added +** Add an INDEXED BY or NOT INDEXED clause to the most recently added ** element of the source-list passed as the second argument. */ SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ @@ -70631,7 +82486,7 @@ SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pI struct SrcList_item *pItem = &p->a[p->nSrc-1]; assert( pItem->notIndexed==0 && pItem->zIndex==0 ); if( pIndexedBy->n==1 && !pIndexedBy->z ){ - /* A "NOT INDEXED" clause was supplied. See parse.y + /* A "NOT INDEXED" clause was supplied. See parse.y ** construct "indexed_opt" for details. */ pItem->notIndexed = 1; }else{ @@ -70656,8 +82511,9 @@ SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pI ** operator with A. This routine shifts that operator over to B. */ SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){ - if( p && p->a ){ + if( p ){ int i; + assert( p->a || p->nSrc==0 ); for(i=p->nSrc-1; i>0; i--){ p->a[i].jointype = p->a[i-1].jointype; } @@ -70733,14 +82589,14 @@ SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse *pParse){ /* ** This function is called by the parser when it parses a command to create, -** release or rollback an SQL savepoint. +** release or rollback an SQL savepoint. */ SQLITE_PRIVATE void sqlite3Savepoint(Parse *pParse, int op, Token *pName){ char *zName = sqlite3NameFromToken(pParse->db, pName); if( zName ){ Vdbe *v = sqlite3GetVdbe(pParse); #ifndef SQLITE_OMIT_AUTHORIZATION - static const char *az[] = { "BEGIN", "RELEASE", "ROLLBACK" }; + static const char * const az[] = { "BEGIN", "RELEASE", "ROLLBACK" }; assert( !SAVEPOINT_BEGIN && SAVEPOINT_RELEASE==1 && SAVEPOINT_ROLLBACK==2 ); #endif if( !v || sqlite3AuthCheck(pParse, SQLITE_SAVEPOINT, az[op], zName, 0) ){ @@ -70760,14 +82616,14 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ if( db->aDb[1].pBt==0 && !pParse->explain ){ int rc; Btree *pBt; - static const int flags = + static const int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TEMP_DB; - rc = sqlite3BtreeFactory(db, 0, 0, SQLITE_DEFAULT_CACHE_SIZE, flags, &pBt); + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags); if( rc!=SQLITE_OK ){ sqlite3ErrorMsg(pParse, "unable to open a temporary database " "file for storing temporary tables"); @@ -70780,7 +82636,6 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ db->mallocFailed = 1; return 1; } - sqlite3PagerJournalMode(sqlite3BtreePager(pBt), db->dfltJournalMode); } return 0; } @@ -70817,12 +82672,13 @@ SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ } if( iDb>=0 ){ sqlite3 *db = pToplevel->db; - int mask; + yDbMask mask; assert( iDb<db->nDb ); assert( db->aDb[iDb].pBt!=0 || iDb==1 ); assert( iDb<SQLITE_MAX_ATTACHED+2 ); - mask = 1<<iDb; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + mask = ((yDbMask)1)<<iDb; if( (pToplevel->cookieMask & mask)==0 ){ pToplevel->cookieMask |= mask; pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; @@ -70834,6 +82690,21 @@ SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ } /* +** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each +** attached database. Otherwise, invoke it for the database named zDb only. +*/ +SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){ + sqlite3 *db = pParse->db; + int i; + for(i=0; i<db->nDb; i++){ + Db *pDb = &db->aDb[i]; + if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){ + sqlite3CodeVerifySchema(pParse, i); + } + } +} + +/* ** Generate VDBE code that prepares for doing an operation that ** might change the database. ** @@ -70849,7 +82720,7 @@ SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ Parse *pToplevel = sqlite3ParseToplevel(pParse); sqlite3CodeVerifySchema(pParse, iDb); - pToplevel->writeMask |= 1<<iDb; + pToplevel->writeMask |= ((yDbMask)1)<<iDb; pToplevel->isMultiWrite |= setStatement; } @@ -70865,9 +82736,9 @@ SQLITE_PRIVATE void sqlite3MultiWrite(Parse *pParse){ pToplevel->isMultiWrite = 1; } -/* +/* ** The code generator calls this routine if is discovers that it is -** possible to abort a statement prior to completion. In order to +** possible to abort a statement prior to completion. In order to ** perform this abort without corrupting the database, we need to make ** sure that the statement is protected by a statement transaction. ** @@ -70876,7 +82747,7 @@ SQLITE_PRIVATE void sqlite3MultiWrite(Parse *pParse){ ** such that the abort must occur after the multiwrite. This makes ** some statements involving the REPLACE conflict resolution algorithm ** go a little faster. But taking advantage of this time dependency -** makes it more difficult to prove that the code is correct (in +** makes it more difficult to prove that the code is correct (in ** particular, it prevents us from writing an effective ** implementation of sqlite3AssertMayAbort()) and so we have chosen ** to take the safe route and skip the optimization. @@ -70949,6 +82820,7 @@ static void reindexDatabases(Parse *pParse, char const *zColl){ HashElem *k; /* For looping over tables in pDb */ Table *pTab; /* A table in the database */ + assert( sqlite3BtreeHoldsAllMutexes(db) ); /* Needed for schema access */ for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){ assert( pDb!=0 ); for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){ @@ -71032,8 +82904,8 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ ** with OP_OpenRead or OP_OpenWrite to access database index pIdx. ** ** If successful, a pointer to the new structure is returned. In this case -** the caller is responsible for calling sqlite3DbFree(db, ) on the returned -** pointer. If an error occurs (out of memory or missing collation +** the caller is responsible for calling sqlite3DbFree(db, ) on the returned +** pointer. If an error occurs (out of memory or missing collation ** sequence), NULL is returned and the state of pParse updated to reflect ** the error. */ @@ -71067,7 +82939,7 @@ SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){ /************** End of build.c ***********************************************/ /************** Begin file callback.c ****************************************/ /* -** 2005 May 23 +** 2005 May 23 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: @@ -71136,8 +83008,8 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ ** This function is responsible for invoking the collation factory callback ** or substituting a collation sequence of a different encoding when the ** requested collation sequence is not available in the desired encoding. -** -** If it is not NULL, then pColl must point to the database native encoding +** +** If it is not NULL, then pColl must point to the database native encoding ** collation sequence with name zName, length nName. ** ** The return value is either the collation sequence to be used in database @@ -71179,7 +83051,7 @@ SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq( ** that have not been defined by sqlite3_create_collation() etc. ** ** If required, this routine calls the 'collation needed' callback to -** request a definition of the collating sequence. If this doesn't work, +** request a definition of the collating sequence. If this doesn't work, ** an equivalent collating sequence that uses a text encoding different ** from the main database is substituted, if one is available. */ @@ -71236,7 +83108,7 @@ static CollSeq *findCollSeqEntry( pColl[0].zName[nName] = 0; pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); - /* If a malloc() failure occurred in sqlite3HashInsert(), it will + /* If a malloc() failure occurred in sqlite3HashInsert(), it will ** return the pColl pointer to be deleted (because it wasn't added ** to the hash table). */ @@ -71307,7 +83179,7 @@ SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq( */ static int matchQuality(FuncDef *p, int nArg, u8 enc){ int match = 0; - if( p->nArg==-1 || p->nArg==nArg + if( p->nArg==-1 || p->nArg==nArg || (nArg==-1 && (p->xFunc!=0 || p->xStep!=0)) ){ match = 1; @@ -71366,8 +83238,8 @@ SQLITE_PRIVATE void sqlite3FuncDefInsert( pHash->a[h] = pDef; } } - - + + /* ** Locate a user function given a name, a number of arguments and a flag @@ -71420,14 +83292,19 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction( /* If no match is found, search the built-in functions. ** + ** If the SQLITE_PreferBuiltin flag is set, then search the built-in + ** functions even if a prior app-defined function was found. And give + ** priority to built-in functions. + ** ** Except, if createFlag is true, that means that we are trying to - ** install a new function. Whatever FuncDef structure is returned will + ** install a new function. Whatever FuncDef structure is returned it will ** have fields overwritten with new information appropriate for the ** new function. But the FuncDefs for built-in functions are read-only. ** So we must not search for built-ins when creating a new function. - */ - if( !createFlag && !pBest ){ + */ + if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){ FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); + bestScore = 0; p = functionSearch(pHash, h, zName, nName); while( p ){ int score = matchQuality(p, nArg, enc); @@ -71443,7 +83320,7 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction( ** exact match for the name, number of arguments and encoding, then add a ** new entry to the hash table and return it. */ - if( createFlag && (bestScore<6 || pBest->nArg!=nArg) && + if( createFlag && (bestScore<6 || pBest->nArg!=nArg) && (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){ pBest->zName = (char *)&pBest[1]; pBest->nArg = (u16)nArg; @@ -71461,13 +83338,13 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction( /* ** Free all resources held by the schema structure. The void* argument points -** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the -** pointer itself, it just cleans up subsiduary resources (i.e. the contents +** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the +** pointer itself, it just cleans up subsidiary resources (i.e. the contents ** of the schema hash tables). ** ** The Schema.cache_size variable is not cleared. */ -SQLITE_PRIVATE void sqlite3SchemaFree(void *p){ +SQLITE_PRIVATE void sqlite3SchemaClear(void *p){ Hash temp1; Hash temp2; HashElem *pElem; @@ -71484,13 +83361,15 @@ SQLITE_PRIVATE void sqlite3SchemaFree(void *p){ sqlite3HashInit(&pSchema->tblHash); for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ Table *pTab = sqliteHashData(pElem); - assert( pTab->dbMem==0 ); - sqlite3DeleteTable(pTab); + sqlite3DeleteTable(0, pTab); } sqlite3HashClear(&temp1); sqlite3HashClear(&pSchema->fkeyHash); pSchema->pSeqTab = 0; - pSchema->flags &= ~DB_SchemaLoaded; + if( pSchema->flags & DB_SchemaLoaded ){ + pSchema->iGeneration++; + pSchema->flags &= ~DB_SchemaLoaded; + } } /* @@ -71500,9 +83379,9 @@ SQLITE_PRIVATE void sqlite3SchemaFree(void *p){ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ Schema * p; if( pBt ){ - p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaFree); + p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); }else{ - p = (Schema *)sqlite3MallocZero(sizeof(Schema)); + p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema)); } if( !p ){ db->mallocFailed = 1; @@ -71534,16 +83413,25 @@ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ */ /* -** Look up every table that is named in pSrc. If any table is not found, -** add an error message to pParse->zErrMsg and return NULL. If all tables -** are found, return a pointer to the last table. +** While a SrcList can in general represent multiple tables and subqueries +** (as in the FROM clause of a SELECT statement) in this case it contains +** the name of a single table, as one might find in an INSERT, DELETE, +** or UPDATE statement. Look up that table in the symbol table and +** return a pointer. Set an error message and return NULL if the table +** name is not found or if any other error occurs. +** +** The following fields are initialized appropriate in pSrc: +** +** pSrc->a[0].pTab Pointer to the Table object +** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one +** */ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ struct SrcList_item *pItem = pSrc->a; Table *pTab; assert( pItem && pSrc->nSrc==1 ); pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase); - sqlite3DeleteTable(pItem->pTab); + sqlite3DeleteTable(pParse->db, pItem->pTab); pItem->pTab = pTab; if( pTab ){ pTab->nRef++; @@ -71565,12 +83453,12 @@ SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ ** 1) It is a virtual table and no implementation of the xUpdate method ** has been provided, or ** 2) It is a system table (i.e. sqlite_master), this call is not - ** part of a nested parse and writable_schema pragma has not + ** part of a nested parse and writable_schema pragma has not ** been specified. ** ** In either case leave an error message in pParse and return non-zero. */ - if( ( IsVirtual(pTab) + if( ( IsVirtual(pTab) && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ) || ( (pTab->tabFlags & TF_Readonly)!=0 && (pParse->db->flags & SQLITE_WriteSchema)==0 @@ -71609,7 +83497,7 @@ SQLITE_PRIVATE void sqlite3MaterializeView( pDup = sqlite3SelectDup(db, pView->pSelect, 0); if( pWhere ){ SrcList *pFrom; - + pWhere = sqlite3ExprDup(db, pWhere, 0); pFrom = sqlite3SrcListAppend(db, 0, 0, 0); if( pFrom ){ @@ -71671,11 +83559,11 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( return pWhere; } - /* Generate a select expression tree to enforce the limit/offset + /* Generate a select expression tree to enforce the limit/offset ** term for the DELETE or UPDATE statement. For example: ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 ** becomes: - ** DELETE FROM table_a WHERE rowid IN ( + ** DELETE FROM table_a WHERE rowid IN ( ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 ** ); */ @@ -71856,9 +83744,9 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( #ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION /* Special case: A DELETE without a WHERE clause deletes everything. ** It is easier just to erase the whole table. Prior to version 3.6.5, - ** this optimization caused the row change count (the value returned by + ** this optimization caused the row change count (the value returned by ** API function sqlite3_count_changes) to be set incorrectly. */ - if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) + if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) && 0==sqlite3FkRequired(pParse, pTab, 0, 0) ){ assert( !isView ); @@ -71881,7 +83769,9 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( /* Collect rowids of every row to be deleted. */ sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,WHERE_DUPLICATES_OK); + pWInfo = sqlite3WhereBegin( + pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK + ); if( pWInfo==0 ) goto delete_from_cleanup; regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid); sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid); @@ -71895,9 +83785,9 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( ** because deleting an item can change the scan order. */ end = sqlite3VdbeMakeLabel(v); - /* Unless this is a view, open cursors for the table we are + /* Unless this is a view, open cursors for the table we are ** deleting from and all its indices. If this is a view, then the - ** only effect this statement has is to fire the INSTEAD OF + ** only effect this statement has is to fire the INSTEAD OF ** triggers. */ if( !isView ){ sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite); @@ -71911,6 +83801,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); sqlite3VtabMakeWritable(pParse, pTab); sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, OE_Abort); sqlite3MayAbort(pParse); }else #endif @@ -71940,7 +83831,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( sqlite3AutoincrementEnd(pParse); } - /* Return the number of rows that were deleted. If this routine is + /* Return the number of rows that were deleted. If this routine is ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ @@ -71982,7 +83873,7 @@ delete_from_cleanup: ** 3. The record number of the row to be deleted must be stored in ** memory cell iRowid. ** -** This routine generates code to remove both the table record and all +** This routine generates code to remove both the table record and all ** index entries that point to that record. */ SQLITE_PRIVATE void sqlite3GenerateRowDelete( @@ -72001,12 +83892,12 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete( /* Vdbe is guaranteed to have been allocated by this stage. */ assert( v ); - /* Seek cursor iCur to the row to delete. If this row no longer exists + /* Seek cursor iCur to the row to delete. If this row no longer exists ** (this can happen if a trigger program has already deleted it), do ** not attempt to delete it or fire any DELETE triggers. */ iLabel = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid); - + /* If there are any triggers to fire, allocate a range of registers to ** use for the old.* references in the triggers. */ if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ @@ -72022,57 +83913,55 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete( iOld = pParse->nMem+1; pParse->nMem += (1 + pTab->nCol); - /* Populate the OLD.* pseudo-table register array. These values will be + /* Populate the OLD.* pseudo-table register array. These values will be ** used by any BEFORE and AFTER triggers that exist. */ sqlite3VdbeAddOp2(v, OP_Copy, iRowid, iOld); for(iCol=0; iCol<pTab->nCol; iCol++){ if( mask==0xffffffff || mask&(1<<iCol) ){ - int iTarget = iOld + iCol + 1; - sqlite3VdbeAddOp3(v, OP_Column, iCur, iCol, iTarget); - sqlite3ColumnDefault(v, pTab, iCol, iTarget); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, iOld+iCol+1); } } /* Invoke BEFORE DELETE trigger programs. */ - sqlite3CodeRowTrigger(pParse, pTrigger, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel ); /* Seek the cursor to the row to be deleted again. It may be that ** the BEFORE triggers coded above have already removed the row - ** being deleted. Do not attempt to delete the row a second time, and + ** being deleted. Do not attempt to delete the row a second time, and ** do not fire AFTER triggers. */ sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid); /* Do FK processing. This call checks that any FK constraints that - ** refer to this table (i.e. constraints attached to other tables) + ** refer to this table (i.e. constraints attached to other tables) ** are not violated by deleting this row. */ sqlite3FkCheck(pParse, pTab, iOld, 0); } /* Delete the index and table entries. Skip this step if pTab is really ** a view (in which case the only effect of the DELETE statement is to - ** fire the INSTEAD OF triggers). */ + ** fire the INSTEAD OF triggers). */ if( pTab->pSelect==0 ){ sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0); sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0)); if( count ){ - sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); + sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT); } } /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to ** handle rows (possibly in other tables) that refer via a foreign key - ** to the row just deleted. */ + ** to the row just deleted. */ sqlite3FkActions(pParse, pTab, 0, iOld); /* Invoke AFTER DELETE trigger programs. */ - sqlite3CodeRowTrigger(pParse, pTrigger, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel ); /* Jump here if the row had already been deleted before any BEFORE - ** trigger programs were invoked. Or if a trigger program throws a + ** trigger programs were invoked. Or if a trigger program throws a ** RAISE(IGNORE) exception. */ sqlite3VdbeResolveLabel(v, iLabel); } @@ -72147,8 +84036,14 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey( } } if( doMakeRec ){ + const char *zAff; + if( pTab->pSelect || (pParse->db->flags & SQLITE_IdxRealAsInt)!=0 ){ + zAff = 0; + }else{ + zAff = sqlite3IndexAffinityStr(v, pIdx); + } sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut); - sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0); + sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT); } sqlite3ReleaseTempRange(pParse, regBase, nCol+1); return regBase; @@ -72168,12 +84063,14 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey( ** ************************************************************************* ** This file contains the C functions that implement various SQL -** functions of SQLite. +** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. */ +/* #include <stdlib.h> */ +/* #include <assert.h> */ /* ** Return the collating function associated with a function. @@ -72274,7 +84171,7 @@ static void lengthFunc( ** Implementation of the abs() function. ** ** IMP: R-23979-26855 The abs(X) function returns the absolute value of -** the numeric argument X. +** the numeric argument X. */ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ assert( argc==1 ); @@ -72291,7 +84188,7 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ return; } iVal = -iVal; - } + } sqlite3_result_int64(context, iVal); break; } @@ -72304,7 +84201,7 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ /* Because sqlite3_value_double() returns 0.0 if the argument is not ** something that can be converted into a number, we have: ** IMP: R-57326-31541 Abs(X) return 0.0 if X is a string or blob that - ** cannot be converted to a numeric value. + ** cannot be converted to a numeric value. */ double rVal = sqlite3_value_double(argv[0]); if( rVal<0 ) rVal = -rVal; @@ -72439,7 +84336,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ sqlite3_result_error_nomem(context); return; } - sqlite3AtoF(zBuf, &r); + sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8); sqlite3_free(zBuf); } sqlite3_result_double(context, r); @@ -72524,7 +84421,7 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ ** comment. */ /* -** Implementation of the IFNULL(), NVL(), and COALESCE() functions. +** Implementation of the IFNULL(), NVL(), and COALESCE() functions. ** All three do the same thing. They return the first non-NULL ** argument. */ @@ -72545,7 +84442,7 @@ static void ifnullFunc( #define ifnullFunc versionFunc /* Substitute function - never called */ /* -** Implementation of random(). Return a random integer. +** Implementation of random(). Return a random integer. */ static void randomFunc( sqlite3_context *context, @@ -72556,11 +84453,11 @@ static void randomFunc( UNUSED_PARAMETER2(NotUsed, NotUsed2); sqlite3_randomness(sizeof(r), &r); if( r<0 ){ - /* We need to prevent a random number of 0x8000000000000000 + /* We need to prevent a random number of 0x8000000000000000 ** (or -9223372036854775808) since when you do abs() of that ** number of you get the same value back again. To do this ** in a way that is testable, mask the sign bit off of negative - ** values, resulting in a positive value. Then take the + ** values, resulting in a positive value. Then take the ** 2s complement of that positive value. The end result can ** therefore be no less than -9223372036854775807. */ @@ -72598,8 +84495,8 @@ static void randomBlob( ** value is the same as the sqlite3_last_insert_rowid() API function. */ static void last_insert_rowid( - sqlite3_context *context, - int NotUsed, + sqlite3_context *context, + int NotUsed, sqlite3_value **NotUsed2 ){ sqlite3 *db = sqlite3_context_db_handle(context); @@ -72660,10 +84557,10 @@ struct compareInfo { ** whereas only characters less than 0x80 do in ASCII. */ #if defined(SQLITE_EBCDIC) -# define sqlite3Utf8Read(A,C) (*(A++)) -# define GlogUpperToLower(A) A = sqlite3UpperToLower[A] +# define sqlite3Utf8Read(A,C) (*(A++)) +# define GlogUpperToLower(A) A = sqlite3UpperToLower[A] #else -# define GlogUpperToLower(A) if( A<0x80 ){ A = sqlite3UpperToLower[A]; } +# define GlogUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; } #endif static const struct compareInfo globInfo = { '*', '?', '[', 0 }; @@ -72706,15 +84603,15 @@ static int patternCompare( const u8 *zPattern, /* The glob pattern */ const u8 *zString, /* The string to compare against the glob */ const struct compareInfo *pInfo, /* Information about how to do the compare */ - const int esc /* The escape character */ + u32 esc /* The escape character */ ){ - int c, c2; + u32 c, c2; int invert; int seen; u8 matchOne = pInfo->matchOne; u8 matchAll = pInfo->matchAll; u8 matchSet = pInfo->matchSet; - u8 noCase = pInfo->noCase; + u8 noCase = pInfo->noCase; int prevEscape = 0; /* True if the previous character was 'escape' */ while( (c = sqlite3Utf8Read(zPattern,&zPattern))!=0 ){ @@ -72762,7 +84659,7 @@ static int patternCompare( return 0; } }else if( c==matchSet ){ - int prior_c = 0; + u32 prior_c = 0; assert( esc==0 ); /* This only occurs for GLOB, not LIKE */ seen = 0; invert = 0; @@ -72833,12 +84730,12 @@ SQLITE_API int sqlite3_like_count = 0; ** the GLOB operator. */ static void likeFunc( - sqlite3_context *context, - int argc, + sqlite3_context *context, + int argc, sqlite3_value **argv ){ const unsigned char *zA, *zB; - int escape = 0; + u32 escape = 0; int nPat; sqlite3 *db = sqlite3_context_db_handle(context); @@ -72864,7 +84761,7 @@ static void likeFunc( const unsigned char *zEsc = sqlite3_value_text(argv[2]); if( zEsc==0 ) return; if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){ - sqlite3_result_error(context, + sqlite3_result_error(context, "ESCAPE expression must be a single character", -1); return; } @@ -72875,7 +84772,7 @@ static void likeFunc( #ifdef SQLITE_TEST sqlite3_like_count++; #endif - + sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)); } } @@ -72929,6 +84826,21 @@ static void sourceidFunc( } /* +** Implementation of the sqlite_log() function. This is a wrapper around +** sqlite3_log(). The return value is NULL. The function exists purely for +** its side-effects. +*/ +static void errlogFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(context); + sqlite3_log(sqlite3_value_int(argv[0]), "%s", sqlite3_value_text(argv[1])); +} + +/* ** Implementation of the sqlite_compileoption_used() function. ** The result is an integer that identifies if the compiler option ** was used to build SQLite. @@ -72942,8 +84854,10 @@ static void compileoptionusedFunc( const char *zOptName; assert( argc==1 ); UNUSED_PARAMETER(argc); - /* IMP: R-xxxx This function is an SQL wrapper around the - ** sqlite3_compileoption_used() C interface. */ + /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL + ** function is a wrapper around the sqlite3_compileoption_used() C/C++ + ** function. + */ if( (zOptName = (const char*)sqlite3_value_text(argv[0]))!=0 ){ sqlite3_result_int(context, sqlite3_compileoption_used(zOptName)); } @@ -72951,8 +84865,8 @@ static void compileoptionusedFunc( #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ /* -** Implementation of the sqlite_compileoption_get() function. -** The result is a string that identifies the compiler options +** Implementation of the sqlite_compileoption_get() function. +** The result is a string that identifies the compiler options ** used to build SQLite. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS @@ -72964,8 +84878,9 @@ static void compileoptiongetFunc( int n; assert( argc==1 ); UNUSED_PARAMETER(argc); - /* IMP: R-xxxx This function is an SQL wrapper around the - ** sqlite3_compileoption_get() C interface. */ + /* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function + ** is a wrapper around the sqlite3_compileoption_get() C/C++ function. + */ n = sqlite3_value_int(argv[0]); sqlite3_result_text(context, sqlite3_compileoption_get(n), -1, SQLITE_STATIC); } @@ -72975,7 +84890,7 @@ static void compileoptiongetFunc( ** digits. */ static const char hexdigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /* @@ -73003,7 +84918,7 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char const *zBlob = sqlite3_value_blob(argv[0]); int nBlob = sqlite3_value_bytes(argv[0]); assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ - zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4); + zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4); if( zText ){ int i; for(i=0; i<nBlob; i++){ @@ -73152,7 +85067,7 @@ static void replaceFunc( if( zOut==0 ){ return; } - loopLimit = nStr - nPattern; + loopLimit = nStr - nPattern; for(i=j=0; i<=loopLimit; i++){ if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){ zOut[j++] = zStr[i]; @@ -73164,14 +85079,14 @@ static void replaceFunc( testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] ); if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ sqlite3_result_error_toobig(context); - sqlite3DbFree(db, zOut); + sqlite3_free(zOut); return; } zOld = zOut; zOut = sqlite3_realloc(zOut, (int)nOut); if( zOut==0 ){ sqlite3_result_error_nomem(context); - sqlite3DbFree(db, zOld); + sqlite3_free(zOld); return; } memcpy(&zOut[j], zRep, nRep); @@ -73281,7 +85196,7 @@ static void trimFunc( ** Compute the soundex encoding of a word. ** ** IMP: R-59782-00072 The soundex(X) function returns a string that is the -** soundex encoding of the string X. +** soundex encoding of the string X. */ static void soundexFunc( sqlite3_context *context, @@ -73362,7 +85277,7 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ typedef struct SumCtx SumCtx; struct SumCtx { double rSum; /* Floating point sum */ - i64 iSum; /* Integer sum */ + i64 iSum; /* Integer sum */ i64 cnt; /* Number of elements summed */ u8 overflow; /* True if integer overflow seen */ u8 approx; /* True if non-integer value was input to the sum */ @@ -73390,13 +85305,8 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ if( type==SQLITE_INTEGER ){ i64 v = sqlite3_value_int64(argv[0]); p->rSum += v; - if( (p->approx|p->overflow)==0 ){ - i64 iNewSum = p->iSum + v; - int s1 = (int)(p->iSum >> (sizeof(i64)*8-1)); - int s2 = (int)(v >> (sizeof(i64)*8-1)); - int s3 = (int)(iNewSum >> (sizeof(i64)*8-1)); - p->overflow = ((s1&s2&~s3) | (~s1&~s2&s3))?1:0; - p->iSum = iNewSum; + if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){ + p->overflow = 1; } }else{ p->rSum += sqlite3_value_double(argv[0]); @@ -73452,13 +85362,13 @@ static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ #ifndef SQLITE_OMIT_DEPRECATED /* The sqlite3_aggregate_count() function is deprecated. But just to make - ** sure it still operates correctly, verify that its count agrees with our + ** sure it still operates correctly, verify that its count agrees with our ** internal count when using count(*) and when the total count can be ** expressed as a 32-bit integer. */ assert( argc==1 || p==0 || p->n>0x7fffffff || p->n==sqlite3_aggregate_count(context) ); #endif -} +} static void countFinalize(sqlite3_context *context){ CountCtx *p; p = sqlite3_aggregate_context(context, 0); @@ -73469,8 +85379,8 @@ static void countFinalize(sqlite3_context *context){ ** Routines to implement min() and max() aggregate functions. */ static void minmaxStep( - sqlite3_context *context, - int NotUsed, + sqlite3_context *context, + int NotUsed, sqlite3_value **argv ){ Mem *pArg = (Mem *)argv[0]; @@ -73532,7 +85442,7 @@ static void groupConcatStep( if( pAccum ){ sqlite3 *db = sqlite3_context_db_handle(context); int firstTerm = pAccum->useMalloc==0; - pAccum->useMalloc = 1; + pAccum->useMalloc = 2; pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; if( !firstTerm ){ if( argc==2 ){ @@ -73557,28 +85467,23 @@ static void groupConcatFinalize(sqlite3_context *context){ sqlite3_result_error_toobig(context); }else if( pAccum->mallocFailed ){ sqlite3_result_error_nomem(context); - }else{ - sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, + }else{ + sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, sqlite3_free); } } } /* -** This function registered all of the above C functions as SQL -** functions. This should be the only routine in this file with -** external linkage. +** This routine does per-connection function registration. Most +** of the built-in functions above are part of the global function set. +** This routine only deals with those that are not global. */ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ -#ifndef SQLITE_OMIT_ALTERTABLE - sqlite3AlterFunctions(db); -#endif - if( !db->mallocFailed ){ - int rc = sqlite3_overload_function(db, "MATCH", 2); - assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); - if( rc==SQLITE_NOMEM ){ - db->mallocFailed = 1; - } + int rc = sqlite3_overload_function(db, "MATCH", 2); + assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; } } @@ -73606,12 +85511,12 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive) }else{ pInfo = (struct compareInfo*)&likeInfoNorm; } - sqlite3CreateFunc(db, "like", 2, SQLITE_ANY, pInfo, likeFunc, 0, 0); - sqlite3CreateFunc(db, "like", 3, SQLITE_ANY, pInfo, likeFunc, 0, 0); - sqlite3CreateFunc(db, "glob", 2, SQLITE_ANY, - (struct compareInfo*)&globInfo, likeFunc, 0,0); + sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); + sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); + sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, + (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0); setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE); - setLikeOptFlag(db, "like", + setLikeOptFlag(db, "like", caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE); } @@ -73624,14 +85529,14 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive) */ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ FuncDef *pDef; - if( pExpr->op!=TK_FUNCTION - || !pExpr->x.pList + if( pExpr->op!=TK_FUNCTION + || !pExpr->x.pList || pExpr->x.pList->nExpr!=2 ){ return 0; } assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - pDef = sqlite3FindFunction(db, pExpr->u.zToken, + pDef = sqlite3FindFunction(db, pExpr->u.zToken, sqlite3Strlen30(pExpr->u.zToken), 2, SQLITE_UTF8, 0); if( NEVER(pDef==0) || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){ @@ -73693,15 +85598,16 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ FUNCTION(coalesce, 1, 0, 0, 0 ), FUNCTION(coalesce, 0, 0, 0, 0 ), /* FUNCTION(coalesce, -1, 0, 0, ifnullFunc ), */ - {-1,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"coalesce",0}, + {-1,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"coalesce",0,0}, FUNCTION(hex, 1, 0, 0, hexFunc ), /* FUNCTION(ifnull, 2, 0, 0, ifnullFunc ), */ - {2,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"ifnull",0}, + {2,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"ifnull",0,0}, FUNCTION(random, 0, 0, 0, randomFunc ), FUNCTION(randomblob, 1, 0, 0, randomBlob ), FUNCTION(nullif, 2, 0, 1, nullifFunc ), FUNCTION(sqlite_version, 0, 0, 0, versionFunc ), FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), + FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), @@ -73723,11 +85629,11 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ), AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ), /* AGGREGATE(count, 0, 0, 0, countStep, countFinalize ), */ - {0,SQLITE_UTF8,SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0}, + {0,SQLITE_UTF8,SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0,0}, AGGREGATE(count, 1, 0, 0, countStep, countFinalize ), AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize), AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize), - + LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), #ifdef SQLITE_CASE_SENSITIVE_LIKE LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), @@ -73746,6 +85652,9 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ sqlite3FuncDefInsert(pHash, &aFunc[i]); } sqlite3RegisterDateTimeFunctions(); +#ifndef SQLITE_OMIT_ALTERTABLE + sqlite3AlterFunctions(); +#endif } /************** End of func.c ************************************************/ @@ -73773,25 +85682,25 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ ** ** Foreign keys in SQLite come in two flavours: deferred and immediate. ** If an immediate foreign key constraint is violated, SQLITE_CONSTRAINT -** is returned and the current statement transaction rolled back. If a -** deferred foreign key constraint is violated, no action is taken -** immediately. However if the application attempts to commit the +** is returned and the current statement transaction rolled back. If a +** deferred foreign key constraint is violated, no action is taken +** immediately. However if the application attempts to commit the ** transaction before fixing the constraint violation, the attempt fails. ** ** Deferred constraints are implemented using a simple counter associated -** with the database handle. The counter is set to zero each time a -** database transaction is opened. Each time a statement is executed +** with the database handle. The counter is set to zero each time a +** database transaction is opened. Each time a statement is executed ** that causes a foreign key violation, the counter is incremented. Each ** time a statement is executed that removes an existing violation from ** the database, the counter is decremented. When the transaction is ** committed, the commit fails if the current value of the counter is ** greater than zero. This scheme has two big drawbacks: ** -** * When a commit fails due to a deferred foreign key constraint, +** * When a commit fails due to a deferred foreign key constraint, ** there is no way to tell which foreign constraint is not satisfied, ** or which row it is not satisfied for. ** -** * If the database contains foreign key violations when the +** * If the database contains foreign key violations when the ** transaction is opened, this may cause the mechanism to malfunction. ** ** Despite these problems, this approach is adopted as it seems simpler @@ -73803,26 +85712,26 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ ** the parent table for a match. If none is found increment the ** constraint counter. ** -** I.2) For each FK for which the table is the parent table, +** I.2) For each FK for which the table is the parent table, ** search the child table for rows that correspond to the new ** row in the parent table. Decrement the counter for each row ** found (as the constraint is now satisfied). ** ** DELETE operations: ** -** D.1) For each FK for which the table is the child table, -** search the parent table for a row that corresponds to the -** deleted row in the child table. If such a row is not found, +** D.1) For each FK for which the table is the child table, +** search the parent table for a row that corresponds to the +** deleted row in the child table. If such a row is not found, ** decrement the counter. ** -** D.2) For each FK for which the table is the parent table, search -** the child table for rows that correspond to the deleted row +** D.2) For each FK for which the table is the parent table, search +** the child table for rows that correspond to the deleted row ** in the parent table. For each found increment the counter. ** ** UPDATE operations: ** ** An UPDATE command requires that all 4 steps above are taken, but only -** for FK constraints for which the affected columns are actually +** for FK constraints for which the affected columns are actually ** modified (values must be compared at runtime). ** ** Note that I.1 and D.1 are very similar operations, as are I.2 and D.2. @@ -73831,10 +85740,10 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ ** For the purposes of immediate FK constraints, the OR REPLACE conflict ** resolution is considered to delete rows before the new row is inserted. ** If a delete caused by OR REPLACE violates an FK constraint, an exception -** is thrown, even if the FK constraint would be satisfied after the new +** is thrown, even if the FK constraint would be satisfied after the new ** row is inserted. ** -** Immediate constraints are usually handled similarly. The only difference +** Immediate constraints are usually handled similarly. The only difference ** is that the counter used is stored as part of each individual statement ** object (struct Vdbe). If, after the statement has run, its immediate ** constraint counter is greater than zero, it returns SQLITE_CONSTRAINT @@ -73844,7 +85753,7 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ ** INSERT violates a foreign key constraint. This is necessary as such ** an INSERT does not open a statement transaction. ** -** TODO: How should dropping a table be handled? How should renaming a +** TODO: How should dropping a table be handled? How should renaming a ** table be handled? ** ** @@ -73855,7 +85764,7 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ ** for those two operations needs to know whether or not the operation ** requires any FK processing and, if so, which columns of the original ** row are required by the FK processing VDBE code (i.e. if FKs were -** implemented using triggers, which of the old.* columns would be +** implemented using triggers, which of the old.* columns would be ** accessed). No information is required by the code-generator before ** coding an INSERT operation. The functions used by the UPDATE/DELETE ** generation code to query for this information are: @@ -73892,13 +85801,13 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ /* ** A foreign key constraint requires that the key columns in the parent ** table are collectively subject to a UNIQUE or PRIMARY KEY constraint. -** Given that pParent is the parent table for foreign key constraint pFKey, -** search the schema a unique index on the parent key columns. -** -** If successful, zero is returned. If the parent key is an INTEGER PRIMARY -** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx -** is set to point to the unique index. +** Given that pParent is the parent table for foreign key constraint pFKey, +** search the schema a unique index on the parent key columns. ** +** If successful, zero is returned. If the parent key is an INTEGER PRIMARY +** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx +** is set to point to the unique index. +** ** If the parent key consists of a single column (the foreign key constraint ** is not a composite foreign key), output variable *paiCol is set to NULL. ** Otherwise, it is set to point to an allocated array of size N, where @@ -73921,8 +85830,8 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ ** PRIMARY KEY, or ** ** 4) No parent key columns were provided explicitly as part of the -** foreign key definition, and the PRIMARY KEY of the parent table -** consists of a a different number of columns to the child key in +** foreign key definition, and the PRIMARY KEY of the parent table +** consists of a a different number of columns to the child key in ** the child table. ** ** then non-zero is returned, and a "foreign key mismatch" error loaded @@ -73946,9 +85855,9 @@ static int locateFkeyIndex( assert( !paiCol || *paiCol==0 ); assert( pParse ); - /* If this is a non-composite (single column) foreign key, check if it - ** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx - ** and *paiCol set to zero and return early. + /* If this is a non-composite (single column) foreign key, check if it + ** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx + ** and *paiCol set to zero and return early. ** ** Otherwise, for a composite foreign key (more than one column), allocate ** space for the aiCol array (returned via output parameter *paiCol). @@ -73957,7 +85866,7 @@ static int locateFkeyIndex( if( nCol==1 ){ /* The FK maps to the IPK if any of the following are true: ** - ** 1) There is an INTEGER PRIMARY KEY column and the FK is implicitly + ** 1) There is an INTEGER PRIMARY KEY column and the FK is implicitly ** mapped to the primary key of table pParent, or ** 2) The FK is explicitly mapped to a column declared as INTEGER ** PRIMARY KEY. @@ -73974,14 +85883,14 @@ static int locateFkeyIndex( } for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->nColumn==nCol && pIdx->onError!=OE_None ){ + if( pIdx->nColumn==nCol && pIdx->onError!=OE_None ){ /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number ** of columns. If each indexed column corresponds to a foreign key ** column of pFKey, then this index is a winner. */ if( zKey==0 ){ - /* If zKey is NULL, then this foreign key is implicitly mapped to - ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be + /* If zKey is NULL, then this foreign key is implicitly mapped to + ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be ** identified by the test (Index.autoIndex==2). */ if( pIdx->autoIndex==2 ){ if( aiCol ){ @@ -74037,15 +85946,15 @@ static int locateFkeyIndex( } /* -** This function is called when a row is inserted into or deleted from the -** child table of foreign key constraint pFKey. If an SQL UPDATE is executed +** This function is called when a row is inserted into or deleted from the +** child table of foreign key constraint pFKey. If an SQL UPDATE is executed ** on the child table of pFKey, this function is invoked twice for each row ** affected - once to "delete" the old row, and then again to "insert" the ** new row. ** ** Each time it is called, this function generates VDBE code to locate the -** row in the parent table that corresponds to the row being inserted into -** or deleted from the child table. If the parent row can be found, no +** row in the parent table that corresponds to the row being inserted into +** or deleted from the child table. If the parent row can be found, no ** special action is taken. Otherwise, if the parent row can *not* be ** found in the parent table: ** @@ -74059,7 +85968,7 @@ static int locateFkeyIndex( ** ** DELETE deferred Decrement the "deferred constraint counter". ** -** These operations are identified in the comment at the top of this file +** These operations are identified in the comment at the top of this file ** (fkey.c) as "I.1" and "D.1". */ static void fkLookupParent( @@ -74082,8 +85991,8 @@ static void fkLookupParent( ** outstanding constraints to resolve. If there are not, there is no need ** to check if deleting this row resolves any outstanding violations. ** - ** Check if any of the key columns in the child table row are NULL. If - ** any are, then the constraint is considered satisfied. No need to + ** Check if any of the key columns in the child table row are NULL. If + ** any are, then the constraint is considered satisfied. No need to ** search for a matching row in the parent table. */ if( nIncr<0 ){ sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk); @@ -74099,15 +86008,15 @@ static void fkLookupParent( ** column of the parent table (table pTab). */ int iMustBeInt; /* Address of MustBeInt instruction */ int regTemp = sqlite3GetTempReg(pParse); - - /* Invoke MustBeInt to coerce the child key value to an integer (i.e. + + /* Invoke MustBeInt to coerce the child key value to an integer (i.e. ** apply the affinity of the parent key). If this fails, then there ** is no matching parent key. Before using MustBeInt, make a copy of ** the value. Otherwise, the value inserted into the child key column ** will have INTEGER affinity applied to it, which may not be correct. */ sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp); iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0); - + /* If the parent table is the same as the child table, and we are about ** to increment the constraint-counter (i.e. this is an INSERT operation), ** then check if the row being inserted matches itself. If so, do not @@ -74115,7 +86024,7 @@ static void fkLookupParent( if( pTab==pFKey->pFrom && nIncr==1 ){ sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); } - + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk); @@ -74127,31 +86036,43 @@ static void fkLookupParent( int regTemp = sqlite3GetTempRange(pParse, nCol); int regRec = sqlite3GetTempReg(pParse); KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); - + sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb); sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF); for(i=0; i<nCol; i++){ - sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[i]+1+regData, regTemp+i); + sqlite3VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i); } - + /* If the parent table is the same as the child table, and we are about ** to increment the constraint-counter (i.e. this is an INSERT operation), ** then check if the row being inserted matches itself. If so, do not - ** increment the constraint-counter. */ + ** increment the constraint-counter. + ** + ** If any of the parent-key values are NULL, then the row cannot match + ** itself. So set JUMPIFNULL to make sure we do the OP_Found if any + ** of the parent-key values are NULL (at this point it is known that + ** none of the child key values are). + */ if( pTab==pFKey->pFrom && nIncr==1 ){ int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1; for(i=0; i<nCol; i++){ int iChild = aiCol[i]+1+regData; int iParent = pIdx->aiColumn[i]+1+regData; + assert( aiCol[i]!=pTab->iPKey ); + if( pIdx->aiColumn[i]==pTab->iPKey ){ + /* The parent key is a composite key that includes the IPK column */ + iParent = regData; + } sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); + sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); } sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk); } - + sqlite3VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec); - sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0); + sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT); sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); - + sqlite3ReleaseTempReg(pParse, regRec); sqlite3ReleaseTempRange(pParse, regTemp, nCol); } @@ -74179,7 +86100,7 @@ static void fkLookupParent( /* ** This function is called to generate code executed when a row is deleted -** from the parent table of foreign key constraint pFKey and, if pFKey is +** from the parent table of foreign key constraint pFKey and, if pFKey is ** deferred, when a row is inserted into the same table. When generating ** code for an SQL UPDATE operation, this function may be called twice - ** once to "delete" the old row and once to "insert" the new row. @@ -74202,7 +86123,7 @@ static void fkLookupParent( ** ** INSERT deferred Decrement the "deferred constraint counter". ** -** These operations are identified in the comment at the top of this file +** These operations are identified in the comment at the top of this file ** (fkey.c) as "I.2" and "D.2". */ static void fkScanChildren( @@ -74241,7 +86162,7 @@ static void fkScanChildren( Expr *pLeft; /* Value from parent table row */ Expr *pRight; /* Column ref to child table */ Expr *pEq; /* Expression (pLeft = pRight) */ - int iCol; /* Index of column in child table */ + int iCol; /* Index of column in child table */ const char *zCol; /* Name of column in child table */ pLeft = sqlite3Expr(db, TK_REGISTER, 0); @@ -74251,7 +86172,8 @@ static void fkScanChildren( if( pIdx ){ Column *pCol; iCol = pIdx->aiColumn[i]; - pCol = &pIdx->pTable->aCol[iCol]; + pCol = &pTab->aCol[iCol]; + if( pTab->iPKey==iCol ) iCol = -1; pLeft->iTable = regData+iCol+1; pLeft->affinity = pCol->affinity; pLeft->pColl = sqlite3LocateCollSeq(pParse, pCol->zColl); @@ -74270,7 +86192,7 @@ static void fkScanChildren( /* If the child table is the same as the parent table, and this scan ** is taking place as part of a DELETE operation (operation D.2), omit the - ** row being deleted from the scan by adding ($rowid != rowid) to the WHERE + ** row being deleted from the scan by adding ($rowid != rowid) to the WHERE ** clause, where $rowid is the rowid of the row being deleted. */ if( pTab==pFKey->pFrom && nIncr>0 ){ Expr *pEq; /* Expression (pLeft = pRight) */ @@ -74298,7 +86220,7 @@ static void fkScanChildren( ** clause. If the constraint is not deferred, throw an exception for ** each row found. Otherwise, for deferred constraints, increment the ** deferred constraint counter by nIncr for each row selected. */ - pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0); + pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0); if( nIncr>0 && pFKey->isDeferred==0 ){ sqlite3ParseToplevel(pParse)->mayAbort = 1; } @@ -74334,7 +86256,7 @@ SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){ } /* -** The second argument is a Trigger structure allocated by the +** The second argument is a Trigger structure allocated by the ** fkActionTrigger() routine. This function deletes the Trigger structure ** and all of its sub-components. ** @@ -74362,7 +86284,7 @@ static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ ** ** (a) The table is the parent table of a FK constraint, or ** (b) The table is the child table of a deferred FK constraint and it is -** determined at runtime that there are outstanding deferred FK +** determined at runtime that there are outstanding deferred FK ** constraint violations in the database, ** ** then the equivalent of "DELETE FROM <tbl>" is executed before dropping @@ -74378,7 +86300,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa assert( v ); /* VDBE has already been allocated */ if( sqlite3FkReferences(pTab)==0 ){ /* Search for a deferred foreign key constraint for which this table - ** is the child table. If one cannot be found, return without + ** is the child table. If one cannot be found, return without ** generating any VDBE code. If one can be found, then jump over ** the entire DELETE if there are no outstanding deferred constraints ** when this statement is run. */ @@ -74395,7 +86317,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0); pParse->disableTriggers = 0; - /* If the DELETE has generated immediate foreign key constraint + /* If the DELETE has generated immediate foreign key constraint ** violations, halt the VDBE and return an error at this point, before ** any modifications to the schema are made. This is because statement ** transactions are not able to rollback schema changes. */ @@ -74412,7 +86334,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa /* ** This function is called when inserting, deleting or updating a row of -** table pTab to generate VDBE code to perform foreign key constraint +** table pTab to generate VDBE code to perform foreign key constraint ** processing for the operation. ** ** For a DELETE operation, parameter regOld is passed the index of the @@ -74428,16 +86350,15 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa ** For an UPDATE operation, this function is called twice. Once before ** the original record is deleted from the table using the calling convention ** described for DELETE. Then again after the original record is deleted -** but before the new record is inserted using the INSERT convention. +** but before the new record is inserted using the INSERT convention. */ SQLITE_PRIVATE void sqlite3FkCheck( Parse *pParse, /* Parse context */ - Table *pTab, /* Row is being deleted from this table */ + Table *pTab, /* Row is being deleted from this table */ int regOld, /* Previous row data is stored here */ int regNew /* New row data is stored here */ ){ sqlite3 *db = pParse->db; /* Database handle */ - Vdbe *v; /* VM to write code to */ FKey *pFKey; /* Used to iterate through FKs */ int iDb; /* Index of database containing pTab */ const char *zDb; /* Name of database containing pTab */ @@ -74449,7 +86370,6 @@ SQLITE_PRIVATE void sqlite3FkCheck( /* If foreign-keys are disabled, this function is a no-op. */ if( (db->flags&SQLITE_ForeignKeys)==0 ) return; - v = sqlite3GetVdbe(pParse); iDb = sqlite3SchemaToIndex(db, pTab->pSchema); zDb = db->aDb[iDb].zName; @@ -74464,9 +86384,9 @@ SQLITE_PRIVATE void sqlite3FkCheck( int i; int isIgnore = 0; - /* Find the parent table of this foreign key. Also find a unique index - ** on the parent key columns in the parent table. If either of these - ** schema items cannot be located, set an error in pParse and return + /* Find the parent table of this foreign key. Also find a unique index + ** on the parent key columns in the parent table. If either of these + ** schema items cannot be located, set an error in pParse and return ** early. */ if( pParse->disableTriggers ){ pTo = sqlite3FindTable(db, pFKey->zTo, zDb); @@ -74474,7 +86394,24 @@ SQLITE_PRIVATE void sqlite3FkCheck( pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb); } if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){ + assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) ); if( !isIgnoreErrors || db->mallocFailed ) return; + if( pTo==0 ){ + /* If isIgnoreErrors is true, then a table is being dropped. In this + ** case SQLite runs a "DELETE FROM xxx" on the table being dropped + ** before actually dropping it in order to check FK constraints. + ** If the parent table of an FK constraint on the current table is + ** missing, behave as if it is empty. i.e. decrement the relevant + ** FK counter for each row of the current table with non-NULL keys. + */ + Vdbe *v = sqlite3GetVdbe(pParse); + int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1; + for(i=0; i<pFKey->nCol; i++){ + int iReg = pFKey->aCol[i].iFrom + regOld + 1; + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); + } + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1); + } continue; } assert( pFKey->nCol==1 || (aiFree && pIdx) ); @@ -74490,7 +86427,7 @@ SQLITE_PRIVATE void sqlite3FkCheck( aiCol[i] = -1; } #ifndef SQLITE_OMIT_AUTHORIZATION - /* Request permission to read the parent key columns. If the + /* Request permission to read the parent key columns. If the ** authorization callback returns SQLITE_IGNORE, behave as if any ** values read from the parent table are NULL. */ if( db->xAuth ){ @@ -74502,21 +86439,21 @@ SQLITE_PRIVATE void sqlite3FkCheck( #endif } - /* Take a shared-cache advisory read-lock on the parent table. Allocate - ** a cursor to use to search the unique index on the parent key columns + /* Take a shared-cache advisory read-lock on the parent table. Allocate + ** a cursor to use to search the unique index on the parent key columns ** in the parent table. */ sqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName); pParse->nTab++; if( regOld!=0 ){ /* A row is being removed from the child table. Search for the parent. - ** If the parent does not exist, removing the child row resolves an + ** If the parent does not exist, removing the child row resolves an ** outstanding foreign key constraint violation. */ fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1,isIgnore); } if( regNew!=0 ){ /* A row is being added to the child table. If a parent row cannot - ** be found, adding the child row has violated the FK constraint. */ + ** be found, adding the child row has violated the FK constraint. */ fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1,isIgnore); } @@ -74542,7 +86479,7 @@ SQLITE_PRIVATE void sqlite3FkCheck( } assert( aiCol || pFKey->nCol==1 ); - /* Create a SrcList structure containing a single table (the table + /* Create a SrcList structure containing a single table (the table ** the foreign key that refers to this table is attached to). This ** is required for the sqlite3WhereXXX() interface. */ pSrc = sqlite3SrcListAppend(db, 0, 0, 0); @@ -74552,13 +86489,13 @@ SQLITE_PRIVATE void sqlite3FkCheck( pItem->zName = pFKey->pFrom->zName; pItem->pTab->nRef++; pItem->iCursor = pParse->nTab++; - + if( regNew!=0 ){ fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1); } if( regOld!=0 ){ /* If there is a RESTRICT action configured for the current operation - ** on the parent table of this FK, then throw an exception + ** on the parent table of this FK, then throw an exception ** immediately if the FK constraint is violated, even if this is a ** deferred trigger. That's what RESTRICT means. To defer checking ** the constraint, the FK should specify NO ACTION (represented @@ -74575,7 +86512,7 @@ SQLITE_PRIVATE void sqlite3FkCheck( #define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x))) /* -** This function is called before generating code to update or delete a +** This function is called before generating code to update or delete a ** row contained in table pTab. */ SQLITE_PRIVATE u32 sqlite3FkOldmask( @@ -74601,17 +86538,17 @@ SQLITE_PRIVATE u32 sqlite3FkOldmask( } /* -** This function is called before generating code to update or delete a +** This function is called before generating code to update or delete a ** row contained in table pTab. If the operation is a DELETE, then ** parameter aChange is passed a NULL value. For an UPDATE, aChange points ** to an array of size N, where N is the number of columns in table pTab. -** If the i'th column is not modified by the UPDATE, then the corresponding +** If the i'th column is not modified by the UPDATE, then the corresponding ** entry in the aChange[] array is set to -1. If the column is modified, ** the value is 0 or greater. Parameter chngRowid is set to true if the ** UPDATE statement modifies the rowid fields of the table. ** ** If any foreign key processing will be required, this function returns -** true. If there is no foreign key related processing, this function +** true. If there is no foreign key related processing, this function ** returns false. */ SQLITE_PRIVATE int sqlite3FkRequired( @@ -74622,8 +86559,8 @@ SQLITE_PRIVATE int sqlite3FkRequired( ){ if( pParse->db->flags&SQLITE_ForeignKeys ){ if( !aChange ){ - /* A DELETE operation. Foreign key processing is required if the - ** table in question is either the child or parent table for any + /* A DELETE operation. Foreign key processing is required if the + ** table in question is either the child or parent table for any ** foreign key constraint. */ return (sqlite3FkReferences(pTab) || pTab->pFKey); }else{ @@ -74661,7 +86598,7 @@ SQLITE_PRIVATE int sqlite3FkRequired( } /* -** This function is called when an UPDATE or DELETE operation is being +** This function is called when an UPDATE or DELETE operation is being ** compiled on table pTab, which is the parent table of foreign-key pFKey. ** If the current operation is an UPDATE, then the pChanges parameter is ** passed a pointer to the list of columns being modified. If it is a @@ -74673,7 +86610,7 @@ SQLITE_PRIVATE int sqlite3FkRequired( ** returned (these actions require no special handling by the triggers ** sub-system, code for them is created by fkScanChildren()). ** -** For example, if pFKey is the foreign key and pTab is table "p" in +** For example, if pFKey is the foreign key and pTab is table "p" in ** the following schema: ** ** CREATE TABLE p(pk PRIMARY KEY); @@ -74686,7 +86623,7 @@ SQLITE_PRIVATE int sqlite3FkRequired( ** END; ** ** The returned pointer is cached as part of the foreign key object. It -** is eventually freed along with the rest of the foreign key object by +** is eventually freed along with the rest of the foreign key object by ** sqlite3FkDelete(). */ static Trigger *fkActionTrigger( @@ -74740,7 +86677,7 @@ static Trigger *fkActionTrigger( ** that the affinity and collation sequence associated with the ** parent table are used for the comparison. */ pEq = sqlite3PExpr(pParse, TK_EQ, - sqlite3PExpr(pParse, TK_DOT, + sqlite3PExpr(pParse, TK_DOT, sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld), sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol) , 0), @@ -74755,22 +86692,22 @@ static Trigger *fkActionTrigger( */ if( pChanges ){ pEq = sqlite3PExpr(pParse, TK_IS, - sqlite3PExpr(pParse, TK_DOT, + sqlite3PExpr(pParse, TK_DOT, sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld), sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol), 0), - sqlite3PExpr(pParse, TK_DOT, + sqlite3PExpr(pParse, TK_DOT, sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew), sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol), 0), 0); pWhen = sqlite3ExprAnd(db, pWhen, pEq); } - + if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){ Expr *pNew; if( action==OE_Cascade ){ - pNew = sqlite3PExpr(pParse, TK_DOT, + pNew = sqlite3PExpr(pParse, TK_DOT, sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew), sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol) , 0); @@ -74795,7 +86732,7 @@ static Trigger *fkActionTrigger( if( action==OE_Restrict ){ Token tFrom; - Expr *pRaise; + Expr *pRaise; tFrom.z = zFrom; tFrom.n = nFrom; @@ -74803,7 +86740,7 @@ static Trigger *fkActionTrigger( if( pRaise ){ pRaise->affinity = OE_Abort; } - pSelect = sqlite3SelectNew(pParse, + pSelect = sqlite3SelectNew(pParse, sqlite3ExprListAppend(pParse, 0, pRaise), sqlite3SrcListAppend(db, 0, &tFrom, 0), pWhere, @@ -74812,15 +86749,11 @@ static Trigger *fkActionTrigger( pWhere = 0; } - /* In the current implementation, pTab->dbMem==0 for all tables except - ** for temporary tables used to describe subqueries. And temporary - ** tables do not have foreign key constraints. Hence, pTab->dbMem - ** should always be 0 there. - */ + /* Disable lookaside memory allocation */ enableLookaside = db->lookaside.bEnabled; db->lookaside.bEnabled = 0; - pTrigger = (Trigger *)sqlite3DbMallocZero(db, + pTrigger = (Trigger *)sqlite3DbMallocZero(db, sizeof(Trigger) + /* struct Trigger */ sizeof(TriggerStep) + /* Single step in trigger program */ nFrom + 1 /* Space for pStep->target.z */ @@ -74830,7 +86763,7 @@ static Trigger *fkActionTrigger( pStep->target.z = (char *)&pStep[1]; pStep->target.n = nFrom; memcpy((char *)pStep->target.z, zFrom, nFrom); - + pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); @@ -74854,12 +86787,12 @@ static Trigger *fkActionTrigger( switch( action ){ case OE_Restrict: - pStep->op = TK_SELECT; + pStep->op = TK_SELECT; break; - case OE_Cascade: - if( !pChanges ){ - pStep->op = TK_DELETE; - break; + case OE_Cascade: + if( !pChanges ){ + pStep->op = TK_DELETE; + break; } default: pStep->op = TK_UPDATE; @@ -74884,9 +86817,9 @@ SQLITE_PRIVATE void sqlite3FkActions( ExprList *pChanges, /* Change-list for UPDATE, NULL for DELETE */ int regOld /* Address of array containing old row */ ){ - /* If foreign-key support is enabled, iterate through all FKs that - ** refer to table pTab. If there is an action associated with the FK - ** for this operation (either update or delete), invoke the associated + /* If foreign-key support is enabled, iterate through all FKs that + ** refer to table pTab. If there is an action associated with the FK + ** for this operation (either update or delete), invoke the associated ** trigger sub-program. */ if( pParse->db->flags&SQLITE_ForeignKeys ){ FKey *pFKey; /* Iterator variable */ @@ -74906,37 +86839,40 @@ SQLITE_PRIVATE void sqlite3FkActions( ** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash ** hash table. */ -SQLITE_PRIVATE void sqlite3FkDelete(Table *pTab){ +SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){ FKey *pFKey; /* Iterator variable */ FKey *pNext; /* Copy of pFKey->pNextFrom */ + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){ /* Remove the FK from the fkeyHash hash table. */ - if( pFKey->pPrevTo ){ - pFKey->pPrevTo->pNextTo = pFKey->pNextTo; - }else{ - void *data = (void *)pFKey->pNextTo; - const char *z = (data ? pFKey->pNextTo->zTo : pFKey->zTo); - sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, sqlite3Strlen30(z), data); - } - if( pFKey->pNextTo ){ - pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; + 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); + sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, sqlite3Strlen30(z), p); + } + if( pFKey->pNextTo ){ + pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; + } } - /* Delete any triggers created to implement actions for this FK. */ -#ifndef SQLITE_OMIT_TRIGGER - fkTriggerDelete(pTab->dbMem, pFKey->apTrigger[0]); - fkTriggerDelete(pTab->dbMem, pFKey->apTrigger[1]); -#endif - /* EV: R-30323-21917 Each foreign key constraint in SQLite is ** classified as either immediate or deferred. */ assert( pFKey->isDeferred==0 || pFKey->isDeferred==1 ); + /* Delete any triggers created to implement actions for this FK. */ +#ifndef SQLITE_OMIT_TRIGGER + fkTriggerDelete(db, pFKey->apTrigger[0]); + fkTriggerDelete(db, pFKey->apTrigger[1]); +#endif + pNext = pFKey->pNextFrom; - sqlite3DbFree(pTab->dbMem, pFKey); + sqlite3DbFree(db, pFKey); } } #endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */ @@ -74980,7 +86916,7 @@ SQLITE_PRIVATE void sqlite3OpenTable( /* ** Return a pointer to the column affinity string associated with index -** pIdx. A column affinity string has one character for each column in +** pIdx. A column affinity string has one character for each column in ** the table, according to the affinity of the column: ** ** Character Column affinity @@ -75011,7 +86947,7 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ int n; Table *pTab = pIdx->pTable; sqlite3 *db = sqlite3VdbeDb(v); - pIdx->zColAff = (char *)sqlite3Malloc(pIdx->nColumn+2); + pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+2); if( !pIdx->zColAff ){ db->mallocFailed = 1; return 0; @@ -75022,7 +86958,7 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ pIdx->zColAff[n++] = SQLITE_AFF_NONE; pIdx->zColAff[n] = 0; } - + return pIdx->zColAff; } @@ -75042,7 +86978,7 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ */ SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ /* The first time a column affinity string for a particular table - ** is required, it is allocated and populated here. It is then + ** is required, it is allocated and populated here. It is then ** stored as a member of the Table structure for subsequent use. ** ** The column affinity string will eventually be deleted by @@ -75053,7 +86989,7 @@ SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ int i; sqlite3 *db = sqlite3VdbeDb(v); - zColAff = (char *)sqlite3Malloc(pTab->nCol+1); + zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); if( !zColAff ){ db->mallocFailed = 1; return; @@ -75067,15 +87003,15 @@ SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ pTab->zColAff = zColAff; } - sqlite3VdbeChangeP4(v, -1, pTab->zColAff, 0); + sqlite3VdbeChangeP4(v, -1, pTab->zColAff, P4_TRANSIENT); } /* ** Return non-zero if the table pTab in database iDb or any of its indices ** have been opened at any point in the VDBE program beginning at location -** iStartAddr throught the end of the program. This is used to see if -** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can -** run without using temporary table for the results of the SELECT. +** iStartAddr throught the end of the program. This is used to see if +** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can +** run without using temporary table for the results of the SELECT. */ static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){ Vdbe *v = sqlite3GetVdbe(p); @@ -75162,7 +87098,7 @@ static int autoIncBegin( /* ** This routine generates code that will initialize all of the -** register used by the autoincrement tracker. +** register used by the autoincrement tracker. */ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){ AutoincInfo *p; /* Information about an AUTOINCREMENT */ @@ -75181,6 +87117,7 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){ for(p = pParse->pAinc; p; p = p->pNext){ pDb = &db->aDb[p->iDb]; memId = p->regCtr; + assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); addr = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0); @@ -75231,6 +87168,7 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ int memId = p->regCtr; iRec = sqlite3GetTempReg(pParse); + assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); j2 = sqlite3VdbeAddOp0(v, OP_Rewind); @@ -75409,7 +87347,6 @@ SQLITE_PRIVATE void sqlite3Insert( int regIns; /* Block of regs holding rowid+data being inserted */ int regRowid; /* registers holding insert rowid */ int regData; /* register holding first column to insert */ - int regRecord; /* Holds the assemblied row record */ int regEof = 0; /* Register recording end of SELECT data */ int *aRegIdx = 0; /* One register allocated to each index */ @@ -75460,7 +87397,7 @@ SQLITE_PRIVATE void sqlite3Insert( assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) ); /* If pTab is really a view, make sure it has been initialized. - ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual + ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual ** module table). */ if( sqlite3ViewGetColumnNames(pParse, pTab) ){ @@ -75468,7 +87405,7 @@ SQLITE_PRIVATE void sqlite3Insert( } /* Ensure that: - * (a) the table is not read-only, + * (a) the table is not read-only, * (b) that if it is a view then ON INSERT triggers exist */ if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ @@ -75566,7 +87503,7 @@ SQLITE_PRIVATE void sqlite3Insert( ** the destination table (template 3). ** ** A temp table must be used if the table being updated is also one - ** of the tables being read by the SELECT statement. Also use a + ** of the tables being read by the SELECT statement. Also use a ** temp table in the case of row triggers. */ if( pTrigger || readsTable(pParse, addrSelect, iDb, pTab) ){ @@ -75630,7 +87567,7 @@ SQLITE_PRIVATE void sqlite3Insert( } } if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "table %S has %d columns but %d values were supplied", pTabList, 0, pTab->nCol-nHidden, nColumn); goto insert_cleanup; @@ -75641,7 +87578,7 @@ SQLITE_PRIVATE void sqlite3Insert( } /* If the INSERT statement included an IDLIST term, then make sure - ** all elements of the IDLIST really are columns of the table and + ** all elements of the IDLIST really are columns of the table and ** remember the column indices. ** ** If the table has an INTEGER PRIMARY KEY column and that column @@ -75671,7 +87608,7 @@ SQLITE_PRIVATE void sqlite3Insert( }else{ sqlite3ErrorMsg(pParse, "table %S has no column named %s", pTabList, 0, pColumn->a[i].zName); - pParse->nErr++; + pParse->checkSchema = 1; goto insert_cleanup; } } @@ -75685,7 +87622,7 @@ SQLITE_PRIVATE void sqlite3Insert( if( pColumn==0 && nColumn>0 ){ keyColumn = pTab->iPKey; } - + /* Initialize the count of rows to be inserted */ if( db->flags & SQLITE_CountRows ){ @@ -75738,7 +87675,6 @@ SQLITE_PRIVATE void sqlite3Insert( /* Allocate registers for holding the rowid of the new row, ** the content of the new row, and the assemblied row record. */ - regRecord = ++pParse->nMem; regRowid = regIns = pParse->nMem+1; pParse->nMem += pTab->nCol + 1; if( IsVirtual(pTab) ){ @@ -75790,10 +87726,10 @@ SQLITE_PRIVATE void sqlite3Insert( if( pColumn->a[j].idx==i ) break; } } - if( pColumn && j>=pColumn->nId ){ + if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId) ){ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1); }else if( useTempTable ){ - sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1); + sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1); }else{ assert( pSelect==0 ); /* Otherwise useTempTable is true */ sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1); @@ -75811,7 +87747,7 @@ SQLITE_PRIVATE void sqlite3Insert( } /* Fire BEFORE or INSTEAD OF triggers */ - sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, pTab, regCols-pTab->nCol-1, onError, endOfLoop); sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1); @@ -75820,7 +87756,7 @@ SQLITE_PRIVATE void sqlite3Insert( /* Push the record number for the new entry onto the stack. The ** record number is a randomly generate integer created by NewRowid ** except when the table has an INTEGER PRIMARY KEY column, in which - ** case the record number is the same as that column. + ** case the record number is the same as that column. */ if( !isView ){ if( IsVirtual(pTab) ){ @@ -75897,7 +87833,7 @@ SQLITE_PRIVATE void sqlite3Insert( if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iRegStore); }else if( useTempTable ){ - sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore); + sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore); }else if( pSelect ){ sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore); }else{ @@ -75913,6 +87849,7 @@ SQLITE_PRIVATE void sqlite3Insert( const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); sqlite3VtabMakeWritable(pParse, pTab); sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError); sqlite3MayAbort(pParse); }else #endif @@ -75936,7 +87873,7 @@ SQLITE_PRIVATE void sqlite3Insert( if( pTrigger ){ /* Code AFTER triggers */ - sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, pTab, regData-2-pTab->nCol, onError, endOfLoop); } @@ -75971,7 +87908,7 @@ insert_end: } /* - ** Return the number of rows inserted. If this routine is + ** Return the number of rows inserted. If this routine is ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ @@ -76021,10 +87958,10 @@ insert_cleanup: ** If isUpdate is true and rowidChng is non-zero, then rowidChng contains ** the address of a register containing the rowid before the update takes ** place. isUpdate is true for UPDATEs and false for INSERTs. If isUpdate -** is false, indicating an INSERT statement, then a non-zero rowidChng +** is false, indicating an INSERT statement, then a non-zero rowidChng ** indicates that the rowid was explicitly specified as part of the ** INSERT statement. If rowidChng is false, it means that the rowid is -** computed automatically in an insert or that the rowid value is not +** computed automatically in an insert or that the rowid value is not ** modified by an update. ** ** The code generated by this routine store new index entries into @@ -76132,7 +88069,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( case OE_Rollback: case OE_Fail: { char *zMsg; - j1 = sqlite3VdbeAddOp3(v, OP_HaltIfNull, + sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT, onError, regData+i); zMsg = sqlite3MPrintf(pParse->db, "%s.%s may not be NULL", pTab->zName, pTab->aCol[i].zName); @@ -76164,6 +88101,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( if( onError==OE_Ignore ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); }else{ + if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */ sqlite3HaltConstraint(pParse, onError, 0, 0); } sqlite3VdbeResolveLabel(v, allOk); @@ -76181,7 +88119,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( }else if( onError==OE_Default ){ onError = OE_Abort; } - + if( isUpdate ){ j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, rowidChng); } @@ -76205,10 +88143,10 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** the triggers and remove both the table and index b-tree entries. ** ** Otherwise, if there are no triggers or the recursive-triggers - ** flag is not set, but the table has one or more indexes, call - ** GenerateRowIndexDelete(). This removes the index b-tree entries - ** only. The table b-tree entry will be replaced by the new entry - ** when it is inserted. + ** flag is not set, but the table has one or more indexes, call + ** GenerateRowIndexDelete(). This removes the index b-tree entries + ** only. The table b-tree entry will be replaced by the new entry + ** when it is inserted. ** ** If either GenerateRowDelete() or GenerateRowIndexDelete() is called, ** also invoke MultiWrite() to indicate that this VDBE may require @@ -76271,12 +88209,12 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i); sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]); - sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0); + sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT); sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1); /* Find out what action to take in case there is an indexing conflict */ onError = pIdx->onError; - if( onError==OE_None ){ + if( onError==OE_None ){ sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1); continue; /* pIdx is not a UNIQUE index */ } @@ -76289,7 +88227,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( if( onError==OE_Ignore ) onError = OE_Replace; else if( onError==OE_Fail ) onError = OE_Abort; } - + /* Check to see if the new index entry will be unique */ regR = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp2(v, OP_SCopy, regOldRowid, regR); @@ -76348,7 +88286,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( sqlite3VdbeJumpHere(v, j3); sqlite3ReleaseTempReg(pParse, regR); } - + if( pbMayReplace ){ *pbMayReplace = seenReplace; } @@ -76411,7 +88349,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( } sqlite3VdbeAddOp3(v, OP_Insert, baseCur, regRec, regRowid); if( !pParse->nested ){ - sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); + sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT); } sqlite3VdbeChangeP5(v, pik_flags); } @@ -76677,6 +88615,18 @@ static int xferOptimization( return 0; /* Tables have different CHECK constraints. Ticket #2252 */ } #endif +#ifndef SQLITE_OMIT_FOREIGN_KEY + /* Disallow the transfer optimization if the destination table constains + ** any foreign key constraints. This is more restrictive than necessary. + ** But the main beneficiary of the transfer optimization is the VACUUM + ** command, and the VACUUM command disables foreign key constraints. So + ** the extra complication to make this rule less restrictive is probably + ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e] + */ + if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){ + return 0; + } +#endif /* If we get this far, it means either: ** @@ -76845,7 +88795,7 @@ SQLITE_API int sqlite3_exec( rc = sqlite3_step(pStmt); /* Invoke the callback function if required */ - if( xCallback && (SQLITE_ROW==rc || + if( xCallback && (SQLITE_ROW==rc || (SQLITE_DONE==rc && !callbackIsInit && db->flags&SQLITE_NullCallback)) ){ if( !callbackIsInit ){ @@ -76955,7 +88905,7 @@ exec_out: ** This header file defines the SQLite interface for use by ** shared libraries that want to be imported as extensions into ** an SQLite instance. Shared libraries that intend to be loaded -** as extensions by SQLite should #include this file instead of +** as extensions by SQLite should #include this file instead of ** sqlite3.h. */ #ifndef _SQLITE3EXT_H_ @@ -77133,6 +89083,30 @@ struct sqlite3_api_routines { sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*); const char *(*sql)(sqlite3_stmt*); int (*status)(int,int*,int*,int); + int (*backup_finish)(sqlite3_backup*); + sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); + int (*backup_pagecount)(sqlite3_backup*); + int (*backup_remaining)(sqlite3_backup*); + int (*backup_step)(sqlite3_backup*,int); + const char *(*compileoption_get)(int); + int (*compileoption_used)(const char*); + int (*create_function_v2)(sqlite3*,const char*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*),void(*xDestroy)(void*)); + int (*db_config)(sqlite3*,int,...); + sqlite3_mutex *(*db_mutex)(sqlite3*); + int (*db_status)(sqlite3*,int,int*,int*,int); + int (*extended_errcode)(sqlite3*); + void (*log)(int,const char*,...); + sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); + const char *(*sourceid)(void); + int (*stmt_status)(sqlite3_stmt*,int,int); + int (*strnicmp)(const char*,const char*,int); + int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*); + int (*wal_autocheckpoint)(sqlite3*,int); + int (*wal_checkpoint)(sqlite3*,const char*); + void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); + int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); + int (*vtab_config)(sqlite3*,int op,...); + int (*vtab_on_conflict)(sqlite3*); }; /* @@ -77312,6 +89286,30 @@ struct sqlite3_api_routines { #define sqlite3_next_stmt sqlite3_api->next_stmt #define sqlite3_sql sqlite3_api->sql #define sqlite3_status sqlite3_api->status +#define sqlite3_backup_finish sqlite3_api->backup_finish +#define sqlite3_backup_init sqlite3_api->backup_init +#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount +#define sqlite3_backup_remaining sqlite3_api->backup_remaining +#define sqlite3_backup_step sqlite3_api->backup_step +#define sqlite3_compileoption_get sqlite3_api->compileoption_get +#define sqlite3_compileoption_used sqlite3_api->compileoption_used +#define sqlite3_create_function_v2 sqlite3_api->create_function_v2 +#define sqlite3_db_config sqlite3_api->db_config +#define sqlite3_db_mutex sqlite3_api->db_mutex +#define sqlite3_db_status sqlite3_api->db_status +#define sqlite3_extended_errcode sqlite3_api->extended_errcode +#define sqlite3_log sqlite3_api->log +#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64 +#define sqlite3_sourceid sqlite3_api->sourceid +#define sqlite3_stmt_status sqlite3_api->stmt_status +#define sqlite3_strnicmp sqlite3_api->strnicmp +#define sqlite3_unlock_notify sqlite3_api->unlock_notify +#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint +#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint +#define sqlite3_wal_hook sqlite3_api->wal_hook +#define sqlite3_blob_reopen sqlite3_api->blob_reopen +#define sqlite3_vtab_config sqlite3_api->vtab_config +#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict #endif /* SQLITE_CORE */ #define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api = 0; @@ -77321,6 +89319,7 @@ struct sqlite3_api_routines { /************** End of sqlite3ext.h ******************************************/ /************** Continuing where we left off in loadext.c ********************/ +/* #include <string.h> */ #ifndef SQLITE_OMIT_LOAD_EXTENSION @@ -77373,6 +89372,11 @@ struct sqlite3_api_routines { # define sqlite3_complete16 0 #endif +#ifdef SQLITE_OMIT_DECLTYPE +# define sqlite3_column_decltype16 0 +# define sqlite3_column_decltype 0 +#endif + #ifdef SQLITE_OMIT_PROGRESS_CALLBACK # define sqlite3_progress_handler 0 #endif @@ -77381,6 +89385,8 @@ struct sqlite3_api_routines { # define sqlite3_create_module 0 # define sqlite3_create_module_v2 0 # define sqlite3_declare_vtab 0 +# define sqlite3_vtab_config 0 +# define sqlite3_vtab_on_conflict 0 #endif #ifdef SQLITE_OMIT_SHARED_CACHE @@ -77404,6 +89410,7 @@ struct sqlite3_api_routines { #define sqlite3_blob_open 0 #define sqlite3_blob_read 0 #define sqlite3_blob_write 0 +#define sqlite3_blob_reopen 0 #endif /* @@ -77589,8 +89596,8 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_memory_highwater, sqlite3_memory_used, #ifdef SQLITE_MUTEX_OMIT - 0, - 0, + 0, + 0, 0, 0, 0, @@ -77629,6 +89636,49 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_next_stmt, sqlite3_sql, sqlite3_status, + + /* + ** Added for 3.7.4 + */ + sqlite3_backup_finish, + sqlite3_backup_init, + sqlite3_backup_pagecount, + sqlite3_backup_remaining, + sqlite3_backup_step, +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + sqlite3_compileoption_get, + sqlite3_compileoption_used, +#else + 0, + 0, +#endif + sqlite3_create_function_v2, + sqlite3_db_config, + sqlite3_db_mutex, + sqlite3_db_status, + sqlite3_extended_errcode, + sqlite3_log, + sqlite3_soft_heap_limit64, + sqlite3_sourceid, + sqlite3_stmt_status, + sqlite3_strnicmp, +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + sqlite3_unlock_notify, +#else + 0, +#endif +#ifndef SQLITE_OMIT_WAL + sqlite3_wal_autocheckpoint, + sqlite3_wal_checkpoint, + sqlite3_wal_hook, +#else + 0, + 0, + 0, +#endif + sqlite3_blob_reopen, + sqlite3_vtab_config, + sqlite3_vtab_on_conflict, }; /* @@ -77639,7 +89689,7 @@ static const sqlite3_api_routines sqlite3Apis = { ** ** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong. ** -** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with ** error message text. The calling function should free this memory ** by calling sqlite3DbFree(db, ). */ @@ -77678,13 +89728,11 @@ static int sqlite3LoadExtension( handle = sqlite3OsDlOpen(pVfs, zFile); if( handle==0 ){ if( pzErrMsg ){ - zErrmsg = sqlite3StackAllocZero(db, nMsg); + *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg); if( zErrmsg ){ - sqlite3_snprintf(nMsg, zErrmsg, + sqlite3_snprintf(nMsg, zErrmsg, "unable to open shared library [%s]", zFile); sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); - *pzErrMsg = sqlite3DbStrDup(0, zErrmsg); - sqlite3StackFree(db, zErrmsg); } } return SQLITE_ERROR; @@ -77693,13 +89741,11 @@ static int sqlite3LoadExtension( sqlite3OsDlSym(pVfs, handle, zProc); if( xInit==0 ){ if( pzErrMsg ){ - zErrmsg = sqlite3StackAllocZero(db, nMsg); + *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg); if( zErrmsg ){ sqlite3_snprintf(nMsg, zErrmsg, "no entry point [%s] in shared library [%s]", zProc,zFile); sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); - *pzErrMsg = sqlite3DbStrDup(0, zErrmsg); - sqlite3StackFree(db, zErrmsg); } sqlite3OsDlClose(pVfs, handle); } @@ -77791,7 +89837,7 @@ static const sqlite3_api_routines sqlite3Apis = { 0 }; */ typedef struct sqlite3AutoExtList sqlite3AutoExtList; static SQLITE_WSD struct sqlite3AutoExtList { - int nExt; /* Number of entries in aExt[] */ + int nExt; /* Number of entries in aExt[] */ void (**aExt)(void); /* Pointers to the extension init functions */ } sqlite3Autoext = { 0, 0 }; @@ -77926,13 +89972,9 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ ** This file contains code used to implement the PRAGMA command. */ -/* Ignore this whole file if pragmas are disabled -*/ -#if !defined(SQLITE_OMIT_PRAGMA) - /* ** Interpret the given string as a safety level. Return 0 for OFF, -** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or +** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or ** unrecognized string argument. ** ** Note that the values returned are one less that the values that @@ -77948,7 +89990,7 @@ static u8 getSafetyLevel(const char *z){ static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2}; int i, n; if( sqlite3Isdigit(*z) ){ - return (u8)atoi(z); + return (u8)sqlite3Atoi(z); } n = sqlite3Strlen30(z); for(i=0; i<ArraySize(iLength); i++){ @@ -77962,10 +90004,16 @@ static u8 getSafetyLevel(const char *z){ /* ** Interpret the given string as a boolean value. */ -static u8 getBoolean(const char *z){ +SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z){ return getSafetyLevel(z)&1; } +/* The sqlite3GetBoolean() function is used by other modules but the +** remainder of this file is specific to PRAGMA processing. So omit +** the rest of the file if PRAGMAs are omitted from the build. +*/ +#if !defined(SQLITE_OMIT_PRAGMA) + /* ** Interpret the given string as a locking mode value. */ @@ -77981,7 +90029,7 @@ static int getLockingMode(const char *z){ /* ** Interpret the given string as an auto-vacuum mode value. ** -** The following strings, "none", "full" and "incremental" are +** The following strings, "none", "full" and "incremental" are ** acceptable, as are their numeric equivalents: 0, 1 and 2 respectively. */ static int getAutoVacuum(const char *z){ @@ -77989,7 +90037,7 @@ static int getAutoVacuum(const char *z){ if( 0==sqlite3StrICmp(z, "none") ) return BTREE_AUTOVACUUM_NONE; if( 0==sqlite3StrICmp(z, "full") ) return BTREE_AUTOVACUUM_FULL; if( 0==sqlite3StrICmp(z, "incremental") ) return BTREE_AUTOVACUUM_INCR; - i = atoi(z); + i = sqlite3Atoi(z); return (u8)((i>=0&&i<=2)?i:0); } #endif /* ifndef SQLITE_OMIT_AUTOVACUUM */ @@ -78028,7 +90076,7 @@ static int invalidateTempStorage(Parse *pParse){ } sqlite3BtreeClose(db->aDb[1].pBt); db->aDb[1].pBt = 0; - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); } return SQLITE_OK; } @@ -78085,7 +90133,11 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ { "empty_result_callbacks", SQLITE_NullCallback }, { "legacy_file_format", SQLITE_LegacyFileFmt }, { "fullfsync", SQLITE_FullFSync }, + { "checkpoint_fullfsync", SQLITE_CkptFullFSync }, { "reverse_unordered_selects", SQLITE_ReverseOrder }, +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX + { "automatic_index", SQLITE_AutoIndex }, +#endif #ifdef SQLITE_DEBUG { "sql_trace", SQLITE_SqlTrace }, { "vdbe_listing", SQLITE_VdbeListing }, @@ -78128,13 +90180,13 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ mask &= ~(SQLITE_ForeignKeys); } - if( getBoolean(zRight) ){ + if( sqlite3GetBoolean(zRight) ){ db->flags |= mask; }else{ db->flags &= ~mask; } - /* Many of the flag-pragmas modify the code generated by the SQL + /* Many of the flag-pragmas modify the code generated by the SQL ** compiler (eg. count_changes). So add an opcode to expire all ** compiled SQL statements after modifying a pragma value. */ @@ -78160,15 +90212,40 @@ static const char *actionName(u8 action){ case OE_SetDflt: zName = "SET DEFAULT"; break; case OE_Cascade: zName = "CASCADE"; break; case OE_Restrict: zName = "RESTRICT"; break; - default: zName = "NO ACTION"; + default: zName = "NO ACTION"; assert( action==OE_None ); break; } return zName; } #endif + +/* +** Parameter eMode must be one of the PAGER_JOURNALMODE_XXX constants +** defined in pager.h. This function returns the associated lowercase +** journal-mode name. +*/ +SQLITE_PRIVATE const char *sqlite3JournalModename(int eMode){ + static char * const azModeName[] = { + "delete", "persist", "off", "truncate", "memory" +#ifndef SQLITE_OMIT_WAL + , "wal" +#endif + }; + assert( PAGER_JOURNALMODE_DELETE==0 ); + assert( PAGER_JOURNALMODE_PERSIST==1 ); + assert( PAGER_JOURNALMODE_OFF==2 ); + assert( PAGER_JOURNALMODE_TRUNCATE==3 ); + assert( PAGER_JOURNALMODE_MEMORY==4 ); + assert( PAGER_JOURNALMODE_WAL==5 ); + assert( eMode>=0 && eMode<=ArraySize(azModeName) ); + + if( eMode==ArraySize(azModeName) ) return 0; + return azModeName[eMode]; +} + /* -** Process a pragma statement. +** Process a pragma statement. ** ** Pragmas are of this form: ** @@ -78183,7 +90260,7 @@ static const char *actionName(u8 action){ ** id and pId2 is any empty string. */ SQLITE_PRIVATE void sqlite3Pragma( - Parse *pParse, + Parse *pParse, Token *pId1, /* First part of [database.]id field */ Token *pId2, /* Second part of [database.]id field, or NULL */ Token *pValue, /* Token for <value>, or NULL */ @@ -78207,8 +90284,8 @@ SQLITE_PRIVATE void sqlite3Pragma( if( iDb<0 ) return; pDb = &db->aDb[iDb]; - /* If the temp database has been explicitly named as part of the - ** pragma, make sure it is open. + /* If the temp database has been explicitly named as part of the + ** pragma, make sure it is open. */ if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){ return; @@ -78227,7 +90304,7 @@ SQLITE_PRIVATE void sqlite3Pragma( if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ goto pragma_out; } - + #ifndef SQLITE_OMIT_PAGER_PRAGMAS /* ** PRAGMA [database.]default_cache_size @@ -78239,11 +90316,11 @@ SQLITE_PRIVATE void sqlite3Pragma( ** page cache size value and the persistent page cache size value ** stored in the database file. ** - ** The default cache size is stored in meta-value 2 of page 1 of the - ** database file. The cache size is actually the absolute value of - ** this memory location. The sign of meta-value 2 determines the - ** synchronous setting. A negative value means synchronous is off - ** and a positive value means synchronous is on. + ** Older versions of SQLite would set the default cache size to a + ** negative number to indicate synchronous=OFF. These days, synchronous + ** is always on by default regardless of the sign of the default cache + ** size. But continue to take the absolute value of the default cache + ** size of historical compatibility. */ if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ static const VdbeOpList getCacheSize[] = { @@ -78268,15 +90345,11 @@ SQLITE_PRIVATE void sqlite3Pragma( sqlite3VdbeChangeP1(v, addr+1, iDb); sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE); }else{ - int size = atoi(zRight); - if( size<0 ) size = -size; + int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp2(v, OP_Integer, size, 1); - sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 2, BTREE_DEFAULT_CACHE_SIZE); - addr = sqlite3VdbeAddOp2(v, OP_IfPos, 2, 0); - sqlite3VdbeAddOp2(v, OP_Integer, -size, 1); - sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } @@ -78301,7 +90374,7 @@ SQLITE_PRIVATE void sqlite3Pragma( /* Malloc may fail when setting the page-size, as there is an internal ** buffer that the pager module resizes using sqlite3_realloc(). */ - db->nextPagesize = atoi(zRight); + db->nextPagesize = sqlite3Atoi(zRight); if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ db->mallocFailed = 1; } @@ -78309,28 +90382,6 @@ SQLITE_PRIVATE void sqlite3Pragma( }else /* - ** PRAGMA [database.]max_page_count - ** PRAGMA [database.]max_page_count=N - ** - ** The first form reports the current setting for the - ** maximum number of pages in the database file. The - ** second form attempts to change this setting. Both - ** forms return the current setting. - */ - if( sqlite3StrICmp(zLeft,"max_page_count")==0 ){ - Btree *pBt = pDb->pBt; - int newMax = 0; - assert( pBt!=0 ); - if( zRight ){ - newMax = atoi(zRight); - } - if( ALWAYS(pBt) ){ - newMax = sqlite3BtreeMaxPageCount(pBt, newMax); - } - returnSingleInt(pParse, "max_page_count", newMax); - }else - - /* ** PRAGMA [database.]secure_delete ** PRAGMA [database.]secure_delete=ON/OFF ** @@ -78343,7 +90394,7 @@ SQLITE_PRIVATE void sqlite3Pragma( int b = -1; assert( pBt!=0 ); if( zRight ){ - b = getBoolean(zRight); + b = sqlite3GetBoolean(zRight); } if( pId2->n==0 && b>=0 ){ int ii; @@ -78356,19 +90407,33 @@ SQLITE_PRIVATE void sqlite3Pragma( }else /* + ** PRAGMA [database.]max_page_count + ** PRAGMA [database.]max_page_count=N + ** + ** The first form reports the current setting for the + ** maximum number of pages in the database file. The + ** second form attempts to change this setting. Both + ** forms return the current setting. + ** ** PRAGMA [database.]page_count ** ** Return the number of pages in the specified database. */ - if( sqlite3StrICmp(zLeft,"page_count")==0 ){ + if( sqlite3StrICmp(zLeft,"page_count")==0 + || sqlite3StrICmp(zLeft,"max_page_count")==0 + ){ int iReg; if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3CodeVerifySchema(pParse, iDb); iReg = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); + if( zLeft[0]=='p' ){ + sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); + }else{ + sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, sqlite3Atoi(zRight)); + } sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "page_count", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); }else /* @@ -78420,62 +90485,49 @@ SQLITE_PRIVATE void sqlite3Pragma( /* ** PRAGMA [database.]journal_mode - ** PRAGMA [database.]journal_mode = (delete|persist|off|truncate|memory) + ** PRAGMA [database.]journal_mode = + ** (delete|persist|off|truncate|memory|wal|off) */ if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){ - int eMode; - static char * const azModeName[] = { - "delete", "persist", "off", "truncate", "memory" - }; + int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ + int ii; /* Loop counter */ + + /* Force the schema to be loaded on all databases. This cases all + ** database files to be opened and the journal_modes set. */ + if( sqlite3ReadSchema(pParse) ){ + goto pragma_out; + } + + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC); if( zRight==0 ){ + /* If there is no "=MODE" part of the pragma, do a query for the + ** current mode */ eMode = PAGER_JOURNALMODE_QUERY; }else{ + const char *zMode; int n = sqlite3Strlen30(zRight); - eMode = sizeof(azModeName)/sizeof(azModeName[0]) - 1; - while( eMode>=0 && sqlite3StrNICmp(zRight, azModeName[eMode], n)!=0 ){ - eMode--; + for(eMode=0; (zMode = sqlite3JournalModename(eMode))!=0; eMode++){ + if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break; + } + if( !zMode ){ + /* If the "=MODE" part does not match any known journal mode, + ** then do a query */ + eMode = PAGER_JOURNALMODE_QUERY; } } - if( pId2->n==0 && eMode==PAGER_JOURNALMODE_QUERY ){ - /* Simple "PRAGMA journal_mode;" statement. This is a query for - ** the current default journal mode (which may be different to - ** the journal-mode of the main database). - */ - eMode = db->dfltJournalMode; - }else{ - Pager *pPager; - if( pId2->n==0 ){ - /* This indicates that no database name was specified as part - ** of the PRAGMA command. In this case the journal-mode must be - ** set on all attached databases, as well as the main db file. - ** - ** Also, the sqlite3.dfltJournalMode variable is set so that - ** any subsequently attached databases also use the specified - ** journal mode. - */ - int ii; - assert(pDb==&db->aDb[0]); - for(ii=1; ii<db->nDb; ii++){ - if( db->aDb[ii].pBt ){ - pPager = sqlite3BtreePager(db->aDb[ii].pBt); - sqlite3PagerJournalMode(pPager, eMode); - } - } - db->dfltJournalMode = (u8)eMode; + if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){ + /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */ + iDb = 0; + pId2->n = 1; + } + for(ii=db->nDb-1; ii>=0; ii--){ + if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ + sqlite3VdbeUsesBtree(v, ii); + sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); } - pPager = sqlite3BtreePager(pDb->pBt); - eMode = sqlite3PagerJournalMode(pPager, eMode); } - assert( eMode==PAGER_JOURNALMODE_DELETE - || eMode==PAGER_JOURNALMODE_TRUNCATE - || eMode==PAGER_JOURNALMODE_PERSIST - || eMode==PAGER_JOURNALMODE_OFF - || eMode==PAGER_JOURNALMODE_MEMORY ); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC); - sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, - azModeName[eMode], P4_STATIC); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); }else @@ -78489,7 +90541,7 @@ SQLITE_PRIVATE void sqlite3Pragma( Pager *pPager = sqlite3BtreePager(pDb->pBt); i64 iLimit = -2; if( zRight ){ - sqlite3Atoi64(zRight, &iLimit); + sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8); if( iLimit<-1 ) iLimit = -1; } iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); @@ -78532,7 +90584,7 @@ SQLITE_PRIVATE void sqlite3Pragma( */ int rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ - /* When setting the auto_vacuum mode to either "full" or + /* When setting the auto_vacuum mode to either "full" or ** "incremental", write the value of meta[6] in the database ** file. Before writing to meta[6], check that meta[3] indicates ** that this really is an auto-vacuum capable database. @@ -78600,11 +90652,11 @@ SQLITE_PRIVATE void sqlite3Pragma( */ if( sqlite3StrICmp(zLeft,"cache_size")==0 ){ if( sqlite3ReadSchema(pParse) ) goto pragma_out; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( !zRight ){ returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); }else{ - int size = atoi(zRight); - if( size<0 ) size = -size; + int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } @@ -78643,7 +90695,7 @@ SQLITE_PRIVATE void sqlite3Pragma( if( !zRight ){ if( sqlite3_temp_directory ){ sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "temp_store_directory", SQLITE_STATIC); sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_temp_directory, 0); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); @@ -78667,7 +90719,7 @@ SQLITE_PRIVATE void sqlite3Pragma( } sqlite3_free(sqlite3_temp_directory); if( zRight[0] ){ - sqlite3_temp_directory = sqlite3DbStrDup(0, zRight); + sqlite3_temp_directory = sqlite3_mprintf("%s", zRight); }else{ sqlite3_temp_directory = 0; } @@ -78696,12 +90748,12 @@ SQLITE_PRIVATE void sqlite3Pragma( Pager *pPager = sqlite3BtreePager(pDb->pBt); char *proxy_file_path = NULL; sqlite3_file *pFile = sqlite3PagerFile(pPager); - sqlite3OsFileControl(pFile, SQLITE_GET_LOCKPROXYFILE, + sqlite3OsFileControl(pFile, SQLITE_GET_LOCKPROXYFILE, &proxy_file_path); - + if( proxy_file_path ){ sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "lock_proxy_file", SQLITE_STATIC); sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, proxy_file_path, 0); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); @@ -78711,10 +90763,10 @@ SQLITE_PRIVATE void sqlite3Pragma( sqlite3_file *pFile = sqlite3PagerFile(pPager); int res; if( zRight[0] ){ - res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, zRight); } else { - res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, NULL); } if( res!=SQLITE_OK ){ @@ -78723,8 +90775,8 @@ SQLITE_PRIVATE void sqlite3Pragma( } } }else -#endif /* SQLITE_ENABLE_LOCKING_STYLE */ - +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + /* ** PRAGMA [database.]synchronous ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL @@ -78740,7 +90792,7 @@ SQLITE_PRIVATE void sqlite3Pragma( returnSingleInt(pParse, "synchronous", pDb->safety_level-1); }else{ if( !db->autoCommit ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "Safety level may not be changed inside a transaction"); }else{ pDb->safety_level = getSafetyLevel(zRight)+1; @@ -78840,7 +90892,7 @@ SQLITE_PRIVATE void sqlite3Pragma( v = sqlite3GetVdbe(pParse); pIdx = pTab->pIndex; if( pIdx ){ - int i = 0; + int i = 0; sqlite3VdbeSetNumCols(v, 3); pParse->nMem = 3; sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); @@ -78903,7 +90955,7 @@ SQLITE_PRIVATE void sqlite3Pragma( v = sqlite3GetVdbe(pParse); pFK = pTab->pFKey; if( pFK ){ - int i = 0; + int i = 0; sqlite3VdbeSetNumCols(v, 8); pParse->nMem = 8; sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE_STATIC); @@ -78942,7 +90994,7 @@ SQLITE_PRIVATE void sqlite3Pragma( #ifndef NDEBUG if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ if( zRight ){ - if( getBoolean(zRight) ){ + if( sqlite3GetBoolean(zRight) ){ sqlite3ParserTrace(stderr, "parser: "); }else{ sqlite3ParserTrace(0, 0); @@ -78956,7 +91008,7 @@ SQLITE_PRIVATE void sqlite3Pragma( */ if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){ if( zRight ){ - sqlite3RegisterLikeFunctions(db, getBoolean(zRight)); + sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight)); } }else @@ -78965,12 +91017,12 @@ SQLITE_PRIVATE void sqlite3Pragma( #endif #ifndef SQLITE_OMIT_INTEGRITY_CHECK - /* Pragma "quick_check" is an experimental reduced version of + /* Pragma "quick_check" is an experimental reduced version of ** integrity_check designed to detect most database corruption ** without most of the overhead of a full integrity-check. */ if( sqlite3StrICmp(zLeft, "integrity_check")==0 - || sqlite3StrICmp(zLeft, "quick_check")==0 + || sqlite3StrICmp(zLeft, "quick_check")==0 ){ int i, j, addr, mxErr; @@ -78996,7 +91048,7 @@ SQLITE_PRIVATE void sqlite3Pragma( /* Set the maximum error count */ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; if( zRight ){ - mxErr = atoi(zRight); + sqlite3GetInt32(zRight, &mxErr); if( mxErr<=0 ){ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; } @@ -79021,6 +91073,7 @@ SQLITE_PRIVATE void sqlite3Pragma( ** Begin by filling registers 2, 3, ... with the root pages numbers ** for all tables and indices in the database. */ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pTbls = &db->aDb[i].pSchema->tblHash; for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); @@ -79086,7 +91139,7 @@ SQLITE_PRIVATE void sqlite3Pragma( addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr); sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC); sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC); - sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_STATIC); + sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT); sqlite3VdbeJumpHere(v, addr+9); sqlite3VdbeJumpHere(v, jmp2); } @@ -79114,11 +91167,11 @@ SQLITE_PRIVATE void sqlite3Pragma( sqlite3VdbeChangeP1(v, addr+3, j+2); sqlite3VdbeChangeP2(v, addr+3, addr+2); sqlite3VdbeJumpHere(v, addr+4); - sqlite3VdbeChangeP4(v, addr+6, + sqlite3VdbeChangeP4(v, addr+6, "wrong # of entries in index ", P4_STATIC); - sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_STATIC); + sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_TRANSIENT); } - } + } } addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); sqlite3VdbeChangeP2(v, addr, -mxErr); @@ -79140,7 +91193,7 @@ SQLITE_PRIVATE void sqlite3Pragma( ** encoding that will be used for the main database file if a new file ** is created. If an existing main database file is opened, then the ** default text encoding for the existing database is used. - ** + ** ** In all cases new databases created using the ATTACH command are ** created to use the same default text encoding as the main database. If ** the main database has not been initialized and/or created when ATTACH @@ -79182,9 +91235,9 @@ SQLITE_PRIVATE void sqlite3Pragma( ** will be overwritten when the schema is next loaded. If it does not ** already exists, it will be created to use the new encoding value. */ - if( - !(DbHasProperty(db, 0, DB_SchemaLoaded)) || - DbHasProperty(db, 0, DB_Empty) + if( + !(DbHasProperty(db, 0, DB_SchemaLoaded)) || + DbHasProperty(db, 0, DB_Empty) ){ for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ @@ -79226,9 +91279,9 @@ SQLITE_PRIVATE void sqlite3Pragma( ** The user-version is not used internally by SQLite. It may be used by ** applications for any purpose. */ - if( sqlite3StrICmp(zLeft, "schema_version")==0 - || sqlite3StrICmp(zLeft, "user_version")==0 - || sqlite3StrICmp(zLeft, "freelist_count")==0 + if( sqlite3StrICmp(zLeft, "schema_version")==0 + || sqlite3StrICmp(zLeft, "user_version")==0 + || sqlite3StrICmp(zLeft, "freelist_count")==0 ){ int iCookie; /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */ sqlite3VdbeUsesBtree(v, iDb); @@ -79253,7 +91306,7 @@ SQLITE_PRIVATE void sqlite3Pragma( }; int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie); sqlite3VdbeChangeP1(v, addr, iDb); - sqlite3VdbeChangeP1(v, addr+1, atoi(zRight)); + sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight)); sqlite3VdbeChangeP1(v, addr+2, iDb); sqlite3VdbeChangeP2(v, addr+2, iCookie); }else{ @@ -79293,6 +91346,51 @@ SQLITE_PRIVATE void sqlite3Pragma( }else #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ +#ifndef SQLITE_OMIT_WAL + /* + ** PRAGMA [database.]wal_checkpoint = passive|full|restart + ** + ** Checkpoint the database. + */ + if( sqlite3StrICmp(zLeft, "wal_checkpoint")==0 ){ + int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); + int eMode = SQLITE_CHECKPOINT_PASSIVE; + if( zRight ){ + if( sqlite3StrICmp(zRight, "full")==0 ){ + eMode = SQLITE_CHECKPOINT_FULL; + }else if( sqlite3StrICmp(zRight, "restart")==0 ){ + eMode = SQLITE_CHECKPOINT_RESTART; + } + } + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + sqlite3VdbeSetNumCols(v, 3); + pParse->nMem = 3; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "log", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "checkpointed", SQLITE_STATIC); + + sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); + }else + + /* + ** PRAGMA wal_autocheckpoint + ** PRAGMA wal_autocheckpoint = N + ** + ** Configure a database connection to automatically checkpoint a database + ** after accumulating N frames in the log. Or query for the current value + ** of N. + */ + if( sqlite3StrICmp(zLeft, "wal_autocheckpoint")==0 ){ + if( zRight ){ + sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight)); + } + returnSingleInt(pParse, "wal_autocheckpoint", + db->xWalCallback==sqlite3WalDefaultHook ? + SQLITE_PTR_TO_INT(db->pWalArg) : 0); + }else +#endif + #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* ** Report the current state of file logs for all databases @@ -79316,7 +91414,7 @@ SQLITE_PRIVATE void sqlite3Pragma( pBt = db->aDb[i].pBt; if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){ zState = "closed"; - }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0, + }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0, SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ zState = azLockName[j]; } @@ -79365,7 +91463,7 @@ SQLITE_PRIVATE void sqlite3Pragma( }else #endif - + {/* Empty ELSE clause */} /* @@ -79375,7 +91473,8 @@ SQLITE_PRIVATE void sqlite3Pragma( #ifndef SQLITE_OMIT_PAGER_PRAGMAS if( db->autoCommit ){ sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level, - (db->flags&SQLITE_FullFSync)!=0); + (db->flags&SQLITE_FullFSync)!=0, + (db->flags&SQLITE_CkptFullFSync)!=0); } #endif pragma_out: @@ -79418,11 +91517,11 @@ static void corruptSchema( sqlite3SetString(pData->pzErrMsg, db, "malformed database schema (%s)", zObj); if( zExtra ){ - *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg, + *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg, "%s - %s", *pData->pzErrMsg, zExtra); } } - pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT; + pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT; } /* @@ -79461,15 +91560,18 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. */ - char *zErr; int rc; + sqlite3_stmt *pStmt; + TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ + assert( db->init.busy ); db->init.iDb = iDb; - db->init.newTnum = atoi(argv[1]); + db->init.newTnum = sqlite3Atoi(argv[1]); db->init.orphanTrigger = 0; - rc = sqlite3_exec(db, argv[2], 0, 0, &zErr); + TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0); + rc = db->errCode; + assert( (rc&0xFF)==(rcp&0xFF) ); db->init.iDb = 0; - assert( rc!=SQLITE_OK || zErr==0 ); if( SQLITE_OK!=rc ){ if( db->init.orphanTrigger ){ assert( iDb==1 ); @@ -79477,12 +91579,12 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char pData->rc = rc; if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; - }else if( rc!=SQLITE_INTERRUPT && rc!=SQLITE_LOCKED ){ - corruptSchema(pData, argv[0], zErr); + }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ + corruptSchema(pData, argv[0], sqlite3_errmsg(db)); } } - sqlite3DbFree(db, zErr); } + sqlite3_finalize(pStmt); }else if( argv[0]==0 ){ corruptSchema(pData, 0, 0); }else{ @@ -79526,13 +91628,13 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ int meta[5]; InitData initData; char const *zMasterSchema; - char const *zMasterName = SCHEMA_TABLE(iDb); + char const *zMasterName; int openedTransaction = 0; /* ** The master database table has a structure like this */ - static const char master_schema[] = + static const char master_schema[] = "CREATE TABLE sqlite_master(\n" " type text,\n" " name text,\n" @@ -79542,7 +91644,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ ")" ; #ifndef SQLITE_OMIT_TEMPDB - static const char temp_master_schema[] = + static const char temp_master_schema[] = "CREATE TEMP TABLE sqlite_temp_master(\n" " type text,\n" " name text,\n" @@ -79601,7 +91703,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ } /* If there is not already a read-only (or read-write) transaction opened - ** on the b-tree database, open one now. If a transaction is opened, it + ** on the b-tree database, open one now. If a transaction is opened, it ** will be closed before this function returns. */ sqlite3BtreeEnter(pDb->pBt); if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){ @@ -79663,9 +91765,8 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ pDb->pSchema->enc = ENC(db); if( pDb->pSchema->cache_size==0 ){ - size = meta[BTREE_DEFAULT_CACHE_SIZE-1]; + size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } - if( size<0 ) size = -size; pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } @@ -79700,7 +91801,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ assert( db->init.busy ); { char *zSql; - zSql = sqlite3MPrintf(db, + zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s ORDER BY rowid", db->aDb[iDb].zName, zMasterName); #ifndef SQLITE_OMIT_AUTHORIZATION @@ -79724,11 +91825,11 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ } if( db->mallocFailed ){ rc = SQLITE_NOMEM; - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); } if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){ /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider - ** the schema loaded, even if errors occurred. In this situation the + ** the schema loaded, even if errors occurred. In this situation the ** current sqlite3_prepare() operation will fail, but the following one ** will attempt to compile the supplied statement against whatever subset ** of the schema was loaded before the error occurred. The primary @@ -79769,7 +91870,7 @@ error_out: SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){ int i, rc; int commit_internal = !(db->flags&SQLITE_InternChanges); - + assert( sqlite3_mutex_held(db->mutex) ); rc = SQLITE_OK; db->init.busy = 1; @@ -79800,7 +91901,7 @@ SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){ sqlite3CommitInternalChanges(db); } - return rc; + return rc; } /* @@ -79841,7 +91942,7 @@ static void schemaIsValid(Parse *pParse){ if( pBt==0 ) continue; /* If there is not already a read-only (or read-write) transaction opened - ** on the b-tree database, open one now. If a transaction is opened, it + ** on the b-tree database, open one now. If a transaction is opened, it ** will be closed immediately after reading the meta-value. */ if( !sqlite3BtreeIsInReadTrans(pBt) ){ rc = sqlite3BtreeBeginTrans(pBt, 0); @@ -79852,11 +91953,13 @@ static void schemaIsValid(Parse *pParse){ openedTransaction = 1; } - /* Read the schema cookie from the database. If it does not match the + /* Read the schema cookie from the database. If it does not match the ** 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 ){ + sqlite3ResetInternalSchema(db, iDb); pParse->rc = SQLITE_SCHEMA; } @@ -79877,13 +91980,13 @@ static void schemaIsValid(Parse *pParse){ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ int i = -1000000; - /* If pSchema is NULL, then return -1000000. This happens when code in + /* If pSchema is NULL, then return -1000000. This happens when code in ** expr.c is trying to resolve a reference to a transient table (i.e. one - ** created by a sub-select). In this case the return value of this + ** created by a sub-select). In this case the return value of this ** function should never be used. ** ** We return -1000000 instead of the more usual -1 simply because using - ** -1000000 as the incorrect index into db->aDb[] is much + ** -1000000 as the incorrect index into db->aDb[] is much ** more likely to cause a segfault than -1 (of course there are assert() ** statements too, but it never hurts to play the odds). */ @@ -79942,8 +92045,8 @@ static int sqlite3Prepare( ** This thread is currently holding mutexes on all Btrees (because ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it ** is not possible for another thread to start a new schema change - ** while this routine is running. Hence, we do not need to hold - ** locks on the schema, we just need to make sure nobody else is + ** while this routine is running. Hence, we do not need to hold + ** locks on the schema, we just need to make sure nobody else is ** holding them. ** ** Note that setting READ_UNCOMMITTED overrides most lock detection, @@ -79967,6 +92070,7 @@ static int sqlite3Prepare( sqlite3VtabUnlockList(db); pParse->db = db; + pParse->nQueryLoop = (double)1; if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ char *zSqlCopy; int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; @@ -79988,6 +92092,7 @@ static int sqlite3Prepare( }else{ sqlite3RunParser(pParse, zSql, &zErrMsg); } + assert( 1==(int)pParse->nQueryLoop ); if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM; @@ -79996,9 +92101,6 @@ static int sqlite3Prepare( if( pParse->checkSchema ){ schemaIsValid(pParse); } - if( pParse->rc==SQLITE_SCHEMA ){ - sqlite3ResetInternalSchema(db, 0); - } if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM; } @@ -80011,13 +92113,13 @@ static int sqlite3Prepare( if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){ static const char * const azColName[] = { "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", - "order", "from", "detail" + "selectid", "order", "from", "detail" }; int iFirst, mx; if( pParse->explain==2 ){ - sqlite3VdbeSetNumCols(pParse->pVdbe, 3); + sqlite3VdbeSetNumCols(pParse->pVdbe, 4); iFirst = 8; - mx = 11; + mx = 12; }else{ sqlite3VdbeSetNumCols(pParse->pVdbe, 8); iFirst = 0; @@ -80053,7 +92155,6 @@ static int sqlite3Prepare( while( pParse->pTriggerPrg ){ TriggerPrg *pT = pParse->pTriggerPrg; pParse->pTriggerPrg = pT->pNext; - sqlite3VdbeProgramDelete(db, pT->pProgram, 0); sqlite3DbFree(db, pT); } @@ -80167,8 +92268,8 @@ SQLITE_API int sqlite3_prepare_v2( ** Compile the UTF-16 encoded SQL statement zSql into a statement handle. */ static int sqlite3Prepare16( - sqlite3 *db, /* Database handle. */ - const void *zSql, /* UTF-8 encoded SQL statement. */ + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ int saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ @@ -80202,7 +92303,7 @@ static int sqlite3Prepare16( int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); } - sqlite3DbFree(db, zSql8); + sqlite3DbFree(db, zSql8); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; @@ -80217,8 +92318,8 @@ static int sqlite3Prepare16( ** occurs. */ SQLITE_API int sqlite3_prepare16( - sqlite3 *db, /* Database handle. */ - const void *zSql, /* UTF-8 encoded SQL statement. */ + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const void **pzTail /* OUT: End of parsed string */ @@ -80229,8 +92330,8 @@ SQLITE_API int sqlite3_prepare16( return rc; } SQLITE_API int sqlite3_prepare16_v2( - sqlite3 *db, /* Database handle. */ - const void *zSql, /* UTF-8 encoded SQL statement. */ + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const void **pzTail /* OUT: End of parsed string */ @@ -80335,6 +92436,8 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( clearSelect(db, pNew); if( pNew!=&standin ) sqlite3DbFree(db, pNew); pNew = 0; + }else{ + assert( pNew->pSrc!=0 || pParse->nErr>0 ); } return pNew; } @@ -80392,7 +92495,7 @@ SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *p for(i=0; i<3 && apAll[i]; i++){ p = apAll[i]; for(j=0; j<ArraySize(aKeyword); j++){ - if( p->n==aKeyword[j].nChar + if( p->n==aKeyword[j].nChar && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){ jointype |= aKeyword[j].code; break; @@ -80414,9 +92517,9 @@ SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *p sqlite3ErrorMsg(pParse, "unknown or unsupported join type: " "%T %T%s%T", pA, pB, zSp, pC); jointype = JT_INNER; - }else if( (jointype & JT_OUTER)!=0 + }else if( (jointype & JT_OUTER)!=0 && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "RIGHT and FULL OUTER JOINs are not currently supported"); jointype = JT_INNER; } @@ -80437,7 +92540,7 @@ static int columnIndex(Table *pTab, const char *zCol){ /* ** Search the first N tables in pSrc, from left to right, looking for a -** table that has a column named zCol. +** table that has a column named zCol. ** ** When found, set *piTab and *piCol to the table index and column index ** of the matching column and return TRUE. @@ -80475,7 +92578,7 @@ static int tableAndColumnIndex( ** ** (tab1.col1 = tab2.col2) ** -** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the +** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the ** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is ** column iColRight of tab2. */ @@ -80546,7 +92649,7 @@ static void setJoinExpr(Expr *p, int iTable){ p->iRightJoinTable = (i16)iTable; setJoinExpr(p->pLeft, iTable); p = p->pRight; - } + } } /* @@ -80620,7 +92723,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ } /* Create extra terms on the WHERE clause for each column named - ** in the USING clause. Example: If the two tables to be joined are + ** in the USING clause. Example: If the two tables to be joined are ** A and B and the USING clause names X, Y, and Z, then add this ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z ** Report an error if any column mentioned in the USING clause is @@ -80665,12 +92768,18 @@ static void pushOntoSorter( int nExpr = pOrderBy->nExpr; int regBase = sqlite3GetTempRange(pParse, nExpr+2); int regRecord = sqlite3GetTempReg(pParse); + int op; sqlite3ExprCacheClear(pParse); sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0); sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord); - sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord); + if( pSelect->selFlags & SF_UseSorter ){ + op = OP_SorterInsert; + }else{ + op = OP_IdxInsert; + } + sqlite3VdbeAddOp2(v, op, pOrderBy->iECursor, regRecord); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); if( pSelect->iLimit ){ @@ -80688,7 +92797,6 @@ static void pushOntoSorter( sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor); sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor); sqlite3VdbeJumpHere(v, addr2); - pSelect->iLimit = 0; } } @@ -80737,11 +92845,13 @@ static void codeDistinct( sqlite3ReleaseTempReg(pParse, r1); } +#ifndef SQLITE_OMIT_SUBQUERY /* ** Generate an error message when a SELECT is used within a subexpression ** (example: "a IN (SELECT * FROM table)") but it has more than 1 result -** column. We do this in a subroutine because the error occurs in multiple -** places. +** column. We do this in a subroutine because the error used to occur +** in multiple places. (The error only occurs in one place now, but we +** retain the subroutine to minimize code disruption.) */ static int checkForMultiColumnSelectError( Parse *pParse, /* Parse context. */ @@ -80757,6 +92867,7 @@ static int checkForMultiColumnSelectError( return 0; } } +#endif /* ** This routine generates the code for the inside of the inner loop @@ -80806,7 +92917,7 @@ static void selectInnerLoop( pDest->iMem = pParse->nMem+1; pDest->nMem = nResultCol; pParse->nMem += nResultCol; - }else{ + }else{ assert( pDest->nMem==nResultCol ); } regResult = pDest->iMem; @@ -80836,10 +92947,6 @@ static void selectInnerLoop( } } - if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){ - return; - } - switch( eDest ){ /* In this mode, write each query result to the key of the temporary ** table iParm. @@ -80968,11 +93075,11 @@ static void selectInnerLoop( #endif } - /* Jump to the end of the loop if the LIMIT is reached. + /* Jump to the end of the loop if the LIMIT is reached. Except, if + ** there is a sorter, in which case the sorter has already limited + ** the output for us. */ - if( p->iLimit ){ - assert( pOrderBy==0 ); /* If there is an ORDER BY, the call to - ** pushOntoSorter() would have cleared p->iLimit */ + if( pOrderBy==0 && p->iLimit ){ sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); } } @@ -81019,6 +93126,92 @@ static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){ return pInfo; } +#ifndef SQLITE_OMIT_COMPOUND_SELECT +/* +** Name of the connection operator, used for error messages. +*/ +static const char *selectOpName(int id){ + char *z; + switch( id ){ + case TK_ALL: z = "UNION ALL"; break; + case TK_INTERSECT: z = "INTERSECT"; break; + case TK_EXCEPT: z = "EXCEPT"; break; + default: z = "UNION"; break; + } + return z; +} +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ + +#ifndef SQLITE_OMIT_EXPLAIN +/* +** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function +** is a no-op. Otherwise, it adds a single row of output to the EQP result, +** where the caption is of the form: +** +** "USE TEMP B-TREE FOR xxx" +** +** where xxx is one of "DISTINCT", "ORDER BY" or "GROUP BY". Exactly which +** is determined by the zUsage argument. +*/ +static void explainTempTable(Parse *pParse, const char *zUsage){ + if( pParse->explain==2 ){ + Vdbe *v = pParse->pVdbe; + char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage); + sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); + } +} + +/* +** Assign expression b to lvalue a. A second, no-op, version of this macro +** is provided when SQLITE_OMIT_EXPLAIN is defined. This allows the code +** in sqlite3Select() to assign values to structure member variables that +** only exist if SQLITE_OMIT_EXPLAIN is not defined without polluting the +** code with #ifndef directives. +*/ +# define explainSetInteger(a, b) a = b + +#else +/* No-op versions of the explainXXX() functions and macros. */ +# define explainTempTable(y,z) +# define explainSetInteger(y,z) +#endif + +#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT) +/* +** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function +** is a no-op. Otherwise, it adds a single row of output to the EQP result, +** where the caption is of one of the two forms: +** +** "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)" +** "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)" +** +** where iSub1 and iSub2 are the integers passed as the corresponding +** function parameters, and op is the text representation of the parameter +** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT, +** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is +** false, or the second form if it is true. +*/ +static void explainComposite( + Parse *pParse, /* Parse context */ + int op, /* One of TK_UNION, TK_EXCEPT etc. */ + int iSub1, /* Subquery id 1 */ + int iSub2, /* Subquery id 2 */ + int bUseTmp /* True if a temp table was used */ +){ + assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL ); + if( pParse->explain==2 ){ + Vdbe *v = pParse->pVdbe; + char *zMsg = sqlite3MPrintf( + pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2, + bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op) + ); + sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); + } +} +#else +/* No-op versions of the explainXXX() functions and macros. */ +# define explainComposite(v,w,x,y,z) +#endif /* ** If the inner loop was generated using a non-null pOrderBy argument, @@ -81055,9 +93248,20 @@ static void generateSortTail( }else{ regRowid = sqlite3GetTempReg(pParse); } - addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); - codeOffset(v, p, addrContinue); - sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr + 1, regRow); + if( p->selFlags & SF_UseSorter ){ + int regSortOut = ++pParse->nMem; + int ptab2 = pParse->nTab++; + sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2); + addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); + codeOffset(v, p, addrContinue); + sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut); + sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow); + sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); + }else{ + addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); + codeOffset(v, p, addrContinue); + sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow); + } switch( eDest ){ case SRT_Table: case SRT_EphemTab: { @@ -81085,7 +93289,7 @@ static void generateSortTail( #endif default: { int i; - assert( eDest==SRT_Output || eDest==SRT_Coroutine ); + assert( eDest==SRT_Output || eDest==SRT_Coroutine ); testcase( eDest==SRT_Output ); testcase( eDest==SRT_Coroutine ); for(i=0; i<nColumn; i++){ @@ -81107,14 +93311,14 @@ static void generateSortTail( sqlite3ReleaseTempReg(pParse, regRow); sqlite3ReleaseTempReg(pParse, regRowid); - /* LIMIT has been implemented by the pushOntoSorter() routine. - */ - assert( p->iLimit==0 ); - /* The bottom of the loop */ sqlite3VdbeResolveLabel(v, addrContinue); - sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); + if( p->selFlags & SF_UseSorter ){ + sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); + }else{ + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); + } sqlite3VdbeResolveLabel(v, addrBreak); if( eDest==SRT_Output || eDest==SRT_Coroutine ){ sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0); @@ -81129,18 +93333,18 @@ static void generateSortTail( ** 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 -** result-set expression in all of the following SELECT statements is +** result-set expression in all of the following SELECT statements is ** considered a column by this function. ** ** SELECT col FROM tbl; ** SELECT (SELECT col FROM tbl; ** SELECT (SELECT col FROM tbl); ** SELECT abc FROM (SELECT col AS abc FROM tbl); -** +** ** The declaration type for any expression other than a column is NULL. */ static const char *columnType( - NameContext *pNC, + NameContext *pNC, Expr *pExpr, const char **pzOriginDb, const char **pzOriginTab, @@ -81179,19 +93383,19 @@ static const char *columnType( if( pTab==0 ){ /* At one time, code such as "SELECT new.x" within a trigger would ** cause this condition to run. Since then, we have restructured how - ** trigger code is generated and so this condition is no longer + ** trigger code is generated and so this condition is no longer ** possible. However, it can still be true for statements like ** the following: ** ** CREATE TABLE t1(col INTEGER); ** SELECT (SELECT t1.col) FROM FROM t1; ** - ** when columnType() is called on the expression "t1.col" in the + ** when columnType() is called on the expression "t1.col" in the ** sub-select. In this case, set the column type to NULL, even ** though it should really be "INTEGER". ** ** This is not a problem, as the column type of "t1.col" is never - ** used. When columnType() is called on the expression + ** used. When columnType() is called on the expression ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT ** branch below. */ break; @@ -81205,7 +93409,7 @@ static const char *columnType( */ if( iCol>=0 && ALWAYS(iCol<pS->pEList->nExpr) ){ /* If iCol is less than zero, then the expression requests the - ** rowid of the sub-select or view. This expression is legal (see + ** rowid of the sub-select or view. This expression is legal (see ** test case misc2.2.2) - it always evaluates to NULL. */ NameContext sNC; @@ -81213,7 +93417,7 @@ static const char *columnType( sNC.pSrcList = pS->pSrc; sNC.pNext = pNC; sNC.pParse = pNC->pParse; - zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); + zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); } }else if( ALWAYS(pTab->pSchema) ){ /* A real table */ @@ -81248,12 +93452,12 @@ static const char *columnType( sNC.pSrcList = pS->pSrc; sNC.pNext = pNC; sNC.pParse = pNC->pParse; - zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); + zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); break; } #endif } - + if( pzOriginDb ){ assert( pzOriginTab && pzOriginCol ); *pzOriginDb = zOriginDb; @@ -81287,7 +93491,7 @@ static void generateColumnTypes( const char *zOrigCol = 0; zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); - /* The vdbe must make its own copy of the column-type and other + /* The vdbe must make its own copy of the column-type and other ** column specific strings, in case the schema is reset before this ** virtual machine is deleted. */ @@ -81353,7 +93557,7 @@ static void generateColumnNames( zCol = pTab->aCol[iCol].zName; } if( !shortNames && !fullNames ){ - sqlite3VdbeSetColName(v, i, COLNAME_NAME, + sqlite3VdbeSetColName(v, i, COLNAME_NAME, sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC); }else if( fullNames ){ char *zName = 0; @@ -81363,29 +93567,13 @@ static void generateColumnNames( sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT); } }else{ - sqlite3VdbeSetColName(v, i, COLNAME_NAME, + sqlite3VdbeSetColName(v, i, COLNAME_NAME, sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC); } } generateColumnTypes(pParse, pTabList, pEList); } -#ifndef SQLITE_OMIT_COMPOUND_SELECT -/* -** Name of the connection operator, used for error messages. -*/ -static const char *selectOpName(int id){ - char *z; - switch( id ){ - case TK_ALL: z = "UNION ALL"; break; - case TK_INTERSECT: z = "INTERSECT"; break; - case TK_EXCEPT: z = "EXCEPT"; break; - default: z = "UNION"; break; - } - return z; -} -#endif /* SQLITE_OMIT_COMPOUND_SELECT */ - /* ** Given a an expression list (which is really the list of expressions ** that form the result set of a SELECT statement) compute appropriate @@ -81482,7 +93670,7 @@ static int selectColumnsFromExprList( /* ** Add type and collation information to a column list based on ** a SELECT statement. -** +** ** 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. @@ -81544,16 +93732,16 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ return 0; } /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside - ** is disabled, so we might as well hard-code pTab->dbMem to NULL. */ + ** is disabled */ assert( db->lookaside.bEnabled==0 ); - pTab->dbMem = 0; pTab->nRef = 1; pTab->zName = 0; + pTab->nRowEst = 1000000; selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect); pTab->iPKey = -1; if( db->mallocFailed ){ - sqlite3DeleteTable(pTab); + sqlite3DeleteTable(db, pTab); return 0; } return pTab; @@ -81581,9 +93769,9 @@ SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){ ** Compute the iLimit and iOffset fields of the SELECT based on the ** pLimit and pOffset expressions. pLimit and pOffset hold the expressions ** that appear in the original SQL statement after the LIMIT and OFFSET -** keywords. Or NULL if those keywords are omitted. iLimit and iOffset -** are the integer memory register numbers for counters used to compute -** the limit and offset. If there is no limit and/or offset, then +** keywords. Or NULL if those keywords are omitted. iLimit and iOffset +** are the integer memory register numbers for counters used to compute +** the limit and offset. If there is no limit and/or offset, then ** iLimit and iOffset are negative. ** ** This routine changes the values of iLimit and iOffset only if @@ -81602,7 +93790,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ int addr1, n; if( p->iLimit ) return; - /* + /* ** "LIMIT -1" always shows all rows. There is some ** contraversy about what the correct behavior should be. ** The current implementation interprets "LIMIT 0" to mean @@ -81619,6 +93807,8 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ VdbeComment((v, "LIMIT counter")); if( n==0 ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak); + }else{ + if( p->nSelectRow > (double)n ) p->nSelectRow = (double)n; } }else{ sqlite3ExprCode(pParse, p->pLimit, iLimit); @@ -81684,7 +93874,7 @@ static int multiSelectOrderBy( ** ** "p" points to the right-most of the two queries. the query on the ** left is p->pPrior. The left query could also be a compound query -** in which case this routine will be called recursively. +** in which case this routine will be called recursively. ** ** The results of the total query are to be written into a destination ** of type eDest with parameter iParm. @@ -81719,6 +93909,10 @@ static int multiSelect( SelectDest dest; /* Alternative data destination */ Select *pDelete = 0; /* Chain of simple selects to delete */ sqlite3 *db; /* Database connection */ +#ifndef SQLITE_OMIT_EXPLAIN + int iSub1; /* EQP id of left-hand query */ + int iSub2; /* EQP id of right-hand query */ +#endif /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. @@ -81750,6 +93944,7 @@ static int multiSelect( if( dest.eDest==SRT_EphemTab ){ assert( p->pEList ); sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr); + sqlite3VdbeChangeP5(v, BTREE_UNORDERED); dest.eDest = SRT_Table; } @@ -81775,9 +93970,11 @@ static int multiSelect( switch( p->op ){ case TK_ALL: { int addr = 0; + int nLimit; assert( !pPrior->pLimit ); pPrior->pLimit = p->pLimit; pPrior->pOffset = p->pOffset; + explainSetInteger(iSub1, pParse->iNextSelectId); rc = sqlite3Select(pParse, pPrior, &dest); p->pLimit = 0; p->pOffset = 0; @@ -81791,10 +93988,18 @@ static int multiSelect( addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); VdbeComment((v, "Jump ahead if LIMIT reached")); } + explainSetInteger(iSub2, pParse->iNextSelectId); rc = sqlite3Select(pParse, p, &dest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; + p->nSelectRow += pPrior->nSelectRow; + if( pPrior->pLimit + && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit) + && p->nSelectRow > (double)nLimit + ){ + p->nSelectRow = (double)nLimit; + } if( addr ){ sqlite3VdbeJumpHere(v, addr); } @@ -81838,6 +94043,7 @@ static int multiSelect( */ assert( !pPrior->pOrderBy ); sqlite3SelectDestInit(&uniondest, priorOp, unionTab); + explainSetInteger(iSub1, pParse->iNextSelectId); rc = sqlite3Select(pParse, pPrior, &uniondest); if( rc ){ goto multi_select_end; @@ -81857,6 +94063,7 @@ static int multiSelect( pOffset = p->pOffset; p->pOffset = 0; uniondest.eDest = op; + explainSetInteger(iSub2, pParse->iNextSelectId); rc = sqlite3Select(pParse, p, &uniondest); testcase( rc!=SQLITE_OK ); /* Query flattening in sqlite3Select() might refill p->pOrderBy. @@ -81865,6 +94072,7 @@ static int multiSelect( pDelete = p->pPrior; p->pPrior = pPrior; p->pOrderBy = 0; + if( p->op==TK_UNION ) p->nSelectRow += pPrior->nSelectRow; sqlite3ExprDelete(db, p->pLimit); p->pLimit = pLimit; p->pOffset = pOffset; @@ -81922,6 +94130,7 @@ static int multiSelect( /* Code the SELECTs to our left into temporary table "tab1". */ sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); + explainSetInteger(iSub1, pParse->iNextSelectId); rc = sqlite3Select(pParse, pPrior, &intersectdest); if( rc ){ goto multi_select_end; @@ -81938,10 +94147,12 @@ static int multiSelect( pOffset = p->pOffset; p->pOffset = 0; intersectdest.iParm = tab2; + explainSetInteger(iSub2, pParse->iNextSelectId); rc = sqlite3Select(pParse, p, &intersectdest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; + if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; sqlite3ExprDelete(db, p->pLimit); p->pLimit = pLimit; p->pOffset = pOffset; @@ -81974,7 +94185,9 @@ static int multiSelect( } } - /* Compute collating sequences used by + explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL); + + /* Compute collating sequences used by ** temporary tables needed to implement the compound select. ** Attach the KeyInfo structure to all temporary tables. ** @@ -82045,7 +94258,7 @@ multi_select_end: ** regReturn is the number of the register holding the subroutine ** return address. ** -** If regPrev>0 then it is a the first register in a vector that +** If regPrev>0 then it is the first register in a vector that ** records the previous output. mem[regPrev] is a flag that is false ** if there has been no previous output. If regPrev>0 then code is ** generated to suppress duplicates. pKeyInfo is used for comparing @@ -82072,7 +94285,7 @@ static int generateOutputSubroutine( addr = sqlite3VdbeCurrentAddr(v); iContinue = sqlite3VdbeMakeLabel(v); - /* Suppress duplicates for UNION, EXCEPT, and INTERSECT + /* Suppress duplicates for UNION, EXCEPT, and INTERSECT */ if( regPrev ){ int j1, j2; @@ -82116,7 +94329,7 @@ static int generateOutputSubroutine( case SRT_Set: { int r1; assert( pIn->nMem==1 ); - p->affinity = + p->affinity = sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity); r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1); @@ -82165,7 +94378,7 @@ static int generateOutputSubroutine( ** SRT_Output. This routine is never called with any other ** destination other than the ones handled above or SRT_Output. ** - ** For SRT_Output, results are stored in a sequence of registers. + ** For SRT_Output, results are stored in a sequence of registers. ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to ** return the next row of result. */ @@ -82223,7 +94436,7 @@ static int generateOutputSubroutine( ** ** EofB: Called when data is exhausted from selectB. ** -** The implementation of the latter five subroutines depend on which +** The implementation of the latter five subroutines depend on which ** <operator> is used: ** ** @@ -82317,6 +94530,10 @@ static int multiSelectOrderBy( ExprList *pOrderBy; /* The ORDER BY clause */ int nOrderBy; /* Number of terms in the ORDER BY clause */ int *aPermute; /* Mapping from ORDER BY terms to result set columns */ +#ifndef SQLITE_OMIT_EXPLAIN + int iSub1; /* EQP id of left-hand query */ + int iSub2; /* EQP id of right-hand query */ +#endif assert( p->pOrderBy!=0 ); assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */ @@ -82329,7 +94546,7 @@ static int multiSelectOrderBy( /* Patch up the ORDER BY clause */ - op = p->op; + op = p->op; pPrior = p->pPrior; assert( pPrior->pOrderBy==0 ); pOrderBy = p->pOrderBy; @@ -82424,11 +94641,10 @@ static int multiSelectOrderBy( } } } - + /* Separate the left and the right query from one another */ p->pPrior = 0; - pPrior->pRightmost = 0; sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER"); if( pPrior->pPrior==0 ){ sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); @@ -82471,12 +94687,13 @@ static int multiSelectOrderBy( */ VdbeNoopComment((v, "Begin coroutine for left SELECT")); pPrior->iLimit = regLimitA; + explainSetInteger(iSub1, pParse->iNextSelectId); sqlite3Select(pParse, pPrior, &destA); sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofA); sqlite3VdbeAddOp1(v, OP_Yield, regAddrA); VdbeNoopComment((v, "End coroutine for left SELECT")); - /* Generate a coroutine to evaluate the SELECT statement on + /* Generate a coroutine to evaluate the SELECT statement on ** the right - the "B" select */ addrSelectB = sqlite3VdbeCurrentAddr(v); @@ -82484,7 +94701,8 @@ static int multiSelectOrderBy( savedLimit = p->iLimit; savedOffset = p->iOffset; p->iLimit = regLimitB; - p->iOffset = 0; + p->iOffset = 0; + explainSetInteger(iSub2, pParse->iNextSelectId); sqlite3Select(pParse, p, &destB); p->iLimit = savedLimit; p->iOffset = savedOffset; @@ -82499,7 +94717,7 @@ static int multiSelectOrderBy( addrOutA = generateOutputSubroutine(pParse, p, &destA, pDest, regOutA, regPrev, pKeyDup, P4_KEYINFO_HANDOFF, labelEnd); - + /* Generate a subroutine that outputs the current row of the B ** select as the next output row of the compound select. */ @@ -82516,11 +94734,12 @@ static int multiSelectOrderBy( VdbeNoopComment((v, "eof-A subroutine")); if( op==TK_EXCEPT || op==TK_INTERSECT ){ addrEofA = sqlite3VdbeAddOp2(v, OP_Goto, 0, labelEnd); - }else{ + }else{ addrEofA = sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd); sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); sqlite3VdbeAddOp1(v, OP_Yield, regAddrB); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA); + p->nSelectRow += pPrior->nSelectRow; } /* Generate a subroutine to run when the results from select B @@ -82528,7 +94747,8 @@ static int multiSelectOrderBy( */ if( op==TK_INTERSECT ){ addrEofB = addrEofA; - }else{ + if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; + }else{ VdbeNoopComment((v, "eof-B subroutine")); addrEofB = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd); sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); @@ -82615,6 +94835,7 @@ static int multiSelectOrderBy( /*** TBD: Insert subroutine calls to close cursors on incomplete **** subqueries ****/ + explainComposite(pParse, p->op, iSub1, iSub2, 0); return SQLITE_OK; } #endif @@ -82627,13 +94848,13 @@ static void substSelect(sqlite3*, Select *, int, ExprList *); /* ** Scan through the expression pExpr. Replace every reference to ** a column in table number iTable with a copy of the iColumn-th -** entry in pEList. (But leave references to the ROWID column +** entry in pEList. (But leave references to the ROWID column ** unchanged.) ** ** This routine is part of the flattening procedure. A subquery ** whose result set is defined by pEList appears as entry in the ** FROM clause of a SELECT such that the VDBE cursor assigned to that -** FORM clause entry is iTable. This routine make the necessary +** FORM clause entry is iTable. This routine make the necessary ** changes to pExpr so that it refers directly to the source table ** of the subquery rather the result set of the subquery. */ @@ -82731,7 +94952,7 @@ static void substSelect( ** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5 ** ** The code generated for this simpification gives the same result -** but only has to scan the data once. And because indices might +** but only has to scan the data once. And because indices might ** exist on the table t1, a complete scan of the data might be ** avoided. ** @@ -82742,12 +94963,13 @@ static void substSelect( ** (2) The subquery is not an aggregate or the outer query is not a join. ** ** (3) The subquery is not the right operand of a left outer join -** (Originally ticket #306. Strenghtened by ticket #3300) +** (Originally ticket #306. Strengthened by ticket #3300) ** -** (4) The subquery is not DISTINCT or the outer query is not a join. +** (4) The subquery is not DISTINCT. ** -** (5) The subquery is not DISTINCT or the outer query does not use -** aggregates. +** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT +** sub-queries that were excluded from this optimization. Restriction +** (4) has since been expanded to exclude all DISTINCT subqueries. ** ** (6) The subquery does not use aggregates or the outer query is not ** DISTINCT. @@ -82767,20 +94989,20 @@ static void substSelect( ** (**) Not implemented. Subsumed into restriction (3). Was previously ** a separate restriction deriving from ticket #350. ** -** (13) The subquery and outer query do not both use LIMIT +** (13) The subquery and outer query do not both use LIMIT. ** -** (14) The subquery does not use OFFSET +** (14) The subquery does not use OFFSET. ** ** (15) The outer query is not part of a compound select or the -** subquery does not have both an ORDER BY and a LIMIT clause. -** (See ticket #2339) +** subquery does not have a LIMIT clause. +** (See ticket #2339 and ticket [02a8e81d44]). ** ** (16) The outer query is not an aggregate or the subquery does ** not contain ORDER BY. (Ticket #2942) This used to not matter -** until we introduced the group_concat() function. +** until we introduced the group_concat() function. ** -** (17) The sub-query is not a compound select, or it is a UNION ALL -** compound clause made up entirely of non-aggregate queries, and +** (17) The sub-query is not a compound select, or it is a UNION ALL +** compound clause made up entirely of non-aggregate queries, and ** the parent query: ** ** * is not itself part of a compound select, @@ -82792,7 +95014,7 @@ static void substSelect( ** LIMIT and OFFSET clauses. ** ** (18) If the sub-query is a compound select, then all terms of the -** ORDER by clause of the parent must be simple references to +** ORDER by clause of the parent must be simple references to ** columns of the sub-query. ** ** (19) The subquery does not use LIMIT or the outer query does not @@ -82804,6 +95026,9 @@ static void substSelect( ** appear as unmodified result columns in the outer query. But ** have other optimizations in mind to deal with that case. ** +** (21) The subquery does not use LIMIT or the outer query is not +** DISTINCT. (See ticket [752e1646fc]). +** ** 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 and subqueryIsAgg is true if the subquery uses aggregates. @@ -82856,13 +95081,13 @@ static int flattenSubquery( ** and (14). */ if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */ if( pSub->pOffset ) return 0; /* Restriction (14) */ - if( p->pRightmost && pSub->pLimit && pSub->pOrderBy ){ + if( p->pRightmost && pSub->pLimit ){ return 0; /* Restriction (15) */ } if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */ - if( ((pSub->selFlags & SF_Distinct)!=0 || pSub->pLimit) - && (pSrc->nSrc>1 || isAgg) ){ /* Restrictions (4)(5)(8)(9) */ - return 0; + if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (5) */ + if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){ + return 0; /* Restrictions (8)(9) */ } if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){ return 0; /* Restriction (6) */ @@ -82872,9 +95097,12 @@ static int flattenSubquery( } if( isAgg && pSub->pOrderBy ) return 0; /* Restriction (16) */ if( pSub->pLimit && p->pWhere ) return 0; /* Restriction (19) */ + if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){ + return 0; /* Restriction (21) */ + } /* OBSOLETE COMMENT 1: - ** Restriction 3: If the subquery is a join, make sure the subquery is + ** Restriction 3: If the subquery is a join, make sure the subquery is ** not used as the right operand of an outer join. Examples of why this ** is not allowed: ** @@ -82925,7 +95153,7 @@ static int flattenSubquery( testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 - || (pSub1->pPrior && pSub1->op!=TK_ALL) + || (pSub1->pPrior && pSub1->op!=TK_ALL) || NEVER(pSub1->pSrc==0) || pSub1->pSrc->nSrc!=1 ){ return 0; @@ -82949,13 +95177,13 @@ static int flattenSubquery( pParse->zAuthContext = zSavedAuthContext; /* If the sub-query is a compound SELECT statement, then (by restrictions - ** 17 and 18 above) it must be a UNION ALL and the parent query must + ** 17 and 18 above) it must be a UNION ALL and the parent query must ** be of the form: ** - ** SELECT <expr-list> FROM (<sub-query>) <where-clause> + ** SELECT <expr-list> FROM (<sub-query>) <where-clause> ** ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block - ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or + ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or ** OFFSET clauses and joins them to the left-hand-side of the original ** using UNION ALL operators. In this case N is the number of simple ** select statements in the compound sub-query. @@ -83006,7 +95234,7 @@ static int flattenSubquery( if( db->mallocFailed ) return 1; } - /* Begin flattening the iFrom-th entry of the FROM clause + /* Begin flattening the iFrom-th entry of the FROM clause ** in the outer query. */ pSub = pSub1 = pSubitem->pSelect; @@ -83104,10 +95332,10 @@ static int flattenSubquery( memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } pSrc->a[iFrom].jointype = jointype; - - /* Now begin substituting subquery result set expressions for + + /* Now begin substituting subquery result set expressions for ** references to the iParent in the outer query. - ** + ** ** Example: ** ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b; @@ -83148,7 +95376,7 @@ static int flattenSubquery( pParent->pHaving = pParent->pWhere; pParent->pWhere = pWhere; pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList); - pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving, + pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving, sqlite3ExprDup(db, pSub->pHaving, 0)); assert( pParent->pGroupBy==0 ); pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0); @@ -83156,12 +95384,12 @@ static int flattenSubquery( pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList); pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere); } - + /* The flattened query is distinct if either the inner or the - ** outer query is distinct. + ** outer query is distinct. */ pParent->selFlags |= pSub->selFlags & SF_Distinct; - + /* ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y; ** @@ -83185,7 +95413,7 @@ static int flattenSubquery( /* ** Analyze the SELECT statement passed as an argument to see if it -** is a min() or max() query. Return WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX if +** is a min() or max() query. Return WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX if ** it is, or 0 otherwise. At present, a query is considered to be ** a min()/max() query if: ** @@ -83216,7 +95444,7 @@ static u8 minMaxQuery(Select *p){ /* ** The select statement passed as the first argument is an aggregate query. -** The second argment is the associated aggregate-info object. This +** The second argment is the associated aggregate-info object. This ** function tests if the SELECT is of the form: ** ** SELECT count(*) FROM <tbl> @@ -83231,7 +95459,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ assert( !p->pGroupBy ); - if( p->pWhere || p->pEList->nExpr!=1 + if( p->pWhere || p->pEList->nExpr!=1 || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect ){ return 0; @@ -83251,8 +95479,8 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ /* ** If the source-list item passed as an argument was augmented with an ** INDEXED BY clause, then try to locate the specified index. If there -** was such a clause and the named index cannot be found, return -** SQLITE_ERROR and leave an error in pParse. Otherwise, populate +** was such a clause and the named index cannot be found, return +** SQLITE_ERROR and leave an error in pParse. Otherwise, populate ** pFrom->pIndex and return SQLITE_OK. */ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){ @@ -83260,12 +95488,13 @@ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pF Table *pTab = pFrom->pTab; char *zIndex = pFrom->zIndex; Index *pIdx; - for(pIdx=pTab->pIndex; - pIdx && sqlite3StrICmp(pIdx->zName, zIndex); + for(pIdx=pTab->pIndex; + pIdx && sqlite3StrICmp(pIdx->zName, zIndex); pIdx=pIdx->pNext ); if( !pIdx ){ sqlite3ErrorMsg(pParse, "no such index: %s", zIndex, 0); + pParse->checkSchema = 1; return SQLITE_ERROR; } pFrom->pIndex = pIdx; @@ -83280,7 +95509,7 @@ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pF ** (1) Make sure VDBE cursor numbers have been assigned to every ** element of the FROM clause. ** -** (2) Fill in the pTabList->a[].pTab fields in the SrcList that +** (2) Fill in the pTabList->a[].pTab fields in the SrcList that ** defines FROM clause. When views appear in the FROM clause, ** fill pTabList->a[].pSelect with a copy of the SELECT statement ** that implements the view. A copy is made of the view's SELECT @@ -83341,18 +95570,18 @@ static int selectExpander(Walker *pWalker, Select *p){ sqlite3WalkSelect(pWalker, pSel); pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; - pTab->dbMem = db->lookaside.bEnabled ? db : 0; pTab->nRef = 1; pTab->zName = sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pTab); while( pSel->pPrior ){ pSel = pSel->pPrior; } selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); pTab->iPKey = -1; + pTab->nRowEst = 1000000; pTab->tabFlags |= TF_Ephemeral; #endif }else{ /* An ordinary table or view name in the FROM clause */ assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = + pFrom->pTab = pTab = sqlite3LocateTable(pParse,0,pFrom->zName,pFrom->zDatabase); if( pTab==0 ) return WRC_Abort; pTab->nRef++; @@ -83465,7 +95694,7 @@ static int selectExpander(Walker *pWalker, Select *p){ if( (pFrom->jointype & JT_NATURAL)!=0 && tableAndColumnIndex(pTabList, i, zName, 0, 0) ){ - /* In a NATURAL join, omit the join columns from the + /* In a NATURAL join, omit the join columns from the ** table to the right of the join */ continue; } @@ -83521,8 +95750,8 @@ static int selectExpander(Walker *pWalker, Select *p){ ** ** When this routine is the Walker.xExprCallback then expression trees ** are walked without any actions being taken at each node. Presumably, -** when this routine is used for Walker.xExprCallback then -** Walker.xSelectCallback is set to do something useful for every +** when this routine is used for Walker.xExprCallback then +** Walker.xSelectCallback is set to do something useful for every ** subquery in the parser tree. */ static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ @@ -83711,7 +95940,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ if( pList ){ nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); - sqlite3ExprCodeExprList(pParse, pList, regAgg, 0); + sqlite3ExprCodeExprList(pParse, pList, regAgg, 1); }else{ nArg = 0; regAgg = 0; @@ -83744,6 +95973,18 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ sqlite3ExprCacheClear(pParse); } } + + /* Before populating the accumulator registers, clear the column cache. + ** Otherwise, if any of the required column values are already present + ** in registers, sqlite3ExprCode() may use OP_SCopy to copy the value + ** to pC->iMem. But by the time the value is used, the original register + ** may have been used, invalidating the underlying buffer holding the + ** text or blob value. See ticket [883034dcb5]. + ** + ** Another solution would be to change the OP_SCopy used to copy cached + ** values to an OP_Copy. + */ + sqlite3ExprCacheClear(pParse); for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){ sqlite3ExprCode(pParse, pC->pExpr, pC->iMem); } @@ -83752,7 +95993,33 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ } /* -** Generate code for the SELECT statement given in the p argument. +** Add a single OP_Explain instruction to the VDBE to explain a simple +** count(*) query ("SELECT count(*) FROM pTab"). +*/ +#ifndef SQLITE_OMIT_EXPLAIN +static void explainSimpleCount( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being queried */ + Index *pIdx /* Index used to optimize scan, or NULL */ +){ + if( pParse->explain==2 ){ + char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s %s%s(~%d rows)", + pTab->zName, + pIdx ? "USING COVERING INDEX " : "", + pIdx ? pIdx->zName : "", + pTab->nRowEst + ); + sqlite3VdbeAddOp4( + pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC + ); + } +} +#else +# define explainSimpleCount(a,b,c) +#endif + +/* +** Generate code for the SELECT statement given in the p argument. ** ** The results are distributed in various ways depending on the ** contents of the SelectDest structure pointed to by argument pDest @@ -83769,7 +96036,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ ** of the query. This destination implies "LIMIT 1". ** ** SRT_Set The result must be a single column. Store each -** row of result as the key in table pDest->iParm. +** row of result as the key in table pDest->iParm. ** Apply the affinity pDest->affinity before storing ** results. Used to implement "IN (SELECT ...)". ** @@ -83824,10 +96091,16 @@ SQLITE_PRIVATE int sqlite3Select( int distinct; /* Table to use for the distinct set */ int rc = 1; /* Value to return from this function */ int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */ + int addrDistinctIndex; /* Address of an OP_OpenEphemeral instruction */ AggInfo sAggInfo; /* Information used by aggregate queries */ int iEnd; /* Address of the end of the query */ sqlite3 *db; /* The database connection */ +#ifndef SQLITE_OMIT_EXPLAIN + int iRestoreSelectId = pParse->iSelectId; + pParse->iSelectId = pParse->iNextSelectId++; +#endif + db = pParse->db; if( p==0 || db->mallocFailed || pParse->nErr ){ return 1; @@ -83836,7 +96109,7 @@ SQLITE_PRIVATE int sqlite3Select( memset(&sAggInfo, 0, sizeof(sAggInfo)); if( IgnorableOrderby(pDest) ){ - assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || + assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard); /* If ORDER BY makes no difference in the output then neither does ** DISTINCT so it can be removed too. */ @@ -83859,6 +96132,15 @@ SQLITE_PRIVATE int sqlite3Select( v = sqlite3GetVdbe(pParse); if( v==0 ) goto select_end; + /* If writing to memory or generating a set + ** only a single column may be output. + */ +#ifndef SQLITE_OMIT_SUBQUERY + if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){ + goto select_end; + } +#endif + /* Generate code for all sub-queries in the FROM clause */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) @@ -83868,7 +96150,11 @@ SQLITE_PRIVATE int sqlite3Select( Select *pSub = pItem->pSelect; int isAggSub; - if( pSub==0 || pItem->isPopulated ) continue; + if( pSub==0 ) continue; + if( pItem->addrFillSub ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub); + continue; + } /* Increment Parse.nHeight by the height of the largest expression ** tree refered to by this, the parent select. The child select @@ -83879,19 +96165,44 @@ SQLITE_PRIVATE int sqlite3Select( */ pParse->nHeight += sqlite3SelectExprHeight(p); - /* Check to see if the subquery can be absorbed into the parent. */ isAggSub = (pSub->selFlags & SF_Aggregate)!=0; if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){ + /* This subquery can be absorbed into its parent. */ if( isAggSub ){ isAgg = 1; p->selFlags |= SF_Aggregate; } i = -1; }else{ + /* Generate a subroutine that will fill an ephemeral table with + ** the content of this subquery. pItem->addrFillSub will point + ** to the address of the generated subroutine. pItem->regReturn + ** is a register allocated to hold the subroutine return address + */ + int topAddr; + int onceAddr = 0; + int retAddr; + assert( pItem->addrFillSub==0 ); + pItem->regReturn = ++pParse->nMem; + topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); + pItem->addrFillSub = topAddr+1; + VdbeNoopComment((v, "materialize %s", pItem->pTab->zName)); + if( pItem->isCorrelated==0 && pParse->pTriggerTab==0 ){ + /* If the subquery is no correlated and if we are not inside of + ** a trigger, then we only need to compute the value of the subquery + ** once. */ + int regOnce = ++pParse->nMem; + onceAddr = sqlite3VdbeAddOp1(v, OP_Once, regOnce); + } sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); - assert( pItem->isPopulated==0 ); + explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); sqlite3Select(pParse, pSub, &dest); - pItem->isPopulated = 1; + pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; + if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); + retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); + VdbeComment((v, "end %s", pItem->pTab->zName)); + sqlite3VdbeChangeP1(v, topAddr, retAddr); + } if( /*pParse->nErr ||*/ db->mallocFailed ){ goto select_end; @@ -83925,35 +96236,53 @@ SQLITE_PRIVATE int sqlite3Select( mxSelect = db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT]; if( mxSelect && cnt>mxSelect ){ sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); - return 1; + goto select_end; } } - return multiSelect(pParse, p, pDest); + rc = multiSelect(pParse, p, pDest); + explainSetInteger(pParse->iSelectId, iRestoreSelectId); + return rc; } #endif - /* If writing to memory or generating a set - ** only a single column may be output. + /* If there is both a GROUP BY and an ORDER BY clause and they are + ** identical, then disable the ORDER BY clause since the GROUP BY + ** will cause elements to come out in the correct order. This is + ** an optimization - the correct answer should result regardless. + ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER + ** to disable this optimization for testing purposes. */ -#ifndef SQLITE_OMIT_SUBQUERY - if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){ - goto select_end; + if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0 + && (db->flags & SQLITE_GroupByOrder)==0 ){ + pOrderBy = 0; } -#endif - /* If possible, rewrite the query to use GROUP BY instead of DISTINCT. - ** GROUP BY might use an index, DISTINCT never does. + /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and + ** if the select-list is the same as the ORDER BY list, then this query + ** can be rewritten as a GROUP BY. In other words, this: + ** + ** SELECT DISTINCT xyz FROM ... ORDER BY xyz + ** + ** is transformed to: + ** + ** SELECT xyz FROM ... GROUP BY xyz + ** + ** The second form is preferred as a single index (or temp-table) may be + ** used for both the ORDER BY and DISTINCT processing. As originally + ** written the query must use a temp-table for at least one of the ORDER + ** BY and DISTINCT, and an index or separate temp-table for the other. */ - assert( p->pGroupBy==0 || (p->selFlags & SF_Aggregate)!=0 ); - if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ){ + if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct + && sqlite3ExprListCompare(pOrderBy, p->pEList)==0 + ){ + p->selFlags &= ~SF_Distinct; p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); pGroupBy = p->pGroupBy; - p->selFlags &= ~SF_Distinct; - isDistinct = 0; + pOrderBy = 0; } /* If there is an ORDER BY clause, then this sorting - ** index might end up being unused if the data can be + ** index might end up being unused if the data can be ** extracted in pre-sorted order. If that is the case, then the ** OP_OpenEphemeral instruction will be changed to an OP_Noop once ** we figure out that the sorting index is not needed. The addrSortIndex @@ -83980,42 +96309,90 @@ SQLITE_PRIVATE int sqlite3Select( /* Set the limiter. */ iEnd = sqlite3VdbeMakeLabel(v); + p->nSelectRow = (double)LARGEST_INT64; computeLimitRegisters(pParse, p, iEnd); + if( p->iLimit==0 && addrSortIndex>=0 ){ + sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen; + p->selFlags |= SF_UseSorter; + } /* Open a virtual index to use for the distinct set. */ - if( isDistinct ){ + if( p->selFlags & SF_Distinct ){ KeyInfo *pKeyInfo; - assert( isAgg || pGroupBy ); distinct = pParse->nTab++; pKeyInfo = keyInfoFromExprList(pParse, p->pEList); - sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0, - (char*)pKeyInfo, P4_KEYINFO_HANDOFF); + addrDistinctIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0, + (char*)pKeyInfo, P4_KEYINFO_HANDOFF); + sqlite3VdbeChangeP5(v, BTREE_UNORDERED); }else{ - distinct = -1; + distinct = addrDistinctIndex = -1; } /* Aggregate and non-aggregate queries are handled differently */ if( !isAgg && pGroupBy==0 ){ - /* This case is for non-aggregate queries - ** Begin the database scan - */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, 0); + ExprList *pDist = (isDistinct ? p->pEList : 0); + + /* Begin the database scan. */ + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0); if( pWInfo==0 ) goto select_end; + if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut; - /* If sorting index that was created by a prior OP_OpenEphemeral + /* 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. */ if( addrSortIndex>=0 && pOrderBy==0 ){ - sqlite3VdbeChangeToNoop(v, addrSortIndex, 1); + sqlite3VdbeChangeToNoop(v, addrSortIndex); p->addrOpenEphm[2] = -1; } - /* Use the standard inner loop - */ - assert(!isDistinct); - selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, -1, pDest, + if( pWInfo->eDistinct ){ + VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ + + assert( addrDistinctIndex>=0 ); + pOp = sqlite3VdbeGetOp(v, addrDistinctIndex); + + assert( isDistinct ); + assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED + || pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE + ); + distinct = -1; + if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED ){ + int iJump; + int iExpr; + int iFlag = ++pParse->nMem; + int iBase = pParse->nMem+1; + int iBase2 = iBase + pEList->nExpr; + pParse->nMem += (pEList->nExpr*2); + + /* Change the OP_OpenEphemeral coded earlier to an OP_Integer. The + ** OP_Integer initializes the "first row" flag. */ + pOp->opcode = OP_Integer; + pOp->p1 = 1; + pOp->p2 = iFlag; + + sqlite3ExprCodeExprList(pParse, pEList, iBase, 1); + iJump = sqlite3VdbeCurrentAddr(v) + 1 + pEList->nExpr + 1 + 1; + sqlite3VdbeAddOp2(v, OP_If, iFlag, iJump-1); + for(iExpr=0; iExpr<pEList->nExpr; iExpr++){ + CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[iExpr].pExpr); + sqlite3VdbeAddOp3(v, OP_Ne, iBase+iExpr, iJump, iBase2+iExpr); + sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iContinue); + + sqlite3VdbeAddOp2(v, OP_Integer, 0, iFlag); + assert( sqlite3VdbeCurrentAddr(v)==iJump ); + sqlite3VdbeAddOp3(v, OP_Move, iBase, iBase2, pEList->nExpr); + }else{ + pOp->opcode = OP_Noop; + } + } + + /* Use the standard inner loop. */ + selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, pDest, pWInfo->iContinue, pWInfo->iBreak); /* End the database scan loop. @@ -84032,6 +96409,8 @@ SQLITE_PRIVATE int sqlite3Select( int iAbortFlag; /* Mem address which causes query abort if positive */ int groupBySort; /* Rows come from source in GROUP BY order */ int addrEnd; /* End of processing for this SELECT */ + int sortPTab = 0; /* Pseudotable used to decode sorting results */ + int sortOut = 0; /* Output register from the sorter */ /* Remove any and all aliases between the result set and the ** GROUP BY clause. @@ -84046,9 +96425,12 @@ SQLITE_PRIVATE int sqlite3Select( for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){ pItem->iAlias = 0; } + if( p->nSelectRow>(double)100 ) p->nSelectRow = (double)100; + }else{ + p->nSelectRow = (double)1; } - + /* Create a label to jump to when we want to abort the query */ addrEnd = sqlite3VdbeMakeLabel(v); @@ -84090,13 +96472,13 @@ SQLITE_PRIVATE int sqlite3Select( /* If there is a GROUP BY clause we might need a sorting index to ** implement it. Allocate that sorting index now. If it turns out - ** that we do not need it after all, the OpenEphemeral instruction - ** will be converted into a Noop. + ** that we do not need it after all, the OP_SorterOpen instruction + ** will be converted into a Noop. */ sAggInfo.sortingIdx = pParse->nTab++; pKeyInfo = keyInfoFromExprList(pParse, pGroupBy); - addrSortingIdx = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, - sAggInfo.sortingIdx, sAggInfo.nSortingColumn, + addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, + sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); /* Initialize memory locations used by GROUP BY aggregate processing @@ -84122,7 +96504,7 @@ SQLITE_PRIVATE int sqlite3Select( ** in the right order to begin with. */ sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0); if( pWInfo==0 ) goto select_end; if( pGroupBy==0 ){ /* The optimizer is able to deliver rows in group by order so @@ -84142,6 +96524,9 @@ SQLITE_PRIVATE int sqlite3Select( int nCol; int nGroupBy; + explainTempTable(pParse, + isDistinct && !(p->selFlags&SF_Distinct)?"DISTINCT":"GROUP BY"); + groupBySort = 1; nGroupBy = pGroupBy->nExpr; nCol = nGroupBy + 1; @@ -84163,7 +96548,7 @@ SQLITE_PRIVATE int sqlite3Select( int r1 = j + regBase; int r2; - r2 = sqlite3ExprCodeGetColumn(pParse, + r2 = sqlite3ExprCodeGetColumn(pParse, pCol->pTab, pCol->iColumn, pCol->iTable, r1); if( r1!=r2 ){ sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1); @@ -84173,11 +96558,14 @@ SQLITE_PRIVATE int sqlite3Select( } regRecord = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); - sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, regRecord); + sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempRange(pParse, regBase, nCol); sqlite3WhereEnd(pWInfo); - sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd); + sAggInfo.sortingIdxPTab = sortPTab = pParse->nTab++; + sortOut = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); + sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); VdbeComment((v, "GROUP BY sort")); sAggInfo.useSortingIdx = 1; sqlite3ExprCacheClear(pParse); @@ -84190,9 +96578,13 @@ SQLITE_PRIVATE int sqlite3Select( */ addrTopOfLoop = sqlite3VdbeCurrentAddr(v); sqlite3ExprCacheClear(pParse); + if( groupBySort ){ + sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut); + } for(j=0; j<pGroupBy->nExpr; j++){ if( groupBySort ){ - sqlite3VdbeAddOp3(v, OP_Column, sAggInfo.sortingIdx, j, iBMem+j); + sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); + if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); }else{ sAggInfo.directMode = 1; sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); @@ -84231,10 +96623,10 @@ SQLITE_PRIVATE int sqlite3Select( /* End of the loop */ if( groupBySort ){ - sqlite3VdbeAddOp2(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop); + sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop); }else{ sqlite3WhereEnd(pWInfo); - sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1); + sqlite3VdbeChangeToNoop(v, addrSortingIdx); } /* Output the final row of result @@ -84275,7 +96667,7 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeResolveLabel(v, addrReset); resetAccumulator(pParse, &sAggInfo); sqlite3VdbeAddOp1(v, OP_Return, regReset); - + } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ else { ExprList *pDel = 0; @@ -84313,11 +96705,13 @@ SQLITE_PRIVATE int sqlite3Select( ** and pKeyInfo to the KeyInfo structure required to navigate the ** index. ** - ** In practice the KeyInfo structure will not be used. It is only + ** (2011-04-15) Do not do a full scan of an unordered index. + ** + ** In practice the KeyInfo structure will not be used. It is only ** passed to keep OP_OpenRead happy. */ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( !pBest || pIdx->nColumn<pBest->nColumn ){ + if( pIdx->bUnordered==0 && (!pBest || pIdx->nColumn<pBest->nColumn) ){ pBest = pIdx; } } @@ -84333,6 +96727,7 @@ SQLITE_PRIVATE int sqlite3Select( } sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem); sqlite3VdbeAddOp1(v, OP_Close, iCsr); + explainSimpleCount(pParse, pTab, pBest); }else #endif /* SQLITE_OMIT_BTREECOUNT */ { @@ -84342,11 +96737,11 @@ SQLITE_PRIVATE int sqlite3Select( ** SELECT max(x) FROM ... ** ** If it is, then ask the code in where.c to attempt to sort results - ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause. + ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause. ** If where.c is able to produce results sorted in this order, then - ** add vdbe code to break out of the processing loop after the - ** first iteration (since the first iteration of the loop is - ** guaranteed to operate on the row with the minimum or maximum + ** add vdbe code to break out of the processing loop after the + ** first iteration (since the first iteration of the loop is + ** guaranteed to operate on the row with the minimum or maximum ** value of x, the only row required). ** ** A special flag must be passed to sqlite3WhereBegin() to slightly @@ -84357,7 +96752,7 @@ SQLITE_PRIVATE int sqlite3Select( ** for x. ** ** + The optimizer code in where.c (the thing that decides which - ** index or indices to use) should place a different priority on + ** index or indices to use) should place a different priority on ** satisfying the 'ORDER BY' clause than it does in other cases. ** Refer to code and comments in where.c for details. */ @@ -84372,13 +96767,13 @@ SQLITE_PRIVATE int sqlite3Select( pMinMax->a[0].pExpr->op = TK_COLUMN; } } - + /* 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. */ resetAccumulator(pParse, &sAggInfo); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, flag); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, 0, flag); if( pWInfo==0 ){ sqlite3ExprListDelete(db, pDel); goto select_end; @@ -84395,18 +96790,23 @@ SQLITE_PRIVATE int sqlite3Select( pOrderBy = 0; sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); - selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1, + selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1, pDest, addrEnd, addrEnd); sqlite3ExprListDelete(db, pDel); } sqlite3VdbeResolveLabel(v, addrEnd); - + } /* endif aggregate query */ + if( distinct>=0 ){ + explainTempTable(pParse, "DISTINCT"); + } + /* If there is an ORDER BY clause, then we need to sort the results ** and send them to the callback one by one. */ if( pOrderBy ){ + explainTempTable(pParse, "ORDER BY"); generateSortTail(pParse, p, v, pEList->nExpr, pDest); } @@ -84423,6 +96823,7 @@ SQLITE_PRIVATE int sqlite3Select( ** successful coding of the SELECT. */ select_end: + explainSetInteger(pParse->iSelectId, iRestoreSelectId); /* Identify column names if results of the SELECT are to be output. */ @@ -84441,7 +96842,7 @@ select_end: ** The following code is used for testing and debugging only. The code ** that follows does not appear in normal builds. ** -** These routines are used to print out the content of all or part of a +** These routines are used to print out the content of all or part of a ** parse structures such as Select or Expr. Such printouts are useful ** for helping to understand what is happening inside the code generator ** during the execution of complex SELECT statements. @@ -84551,6 +96952,8 @@ SQLITE_PRIVATE void sqlite3PrintSelect(Select *p, int indent){ ** These routines are in a separate files so that they will not be linked ** if they are not used. */ +/* #include <stdlib.h> */ +/* #include <string.h> */ #ifndef SQLITE_OMIT_GET_TABLE @@ -84643,7 +97046,7 @@ malloc_failed: ** at the conclusion of the call. ** ** The result that is written to ***pazResult is held in memory obtained -** from malloc(). But the caller cannot free this memory directly. +** from malloc(). But the caller cannot free this memory directly. ** Instead, the entire table should be passed to sqlite3_free_table() when ** the calling procedure is finished using it. */ @@ -84762,7 +97165,7 @@ SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerS } /* -** Given table pTab, return a list of all the triggers attached to +** Given table pTab, return a list of all the triggers attached to ** the table. The list is connected by Trigger.pNext pointers. ** ** All of the triggers on pTab that are in the same database as pTab @@ -84785,10 +97188,11 @@ SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ if( pTmpSchema!=pTab->pSchema ){ HashElem *p; + assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) ); for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){ Trigger *pTrig = (Trigger *)sqliteHashData(p); if( pTrig->pTabSchema==pTab->pSchema - && 0==sqlite3StrICmp(pTrig->table, pTab->zName) + && 0==sqlite3StrICmp(pTrig->table, pTab->zName) ){ pTrig->pNext = (pList ? pList : pTab->pTrigger); pList = pTrig; @@ -84847,15 +97251,28 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( goto trigger_cleanup; } } + if( !pTableName || db->mallocFailed ){ + goto trigger_cleanup; + } + + /* A long-standing parser bug is that this syntax was allowed: + ** + ** CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab .... + ** ^^^^^^^^ + ** + ** To maintain backwards compatibility, ignore the database + ** name on pTableName if we are reparsing our of SQLITE_MASTER. + */ + if( db->init.busy && iDb!=1 ){ + sqlite3DbFree(db, pTableName->a[0].zDatabase); + pTableName->a[0].zDatabase = 0; + } /* If the trigger name was unqualified, and the table is a temp table, ** then set iDb to 1 to create the trigger in the temporary database. ** If sqlite3SrcListLookup() returns 0, indicating the table does not ** exist, the error is caught by the block below. */ - if( !pTableName || db->mallocFailed ){ - goto trigger_cleanup; - } pTab = sqlite3SrcListLookup(pParse, pTableName); if( db->init.busy==0 && pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ @@ -84865,7 +97282,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( /* Ensure the table name matches database name and that the table exists */ if( db->mallocFailed ) goto trigger_cleanup; assert( pTableName->nSrc==1 ); - if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && + if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && sqlite3FixSrcList(&sFix, pTableName) ){ goto trigger_cleanup; } @@ -84896,10 +97313,14 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto trigger_cleanup; } + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName, sqlite3Strlen30(zName)) ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); } goto trigger_cleanup; } @@ -84915,7 +97336,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( ** of triggers. */ if( pTab->pSelect && tr_tm!=TK_INSTEAD ){ - sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", + sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0); goto trigger_cleanup; } @@ -84993,7 +97414,6 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( int iDb; /* Database containing the trigger */ Token nameToken; /* Trigger name for error reporting */ - pTrig = pParse->pNewTrigger; pParse->pNewTrigger = 0; if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup; zName = pTrig->zName; @@ -85005,7 +97425,7 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( } nameToken.z = pTrig->zName; nameToken.n = sqlite3Strlen30(nameToken.z); - if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken) + if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken) && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){ goto triggerfinish_cleanup; } @@ -85028,14 +97448,14 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( pTrig->table, z); sqlite3DbFree(db, z); sqlite3ChangeCookie(pParse, iDb); - sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, sqlite3MPrintf( - db, "type='trigger' AND name='%q'", zName), P4_DYNAMIC - ); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName)); } if( db->init.busy ){ Trigger *pLink = pTrig; Hash *pHash = &db->aDb[iDb].pSchema->trigHash; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pTrig = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), pTrig); if( pTrig ){ db->mallocFailed = 1; @@ -85060,7 +97480,7 @@ triggerfinish_cleanup: ** a trigger step. Return a pointer to a TriggerStep structure. ** ** The parser calls this routine when it finds a SELECT statement in -** body of a TRIGGER. +** body of a TRIGGER. */ SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){ TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); @@ -85179,7 +97599,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( return pTriggerStep; } -/* +/* ** Recursively delete a Trigger structure */ SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ @@ -85193,7 +97613,7 @@ SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ } /* -** This function is called to drop a trigger from the database schema. +** This function is called to drop a trigger from the database schema. ** ** This may be called directly from the parser and therefore identifies ** the trigger by name. The sqlite3DropTriggerPtr() routine does the @@ -85217,16 +97637,21 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr) zDb = pName->a[0].zDatabase; zName = pName->a[0].zName; nName = sqlite3Strlen30(zName); + assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); for(i=OMIT_TEMPDB; i<db->nDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName); if( pTrigger ) break; } if( !pTrigger ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); + }else{ + sqlite3CodeVerifyNamedSchema(pParse, zDb); } + pParse->checkSchema = 1; goto drop_trigger_cleanup; } sqlite3DropTriggerPtr(pParse, pTrigger); @@ -85246,7 +97671,7 @@ static Table *tableOfTrigger(Trigger *pTrigger){ /* -** Drop a trigger given a pointer to that trigger. +** Drop a trigger given a pointer to that trigger. */ SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ Table *pTable; @@ -85292,7 +97717,7 @@ SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3OpenMasterTable(pParse, iDb); base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger); - sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, 0); + sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, P4_TRANSIENT); sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddOp2(v, OP_Close, 0, 0); @@ -85307,8 +97732,11 @@ SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ ** Remove a trigger from the hash tables of the sqlite* pointer. */ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){ - Hash *pHash = &(db->aDb[iDb].pSchema->trigHash); Trigger *pTrigger; + Hash *pHash; + + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pHash = &(db->aDb[iDb].pSchema->trigHash); pTrigger = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), 0); if( ALWAYS(pTrigger) ){ if( pTrigger->pSchema==pTrigger->pTabSchema ){ @@ -85337,12 +97765,12 @@ static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){ for(e=0; e<pEList->nExpr; e++){ if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1; } - return 0; + return 0; } /* ** Return a list of all triggers on table pTab if there exists at least -** one trigger that must be fired when an operation of type 'op' is +** one trigger that must be fired when an operation of type 'op' is ** performed on the table, and, if that operation is an UPDATE, if at ** least one of the columns in pChanges is being modified. */ @@ -85354,8 +97782,12 @@ SQLITE_PRIVATE Trigger *sqlite3TriggersExist( int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ ){ int mask = 0; - Trigger *pList = sqlite3TriggerList(pParse, pTab); + Trigger *pList = 0; Trigger *p; + + if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){ + pList = sqlite3TriggerList(pParse, pTab); + } assert( pList==0 || IsVirtual(pTab)==0 ); for(p=pList; p; p=p->pNext){ if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ @@ -85400,13 +97832,13 @@ static SrcList *targetSrcList( } /* -** Generate VDBE code for the statements inside the body of a single +** Generate VDBE code for the statements inside the body of a single ** trigger. */ static int codeTriggerProgram( Parse *pParse, /* The parser context */ TriggerStep *pStepList, /* List of statements inside the trigger body */ - int orconf /* Conflict algorithm. (OE_Abort, etc) */ + int orconf /* Conflict algorithm. (OE_Abort, etc) */ ){ TriggerStep *pStep; Vdbe *v = pParse->pVdbe; @@ -85433,26 +97865,26 @@ static int codeTriggerProgram( switch( pStep->op ){ case TK_UPDATE: { - sqlite3Update(pParse, + sqlite3Update(pParse, targetSrcList(pParse, pStep), - sqlite3ExprListDup(db, pStep->pExprList, 0), - sqlite3ExprDup(db, pStep->pWhere, 0), + sqlite3ExprListDup(db, pStep->pExprList, 0), + sqlite3ExprDup(db, pStep->pWhere, 0), pParse->eOrconf ); break; } case TK_INSERT: { - sqlite3Insert(pParse, + sqlite3Insert(pParse, targetSrcList(pParse, pStep), - sqlite3ExprListDup(db, pStep->pExprList, 0), - sqlite3SelectDup(db, pStep->pSelect, 0), - sqlite3IdListDup(db, pStep->pIdList), + sqlite3ExprListDup(db, pStep->pExprList, 0), + sqlite3SelectDup(db, pStep->pSelect, 0), + sqlite3IdListDup(db, pStep->pIdList), pParse->eOrconf ); break; } case TK_DELETE: { - sqlite3DeleteFrom(pParse, + sqlite3DeleteFrom(pParse, targetSrcList(pParse, pStep), sqlite3ExprDup(db, pStep->pWhere, 0) ); @@ -85466,7 +97898,7 @@ static int codeTriggerProgram( sqlite3SelectDelete(db, pSelect); break; } - } + } if( pStep->op!=TK_SELECT ){ sqlite3VdbeAddOp0(v, OP_ResetCount); } @@ -85510,7 +97942,7 @@ static void transferParseError(Parse *pTo, Parse *pFrom){ } /* -** Create and populate a new TriggerPrg object with a sub-program +** Create and populate a new TriggerPrg object with a sub-program ** implementing trigger pTrigger with ON CONFLICT policy orconf. */ static TriggerPrg *codeRowTrigger( @@ -85530,9 +97962,10 @@ static TriggerPrg *codeRowTrigger( int iEndTrigger = 0; /* Label to jump to if WHEN is false */ assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); + assert( pTop->pVdbe ); /* Allocate the TriggerPrg and SubProgram objects. To ensure that they - ** are freed if an error occurs, link them into the Parse.pTriggerPrg + ** are freed if an error occurs, link them into the Parse.pTriggerPrg ** list of the top-level Parse object sooner rather than later. */ pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg)); if( !pPrg ) return 0; @@ -85540,13 +97973,13 @@ static TriggerPrg *codeRowTrigger( pTop->pTriggerPrg = pPrg; pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram)); if( !pProgram ) return 0; - pProgram->nRef = 1; + sqlite3VdbeLinkSubProgram(pTop->pVdbe, pProgram); pPrg->pTrigger = pTrigger; pPrg->orconf = orconf; pPrg->aColmask[0] = 0xffffffff; pPrg->aColmask[1] = 0xffffffff; - /* Allocate and populate a new Parse context to use for coding the + /* Allocate and populate a new Parse context to use for coding the ** trigger sub-program. */ pSubParse = sqlite3StackAllocZero(db, sizeof(Parse)); if( !pSubParse ) return 0; @@ -85557,10 +97990,11 @@ static TriggerPrg *codeRowTrigger( pSubParse->pToplevel = pTop; pSubParse->zAuthContext = pTrigger->zName; pSubParse->eTriggerOp = pTrigger->op; + pSubParse->nQueryLoop = pParse->nQueryLoop; v = sqlite3GetVdbe(pSubParse); if( v ){ - VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", + VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", pTrigger->zName, onErrorText(orconf), (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"), (pTrigger->op==TK_UPDATE ? "UPDATE" : ""), @@ -85569,18 +98003,18 @@ static TriggerPrg *codeRowTrigger( pTab->zName )); #ifndef SQLITE_OMIT_TRACE - sqlite3VdbeChangeP4(v, -1, + sqlite3VdbeChangeP4(v, -1, sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC ); #endif /* If one was specified, code the WHEN clause. If it evaluates to false - ** (or NULL) the sub-vdbe is immediately halted by jumping to the + ** (or NULL) the sub-vdbe is immediately halted by jumping to the ** OP_Halt inserted at the end of the program. */ if( pTrigger->pWhen ){ pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0); - if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) - && db->mallocFailed==0 + if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) + && db->mallocFailed==0 ){ iEndTrigger = sqlite3VdbeMakeLabel(v); sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); @@ -85616,7 +98050,7 @@ static TriggerPrg *codeRowTrigger( return pPrg; } - + /* ** Return a pointer to a TriggerPrg object containing the sub-program for ** trigger pTrigger with default ON CONFLICT algorithm orconf. If no such @@ -85638,8 +98072,8 @@ static TriggerPrg *getRowTrigger( ** process of being coded). If this is the case, then an entry with ** a matching TriggerPrg.pTrigger field will be present somewhere ** in the Parse.pTriggerPrg list. Search for such an entry. */ - for(pPrg=pRoot->pTriggerPrg; - pPrg && (pPrg->pTrigger!=pTrigger || pPrg->orconf!=orconf); + for(pPrg=pRoot->pTriggerPrg; + pPrg && (pPrg->pTrigger!=pTrigger || pPrg->orconf!=orconf); pPrg=pPrg->pNext ); @@ -85652,7 +98086,7 @@ static TriggerPrg *getRowTrigger( } /* -** Generate code for the trigger program associated with trigger p on +** Generate code for the trigger program associated with trigger p on ** table pTab. The reg, orconf and ignoreJump parameters passed to this ** function are the same as those described in the header function for ** sqlite3CodeRowTrigger() @@ -85670,11 +98104,12 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( pPrg = getRowTrigger(pParse, p, pTab, orconf); assert( pPrg || pParse->nErr || pParse->db->mallocFailed ); - /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program + /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program ** is a pointer to the sub-vdbe containing the trigger program. */ if( pPrg ){ + int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers)); + sqlite3VdbeAddOp3(v, OP_Program, reg, ignoreJump, ++pParse->nMem); - pPrg->pProgram->nRef++; sqlite3VdbeChangeP4(v, -1, (const char *)pPrg->pProgram, P4_SUBPROGRAM); VdbeComment( (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf))); @@ -85684,7 +98119,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( ** invocation is disallowed if (a) the sub-program is really a trigger, ** not a foreign key action, and (b) the flag to enable recursive triggers ** is clear. */ - sqlite3VdbeChangeP5(v, (u8)(p->zName && !(pParse->db->flags&SQLITE_RecTriggers))); + sqlite3VdbeChangeP5(v, (u8)bRecursive); } } @@ -85698,7 +98133,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( ** If there are no triggers that fire at the specified time for the specified ** operation on pTab, this function is a no-op. ** -** The reg argument is the address of the first in an array of registers +** The reg argument is the address of the first in an array of registers ** that contain the values substituted for the new.* and old.* references ** in the trigger program. If N is the number of columns in table pTab ** (a copy of pTab->nCol), then registers are populated as follows: @@ -85715,12 +98150,12 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( ** reg+N+N+1 NEW.* value of right-most column of pTab ** ** For ON DELETE triggers, the registers containing the NEW.* values will -** never be accessed by the trigger program, so they are not allocated or -** populated by the caller (there is no data to populate them with anyway). +** never be accessed by the trigger program, so they are not allocated or +** populated by the caller (there is no data to populate them with anyway). ** Similarly, for ON INSERT triggers the values stored in the OLD.* registers ** are never accessed, and so are not allocated by the caller. So, for an ** ON INSERT trigger, the value passed to this function as parameter reg -** is not a readable register, although registers (reg+N) through +** is not a readable register, although registers (reg+N) through ** (reg+N+N+1) are. ** ** Parameter orconf is the default conflict resolution algorithm for the @@ -85752,12 +98187,12 @@ SQLITE_PRIVATE void sqlite3CodeRowTrigger( ** or else it must be a TEMP trigger. */ assert( p->pSchema!=0 ); assert( p->pTabSchema!=0 ); - assert( p->pSchema==p->pTabSchema + assert( p->pSchema==p->pTabSchema || p->pSchema==pParse->db->aDb[1].pSchema ); /* Determine whether we should code this trigger */ - if( p->op==op - && p->tr_tm==tr_tm + if( p->op==op + && p->tr_tm==tr_tm && checkColumnOverlap(p->pColumns, pChanges) ){ sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); @@ -85766,9 +98201,9 @@ SQLITE_PRIVATE void sqlite3CodeRowTrigger( } /* -** Triggers may access values stored in the old.* or new.* pseudo-table. -** This function returns a 32-bit bitmask indicating which columns of the -** old.* or new.* tables actually are used by triggers. This information +** Triggers may access values stored in the old.* or new.* pseudo-table. +** This function returns a 32-bit bitmask indicating which columns of the +** old.* or new.* tables actually are used by triggers. This information ** may be used by the caller, for example, to avoid having to load the entire ** old.* record into memory when executing an UPDATE or DELETE command. ** @@ -85778,7 +98213,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTrigger( ** are more than 32 columns in the table, and at least one of the columns ** with an index greater than 32 may be accessed, 0xffffffff is returned. ** -** It is not possible to determine if the old.rowid or new.rowid column is +** It is not possible to determine if the old.rowid or new.rowid column is ** accessed by triggers. The caller must always assume that it is. ** ** Parameter isNew must be either 1 or 0. If it is 0, then the mask returned @@ -85847,16 +98282,17 @@ static void updateVirtualTable( ExprList *pChanges, /* The columns to change in the UPDATE statement */ Expr *pRowidExpr, /* Expression used to recompute the rowid */ int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ - Expr *pWhere /* WHERE clause of the UPDATE statement */ + Expr *pWhere, /* WHERE clause of the UPDATE statement */ + int onError /* ON CONFLICT strategy */ ); #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* ** The most recently coded instruction was an OP_Column to retrieve the -** i-th column of table pTab. This routine sets the P4 parameter of the +** i-th column of table pTab. This routine sets the P4 parameter of the ** OP_Column to the default value, if any. ** -** The default value of a column is specified by a DEFAULT clause in the +** The default value of a column is specified by a DEFAULT clause in the ** column definition. This was either supplied by the user when the table ** was created, or added later to the table definition by an ALTER TABLE ** command. If the latter, then the row-records in the table btree on disk @@ -85865,9 +98301,9 @@ static void updateVirtualTable( ** If the former, then all row-records are guaranteed to include a value ** for the column and the P4 value is not required. ** -** Column definitions created by an ALTER TABLE command may only have +** Column definitions created by an ALTER TABLE command may only have ** literal default values specified: a number, null or a string. (If a more -** complicated default expression value was provided, it is evaluated +** complicated default expression value was provided, it is evaluated ** when the ALTER TABLE is executed and one of the literal values written ** into the sqlite_master table.) ** @@ -85877,8 +98313,8 @@ static void updateVirtualTable( ** sqlite3_value objects. ** ** If parameter iReg is not negative, code an OP_RealAffinity instruction -** on register iReg. This is used when an equivalent integer value is -** stored in place of an 8-byte floating point value in order to save +** on register iReg. This is used when an equivalent integer value is +** stored in place of an 8-byte floating point value in order to save ** space. */ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ @@ -85889,7 +98325,7 @@ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ Column *pCol = &pTab->aCol[i]; VdbeComment((v, "%s.%s", pTab->zName, pCol->zName)); assert( i<pTab->nCol ); - sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, + sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, pCol->affinity, &pValue); if( pValue ){ sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM); @@ -85952,7 +98388,6 @@ SQLITE_PRIVATE void sqlite3Update( int regNew; int regOld = 0; int regRowSet = 0; /* Rowset of rows to be updated */ - int regRec; /* Register used for new table record to insert */ memset(&sContext, 0, sizeof(sContext)); db = pParse->db; @@ -85961,7 +98396,7 @@ SQLITE_PRIVATE void sqlite3Update( } assert( pTabList->nSrc==1 ); - /* Locate the table which we want to update. + /* Locate the table which we want to update. */ pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ) goto update_cleanup; @@ -86036,6 +98471,7 @@ SQLITE_PRIVATE void sqlite3Update( pRowidExpr = pChanges->a[i].pExpr; }else{ sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName); + pParse->checkSchema = 1; goto update_cleanup; } } @@ -86067,7 +98503,7 @@ SQLITE_PRIVATE void sqlite3Update( } for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int reg; - if( chngRowid ){ + if( hasFK || chngRowid ){ reg = ++pParse->nMem; }else{ reg = 0; @@ -86091,7 +98527,7 @@ SQLITE_PRIVATE void sqlite3Update( /* Virtual tables must be handled separately */ if( IsVirtual(pTab) ){ updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef, - pWhere); + pWhere, onError); pWhere = 0; pTabList = 0; goto update_cleanup; @@ -86109,7 +98545,6 @@ SQLITE_PRIVATE void sqlite3Update( } regNew = pParse->nMem + 1; pParse->nMem += pTab->nCol; - regRec = ++pParse->nMem; /* Start the view context. */ if( isView ){ @@ -86135,7 +98570,9 @@ SQLITE_PRIVATE void sqlite3Update( /* Begin the database scan */ sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0, WHERE_ONEPASS_DESIRED); + pWInfo = sqlite3WhereBegin( + pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED + ); if( pWInfo==0 ) goto update_cleanup; okOnePass = pWInfo->okOnePass; @@ -86159,13 +98596,13 @@ SQLITE_PRIVATE void sqlite3Update( } if( !isView ){ - /* + /* ** Open every index that needs updating. Note that if any - ** index could potentially invoke a REPLACE conflict resolution + ** index could potentially invoke a REPLACE conflict resolution ** action, then we need to open all indices because we might need ** to be deleting some records. */ - if( !okOnePass ) sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); + if( !okOnePass ) sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); if( onError==OE_Replace ){ openAll = 1; }else{ @@ -86211,17 +98648,16 @@ SQLITE_PRIVATE void sqlite3Update( sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); } - /* If there are triggers on this table, populate an array of registers + /* If there are triggers on this table, populate an array of registers ** with the required old.* column data. */ if( hasFK || pTrigger ){ u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0); - oldmask |= sqlite3TriggerColmask(pParse, + oldmask |= sqlite3TriggerColmask(pParse, pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError ); for(i=0; i<pTab->nCol; i++){ - if( aXRef[i]<0 || oldmask==0xffffffff || (oldmask & (1<<i)) ){ - sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regOld+i); - sqlite3ColumnDefault(v, pTab, i, regOld+i); + if( aXRef[i]<0 || oldmask==0xffffffff || (i<32 && (oldmask & (1<<i))) ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOld+i); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i); } @@ -86239,8 +98675,8 @@ SQLITE_PRIVATE void sqlite3Update( ** If there are one or more BEFORE triggers, then do not populate the ** registers associated with columns that are (a) not modified by ** this UPDATE statement and (b) not accessed by new.* references. The - ** values for registers not modified by the UPDATE must be reloaded from - ** the database after the BEFORE triggers are fired anyway (as the trigger + ** values for registers not modified by the UPDATE must be reloaded from + ** the database after the BEFORE triggers are fired anyway (as the trigger ** may have modified them). So not loading those that are not going to ** be used eliminates some redundant opcodes. */ @@ -86255,7 +98691,7 @@ SQLITE_PRIVATE void sqlite3Update( if( j>=0 ){ sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i); }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask&(1<<i)) ){ - /* This branch loads the value of a column that will not be changed + /* This branch loads the value of a column that will not be changed ** into a register. This is done if there are no BEFORE triggers, or ** if there are one or more BEFORE triggers that use this value via ** a new.* reference in a trigger program. @@ -86274,20 +98710,20 @@ SQLITE_PRIVATE void sqlite3Update( if( tmask&TRIGGER_BEFORE ){ sqlite3VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol); sqlite3TableAffinityStr(v, pTab); - sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab, regOldRowid, onError, addr); /* The row-trigger may have deleted the row being updated. In this - ** case, jump to the next row. No updates or AFTER triggers are + ** case, jump to the next row. No updates or AFTER triggers are ** required. This behaviour - what happens when the row being updated ** is deleted or renamed by a BEFORE trigger - is left undefined in the ** documentation. */ sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid); - /* If it did not delete it, the row-trigger may still have modified - ** some of the columns of the row being updated. Load the values for - ** all columns not modified by the update statement into their + /* If it did not delete it, the row-trigger may still have modified + ** some of the columns of the row being updated. Load the values for + ** all columns not modified by the update statement into their ** registers in case this has happened. */ for(i=0; i<pTab->nCol; i++){ @@ -86313,7 +98749,7 @@ SQLITE_PRIVATE void sqlite3Update( /* Delete the index entries associated with the current record. */ j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid); sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx); - + /* If changing the record number, delete the old record. */ if( hasFK || chngRowid ){ sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0); @@ -86323,25 +98759,25 @@ SQLITE_PRIVATE void sqlite3Update( if( hasFK ){ sqlite3FkCheck(pParse, pTab, 0, regNewRowid); } - + /* Insert the new index entries and the new record. */ sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, aRegIdx, 1, 0, 0); /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to ** handle rows (possibly in other tables) that refer via a foreign key - ** to the row just updated. */ + ** to the row just updated. */ if( hasFK ){ sqlite3FkActions(pParse, pTab, pChanges, regOldRowid); } } - /* Increment the row counter + /* Increment the row counter */ if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){ sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); } - sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, TRIGGER_AFTER, pTab, regOldRowid, onError, addr); /* Repeat the above with the next record to be updated, until @@ -86367,7 +98803,7 @@ SQLITE_PRIVATE void sqlite3Update( } /* - ** Return the number of rows that were changed. If this routine is + ** Return the number of rows that were changed. If this routine is ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ @@ -86423,7 +98859,8 @@ static void updateVirtualTable( ExprList *pChanges, /* The columns to change in the UPDATE statement */ Expr *pRowid, /* Expression used to recompute the rowid */ int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ - Expr *pWhere /* WHERE clause of the UPDATE statement */ + Expr *pWhere, /* WHERE clause of the UPDATE statement */ + int onError /* ON CONFLICT strategy */ ){ Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */ ExprList *pEList = 0; /* The result set of the SELECT statement */ @@ -86438,7 +98875,7 @@ static void updateVirtualTable( SelectDest dest; /* Construct the SELECT statement that will find the new values for - ** all updated rows. + ** all updated rows. */ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, "_rowid_")); if( pRowid ){ @@ -86455,15 +98892,16 @@ static void updateVirtualTable( pEList = sqlite3ExprListAppend(pParse, pEList, pExpr); } pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0); - + /* Create the ephemeral table into which the update results will ** be stored. */ assert( v ); ephemTab = pParse->nTab++; sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0)); + sqlite3VdbeChangeP5(v, BTREE_UNORDERED); - /* fill the ephemeral table + /* fill the ephemeral table */ sqlite3SelectDestInit(&dest, SRT_Table, ephemTab); sqlite3Select(pParse, pSelect, &dest); @@ -86479,13 +98917,14 @@ static void updateVirtualTable( } sqlite3VtabMakeWritable(pParse, pTab); sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError); sqlite3MayAbort(pParse); sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0); /* Cleanup */ - sqlite3SelectDelete(db, pSelect); + sqlite3SelectDelete(db, pSelect); } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -86594,21 +99033,26 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ void (*saved_xTrace)(void*,const char*); /* Saved db->xTrace */ Db *pDb = 0; /* Database to detach at end of vacuum */ int isMemDb; /* True if vacuuming a :memory: database */ - int nRes; + int nRes; /* Bytes of reserved space at the end of each page */ + int nDb; /* Number of attached databases */ if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); return SQLITE_ERROR; } + if( db->activeVdbeCnt>1 ){ + sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress"); + return SQLITE_ERROR; + } - /* Save the current value of the database flags so that it can be + /* Save the current value of the database flags so that it can be ** restored before returning. Then set the writable-schema flag, and ** disable CHECK and foreign key constraints. */ saved_flags = db->flags; saved_nChange = db->nChange; saved_nTotalChange = db->nTotalChange; saved_xTrace = db->xTrace; - db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks; + db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin; db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder); db->xTrace = 0; @@ -86629,15 +99073,18 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ ** time to parse and run the PRAGMA to turn journalling off than it does ** to write the journal header file. */ + nDb = db->nDb; if( sqlite3TempInMemory(db) ){ zSql = "ATTACH ':memory:' AS vacuum_db;"; }else{ zSql = "ATTACH '' AS vacuum_db;"; } rc = execSql(db, pzErrMsg, zSql); + if( db->nDb>nDb ){ + pDb = &db->aDb[db->nDb-1]; + assert( strcmp(pDb->zName,"vacuum_db")==0 ); + } if( rc!=SQLITE_OK ) goto end_of_vacuum; - pDb = &db->aDb[db->nDb-1]; - assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 ); pTemp = db->aDb[db->nDb-1].pBt; /* The call to execSql() to attach the temp database has left the file @@ -86659,6 +99106,12 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ } #endif + /* Do not attempt to change the page size for a WAL database */ + if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain)) + ==PAGER_JOURNALMODE_WAL ){ + db->nextPagesize = 0; + } + if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0) || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0)) || NEVER(db->mallocFailed) @@ -86795,6 +99248,7 @@ end_of_vacuum: db->nChange = saved_nChange; db->nTotalChange = saved_nTotalChange; db->xTrace = saved_xTrace; + sqlite3BtreeSetPageSize(pMain, -1, -1, 1); /* Currently there is an SQL level transaction open on the vacuum ** database. No locks are held on any other files (since the main file @@ -86811,10 +99265,13 @@ end_of_vacuum: pDb->pSchema = 0; } - sqlite3ResetInternalSchema(db, 0); + /* This both clears the schemas and reduces the size of the db->aDb[] + ** array. */ + sqlite3ResetInternalSchema(db, -1); return rc; } + #endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */ /************** End of vacuum.c **********************************************/ @@ -86835,6 +99292,18 @@ end_of_vacuum: #ifndef SQLITE_OMIT_VIRTUALTABLE /* +** Before a virtual table xCreate() or xConnect() method is invoked, the +** sqlite3.pVtabCtx member variable is set to point to an instance of +** this struct allocated on the stack. It is used by the implementation of +** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which +** are invoked only from within xCreate and xConnect methods. +*/ +struct VtabCtx { + Table *pTab; + VTable *pVTable; +}; + +/* ** The actual function that does the work of creating a new module. ** This function implements the sqlite3_create_module() and ** sqlite3_create_module_v2() interfaces. @@ -86862,13 +99331,13 @@ static int createModule( pMod->xDestroy = xDestroy; pDel = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod); if( pDel && pDel->xDestroy ){ + sqlite3ResetInternalSchema(db, -1); pDel->xDestroy(pDel->pAux); } sqlite3DbFree(db, pDel); if( pDel==pMod ){ db->mallocFailed = 1; } - sqlite3ResetInternalSchema(db, 0); }else if( xDestroy ){ xDestroy(pAux); } @@ -86906,7 +99375,7 @@ SQLITE_API int sqlite3_create_module_v2( /* ** Lock the virtual table so that it cannot be disconnected. ** Locks nest. Every lock should have a corresponding unlock. -** If an unlock is omitted, resources leaks will occur. +** If an unlock is omitted, resources leaks will occur. ** ** If a disconnect is attempted while a virtual table is locked, ** the disconnect is deferred until all locks have been removed. @@ -86918,7 +99387,7 @@ SQLITE_PRIVATE void sqlite3VtabLock(VTable *pVTab){ /* ** pTab is a pointer to a Table structure representing a virtual-table. -** Return a pointer to the VTable object used by connection db to access +** Return a pointer to the VTable object used by connection db to access ** this virtual-table, if one has been created, or NULL otherwise. */ SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){ @@ -86952,7 +99421,7 @@ SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){ /* ** Table p is a virtual table. This function moves all elements in the ** p->pVTable list to the sqlite3.pDisconnect lists of their associated -** database connections to be disconnected at the next opportunity. +** database connections to be disconnected at the next opportunity. ** Except, if argument db is not NULL, then the entry associated with ** connection db is left in the p->pVTable list. */ @@ -86961,14 +99430,13 @@ static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ VTable *pVTable = p->pVTable; p->pVTable = 0; - /* Assert that the mutex (if any) associated with the BtShared database - ** that contains table p is held by the caller. See header comments + /* Assert that the mutex (if any) associated with the BtShared database + ** that contains table p is held by the caller. See header comments ** above function sqlite3VtabUnlockList() for an explanation of why ** this makes it safe to access the sqlite3.pDisconnect list of any - ** database connection that may have an entry in the p->pVTable list. */ - assert( db==0 || - sqlite3BtreeHoldsMutex(db->aDb[sqlite3SchemaToIndex(db, p->pSchema)].pBt) - ); + ** database connection that may have an entry in the p->pVTable list. + */ + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); while( pVTable ){ sqlite3 *db2 = pVTable->db; @@ -86994,7 +99462,7 @@ static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ ** Disconnect all the virtual table objects in the sqlite3.pDisconnect list. ** ** This function may only be called when the mutexes associated with all -** shared b-tree databases opened using connection db are held by the +** shared b-tree databases opened using connection db are held by the ** caller. This is done to protect the sqlite3.pDisconnect list. The ** sqlite3.pDisconnect list is accessed only as follows: ** @@ -87007,7 +99475,7 @@ static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ ** or, if the virtual table is stored in a non-sharable database, then ** the database handle mutex is held. ** -** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously +** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously ** by multiple threads. It is thread-safe. */ SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ @@ -87033,22 +99501,22 @@ SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ ** record. ** ** Since it is a virtual-table, the Table structure contains a pointer -** to the head of a linked list of VTable structures. Each VTable +** to the head of a linked list of VTable structures. Each VTable ** structure is associated with a single sqlite3* user of the schema. -** The reference count of the VTable structure associated with database -** connection db is decremented immediately (which may lead to the +** The reference count of the VTable structure associated with database +** connection db is decremented immediately (which may lead to the ** structure being xDisconnected and free). Any other VTable structures -** in the list are moved to the sqlite3.pDisconnect list of the associated +** in the list are moved to the sqlite3.pDisconnect list of the associated ** database connection. */ -SQLITE_PRIVATE void sqlite3VtabClear(Table *p){ - vtabDisconnectAll(0, p); +SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){ + if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); if( p->azModuleArg ){ int i; for(i=0; i<p->nModuleArg; i++){ - sqlite3DbFree(p->dbMem, p->azModuleArg[i]); + sqlite3DbFree(db, p->azModuleArg[i]); } - sqlite3DbFree(p->dbMem, p->azModuleArg); + sqlite3DbFree(db, p->azModuleArg); } } @@ -87116,7 +99584,7 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse( ** The second call, to obtain permission to create the table, is made now. */ if( pTable->azModuleArg ){ - sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, + sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, pTable->azModuleArg[0], pParse->db->aDb[iDb].zName); } #endif @@ -87148,7 +99616,7 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ addArgumentToVtab(pParse); pParse->sArg.z = 0; if( pTab->nModuleArg<1 ) return; - + /* If the CREATE VIRTUAL TABLE statement is being entered for the ** first time (in other words if the virtual table is actually being ** created now instead of just being read out of sqlite_master) then @@ -87167,9 +99635,9 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ } zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken); - /* A slot for the record has already been allocated in the + /* A slot for the record has already been allocated in the ** SQLITE_MASTER table. We just need to update that slot with all - ** the information we've collected. + ** the information we've collected. ** ** The VM register number pParse->regRowid holds the rowid of an ** entry in the sqlite_master table tht was created for this vtab @@ -87191,9 +99659,9 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); - zWhere = sqlite3MPrintf(db, "name='%q'", pTab->zName); - sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 1, 0, zWhere, P4_DYNAMIC); - sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0, + zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName); + sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); + sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0, pTab->zName, sqlite3Strlen30(pTab->zName) + 1); } @@ -87207,13 +99675,13 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ Schema *pSchema = pTab->pSchema; const char *zName = pTab->zName; int nName = sqlite3Strlen30(zName); + assert( sqlite3SchemaMutexHeld(db, 0, pSchema) ); pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab); if( pOld ){ db->mallocFailed = 1; assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ return; } - pSchema->db = pParse->db; pParse->pNewTable = 0; } } @@ -87249,12 +99717,13 @@ SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){ ** to this procedure. */ static int vtabCallConstructor( - sqlite3 *db, + sqlite3 *db, Table *pTab, Module *pMod, int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), char **pzErr ){ + VtabCtx sCtx; VTable *pVTable; int rc; const char *const*azArg = (const char *const*)pTab->azModuleArg; @@ -87274,12 +99743,14 @@ static int vtabCallConstructor( pVTable->db = db; pVTable->pMod = pMod; - assert( !db->pVTab ); - assert( xConstruct ); - db->pVTab = pTab; - /* Invoke the virtual table constructor */ + assert( &db->pVtabCtx ); + assert( xConstruct ); + sCtx.pTab = pTab; + sCtx.pVTable = pVTable; + db->pVtabCtx = &sCtx; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); + db->pVtabCtx = 0; if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; if( SQLITE_OK!=rc ){ @@ -87287,7 +99758,7 @@ static int vtabCallConstructor( *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); }else { *pzErr = sqlite3MPrintf(db, "%s", zErr); - sqlite3DbFree(db, zErr); + sqlite3_free(zErr); } sqlite3DbFree(db, pVTable); }else if( ALWAYS(pVTable->pVtab) ){ @@ -87295,7 +99766,7 @@ static int vtabCallConstructor( ** the sqlite3_vtab object if successful. */ pVTable->pVtab->pModule = pMod->pModule; pVTable->nRef = 1; - if( db->pVTab ){ + if( sCtx.pTab ){ const char *zFormat = "vtable constructor did not declare schema: %s"; *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); sqlite3VtabUnlock(pVTable); @@ -87303,7 +99774,7 @@ static int vtabCallConstructor( }else{ int iCol; /* If everything went according to plan, link the new VTable structure - ** into the linked list headed by pTab->pVTable. Then loop through the + ** into the linked list headed by pTab->pVTable. Then loop through the ** columns of the table to see if any of them contain the token "hidden". ** If so, set the Column.isHidden flag and remove the token from ** the type string. */ @@ -87343,13 +99814,12 @@ static int vtabCallConstructor( } sqlite3DbFree(db, zModuleName); - db->pVTab = 0; return rc; } /* ** This function is invoked by the parser to call the xConnect() method -** of the virtual table pTab. If an error occurs, an error code is returned +** of the virtual table pTab. If an error occurs, an error code is returned ** and an error left in pParse. ** ** This call is a no-op if table pTab is not a virtual table. @@ -87384,11 +99854,11 @@ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ return rc; } - /* -** Add the virtual table pVTab to the array sqlite3.aVTrans[]. +** Grow the db->aVTrans[] array so that there is room for at least one +** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise. */ -static int addToVTrans(sqlite3 *db, VTable *pVTab){ +static int growVTrans(sqlite3 *db){ const int ARRAY_INCR = 5; /* Grow the sqlite3.aVTrans array if required */ @@ -87403,15 +99873,22 @@ static int addToVTrans(sqlite3 *db, VTable *pVTab){ db->aVTrans = aVTrans; } + return SQLITE_OK; +} + +/* +** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should +** have already been reserved using growVTrans(). +*/ +static void addToVTrans(sqlite3 *db, VTable *pVTab){ /* Add pVtab to the end of sqlite3.aVTrans */ db->aVTrans[db->nVTrans++] = pVTab; sqlite3VtabLock(pVTab); - return SQLITE_OK; } /* ** This function is invoked by the vdbe to call the xCreate method -** of the virtual table named zTab in database iDb. +** of the virtual table named zTab in database iDb. ** ** If an error occurs, *pzErr is set to point an an English language ** description of the error and an SQLITE_XXX error code is returned. @@ -87430,8 +99907,8 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, zMod = pTab->azModuleArg[0]; pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod)); - /* If the module has been registered and includes a Create method, - ** invoke it now. If the module has not been registered, return an + /* If the module has been registered and includes a Create method, + ** invoke it now. If the module has not been registered, return an ** error. Otherwise, do nothing. */ if( !pMod ){ @@ -87444,7 +99921,10 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, /* Justification of ALWAYS(): The xConstructor method is required to ** create a valid sqlite3_vtab if it returns SQLITE_OK. */ if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){ - rc = addToVTrans(db, sqlite3GetVTable(db, pTab)); + rc = growVTrans(db); + if( rc==SQLITE_OK ){ + addToVTrans(db, sqlite3GetVTable(db, pTab)); + } } return rc; @@ -87463,8 +99943,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ char *zErr = 0; sqlite3_mutex_enter(db->mutex); - pTab = db->pVTab; - if( !pTab ){ + if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){ sqlite3Error(db, SQLITE_MISUSE, 0); sqlite3_mutex_leave(db->mutex); return SQLITE_MISUSE_BKPT; @@ -87477,8 +99956,9 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ }else{ pParse->declareVtab = 1; pParse->db = db; - - if( SQLITE_OK==sqlite3RunParser(pParse, zCreateTable, &zErr) + pParse->nQueryLoop = 1; + + if( SQLITE_OK==sqlite3RunParser(pParse, zCreateTable, &zErr) && pParse->pNewTable && !db->mallocFailed && !pParse->pNewTable->pSelect @@ -87490,18 +99970,18 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ pParse->pNewTable->nCol = 0; pParse->pNewTable->aCol = 0; } - db->pVTab = 0; + db->pVtabCtx->pTab = 0; }else{ - sqlite3Error(db, SQLITE_ERROR, zErr); + sqlite3Error(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); sqlite3DbFree(db, zErr); rc = SQLITE_ERROR; } pParse->declareVtab = 0; - + if( pParse->pVdbe ){ sqlite3VdbeFinalize(pParse->pVdbe); } - sqlite3DeleteTable(pParse->pNewTable); + sqlite3DeleteTable(db, pParse->pNewTable); sqlite3StackFree(db, pParse); } @@ -87547,7 +100027,7 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab ** called is identified by the second argument, "offset", which is ** the offset of the method to call in the sqlite3_module structure. ** -** The array is cleared after invoking the callbacks. +** The array is cleared after invoking the callbacks. */ static void callFinaliser(sqlite3 *db, int offset){ int i; @@ -87560,6 +100040,7 @@ static void callFinaliser(sqlite3 *db, int offset){ x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset); if( x ) x(p); } + pVTab->iSavepoint = 0; sqlite3VtabUnlock(pVTab); } sqlite3DbFree(db, db->aVTrans); @@ -87573,7 +100054,7 @@ static void callFinaliser(sqlite3 *db, int offset){ ** array. Return the error code for the first error that occurs, or ** SQLITE_OK if all xSync operations are successful. ** -** Set *pzErrmsg to point to a buffer that should be released using +** Set *pzErrmsg to point to a buffer that should be released using ** sqlite3DbFree() containing an error message, if one is available. */ SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){ @@ -87588,8 +100069,8 @@ SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){ if( pVtab && (x = pVtab->pModule->xSync)!=0 ){ rc = x(pVtab); sqlite3DbFree(db, *pzErrmsg); - *pzErrmsg = pVtab->zErrMsg; - pVtab->zErrMsg = 0; + *pzErrmsg = sqlite3DbStrDup(db, pVtab->zErrMsg); + sqlite3_free(pVtab->zErrMsg); } } db->aVTrans = aVTrans; @@ -87597,7 +100078,7 @@ SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){ } /* -** Invoke the xRollback method of all virtual tables in the +** Invoke the xRollback method of all virtual tables in the ** sqlite3.aVTrans array. Then clear the array itself. */ SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db){ @@ -87606,7 +100087,7 @@ SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db){ } /* -** Invoke the xCommit method of all virtual tables in the +** Invoke the xCommit method of all virtual tables in the ** sqlite3.aVTrans array. Then clear the array itself. */ SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db){ @@ -87628,7 +100109,7 @@ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){ /* Special case: If db->aVTrans is NULL and db->nVTrans is greater ** than zero, then this function is being called from within a - ** virtual module xSync() callback. It is illegal to write to + ** virtual module xSync() callback. It is illegal to write to ** virtual module tables in this case, so return SQLITE_LOCKED. */ if( sqlite3VtabInSync(db) ){ @@ -87636,13 +100117,12 @@ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){ } if( !pVTab ){ return SQLITE_OK; - } + } pModule = pVTab->pVtab->pModule; if( pModule->xBegin ){ int i; - /* If pVtab is already in the aVTrans array, return early */ for(i=0; i<db->nVTrans; i++){ if( db->aVTrans[i]==pVTab ){ @@ -87650,10 +100130,62 @@ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){ } } - /* Invoke the xBegin method */ - rc = pModule->xBegin(pVTab->pVtab); + /* Invoke the xBegin method. If successful, add the vtab to the + ** sqlite3.aVTrans[] array. */ + rc = growVTrans(db); if( rc==SQLITE_OK ){ - rc = addToVTrans(db, pVTab); + rc = pModule->xBegin(pVTab->pVtab); + if( rc==SQLITE_OK ){ + addToVTrans(db, pVTab); + } + } + } + return rc; +} + +/* +** Invoke either the xSavepoint, xRollbackTo or xRelease method of all +** virtual tables that currently have an open transaction. Pass iSavepoint +** as the second argument to the virtual table method invoked. +** +** If op is SAVEPOINT_BEGIN, the xSavepoint method is invoked. If it is +** SAVEPOINT_ROLLBACK, the xRollbackTo method. Otherwise, if op is +** SAVEPOINT_RELEASE, then the xRelease method of each virtual table with +** an open transaction is invoked. +** +** If any virtual table method returns an error code other than SQLITE_OK, +** processing is abandoned and the error returned to the caller of this +** function immediately. If all calls to virtual table methods are successful, +** SQLITE_OK is returned. +*/ +SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ + int rc = SQLITE_OK; + + assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); + assert( iSavepoint>=0 ); + if( db->aVTrans ){ + int i; + for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ + VTable *pVTab = db->aVTrans[i]; + const sqlite3_module *pMod = pVTab->pMod->pModule; + if( pMod->iVersion>=2 ){ + int (*xMethod)(sqlite3_vtab *, int); + switch( op ){ + case SAVEPOINT_BEGIN: + xMethod = pMod->xSavepoint; + pVTab->iSavepoint = iSavepoint+1; + break; + case SAVEPOINT_ROLLBACK: + xMethod = pMod->xRollbackTo; + break; + default: + xMethod = pMod->xRelease; + break; + } + if( xMethod && pVTab->iSavepoint>iSavepoint ){ + rc = xMethod(db->aVTrans[i]->pVtab, iSavepoint); + } + } } } return rc; @@ -87668,7 +100200,7 @@ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){ ** This routine is used to allow virtual table implementations to ** overload MATCH, LIKE, GLOB, and REGEXP operators. ** -** Return either the pDef argument (indicating no change) or a +** Return either the pDef argument (indicating no change) or a ** new FuncDef structure that is marked as ephemeral using the ** SQLITE_FUNC_EPHEM flag. */ @@ -87700,9 +100232,9 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( assert( pVtab->pModule!=0 ); pMod = (sqlite3_module *)pVtab->pModule; if( pMod->xFindFunction==0 ) return pDef; - + /* Call the xFindFunction method on the virtual table implementation - ** to see if the implementation wants to overload this function + ** to see if the implementation wants to overload this function */ zLowerName = sqlite3DbStrDup(db, pDef->zName); if( zLowerName ){ @@ -87757,6 +100289,57 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ } } +/* +** Return the ON CONFLICT resolution mode in effect for the virtual +** table update operation currently in progress. +** +** The results of this routine are undefined unless it is called from +** within an xUpdate method. +*/ +SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){ + static const unsigned char aMap[] = { + SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE + }; + assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 ); + assert( OE_Ignore==4 && OE_Replace==5 ); + assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 ); + return (int)aMap[db->vtabOnConflict-1]; +} + +/* +** Call from within the xCreate() or xConnect() methods to provide +** the SQLite core with additional information about the behavior +** of the virtual table being implemented. +*/ +SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){ + va_list ap; + int rc = SQLITE_OK; + + sqlite3_mutex_enter(db->mutex); + + va_start(ap, op); + switch( op ){ + case SQLITE_VTAB_CONSTRAINT_SUPPORT: { + VtabCtx *p = db->pVtabCtx; + if( !p ){ + rc = SQLITE_MISUSE_BKPT; + }else{ + assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 ); + p->pVTable->bConstraint = (u8)va_arg(ap, int); + } + break; + } + default: + rc = SQLITE_MISUSE_BKPT; + break; + } + va_end(ap); + + if( rc!=SQLITE_OK ) sqlite3Error(db, rc, 0); + sqlite3_mutex_leave(db->mutex); + return rc; +} + #endif /* SQLITE_OMIT_VIRTUALTABLE */ /************** End of vtab.c ************************************************/ @@ -87780,6 +100363,7 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ ** indices, you might also think of this module as the "query optimizer". */ + /* ** Trace output macros */ @@ -87806,7 +100390,7 @@ typedef struct WhereCost WhereCost; ** clause subexpression is separated from the others by AND operators, ** usually, or sometimes subexpressions separated by OR. ** -** All WhereTerms are collected into a single WhereClause structure. +** All WhereTerms are collected into a single WhereClause structure. ** The following identity holds: ** ** WhereTerm.pWC->a[WhereTerm.idx] == WhereTerm @@ -87879,6 +100463,11 @@ struct WhereTerm { #define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ #define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */ #define TERM_OR_OK 0x40 /* Used during OR-clause processing */ +#ifdef SQLITE_ENABLE_STAT2 +# define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */ +#else +# define TERM_VNULL 0x00 /* Disabled if not using stat2 */ +#endif /* ** An instance of the following structure holds all information about a @@ -87920,8 +100509,8 @@ struct WhereAndInfo { ** 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 -** SrcList_item.iCursor and Expr.iTable fields. For any given WHERE +** The VDBE cursor numbers are small integers contained in +** 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 @@ -87954,7 +100543,6 @@ struct WhereMaskSet { struct WhereCost { WherePlan plan; /* The lookup strategy */ double rCost; /* Overall cost of pursuing this search strategy */ - double nRow; /* Estimated number of output rows */ Bitmask used; /* Bitmask of cursors used by this plan */ }; @@ -87973,6 +100561,7 @@ struct WhereCost { #define WO_ISNULL 0x080 #define WO_OR 0x100 /* Two or more OR-connected terms */ #define WO_AND 0x200 /* Two or more AND-connected terms */ +#define WO_NOOP 0x800 /* This term does not restrict search space */ #define WO_ALL 0xfff /* Mask of all possible WO_* values */ #define WO_SINGLE 0x0ff /* Mask of all non-compound WO_* values */ @@ -87997,15 +100586,19 @@ struct WhereCost { #define WHERE_COLUMN_IN 0x00040000 /* x IN (...) */ #define WHERE_COLUMN_NULL 0x00080000 /* x IS NULL */ #define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */ +#define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */ #define WHERE_IN_ABLE 0x000f1000 /* Able to support an IN operator */ #define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */ #define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */ +#define WHERE_BOTH_LIMIT 0x00300000 /* Both x>EXPR and x<EXPR */ #define WHERE_IDX_ONLY 0x00800000 /* Use index only - omit table */ #define WHERE_ORDERBY 0x01000000 /* Output will appear in correct order */ #define WHERE_REVERSE 0x02000000 /* Scan in reverse order */ #define WHERE_UNIQUE 0x04000000 /* Selects no more than one row */ #define WHERE_VIRTUALTABLE 0x08000000 /* Use virtual-table processing */ #define WHERE_MULTI_OR 0x10000000 /* OR using multiple indices */ +#define WHERE_TEMP_INDEX 0x20000000 /* Uses an ephemeral index */ +#define WHERE_DISTINCT 0x40000000 /* Correct order for DISTINCT */ /* ** Initialize a preallocated WhereClause structure. @@ -88087,6 +100680,7 @@ static void whereClauseClear(WhereClause *pWC){ static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){ WhereTerm *pTerm; int idx; + testcase( wtFlags & TERM_VIRTUAL ); /* EV: R-00211-15100 */ if( pWC->nTerm>=pWC->nSlot ){ WhereTerm *pOld = pWC->a; sqlite3 *db = pWC->pParse->db; @@ -88151,7 +100745,7 @@ static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){ */ static Bitmask getMask(WhereMaskSet *pMaskSet, int iCursor){ int i; - assert( pMaskSet->n<=sizeof(Bitmask)*8 ); + assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 ); for(i=0; i<pMaskSet->n; i++){ if( pMaskSet->ix[i]==iCursor ){ return ((Bitmask)1)<<i; @@ -88218,11 +100812,19 @@ static Bitmask exprListTableUsage(WhereMaskSet *pMaskSet, ExprList *pList){ static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){ Bitmask mask = 0; while( pS ){ + SrcList *pSrc = pS->pSrc; mask |= exprListTableUsage(pMaskSet, pS->pEList); mask |= exprListTableUsage(pMaskSet, pS->pGroupBy); mask |= exprListTableUsage(pMaskSet, pS->pOrderBy); mask |= exprTableUsage(pMaskSet, pS->pWhere); mask |= exprTableUsage(pMaskSet, pS->pHaving); + if( ALWAYS(pSrc!=0) ){ + int i; + for(i=0; i<pSrc->nSrc; i++){ + mask |= exprSelectTableUsage(pMaskSet, pSrc->a[i].pSelect); + mask |= exprTableUsage(pMaskSet, pSrc->a[i].pOn); + } + } pS = pS->pPrior; } return mask; @@ -88232,6 +100834,13 @@ static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){ ** Return TRUE if the given operator is one of the operators that is ** allowed for an indexable WHERE clause term. The allowed operators are ** "=", "<", ">", "<=", ">=", and "IN". +** +** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be +** of one of the following forms: column = expression column > expression +** column >= expression column < expression column <= expression +** expression = column expression > column expression >= column +** expression < column expression <= column column IN +** (expression-list) column IN (subquery) column IS NULL */ static int allowedOp(int op){ assert( TK_GT>TK_EQ && TK_GT<TK_GE ); @@ -88252,9 +100861,9 @@ static int allowedOp(int op){ ** ** If a collation sequence is associated with either the left or right ** side of the comparison, it remains associated with the same side after -** the commutation. So "Y collate NOCASE op X" becomes +** the commutation. So "Y collate NOCASE op X" becomes ** "X collate NOCASE op Y". This is because any collation sequence on -** the left hand side of a comparison overrides any collation sequence +** the left hand side of a comparison overrides any collation sequence ** attached to the right. For the same reason the EP_ExpCollate flag ** is not commuted. */ @@ -88359,7 +100968,7 @@ static WhereTerm *findTerm( static void exprAnalyze(SrcList*, WhereClause*, int); /* -** Call exprAnalyze on all terms in a WHERE clause. +** Call exprAnalyze on all terms in a WHERE clause. ** ** */ @@ -88380,7 +100989,7 @@ static void exprAnalyzeAll( ** so and false if not. ** ** In order for the operator to be optimizible, the RHS must be a string -** literal that does not begin with a wildcard. +** literal that does not begin with a wildcard. */ static int isLikeOrGlob( Parse *pParse, /* Parsing and code generating context */ @@ -88395,7 +101004,6 @@ static int isLikeOrGlob( int c; /* One character in z[] */ int cnt; /* Number of non-wildcard prefix characters */ char wc[3]; /* Wildcard characters */ - CollSeq *pColl; /* Collating sequence for LHS */ sqlite3 *db = pParse->db; /* Database connection */ sqlite3_value *pVal = 0; int op; /* Opcode of pRight */ @@ -88414,19 +101022,6 @@ static int isLikeOrGlob( return 0; } assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */ - pColl = sqlite3ExprCollSeq(pParse, pLeft); - if( pColl==0 ) return 0; /* Happens when LHS has an undefined collation */ - if( (pColl->type!=SQLITE_COLL_BINARY || *pnoCase) && - (pColl->type!=SQLITE_COLL_NOCASE || !*pnoCase) ){ - /* IMP: R-09003-32046 For the GLOB operator, the column must use the - ** default BINARY collating sequence. - ** IMP: R-41408-28306 For the LIKE operator, if case_sensitive_like mode - ** is enabled then the column must use the default BINARY collating - ** sequence, or if case_sensitive_like mode is disabled then the column - ** must use the built-in NOCASE collating sequence. - */ - return 0; - } pRight = pList->a[0].pExpr; op = pRight->op; @@ -88435,11 +101030,12 @@ static int isLikeOrGlob( } if( op==TK_VARIABLE ){ Vdbe *pReprepare = pParse->pReprepare; - pVal = sqlite3VdbeGetValue(pReprepare, pRight->iColumn, SQLITE_AFF_NONE); + int iCol = pRight->iColumn; + pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE); if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){ z = (char *)sqlite3_value_text(pVal); } - sqlite3VdbeSetVarmask(pParse->pVdbe, pRight->iColumn); + sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); /* IMP: R-23257-02778 */ assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); }else if( op==TK_STRING ){ z = pRight->u.zToken; @@ -88449,22 +101045,22 @@ static int isLikeOrGlob( while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ cnt++; } - if( cnt!=0 && c!=0 && 255!=(u8)z[cnt-1] ){ + if( cnt!=0 && 255!=(u8)z[cnt-1] ){ Expr *pPrefix; - *pisComplete = z[cnt]==wc[0] && z[cnt+1]==0; + *pisComplete = c==wc[0] && z[cnt+1]==0; pPrefix = sqlite3Expr(db, TK_STRING, z); if( pPrefix ) pPrefix->u.zToken[cnt] = 0; *ppPrefix = pPrefix; if( op==TK_VARIABLE ){ Vdbe *v = pParse->pVdbe; - sqlite3VdbeSetVarmask(v, pRight->iColumn); + sqlite3VdbeSetVarmask(v, pRight->iColumn); /* IMP: R-23257-02778 */ if( *pisComplete && pRight->u.zToken[1] ){ /* If the rhs of the LIKE expression is a variable, and the current ** value of the variable means there is no need to invoke the LIKE ** function, then no OP_Variable will be added to the program. ** This causes problems for the sqlite3_bind_parameter_name() ** API. To workaround them, add a dummy OP_Variable here. - */ + */ int r1 = sqlite3GetTempReg(pParse); sqlite3ExprCodeTarget(pParse, pRight, r1); sqlite3VdbeChangeP3(v, sqlite3VdbeCurrentAddr(v)-1, 0); @@ -88567,10 +101163,10 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ ** WhereTerm.u.pOrInfo->indexable |= the cursor number for table T ** ** A subterm is "indexable" if it is of the form -** "T.C <op> <expr>" where C is any column of table T and +** "T.C <op> <expr>" where C is any column of table T and ** <op> is one of "=", "<", "<=", ">", ">=", "IS NULL", or "IN". ** A subterm is also indexable if it is an AND of two or more -** subsubterms at least one of which is indexable. Indexable AND +** subsubterms at least one of which is indexable. Indexable AND ** subterms have their eOperator set to WO_AND and they have ** u.pAndInfo set to a dynamically allocated WhereAndTerm object. ** @@ -88740,7 +101336,7 @@ static void exprAnalyzeOrTerm( if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ){ /* This term must be of the form t1.a==t2.b where t2 is in the ** chngToIN set but t1 is not. This term will be either preceeded - ** or follwed by an inverted copy (t2.b==t1.a). Skip this term + ** or follwed by an inverted copy (t2.b==t1.a). Skip this term ** and use its inversion. */ testcase( pOrTerm->wtFlags & TERM_COPIED ); testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); @@ -88788,8 +101384,10 @@ static void exprAnalyzeOrTerm( } /* At this point, okToChngToIN is true if original pTerm satisfies - ** case 1. In that case, construct a new virtual term that is + ** case 1. In that case, construct a new virtual term that is ** pTerm converted into an IN operator. + ** + ** EV: R-00211-15100 */ if( okToChngToIN ){ Expr *pDup; /* A transient duplicate expression */ @@ -88823,7 +101421,7 @@ static void exprAnalyzeOrTerm( }else{ sqlite3ExprListDelete(db, pList); } - pTerm->eOperator = 0; /* case 1 trumps case 2 */ + pTerm->eOperator = WO_NOOP; /* case 1 trumps case 2 */ } } } @@ -88962,7 +101560,7 @@ static void exprAnalyze( for(i=0; i<2; i++){ Expr *pNewExpr; int idxNew; - pNewExpr = sqlite3PExpr(pParse, ops[i], + pNewExpr = sqlite3PExpr(pParse, ops[i], sqlite3ExprDup(db, pExpr->pLeft, 0), sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); @@ -88997,7 +101595,7 @@ static void exprAnalyze( ** The last character of the prefix "abc" is incremented to form the ** termination condition "abd". */ - if( pWC->op==TK_AND + if( pWC->op==TK_AND && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase) ){ Expr *pLeft; /* LHS of LIKE/GLOB operator */ @@ -89006,6 +101604,7 @@ static void exprAnalyze( Expr *pNewExpr2; int idxNew1; int idxNew2; + CollSeq *pColl; /* Collating sequence to use */ pLeft = pExpr->x.pList->a[1].pExpr; pStr2 = sqlite3ExprDup(db, pStr1, 0); @@ -89016,21 +101615,27 @@ static void exprAnalyze( if( noCase ){ /* The point is to increment the last character before the first ** wildcard. But if we increment '@', that will push it into the - ** alphabetic range where case conversions will mess up the + ** alphabetic range where case conversions will mess up the ** inequality. To avoid this, make sure to also run the full ** LIKE on all candidate expressions by clearing the isComplete flag */ - if( c=='A'-1 ) isComplete = 0; + if( c=='A'-1 ) isComplete = 0; /* EV: R-64339-08207 */ + c = sqlite3UpperToLower[c]; } *pC = c + 1; } - pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprDup(db,pLeft,0),pStr1,0); + pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, noCase ? "NOCASE" : "BINARY",0); + pNewExpr1 = sqlite3PExpr(pParse, TK_GE, + sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl), + pStr1, 0); idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew1==0 ); exprAnalyze(pSrc, pWC, idxNew1); - pNewExpr2 = sqlite3PExpr(pParse, TK_LT, sqlite3ExprDup(db,pLeft,0),pStr2,0); + pNewExpr2 = sqlite3PExpr(pParse, TK_LT, + sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl), + pStr2, 0); idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew2==0 ); exprAnalyze(pSrc, pWC, idxNew2); @@ -89062,7 +101667,7 @@ static void exprAnalyze( prereqColumn = exprTableUsage(pMaskSet, pLeft); if( (prereqExpr & prereqColumn)==0 ){ Expr *pNewExpr; - pNewExpr = sqlite3PExpr(pParse, TK_MATCH, + pNewExpr = sqlite3PExpr(pParse, TK_MATCH, 0, sqlite3ExprDup(db, pRight, 0), 0); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); @@ -89080,6 +101685,47 @@ static void exprAnalyze( } #endif /* SQLITE_OMIT_VIRTUALTABLE */ +#ifdef SQLITE_ENABLE_STAT2 + /* When sqlite_stat2 histogram data is available an operator of the + ** form "x IS NOT NULL" can sometimes be evaluated more efficiently + ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a + ** virtual term of that form. + ** + ** Note that the virtual term must be tagged with TERM_VNULL. This + ** TERM_VNULL tag will suppress the not-null check at the beginning + ** of the loop. Without the TERM_VNULL flag, the not-null check at + ** the start of the loop will prevent any results from being returned. + */ + if( pExpr->op==TK_NOTNULL + && pExpr->pLeft->op==TK_COLUMN + && pExpr->pLeft->iColumn>=0 + ){ + Expr *pNewExpr; + Expr *pLeft = pExpr->pLeft; + int idxNew; + WhereTerm *pNewTerm; + + pNewExpr = sqlite3PExpr(pParse, TK_GT, + sqlite3ExprDup(db, pLeft, 0), + sqlite3PExpr(pParse, TK_NULL, 0, 0, 0), 0); + + idxNew = whereClauseInsert(pWC, pNewExpr, + TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); + if( idxNew ){ + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = 0; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->u.leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_GT; + pNewTerm->iParent = idxTerm; + pTerm = &pWC->a[idxTerm]; + pTerm->nChild = 1; + pTerm->wtFlags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; + } + } +#endif /* SQLITE_ENABLE_STAT2 */ + /* Prevent ON clause terms of a LEFT JOIN from being used to drive ** an index for tables to the left of the join. */ @@ -89105,6 +101751,162 @@ static int referencesOtherTables( return 0; } +/* +** This function searches the expression list passed as the second argument +** for an expression of type TK_COLUMN that refers to the same column and +** uses the same collation sequence as the iCol'th column of index pIdx. +** Argument iBase is the cursor number used for the table that pIdx refers +** to. +** +** If such an expression is found, its index in pList->a[] is returned. If +** no expression is found, -1 is returned. +*/ +static int findIndexCol( + Parse *pParse, /* Parse context */ + ExprList *pList, /* Expression list to search */ + int iBase, /* Cursor for table associated with pIdx */ + Index *pIdx, /* Index to match column of */ + int iCol /* Column of index to match */ +){ + int i; + const char *zColl = pIdx->azColl[iCol]; + + for(i=0; i<pList->nExpr; i++){ + Expr *p = pList->a[i].pExpr; + if( p->op==TK_COLUMN + && p->iColumn==pIdx->aiColumn[iCol] + && p->iTable==iBase + ){ + CollSeq *pColl = sqlite3ExprCollSeq(pParse, p); + if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){ + return i; + } + } + } + + return -1; +} + +/* +** This routine determines if pIdx can be used to assist in processing a +** DISTINCT qualifier. In other words, it tests whether or not using this +** index for the outer loop guarantees that rows with equal values for +** all expressions in the pDistinct list are delivered grouped together. +** +** For example, the query +** +** SELECT DISTINCT a, b, c FROM tbl WHERE a = ? +** +** can benefit from any index on columns "b" and "c". +*/ +static int isDistinctIndex( + Parse *pParse, /* Parsing context */ + WhereClause *pWC, /* The WHERE clause */ + Index *pIdx, /* The index being considered */ + int base, /* Cursor number for the table pIdx is on */ + ExprList *pDistinct, /* The DISTINCT expressions */ + int nEqCol /* Number of index columns with == */ +){ + Bitmask mask = 0; /* Mask of unaccounted for pDistinct exprs */ + int i; /* Iterator variable */ + + if( pIdx->zName==0 || pDistinct==0 || pDistinct->nExpr>=BMS ) return 0; + testcase( pDistinct->nExpr==BMS-1 ); + + /* Loop through all the expressions in the distinct list. If any of them + ** are not simple column references, return early. Otherwise, test if the + ** WHERE clause contains a "col=X" clause. If it does, the expression + ** can be ignored. If it does not, and the column does not belong to the + ** same table as index pIdx, return early. Finally, if there is no + ** matching "col=X" expression and the column is on the same table as pIdx, + ** set the corresponding bit in variable mask. + */ + for(i=0; i<pDistinct->nExpr; i++){ + WhereTerm *pTerm; + Expr *p = pDistinct->a[i].pExpr; + if( p->op!=TK_COLUMN ) return 0; + pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0); + if( pTerm ){ + Expr *pX = pTerm->pExpr; + CollSeq *p1 = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); + CollSeq *p2 = sqlite3ExprCollSeq(pParse, p); + if( p1==p2 ) continue; + } + if( p->iTable!=base ) return 0; + mask |= (((Bitmask)1) << i); + } + + for(i=nEqCol; mask && i<pIdx->nColumn; i++){ + int iExpr = findIndexCol(pParse, pDistinct, base, pIdx, i); + if( iExpr<0 ) break; + mask &= ~(((Bitmask)1) << iExpr); + } + + return (mask==0); +} + + +/* +** Return true if the DISTINCT expression-list passed as the third argument +** is redundant. A DISTINCT list is redundant if the database contains a +** UNIQUE index that guarantees that the result of the query will be distinct +** anyway. +*/ +static int isDistinctRedundant( + Parse *pParse, + SrcList *pTabList, + WhereClause *pWC, + ExprList *pDistinct +){ + Table *pTab; + Index *pIdx; + int i; + int iBase; + + /* If there is more than one table or sub-select in the FROM clause of + ** this query, then it will not be possible to show that the DISTINCT + ** clause is redundant. */ + if( pTabList->nSrc!=1 ) return 0; + iBase = pTabList->a[0].iCursor; + pTab = pTabList->a[0].pTab; + + /* If any of the expressions is an IPK column on table iBase, then return + ** true. Note: The (p->iTable==iBase) part of this test may be false if the + ** current SELECT is a correlated sub-query. + */ + for(i=0; i<pDistinct->nExpr; i++){ + Expr *p = pDistinct->a[i].pExpr; + if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1; + } + + /* Loop through all indices on the table, checking each to see if it makes + ** the DISTINCT qualifier redundant. It does so if: + ** + ** 1. The index is itself UNIQUE, and + ** + ** 2. All of the columns in the index are either part of the pDistinct + ** list, or else the WHERE clause contains a term of the form "col=X", + ** where X is a constant value. The collation sequences of the + ** comparison and select-list expressions must match those of the index. + */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->onError==OE_None ) continue; + for(i=0; i<pIdx->nColumn; i++){ + int iCol = pIdx->aiColumn[i]; + if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) + && 0>findIndexCol(pParse, pDistinct, iBase, pIdx, i) + ){ + break; + } + } + if( i==pIdx->nColumn ){ + /* This index implies that the DISTINCT qualifier is redundant. */ + return 1; + } + } + + return 0; +} /* ** This routine decides if pIdx can be used to satisfy the ORDER BY @@ -89132,6 +101934,7 @@ static int isSortingIndex( int base, /* Cursor number for the table to be sorted */ ExprList *pOrderBy, /* The ORDER BY clause */ int nEqCol, /* Number of index columns with == constraints */ + int wsFlags, /* Index usages flags */ int *pbRev /* Set to 1 if ORDER BY is DESC */ ){ int i, j; /* Loop counters */ @@ -89140,11 +101943,14 @@ static int isSortingIndex( struct ExprList_item *pTerm; /* A term of the ORDER BY clause */ sqlite3 *db = pParse->db; - assert( pOrderBy!=0 ); + if( !pOrderBy ) return 0; + if( wsFlags & WHERE_COLUMN_IN ) return 0; + if( pIdx->bUnordered ) return 0; + nTerm = pOrderBy->nExpr; assert( nTerm>0 ); - /* Argument pIdx must either point to a 'real' named index structure, + /* Argument pIdx must either point to a 'real' named index structure, ** or an index structure allocated on the stack by bestBtreeIndex() to ** represent the rowid index that is part of every table. */ assert( pIdx->zName || (pIdx->nColumn==1 && pIdx->aiColumn[0]==-1) ); @@ -89222,7 +102028,7 @@ static int isSortingIndex( if( iColumn<0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){ /* If the indexed column is the primary key and everything matches ** so far and none of the ORDER BY terms to the right reference other - ** tables in the join, then we are assured that the index can be used + ** tables in the join, then we are assured that the index can be used ** to sort because the primary key is unique and so none of the other ** columns will make any difference */ @@ -89237,11 +102043,14 @@ static int isSortingIndex( return 1; } if( pIdx->onError!=OE_None && i==pIdx->nColumn + && (wsFlags & WHERE_COLUMN_NULL)==0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){ /* All terms of this index match some prefix of the ORDER BY clause ** and the index is UNIQUE and no terms on the tail of the ORDER BY ** clause reference other tables in a join. If this is all true then - ** the order by clause is superfluous. */ + ** the order by clause is superfluous. Not that if the matching + ** condition is IS NULL then the result is not necessarily unique + ** even on a UNIQUE index, so disallow those cases. */ return 1; } return 0; @@ -89308,15 +102117,16 @@ static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){ #define TRACE_IDX_OUTPUTS(A) #endif -/* -** Required because bestIndex() is called by bestOrClauseIndex() +/* +** Required because bestIndex() is called by bestOrClauseIndex() */ static void bestIndex( - Parse*, WhereClause*, struct SrcList_item*, Bitmask, ExprList*, WhereCost*); + Parse*, WhereClause*, struct SrcList_item*, + Bitmask, Bitmask, ExprList*, WhereCost*); /* -** This routine attempts to find an scanning strategy that can be used -** to optimize an 'OR' expression that is part of a WHERE clause. +** This routine attempts to find an scanning strategy that can be used +** to optimize an 'OR' expression that is part of a WHERE clause. ** ** The table associated with FROM clause term pSrc may be either a ** regular B-Tree table or a virtual table. @@ -89325,7 +102135,8 @@ static void bestOrClauseIndex( Parse *pParse, /* The parsing context */ WhereClause *pWC, /* The WHERE clause */ struct SrcList_item *pSrc, /* The FROM clause term to search */ - Bitmask notReady, /* Mask of cursors that are not available */ + Bitmask notReady, /* Mask of cursors not available for indexing */ + Bitmask notValid, /* Cursors not available for any purpose */ ExprList *pOrderBy, /* The ORDER BY clause */ WhereCost *pCost /* Lowest cost query plan */ ){ @@ -89335,11 +102146,17 @@ static void bestOrClauseIndex( WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm]; /* End of pWC->a[] */ WhereTerm *pTerm; /* A single term of the WHERE clause */ + /* No OR-clause optimization allowed if the INDEXED BY or NOT INDEXED clauses + ** are used */ + if( pSrc->notIndexed || pSrc->pIndex!=0 ){ + return; + } + /* Search the WHERE clause terms for a usable WO_OR term. */ for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ - if( pTerm->eOperator==WO_OR + if( pTerm->eOperator==WO_OR && ((pTerm->prereqAll & ~maskSrc) & notReady)==0 - && (pTerm->u.pOrInfo->indexable & maskSrc)!=0 + && (pTerm->u.pOrInfo->indexable & maskSrc)!=0 ){ WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc; WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm]; @@ -89351,12 +102168,12 @@ static void bestOrClauseIndex( for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){ WhereCost sTermCost; - WHERETRACE(("... Multi-index OR testing for term %d of %d....\n", + WHERETRACE(("... Multi-index OR testing for term %d of %d....\n", (pOrTerm - pOrWC->a), (pTerm - pWC->a) )); if( pOrTerm->eOperator==WO_AND ){ WhereClause *pAndWC = &pOrTerm->u.pAndInfo->wc; - bestIndex(pParse, pAndWC, pSrc, notReady, 0, &sTermCost); + bestIndex(pParse, pAndWC, pSrc, notReady, notValid, 0, &sTermCost); }else if( pOrTerm->leftCursor==iCur ){ WhereClause tempWC; tempWC.pParse = pWC->pParse; @@ -89364,21 +102181,22 @@ static void bestOrClauseIndex( tempWC.op = TK_AND; tempWC.a = pOrTerm; tempWC.nTerm = 1; - bestIndex(pParse, &tempWC, pSrc, notReady, 0, &sTermCost); + bestIndex(pParse, &tempWC, pSrc, notReady, notValid, 0, &sTermCost); }else{ continue; } rTotal += sTermCost.rCost; - nRow += sTermCost.nRow; + nRow += sTermCost.plan.nRow; used |= sTermCost.used; if( rTotal>=pCost->rCost ) break; } - /* If there is an ORDER BY clause, increase the scan cost to account + /* If there is an ORDER BY clause, increase the scan cost to account ** for the cost of the sort. */ if( pOrderBy!=0 ){ + WHERETRACE(("... sorting increases OR cost %.9g to %.9g\n", + rTotal, rTotal+nRow*estLog(nRow))); rTotal += nRow*estLog(nRow); - WHERETRACE(("... sorting increases OR cost to %.9g\n", rTotal)); } /* If the cost of scanning using this OR term for optimization is @@ -89387,8 +102205,8 @@ static void bestOrClauseIndex( WHERETRACE(("... multi-index OR cost=%.9g nrow=%.9g\n", rTotal, nRow)); if( rTotal<pCost->rCost ){ pCost->rCost = rTotal; - pCost->nRow = nRow; pCost->used = used; + pCost->plan.nRow = nRow; pCost->plan.wsFlags = flags; pCost->plan.u.pTerm = pTerm; } @@ -89397,14 +102215,262 @@ static void bestOrClauseIndex( #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ } +#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 +** index existed. +*/ +static int termCanDriveIndex( + WhereTerm *pTerm, /* WHERE clause term to check */ + struct SrcList_item *pSrc, /* Table we are trying to access */ + Bitmask notReady /* Tables in outer loops of the join */ +){ + char aff; + if( pTerm->leftCursor!=pSrc->iCursor ) return 0; + if( pTerm->eOperator!=WO_EQ ) return 0; + if( (pTerm->prereqRight & notReady)!=0 ) return 0; + aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity; + if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; + return 1; +} +#endif + +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX +/* +** If the query plan for pSrc specified in pCost is a full table scan +** and indexing is allows (if there is no NOT INDEXED clause) and it +** possible to construct a transient index that would perform better +** than a full table scan even when the cost of constructing the index +** is taken into account, then alter the query plan to use the +** transient index. +*/ +static void bestAutomaticIndex( + Parse *pParse, /* The parsing context */ + WhereClause *pWC, /* The WHERE clause */ + struct SrcList_item *pSrc, /* The FROM clause term to search */ + Bitmask notReady, /* Mask of cursors that are not available */ + WhereCost *pCost /* Lowest cost query plan */ +){ + double nTableRow; /* Rows in the input table */ + double logN; /* log(nTableRow) */ + double costTempIdx; /* per-query cost of the transient index */ + WhereTerm *pTerm; /* A single term of the WHERE clause */ + WhereTerm *pWCEnd; /* End of pWC->a[] */ + Table *pTable; /* Table tht might be indexed */ + + if( pParse->nQueryLoop<=(double)1 ){ + /* There is no point in building an automatic index for a single scan */ + return; + } + if( (pParse->db->flags & SQLITE_AutoIndex)==0 ){ + /* Automatic indices are disabled at run-time */ + return; + } + if( (pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){ + /* We already have some kind of index in use for this query. */ + return; + } + if( pSrc->notIndexed ){ + /* The NOT INDEXED clause appears in the SQL. */ + return; + } + if( pSrc->isCorrelated ){ + /* The source is a correlated sub-query. No point in indexing it. */ + return; + } + + assert( pParse->nQueryLoop >= (double)1 ); + pTable = pSrc->pTab; + nTableRow = pTable->nRowEst; + logN = estLog(nTableRow); + costTempIdx = 2*logN*(nTableRow/pParse->nQueryLoop + 1); + if( costTempIdx>=pCost->rCost ){ + /* The cost of creating the transient table would be greater than + ** doing the full table scan */ + return; + } + + /* Search for any equality comparison term */ + pWCEnd = &pWC->a[pWC->nTerm]; + for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ + if( termCanDriveIndex(pTerm, pSrc, notReady) ){ + WHERETRACE(("auto-index reduces cost from %.1f to %.1f\n", + pCost->rCost, costTempIdx)); + pCost->rCost = costTempIdx; + pCost->plan.nRow = logN + 1; + pCost->plan.wsFlags = WHERE_TEMP_INDEX; + pCost->used = pTerm->prereqRight; + break; + } + } +} +#else +# define bestAutomaticIndex(A,B,C,D,E) /* no-op */ +#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ + + +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX +/* +** 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. +*/ +static void constructAutomaticIndex( + Parse *pParse, /* The parsing context */ + WhereClause *pWC, /* The WHERE clause */ + struct SrcList_item *pSrc, /* The FROM clause term to get the next index */ + Bitmask notReady, /* Mask of cursors that are not available */ + WhereLevel *pLevel /* Write new index here */ +){ + int nColumn; /* Number of columns in the constructed index */ + WhereTerm *pTerm; /* A single term of the WHERE clause */ + WhereTerm *pWCEnd; /* End of pWC->a[] */ + int nByte; /* Byte of memory needed for pIdx */ + Index *pIdx; /* Object describing the transient index */ + Vdbe *v; /* Prepared statement under construction */ + int regIsInit; /* Register set by initialization */ + int addrInit; /* Address of the initialization bypass jump */ + Table *pTable; /* The table being indexed */ + KeyInfo *pKeyinfo; /* Key information for the index */ + int addrTop; /* Top of the index fill loop */ + int regRecord; /* Register holding an index record */ + int n; /* Column counter */ + int i; /* Loop counter */ + int mxBitCol; /* Maximum column in pSrc->colUsed */ + CollSeq *pColl; /* Collating sequence to on a column */ + Bitmask idxCols; /* Bitmap of columns used for indexing */ + Bitmask extraCols; /* Bitmap of additional columns */ + + /* 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 ); + regIsInit = ++pParse->nMem; + addrInit = sqlite3VdbeAddOp1(v, OP_Once, regIsInit); + + /* Count the number of columns that will be added to the index + ** and used to match WHERE clause constraints */ + nColumn = 0; + pTable = pSrc->pTab; + pWCEnd = &pWC->a[pWC->nTerm]; + idxCols = 0; + for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ + if( termCanDriveIndex(pTerm, pSrc, notReady) ){ + int iCol = pTerm->u.leftColumn; + Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol; + testcase( iCol==BMS ); + testcase( iCol==BMS-1 ); + if( (idxCols & cMask)==0 ){ + nColumn++; + idxCols |= cMask; + } + } + } + assert( nColumn>0 ); + pLevel->plan.nEq = nColumn; + + /* Count the number of additional columns needed to create a + ** covering index. A "covering index" is an index that contains all + ** columns that are needed by the query. With a covering index, the + ** original table never needs to be accessed. Automatic indices must + ** be a covering index because the index will not be updated if the + ** original table changes and the index and table cannot both be used + ** if they go out of sync. + */ + extraCols = pSrc->colUsed & (~idxCols | (((Bitmask)1)<<(BMS-1))); + mxBitCol = (pTable->nCol >= BMS-1) ? BMS-1 : pTable->nCol; + testcase( pTable->nCol==BMS-1 ); + testcase( pTable->nCol==BMS-2 ); + for(i=0; i<mxBitCol; i++){ + if( extraCols & (((Bitmask)1)<<i) ) nColumn++; + } + if( pSrc->colUsed & (((Bitmask)1)<<(BMS-1)) ){ + nColumn += pTable->nCol - BMS + 1; + } + pLevel->plan.wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WO_EQ; + + /* Construct the Index object to describe this index */ + nByte = sizeof(Index); + nByte += nColumn*sizeof(int); /* Index.aiColumn */ + nByte += nColumn*sizeof(char*); /* Index.azColl */ + nByte += nColumn; /* Index.aSortOrder */ + pIdx = sqlite3DbMallocZero(pParse->db, nByte); + if( pIdx==0 ) return; + pLevel->plan.u.pIdx = pIdx; + pIdx->azColl = (char**)&pIdx[1]; + pIdx->aiColumn = (int*)&pIdx->azColl[nColumn]; + pIdx->aSortOrder = (u8*)&pIdx->aiColumn[nColumn]; + pIdx->zName = "auto-index"; + pIdx->nColumn = nColumn; + pIdx->pTable = pTable; + n = 0; + idxCols = 0; + for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ + if( termCanDriveIndex(pTerm, pSrc, notReady) ){ + int iCol = pTerm->u.leftColumn; + Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol; + if( (idxCols & cMask)==0 ){ + Expr *pX = pTerm->pExpr; + idxCols |= cMask; + pIdx->aiColumn[n] = pTerm->u.leftColumn; + pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); + pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : "BINARY"; + n++; + } + } + } + assert( (u32)n==pLevel->plan.nEq ); + + /* Add additional columns needed to make the automatic index into + ** a covering index */ + for(i=0; i<mxBitCol; i++){ + if( extraCols & (((Bitmask)1)<<i) ){ + pIdx->aiColumn[n] = i; + pIdx->azColl[n] = "BINARY"; + n++; + } + } + if( pSrc->colUsed & (((Bitmask)1)<<(BMS-1)) ){ + for(i=BMS-1; i<pTable->nCol; i++){ + pIdx->aiColumn[n] = i; + pIdx->azColl[n] = "BINARY"; + n++; + } + } + assert( n==nColumn ); + + /* Create the automatic index */ + pKeyinfo = sqlite3IndexKeyinfo(pParse, pIdx); + assert( pLevel->iIdxCur>=0 ); + sqlite3VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nColumn+1, 0, + (char*)pKeyinfo, P4_KEYINFO_HANDOFF); + VdbeComment((v, "for %s", pTable->zName)); + + /* Fill the automatic index with content */ + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); + regRecord = sqlite3GetTempReg(pParse); + sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); + sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); + sqlite3VdbeJumpHere(v, addrTop); + sqlite3ReleaseTempReg(pParse, regRecord); + + /* Jump here when skipping the initialization */ + sqlite3VdbeJumpHere(v, addrInit); +} +#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ + #ifndef SQLITE_OMIT_VIRTUALTABLE /* -** Allocate and populate an sqlite3_index_info structure. It is the +** Allocate and populate an sqlite3_index_info structure. It is the ** responsibility of the caller to eventually release the structure ** by passing the pointer returned by this function to sqlite3_free(). */ static sqlite3_index_info *allocateIndexInfo( - Parse *pParse, + Parse *pParse, WhereClause *pWC, struct SrcList_item *pSrc, ExprList *pOrderBy @@ -89428,10 +102494,11 @@ static sqlite3_index_info *allocateIndexInfo( testcase( pTerm->eOperator==WO_IN ); testcase( pTerm->eOperator==WO_ISNULL ); if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue; + if( pTerm->wtFlags & TERM_VNULL ) continue; nTerm++; } - /* If the ORDER BY clause contains only columns in the current + /* If the ORDER BY clause contains only columns in the current ** virtual table then allocate space for the aOrderBy part of ** the sqlite3_index_info structure. */ @@ -89478,6 +102545,7 @@ static sqlite3_index_info *allocateIndexInfo( testcase( pTerm->eOperator==WO_IN ); testcase( pTerm->eOperator==WO_ISNULL ); if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue; + if( pTerm->wtFlags & TERM_VNULL ) continue; pIdxCons[j].iColumn = pTerm->u.leftColumn; pIdxCons[j].iTermOffset = i; pIdxCons[j].op = (u8)pTerm->eOperator; @@ -89535,12 +102603,12 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg); } } - sqlite3DbFree(pParse->db, pVtab->zErrMsg); + sqlite3_free(pVtab->zErrMsg); pVtab->zErrMsg = 0; for(i=0; i<p->nConstraint; i++){ if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "table %s: xBestIndex returned an invalid plan", pTab->zName); } } @@ -89561,7 +102629,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ ** same virtual table. The sqlite3_index_info structure is created ** and initialized on the first invocation and reused on all subsequent ** invocations. The sqlite3_index_info structure is also used when -** code is generated to access the virtual table. The whereInfoDelete() +** code is generated to access the virtual table. The whereInfoDelete() ** routine takes care of freeing the sqlite3_index_info structure after ** everybody has finished with it. */ @@ -89569,7 +102637,8 @@ static void bestVirtualIndex( Parse *pParse, /* The parsing context */ WhereClause *pWC, /* The WHERE clause */ struct SrcList_item *pSrc, /* The FROM clause term to search */ - Bitmask notReady, /* Mask of cursors that are not available */ + Bitmask notReady, /* Mask of cursors not available for index */ + Bitmask notValid, /* Cursors not valid for any purpose */ ExprList *pOrderBy, /* The order by clause */ WhereCost *pCost, /* Lowest cost query plan */ sqlite3_index_info **ppIdxInfo /* Index information passed to xBestIndex */ @@ -89581,8 +102650,9 @@ static void bestVirtualIndex( WhereTerm *pTerm; int i, j; int nOrderBy; + double rCost; - /* Make sure wsFlags is initialized to some sane value. Otherwise, if the + /* Make sure wsFlags is initialized to some sane value. Otherwise, if the ** malloc in allocateIndexInfo() fails and this function returns leaving ** wsFlags in an uninitialized state, the caller may behave unpredictably. */ @@ -89609,12 +102679,12 @@ static void bestVirtualIndex( /* The module name must be defined. Also, by this point there must ** be a pointer to an sqlite3_vtab structure. Otherwise - ** sqlite3ViewGetColumnNames() would have picked up the error. + ** sqlite3ViewGetColumnNames() would have picked up the error. */ assert( pTab->azModuleArg && pTab->azModuleArg[0] ); assert( sqlite3GetVTable(pParse->db, pTab) ); - /* Set the aConstraint[].usable fields and initialize all + /* Set the aConstraint[].usable fields and initialize all ** output variables to zero. ** ** aConstraint[].usable is true for constraints where the right-hand @@ -89623,7 +102693,7 @@ static void bestVirtualIndex( ** ** column = expr ** - ** and we are evaluating a join, then the constraint on column is + ** and we are evaluating a join, then the constraint on column is ** only valid if all tables referenced in expr occur to the left ** of the table containing column. ** @@ -89667,17 +102737,26 @@ static void bestVirtualIndex( } } + /* If there is an ORDER BY clause, and the selected virtual table index + ** does not satisfy it, increase the cost of the scan accordingly. This + ** matches the processing for non-virtual tables in bestBtreeIndex(). + */ + rCost = pIdxInfo->estimatedCost; + if( pOrderBy && pIdxInfo->orderByConsumed==0 ){ + rCost += estLog(rCost)*rCost; + } + /* The cost is not allowed to be larger than SQLITE_BIG_DBL (the ** inital value of lowestCost in this loop. If it is, then the ** (cost<lowestCost) test below will never be true. - ** - ** Use "(double)2" instead of "2.0" in case OMIT_FLOATING_POINT + ** + ** Use "(double)2" instead of "2.0" in case OMIT_FLOATING_POINT ** is defined. */ - if( (SQLITE_BIG_DBL/((double)2))<pIdxInfo->estimatedCost ){ + if( (SQLITE_BIG_DBL/((double)2))<rCost ){ pCost->rCost = (SQLITE_BIG_DBL/((double)2)); }else{ - pCost->rCost = pIdxInfo->estimatedCost; + pCost->rCost = rCost; } pCost->plan.u.pVtabIdx = pIdxInfo; if( pIdxInfo->orderByConsumed ){ @@ -89687,22 +102766,29 @@ static void bestVirtualIndex( pIdxInfo->nOrderBy = nOrderBy; /* Try to find a more efficient access pattern by using multiple indexes - ** to optimize an OR expression within the WHERE clause. + ** to optimize an OR expression within the WHERE clause. */ - bestOrClauseIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost); + bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost); } #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* ** Argument pIdx is a pointer to an index structure that has an array of ** SQLITE_INDEX_SAMPLES evenly spaced samples of the first indexed column -** stored in Index.aSample. The domain of values stored in said column -** may be thought of as divided into (SQLITE_INDEX_SAMPLES+1) regions. -** Region 0 contains all values smaller than the first sample value. Region -** 1 contains values larger than or equal to the value of the first sample, -** but smaller than the value of the second. And so on. -** -** If successful, this function determines which of the regions value +** stored in Index.aSample. These samples divide the domain of values stored +** the index into (SQLITE_INDEX_SAMPLES+1) regions. +** Region 0 contains all values less than the first sample value. Region +** 1 contains values between the first and second samples. Region 2 contains +** values between samples 2 and 3. And so on. Region SQLITE_INDEX_SAMPLES +** contains values larger than the last sample. +** +** If the index contains many duplicates of a single value, then it is +** possible that two or more adjacent samples can hold the same value. +** When that is the case, the smallest possible region code is returned +** when roundUp is false and the largest possible region code is returned +** when roundUp is true. +** +** If successful, this function determines which of the regions value ** pVal lies in, sets *piRegion to the region index (a value between 0 ** and SQLITE_INDEX_SAMPLES+1, inclusive) and returns SQLITE_OK. ** Or, if an OOM occurs while converting text values between encodings, @@ -89713,8 +102799,10 @@ static int whereRangeRegion( Parse *pParse, /* Database connection */ Index *pIdx, /* Index to consider domain of */ sqlite3_value *pVal, /* Value to consider */ + int roundUp, /* Return largest valid region if true */ int *piRegion /* OUT: Region of domain in which value lies */ ){ + assert( roundUp==0 || roundUp==1 ); if( ALWAYS(pVal) ){ IndexSample *aSample = pIdx->aSample; int i = 0; @@ -89724,9 +102812,19 @@ static int whereRangeRegion( double r = sqlite3_value_double(pVal); for(i=0; i<SQLITE_INDEX_SAMPLES; i++){ if( aSample[i].eType==SQLITE_NULL ) continue; - if( aSample[i].eType>=SQLITE_TEXT || aSample[i].u.r>r ) break; + if( aSample[i].eType>=SQLITE_TEXT ) break; + if( roundUp ){ + if( aSample[i].u.r>r ) break; + }else{ + if( aSample[i].u.r>=r ) break; + } } - }else{ + }else if( eType==SQLITE_NULL ){ + i = 0; + if( roundUp ){ + while( i<SQLITE_INDEX_SAMPLES && aSample[i].eType==SQLITE_NULL ) i++; + } + }else{ sqlite3 *db = pParse->db; CollSeq *pColl; const u8 *z; @@ -89755,7 +102853,7 @@ static int whereRangeRegion( n = sqlite3ValueBytes(pVal, pColl->enc); for(i=0; i<SQLITE_INDEX_SAMPLES; i++){ - int r; + int c; int eSampletype = aSample[i].eType; if( eSampletype==SQLITE_NULL || eSampletype<eType ) continue; if( (eSampletype!=eType) ) break; @@ -89769,14 +102867,14 @@ static int whereRangeRegion( assert( db->mallocFailed ); return SQLITE_NOMEM; } - r = pColl->xCmp(pColl->pUser, nSample, zSample, n, z); + c = pColl->xCmp(pColl->pUser, nSample, zSample, n, z); sqlite3DbFree(db, zSample); }else #endif { - r = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z); + c = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z); } - if( r>0 ) break; + if( c-roundUp>=0 ) break; } } @@ -89790,8 +102888,8 @@ static int whereRangeRegion( /* ** If expression pExpr represents a literal value, set *pp to point to ** an sqlite3_value structure containing the same value, with affinity -** aff applied to it, before returning. It is the responsibility of the -** caller to eventually release this structure by passing it to +** aff applied to it, before returning. It is the responsibility of the +** caller to eventually release this structure by passing it to ** sqlite3ValueFree(). ** ** If the current parse is a recompile (sqlite3Reprepare()) and pExpr @@ -89805,17 +102903,16 @@ static int whereRangeRegion( */ #ifdef SQLITE_ENABLE_STAT2 static int valueFromExpr( - Parse *pParse, - Expr *pExpr, - u8 aff, + Parse *pParse, + Expr *pExpr, + u8 aff, sqlite3_value **pp ){ - /* The evalConstExpr() function will have already converted any TK_VARIABLE - ** expression involved in an comparison into a TK_REGISTER. */ - assert( pExpr->op!=TK_VARIABLE ); - if( pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE ){ + if( pExpr->op==TK_VARIABLE + || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) + ){ int iVar = pExpr->iColumn; - sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); + sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); /* IMP: R-23257-02778 */ *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff); return SQLITE_OK; } @@ -89860,9 +102957,9 @@ static int valueFromExpr( ** constraints. ** ** In the absence of sqlite_stat2 ANALYZE data, each range inequality -** reduces the search space by 2/3rds. Hence a single constraint (x>?) -** results in a return of 33 and a range constraint (x>? AND x<?) results -** in a return of 11. +** reduces the search space by 3/4ths. Hence a single constraint (x>?) +** results in a return of 25 and a range constraint (x>? AND x<?) results +** in a return of 6. */ static int whereRangeScanEst( Parse *pParse, /* Parsing & code generating context */ @@ -89882,15 +102979,21 @@ static int whereRangeScanEst( int iEst; int iLower = 0; int iUpper = SQLITE_INDEX_SAMPLES; + int roundUpUpper = 0; + int roundUpLower = 0; u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity; if( pLower ){ Expr *pExpr = pLower->pExpr->pRight; rc = valueFromExpr(pParse, pExpr, aff, &pLowerVal); + assert( pLower->eOperator==WO_GT || pLower->eOperator==WO_GE ); + roundUpLower = (pLower->eOperator==WO_GT) ?1:0; } if( rc==SQLITE_OK && pUpper ){ Expr *pExpr = pUpper->pExpr->pRight; rc = valueFromExpr(pParse, pExpr, aff, &pUpperVal); + assert( pUpper->eOperator==WO_LT || pUpper->eOperator==WO_LE ); + roundUpUpper = (pUpper->eOperator==WO_LE) ?1:0; } if( rc!=SQLITE_OK || (pLowerVal==0 && pUpperVal==0) ){ @@ -89898,28 +103001,29 @@ static int whereRangeScanEst( sqlite3ValueFree(pUpperVal); goto range_est_fallback; }else if( pLowerVal==0 ){ - rc = whereRangeRegion(pParse, p, pUpperVal, &iUpper); + rc = whereRangeRegion(pParse, p, pUpperVal, roundUpUpper, &iUpper); if( pLower ) iLower = iUpper/2; }else if( pUpperVal==0 ){ - rc = whereRangeRegion(pParse, p, pLowerVal, &iLower); + rc = whereRangeRegion(pParse, p, pLowerVal, roundUpLower, &iLower); if( pUpper ) iUpper = (iLower + SQLITE_INDEX_SAMPLES + 1)/2; }else{ - rc = whereRangeRegion(pParse, p, pUpperVal, &iUpper); + rc = whereRangeRegion(pParse, p, pUpperVal, roundUpUpper, &iUpper); if( rc==SQLITE_OK ){ - rc = whereRangeRegion(pParse, p, pLowerVal, &iLower); + rc = whereRangeRegion(pParse, p, pLowerVal, roundUpLower, &iLower); } } + WHERETRACE(("range scan regions: %d..%d\n", iLower, iUpper)); iEst = iUpper - iLower; testcase( iEst==SQLITE_INDEX_SAMPLES ); assert( iEst<=SQLITE_INDEX_SAMPLES ); if( iEst<1 ){ - iEst = 1; + *piEst = 50/SQLITE_INDEX_SAMPLES; + }else{ + *piEst = (iEst*100)/SQLITE_INDEX_SAMPLES; } - sqlite3ValueFree(pLowerVal); sqlite3ValueFree(pUpperVal); - *piEst = (iEst * 100)/SQLITE_INDEX_SAMPLES; return rc; } range_est_fallback: @@ -89929,22 +103033,156 @@ range_est_fallback: UNUSED_PARAMETER(nEq); #endif assert( pLower || pUpper ); - if( pLower && pUpper ){ - *piEst = 11; + *piEst = 100; + if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *piEst /= 4; + if( pUpper ) *piEst /= 4; + return rc; +} + +#ifdef SQLITE_ENABLE_STAT2 +/* +** Estimate the number of rows that will be returned based on +** an equality constraint x=VALUE and where that VALUE occurs in +** the histogram data. This only works when x is the left-most +** column of an index and sqlite_stat2 histogram data is available +** for that index. When pExpr==NULL that means the constraint is +** "x IS NULL" instead of "x=VALUE". +** +** Write the estimated row count into *pnRow and return SQLITE_OK. +** If unable to make an estimate, leave *pnRow unchanged and return +** non-zero. +** +** This routine can fail if it is unable to load a collating sequence +** required for string comparison, or if unable to allocate memory +** for a UTF conversion required for comparison. The error is stored +** in the pParse structure. +*/ +static int whereEqualScanEst( + Parse *pParse, /* Parsing & code generating context */ + Index *p, /* The index whose left-most column is pTerm */ + Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */ + double *pnRow /* Write the revised row estimate here */ +){ + sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */ + int iLower, iUpper; /* Range of histogram regions containing pRhs */ + u8 aff; /* Column affinity */ + int rc; /* Subfunction return code */ + double nRowEst; /* New estimate of the number of rows */ + + assert( p->aSample!=0 ); + aff = p->pTable->aCol[p->aiColumn[0]].affinity; + if( pExpr ){ + rc = valueFromExpr(pParse, pExpr, aff, &pRhs); + if( rc ) goto whereEqualScanEst_cancel; + }else{ + pRhs = sqlite3ValueNew(pParse->db); + } + if( pRhs==0 ) return SQLITE_NOTFOUND; + rc = whereRangeRegion(pParse, p, pRhs, 0, &iLower); + if( rc ) goto whereEqualScanEst_cancel; + rc = whereRangeRegion(pParse, p, pRhs, 1, &iUpper); + if( rc ) goto whereEqualScanEst_cancel; + WHERETRACE(("equality scan regions: %d..%d\n", iLower, iUpper)); + if( iLower>=iUpper ){ + nRowEst = p->aiRowEst[0]/(SQLITE_INDEX_SAMPLES*2); + if( nRowEst<*pnRow ) *pnRow = nRowEst; }else{ - *piEst = 33; + nRowEst = (iUpper-iLower)*p->aiRowEst[0]/SQLITE_INDEX_SAMPLES; + *pnRow = nRowEst; + } + +whereEqualScanEst_cancel: + sqlite3ValueFree(pRhs); + return rc; +} +#endif /* defined(SQLITE_ENABLE_STAT2) */ + +#ifdef SQLITE_ENABLE_STAT2 +/* +** Estimate the number of rows that will be returned based on +** an IN constraint where the right-hand side of the IN operator +** is a list of values. Example: +** +** WHERE x IN (1,2,3,4) +** +** Write the estimated row count into *pnRow and return SQLITE_OK. +** If unable to make an estimate, leave *pnRow unchanged and return +** non-zero. +** +** This routine can fail if it is unable to load a collating sequence +** required for string comparison, or if unable to allocate memory +** for a UTF conversion required for comparison. The error is stored +** in the pParse structure. +*/ +static int whereInScanEst( + Parse *pParse, /* Parsing & code generating context */ + Index *p, /* The index whose left-most column is pTerm */ + ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ + double *pnRow /* Write the revised row estimate here */ +){ + sqlite3_value *pVal = 0; /* One value from list */ + int iLower, iUpper; /* Range of histogram regions containing pRhs */ + u8 aff; /* Column affinity */ + int rc = SQLITE_OK; /* Subfunction return code */ + double nRowEst; /* New estimate of the number of rows */ + int nSpan = 0; /* Number of histogram regions spanned */ + int nSingle = 0; /* Histogram regions hit by a single value */ + int nNotFound = 0; /* Count of values that are not constants */ + int i; /* Loop counter */ + u8 aSpan[SQLITE_INDEX_SAMPLES+1]; /* Histogram regions that are spanned */ + u8 aSingle[SQLITE_INDEX_SAMPLES+1]; /* Histogram regions hit once */ + + assert( p->aSample!=0 ); + aff = p->pTable->aCol[p->aiColumn[0]].affinity; + memset(aSpan, 0, sizeof(aSpan)); + memset(aSingle, 0, sizeof(aSingle)); + for(i=0; i<pList->nExpr; i++){ + sqlite3ValueFree(pVal); + rc = valueFromExpr(pParse, pList->a[i].pExpr, aff, &pVal); + if( rc ) break; + if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){ + nNotFound++; + continue; + } + rc = whereRangeRegion(pParse, p, pVal, 0, &iLower); + if( rc ) break; + rc = whereRangeRegion(pParse, p, pVal, 1, &iUpper); + if( rc ) break; + if( iLower>=iUpper ){ + aSingle[iLower] = 1; + }else{ + assert( iLower>=0 && iUpper<=SQLITE_INDEX_SAMPLES ); + while( iLower<iUpper ) aSpan[iLower++] = 1; + } + } + if( rc==SQLITE_OK ){ + for(i=nSpan=0; i<=SQLITE_INDEX_SAMPLES; i++){ + if( aSpan[i] ){ + nSpan++; + }else if( aSingle[i] ){ + nSingle++; + } + } + nRowEst = (nSpan*2+nSingle)*p->aiRowEst[0]/(2*SQLITE_INDEX_SAMPLES) + + nNotFound*p->aiRowEst[1]; + if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0]; + *pnRow = nRowEst; + WHERETRACE(("IN row estimate: nSpan=%d, nSingle=%d, nNotFound=%d, est=%g\n", + nSpan, nSingle, nNotFound, nRowEst)); } + sqlite3ValueFree(pVal); return rc; } +#endif /* defined(SQLITE_ENABLE_STAT2) */ /* -** Find the query plan for accessing a particular table. Write the +** Find the best query plan for accessing a particular table. Write the ** best query plan and its cost into the WhereCost object supplied as the ** last parameter. ** ** The lowest cost plan wins. The cost is an estimate of the amount of -** CPU and disk I/O need to process the request using the selected plan. +** CPU and disk I/O needed to process the requested result. ** Factors that influence cost include: ** ** * The estimated number of rows that will be retrieved. (The @@ -89956,22 +103194,24 @@ range_est_fallback: ** index and in the main table. ** ** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in -** the SQL statement, then this function only considers plans using the +** the SQL statement, then this function only considers plans using the ** named index. If no such plan is found, then the returned cost is -** SQLITE_BIG_DBL. If a plan is found that uses the named index, +** SQLITE_BIG_DBL. If a plan is found that uses the named index, ** then the cost is calculated in the usual way. ** -** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table -** in the SELECT statement, then no indexes are considered. However, the -** selected plan may still take advantage of the tables built-in rowid +** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table +** in the SELECT statement, then no indexes are considered. However, the +** selected plan may still take advantage of the built-in rowid primary key ** index. */ static void bestBtreeIndex( Parse *pParse, /* The parsing context */ WhereClause *pWC, /* The WHERE clause */ struct SrcList_item *pSrc, /* The FROM clause term to search */ - Bitmask notReady, /* Mask of cursors that are not available */ + Bitmask notReady, /* Mask of cursors not available for indexing */ + Bitmask notValid, /* Cursors not available for any purpose */ ExprList *pOrderBy, /* The ORDER BY clause */ + ExprList *pDistinct, /* The select-list if query is DISTINCT */ WhereCost *pCost /* Lowest cost query plan */ ){ int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */ @@ -90005,30 +103245,25 @@ static void bestBtreeIndex( wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE); eqTermMask = idxEqTermMask; }else{ - /* There is no INDEXED BY clause. Create a fake Index object to - ** represent the primary key */ - Index *pFirst; /* Any other index on the table */ + /* There is no INDEXED BY clause. Create a fake Index object in local + ** variable sPk to represent the rowid primary key index. Make this + ** fake index the first in a chain of Index objects with all of the real + ** indices to follow */ + Index *pFirst; /* First of real indices on the table */ memset(&sPk, 0, sizeof(Index)); sPk.nColumn = 1; sPk.aiColumn = &aiColumnPk; sPk.aiRowEst = aiRowEstPk; - aiRowEstPk[1] = 1; sPk.onError = OE_Replace; sPk.pTable = pSrc->pTab; + aiRowEstPk[0] = pSrc->pTab->nRowEst; + aiRowEstPk[1] = 1; pFirst = pSrc->pTab->pIndex; if( pSrc->notIndexed==0 ){ + /* The real indices of the table are only considered if the + ** NOT INDEXED qualifier is omitted from the FROM clause */ sPk.pNext = pFirst; } - /* The aiRowEstPk[0] is an estimate of the total number of rows in the - ** table. Get this information from the ANALYZE information if it is - ** available. If not available, assume the table 1 million rows in size. - */ - if( pFirst ){ - assert( pFirst->aiRowEst!=0 ); /* Allocated together with pFirst */ - aiRowEstPk[0] = pFirst->aiRowEst[0]; - }else{ - aiRowEstPk[0] = 1000000; - } pProbe = &sPk; wsFlagMask = ~( WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE @@ -90043,26 +103278,29 @@ static void bestBtreeIndex( const unsigned int * const aiRowEst = pProbe->aiRowEst; double cost; /* Cost of using pProbe */ double nRow; /* Estimated number of rows in result set */ + double log10N; /* base-10 logarithm of nRow (inexact) */ int rev; /* True to scan in reverse order */ int wsFlags = 0; Bitmask used = 0; /* The following variables are populated based on the properties of - ** scan being evaluated. They are then used to determine the expected + ** index being evaluated. They are then used to determine the expected ** cost and number of rows returned. ** - ** nEq: + ** nEq: ** Number of equality terms that can be implemented using the index. + ** In other words, the number of initial fields in the index that + ** are used in == or IN or NOT NULL constraints of the WHERE clause. ** - ** nInMul: - ** The "in-multiplier". This is an estimate of how many seek operations - ** SQLite must perform on the index in question. For example, if the + ** nInMul: + ** The "in-multiplier". This is an estimate of how many seek operations + ** SQLite must perform on the index in question. For example, if the ** WHERE clause is: ** ** WHERE a IN (1, 2, 3) AND b IN (4, 5, 6) ** - ** SQLite must perform 9 lookups on an index on (a, b), so nInMul is - ** set to 9. Given the same schema and either of the following WHERE + ** SQLite must perform 9 lookups on an index on (a, b), so nInMul is + ** set to 9. Given the same schema and either of the following WHERE ** clauses: ** ** WHERE a = 1 @@ -90070,50 +103308,60 @@ static void bestBtreeIndex( ** ** nInMul is set to 1. ** - ** If there exists a WHERE term of the form "x IN (SELECT ...)", then - ** the sub-select is assumed to return 25 rows for the purposes of + ** If there exists a WHERE term of the form "x IN (SELECT ...)", then + ** the sub-select is assumed to return 25 rows for the purposes of ** determining nInMul. ** - ** bInEst: - ** Set to true if there was at least one "x IN (SELECT ...)" term used - ** in determining the value of nInMul. + ** bInEst: + ** Set to true if there was at least one "x IN (SELECT ...)" term used + ** in determining the value of nInMul. Note that the RHS of the + ** IN operator must be a SELECT, not a value list, for this variable + ** to be true. ** - ** nBound: + ** estBound: ** An estimate on the amount of the table that must be searched. A ** value of 100 means the entire table is searched. Range constraints ** might reduce this to a value less than 100 to indicate that only ** a fraction of the table needs searching. In the absence of ** sqlite_stat2 ANALYZE data, a single inequality reduces the search - ** space to 1/3rd its original size. So an x>? constraint reduces - ** nBound to 33. Two constraints (x>? AND x<?) reduce nBound to 11. + ** space to 1/4rd its original size. So an x>? constraint reduces + ** estBound to 25. Two constraints (x>? AND x<?) reduce estBound to 6. ** - ** bSort: - ** Boolean. True if there is an ORDER BY clause that will require an - ** external sort (i.e. scanning the index being evaluated will not + ** bSort: + ** Boolean. True if there is an ORDER BY clause that will require an + ** external sort (i.e. scanning the index being evaluated will not ** correctly order records). ** - ** bLookup: - ** Boolean. True if for each index entry visited a lookup on the - ** corresponding table b-tree is required. This is always false - ** for the rowid index. For other indexes, it is true unless all the - ** columns of the table used by the SELECT statement are present in - ** the index (such an index is sometimes described as a covering index). - ** For example, given the index on (a, b), the second of the following - ** two queries requires table b-tree lookups, but the first does not. + ** bLookup: + ** Boolean. True if a table lookup is required for each index entry + ** visited. In other words, true if this is not a covering index. + ** This is always false for the rowid primary key index of a table. + ** For other indexes, it is true unless all the columns of the table + ** used by the SELECT statement are present in the index (such an + ** index is sometimes described as a covering index). + ** For example, given the index on (a, b), the second of the following + ** two queries requires table b-tree lookups in order to find the value + ** of column c, but the first does not because columns a and b are + ** both available in the index. ** ** SELECT a, b FROM tbl WHERE a = 1; ** SELECT a, b, c FROM tbl WHERE a = 1; */ - int nEq; - int bInEst = 0; - int nInMul = 1; - int nBound = 100; - int bSort = 0; - int bLookup = 0; + int nEq; /* Number of == or IN terms matching index */ + int bInEst = 0; /* True if "x IN (SELECT...)" seen */ + int nInMul = 1; /* Number of distinct equalities to lookup */ + int estBound = 100; /* Estimated reduction in search space */ + int nBound = 0; /* Number of range constraints seen */ + int bSort = !!pOrderBy; /* True if external sort required */ + int bDist = !!pDistinct; /* True if index cannot help with DISTINCT */ + int bLookup = 0; /* True if not a covering index */ + WhereTerm *pTerm; /* A single term of the WHERE clause */ +#ifdef SQLITE_ENABLE_STAT2 + WhereTerm *pFirstTerm = 0; /* First term matching the index */ +#endif /* Determine the values of nEq and nInMul */ for(nEq=0; nEq<pProbe->nColumn; nEq++){ - WhereTerm *pTerm; /* A single term of the WHERE clause */ int j = pProbe->aiColumn[nEq]; pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx); if( pTerm==0 ) break; @@ -90122,29 +103370,36 @@ static void bestBtreeIndex( Expr *pExpr = pTerm->pExpr; wsFlags |= WHERE_COLUMN_IN; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + /* "x IN (SELECT ...)": Assume the SELECT returns 25 rows */ nInMul *= 25; bInEst = 1; - }else if( pExpr->x.pList ){ - nInMul *= pExpr->x.pList->nExpr + 1; + }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ + /* "x IN (value, value, ...)" */ + nInMul *= pExpr->x.pList->nExpr; } }else if( pTerm->eOperator & WO_ISNULL ){ wsFlags |= WHERE_COLUMN_NULL; } +#ifdef SQLITE_ENABLE_STAT2 + if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm; +#endif used |= pTerm->prereqRight; } - /* Determine the value of nBound. */ - if( nEq<pProbe->nColumn ){ + /* Determine the value of estBound. */ + if( nEq<pProbe->nColumn && pProbe->bUnordered==0 ){ int j = pProbe->aiColumn[nEq]; if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){ WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx); WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx); - whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &nBound); + whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &estBound); if( pTop ){ + nBound = 1; wsFlags |= WHERE_TOP_LIMIT; used |= pTop->prereqRight; } if( pBtm ){ + nBound++; wsFlags |= WHERE_BTM_LIMIT; used |= pBtm->prereqRight; } @@ -90162,20 +103417,25 @@ static void bestBtreeIndex( ** naturally scan rows in the required order, set the appropriate flags ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index ** will scan rows in a different order, set the bSort variable. */ - if( pOrderBy ){ - if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 - && isSortingIndex(pParse,pWC->pMaskSet,pProbe,iCur,pOrderBy,nEq,&rev) - ){ - wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY; - wsFlags |= (rev ? WHERE_REVERSE : 0); - }else{ - bSort = 1; - } + if( isSortingIndex( + pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy, nEq, wsFlags, &rev) + ){ + bSort = 0; + wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY; + wsFlags |= (rev ? WHERE_REVERSE : 0); + } + + /* If there is a DISTINCT qualifier and this index will scan rows in + ** order of the DISTINCT expressions, clear bDist and set the appropriate + ** flags in wsFlags. */ + if( isDistinctIndex(pParse, pWC, pProbe, iCur, pDistinct, nEq) ){ + bDist = 0; + wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_DISTINCT; } /* If currently calculating the cost of using an index (not the IPK - ** index), determine if all required column data may be obtained without - ** seeking to entries in the main table (i.e. if the index is a covering + ** index), determine if all required column data may be obtained without + ** using the main table (i.e. if the index is a covering ** index for this query). If it is, set the WHERE_IDX_ONLY flag in ** wsFlags. Otherwise, set the bLookup variable to true. */ if( pIdx && wsFlags ){ @@ -90194,10 +103454,9 @@ static void bestBtreeIndex( } } - /**** Begin adding up the cost of using this index (Needs improvements) - ** - ** Estimate the number of rows of output. For an IN operator, - ** do not let the estimate exceed half the rows in the table. + /* + ** Estimate the number of rows of output. For an "x IN (SELECT...)" + ** constraint, do not let the estimate exceed half the rows in the table. */ nRow = (double)(aiRowEst[nEq] * nInMul); if( bInEst && nRow*2>aiRowEst[0] ){ @@ -90205,47 +103464,172 @@ static void bestBtreeIndex( nInMul = (int)(nRow / aiRowEst[nEq]); } - /* Assume constant cost to access a row and logarithmic cost to - ** do a binary search. Hence, the initial cost is the number of output - ** rows plus log2(table-size) times the number of binary searches. +#ifdef SQLITE_ENABLE_STAT2 + /* If the constraint is of the form x=VALUE or x IN (E1,E2,...) + ** and we do not think that values of x are unique and if histogram + ** data is available for column x, then it might be possible + ** to get a better estimate on the number of rows based on + ** VALUE and how common that value is according to the histogram. */ - cost = nRow + nInMul*estLog(aiRowEst[0]); + if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 && aiRowEst[1]>1 ){ + if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){ + testcase( pFirstTerm->eOperator==WO_EQ ); + testcase( pFirstTerm->eOperator==WO_ISNULL ); + whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow); + }else if( pFirstTerm->eOperator==WO_IN && bInEst==0 ){ + whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow); + } + } +#endif /* SQLITE_ENABLE_STAT2 */ - /* Adjust the number of rows and the cost downward to reflect rows + /* Adjust the number of output rows and downward to reflect rows ** that are excluded by range constraints. */ - nRow = (nRow * (double)nBound) / (double)100; - cost = (cost * (double)nBound) / (double)100; + nRow = (nRow * (double)estBound) / (double)100; + if( nRow<1 ) nRow = 1; + + /* Experiments run on real SQLite databases show that the time needed + ** to do a binary search to locate a row in a table or index is roughly + ** log10(N) times the time to move from one row to the next row within + ** a table or index. The actual times can vary, with the size of + ** records being an important factor. Both moves and searches are + ** slower with larger records, presumably because fewer records fit + ** on one page and hence more pages have to be fetched. + ** + ** The ANALYZE command and the sqlite_stat1 and sqlite_stat2 tables do + ** not give us data on the relative sizes of table and index records. + ** So this computation assumes table records are about twice as big + ** as index records + */ + if( (wsFlags & WHERE_NOT_FULLSCAN)==0 ){ + /* The cost of a full table scan is a number of move operations equal + ** to the number of rows in the table. + ** + ** We add an additional 4x penalty to full table scans. This causes + ** the cost function to err on the side of choosing an index over + ** choosing a full scan. This 4x full-scan penalty is an arguable + ** decision and one which we expect to revisit in the future. But + ** it seems to be working well enough at the moment. + */ + cost = aiRowEst[0]*4; + }else{ + log10N = estLog(aiRowEst[0]); + cost = nRow; + if( pIdx ){ + if( bLookup ){ + /* For an index lookup followed by a table lookup: + ** nInMul index searches to find the start of each index range + ** + nRow steps through the index + ** + nRow table searches to lookup the table entry using the rowid + */ + cost += (nInMul + nRow)*log10N; + }else{ + /* For a covering index: + ** nInMul index searches to find the initial entry + ** + nRow steps through the index + */ + cost += nInMul*log10N; + } + }else{ + /* For a rowid primary key lookup: + ** nInMult table searches to find the initial entry for each range + ** + nRow steps through the table + */ + cost += nInMul*log10N; + } + } - /* Add in the estimated cost of sorting the result + /* Add in the estimated cost of sorting the result. Actual experimental + ** measurements of sorting performance in SQLite show that sorting time + ** adds C*N*log10(N) to the cost, where N is the number of rows to be + ** sorted and C is a factor between 1.95 and 4.3. We will split the + ** difference and select C of 3.0. */ if( bSort ){ - cost += cost*estLog(cost); + cost += nRow*estLog(nRow)*3; + } + if( bDist ){ + cost += nRow*estLog(nRow)*3; } - /* If all information can be taken directly from the index, we avoid - ** doing table lookups. This reduces the cost by half. (Not really - - ** this needs to be fixed.) + /**** Cost of using this index has now been computed ****/ + + /* If there are additional constraints on this table that cannot + ** be used with the current index, but which might lower the number + ** of output rows, adjust the nRow value accordingly. This only + ** matters if the current index is the least costly, so do not bother + ** with this step if we already know this index will not be chosen. + ** Also, never reduce the output row count below 2 using this step. + ** + ** It is critical that the notValid mask be used here instead of + ** the notReady mask. When computing an "optimal" index, the notReady + ** mask will only have one bit set - the bit for the current table. + ** The notValid mask, on the other hand, always has all bits set for + ** tables that are not in outer loops. If notReady is used here instead + ** of notValid, then a optimal index that depends on inner joins loops + ** might be selected even when there exists an optimal index that has + ** no such dependency. */ - if( pIdx && bLookup==0 ){ - cost /= (double)2; + if( nRow>2 && cost<=pCost->rCost ){ + int k; /* Loop counter */ + int nSkipEq = nEq; /* Number of == constraints to skip */ + int nSkipRange = nBound; /* Number of < constraints to skip */ + Bitmask thisTab; /* Bitmap for pSrc */ + + thisTab = getMask(pWC->pMaskSet, iCur); + for(pTerm=pWC->a, k=pWC->nTerm; nRow>2 && k; k--, pTerm++){ + if( pTerm->wtFlags & TERM_VIRTUAL ) continue; + if( (pTerm->prereqAll & notValid)!=thisTab ) continue; + if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){ + if( nSkipEq ){ + /* Ignore the first nEq equality matches since the index + ** has already accounted for these */ + nSkipEq--; + }else{ + /* Assume each additional equality match reduces the result + ** set size by a factor of 10 */ + nRow /= 10; + } + }else if( pTerm->eOperator & (WO_LT|WO_LE|WO_GT|WO_GE) ){ + if( nSkipRange ){ + /* Ignore the first nSkipRange range constraints since the index + ** has already accounted for these */ + nSkipRange--; + }else{ + /* Assume each additional range constraint reduces the result + ** set size by a factor of 3. Indexed range constraints reduce + ** the search space by a larger factor: 4. We make indexed range + ** more selective intentionally because of the subjective + ** observation that indexed range constraints really are more + ** selective in practice, on average. */ + nRow /= 3; + } + }else if( pTerm->eOperator!=WO_NOOP ){ + /* Any other expression lowers the output row count by half */ + nRow /= 2; + } + } + if( nRow<2 ) nRow = 2; } - /**** Cost of using this index has now been computed ****/ + WHERETRACE(( - "tbl=%s idx=%s nEq=%d nInMul=%d nBound=%d bSort=%d bLookup=%d" - " wsFlags=%d (nRow=%.2f cost=%.2f)\n", - pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), - nEq, nInMul, nBound, bSort, bLookup, wsFlags, nRow, cost + "%s(%s): nEq=%d nInMul=%d estBound=%d bSort=%d bLookup=%d wsFlags=0x%x\n" + " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n", + pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), + nEq, nInMul, estBound, bSort, bLookup, wsFlags, + notReady, log10N, nRow, cost, used )); /* If this index is the best we have seen so far, then record this ** index and its cost in the pCost structure. */ - if( (!pIdx || wsFlags) && cost<pCost->rCost ){ + if( (!pIdx || wsFlags) + && (cost<pCost->rCost || (cost<=pCost->rCost && nRow<pCost->plan.nRow)) + ){ pCost->rCost = cost; - pCost->nRow = nRow; pCost->used = used; + pCost->plan.nRow = nRow; pCost->plan.wsFlags = (wsFlags&wsFlagMask); pCost->plan.nEq = nEq; pCost->plan.u.pIdx = pIdx; @@ -90271,22 +103655,24 @@ static void bestBtreeIndex( assert( pOrderBy || (pCost->plan.wsFlags&WHERE_ORDERBY)==0 ); assert( pCost->plan.u.pIdx==0 || (pCost->plan.wsFlags&WHERE_ROWID_EQ)==0 ); - assert( pSrc->pIndex==0 - || pCost->plan.u.pIdx==0 - || pCost->plan.u.pIdx==pSrc->pIndex + assert( pSrc->pIndex==0 + || pCost->plan.u.pIdx==0 + || pCost->plan.u.pIdx==pSrc->pIndex ); - WHERETRACE(("best index is: %s\n", - (pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk") + WHERETRACE(("best index is: %s\n", + ((pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ? "none" : + pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk") )); - - bestOrClauseIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost); + + bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost); + bestAutomaticIndex(pParse, pWC, pSrc, notReady, pCost); pCost->plan.wsFlags |= eqTermMask; } /* ** Find the query plan for accessing table pSrc->pTab. Write the -** best query plan and its cost into the WhereCost object supplied +** best query plan and its cost into the WhereCost object supplied ** as the last parameter. This function may calculate the cost of ** both real and virtual table scans. */ @@ -90294,14 +103680,15 @@ static void bestIndex( Parse *pParse, /* The parsing context */ WhereClause *pWC, /* The WHERE clause */ struct SrcList_item *pSrc, /* The FROM clause term to search */ - Bitmask notReady, /* Mask of cursors that are not available */ + Bitmask notReady, /* Mask of cursors not available for indexing */ + Bitmask notValid, /* Cursors not available for any purpose */ ExprList *pOrderBy, /* The ORDER BY clause */ WhereCost *pCost /* Lowest cost query plan */ ){ #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pSrc->pTab) ){ sqlite3_index_info *p = 0; - bestVirtualIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost, &p); + bestVirtualIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost,&p); if( p->needToFreeIdxStr ){ sqlite3_free(p->idxStr); } @@ -90309,7 +103696,7 @@ static void bestIndex( }else #endif { - bestBtreeIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost); + bestBtreeIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, 0, pCost); } } @@ -90328,6 +103715,9 @@ static void bestIndex( ** in the ON clause. The term is disabled in (3) because it is not part ** of a LEFT OUTER JOIN. In (1), the term is not disabled. ** +** IMPLEMENTATION-OF: R-24597-58655 No tests are done for terms that are +** completely satisfied by indices. +** ** Disabling a term causes that term to not be tested in the inner loop ** of the join. Disabling is an optimization. When terms are satisfied ** by indices, we disable them to prevent redundant tests in the inner @@ -90338,7 +103728,7 @@ static void bestIndex( */ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ if( pTerm - && ALWAYS((pTerm->wtFlags & TERM_CODED)==0) + && (pTerm->wtFlags & TERM_CODED)==0 && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) ){ pTerm->wtFlags |= TERM_CODED; @@ -90353,7 +103743,7 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ /* ** Code an OP_Affinity opcode to apply the column affinity string zAff -** to the n registers starting at base. +** to the n registers starting at base. ** ** As an optimization, SQLITE_AFF_NONE entries (which are no-ops) at the ** beginning and end of zAff are ignored. If all entries in zAff are @@ -90393,7 +103783,7 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ /* ** Generate code for a single equality term of the WHERE clause. An equality -** term can be either X=expr or X IN (...). pTerm is the term to be +** term can be either X=expr or X IN (...). pTerm is the term to be ** coded. ** ** The current value for the constraint is left in register iReg. @@ -90463,7 +103853,7 @@ static int codeEqualityTerm( ** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c). ** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10 ** The index has as many as three equality constraints, but in this -** example, the third "c" value is an inequality. So only two +** example, the third "c" value is an inequality. So only two ** constraints are coded. This routine will generate code to evaluate ** a==5 and b IN (1,2,3). The current values for a and b will be stored ** in consecutive registers and the index of the first register is returned. @@ -90536,7 +103926,10 @@ static int codeAllEqualityTerms( int k = pIdx->aiColumn[j]; pTerm = findTerm(pWC, iCur, k, notReady, pLevel->plan.wsFlags, pIdx); if( NEVER(pTerm==0) ) break; - assert( (pTerm->wtFlags & TERM_CODED)==0 ); + /* The following true for indices with redundant columns. + ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */ + testcase( (pTerm->wtFlags & TERM_CODED)!=0 ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j); if( r1!=regBase+j ){ if( nReg==1 ){ @@ -90565,6 +103958,161 @@ static int codeAllEqualityTerms( return regBase; } +#ifndef SQLITE_OMIT_EXPLAIN +/* +** This routine is a helper for explainIndexRange() below +** +** pStr holds the text of an expression that we are building up one term +** at a time. This routine adds a new term to the end of the expression. +** Terms are separated by AND so add the "AND" text for second and subsequent +** terms only. +*/ +static void explainAppendTerm( + StrAccum *pStr, /* The text expression being built */ + int iTerm, /* Index of this term. First is zero */ + const char *zColumn, /* Name of the column */ + const char *zOp /* Name of the operator */ +){ + if( iTerm ) sqlite3StrAccumAppend(pStr, " AND ", 5); + sqlite3StrAccumAppend(pStr, zColumn, -1); + sqlite3StrAccumAppend(pStr, zOp, 1); + sqlite3StrAccumAppend(pStr, "?", 1); +} + +/* +** Argument pLevel describes a strategy for scanning table pTab. This +** function returns a pointer to a string buffer containing a description +** of the subset of table rows scanned by the strategy in the form of an +** SQL expression. Or, if all rows are scanned, NULL is returned. +** +** For example, if the query: +** +** SELECT * FROM t1 WHERE a=1 AND b>2; +** +** is run and there is an index on (a, b), then this function returns a +** string similar to: +** +** "a=? AND b>?" +** +** The returned pointer points to memory obtained from sqlite3DbMalloc(). +** It is the responsibility of the caller to free the buffer when it is +** no longer required. +*/ +static char *explainIndexRange(sqlite3 *db, WhereLevel *pLevel, Table *pTab){ + WherePlan *pPlan = &pLevel->plan; + Index *pIndex = pPlan->u.pIdx; + int nEq = pPlan->nEq; + int i, j; + Column *aCol = pTab->aCol; + int *aiColumn = pIndex->aiColumn; + StrAccum txt; + + if( nEq==0 && (pPlan->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){ + return 0; + } + sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH); + txt.db = db; + sqlite3StrAccumAppend(&txt, " (", 2); + for(i=0; i<nEq; i++){ + explainAppendTerm(&txt, i, aCol[aiColumn[i]].zName, "="); + } + + j = i; + if( pPlan->wsFlags&WHERE_BTM_LIMIT ){ + explainAppendTerm(&txt, i++, aCol[aiColumn[j]].zName, ">"); + } + if( pPlan->wsFlags&WHERE_TOP_LIMIT ){ + explainAppendTerm(&txt, i, aCol[aiColumn[j]].zName, "<"); + } + sqlite3StrAccumAppend(&txt, ")", 1); + return sqlite3StrAccumFinish(&txt); +} + +/* +** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN +** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single +** record is added to the output to describe the table scan strategy in +** pLevel. +*/ +static void explainOneScan( + Parse *pParse, /* Parse context */ + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + int iLevel, /* Value for "level" column of output */ + int iFrom, /* Value for "from" column of output */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +){ + if( pParse->explain==2 ){ + u32 flags = pLevel->plan.wsFlags; + struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; + Vdbe *v = pParse->pVdbe; /* VM being constructed */ + sqlite3 *db = pParse->db; /* Database handle */ + char *zMsg; /* Text to add to EQP output */ + sqlite3_int64 nRow; /* Expected number of rows visited by scan */ + int iId = pParse->iSelectId; /* Select id (left-most output column) */ + int isSearch; /* True for a SEARCH. False for SCAN. */ + + if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return; + + isSearch = (pLevel->plan.nEq>0) + || (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 + || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); + + zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN"); + if( pItem->pSelect ){ + zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId); + }else{ + zMsg = sqlite3MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName); + } + + if( pItem->zAlias ){ + zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias); + } + if( (flags & WHERE_INDEXED)!=0 ){ + char *zWhere = explainIndexRange(db, pLevel, pItem->pTab); + zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg, + ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""), + ((flags & WHERE_IDX_ONLY)?"COVERING ":""), + ((flags & WHERE_TEMP_INDEX)?"":" "), + ((flags & WHERE_TEMP_INDEX)?"": pLevel->plan.u.pIdx->zName), + zWhere + ); + sqlite3DbFree(db, zWhere); + }else if( flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ + zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg); + + if( flags&WHERE_ROWID_EQ ){ + zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg); + }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){ + zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg); + }else if( flags&WHERE_BTM_LIMIT ){ + zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg); + }else if( flags&WHERE_TOP_LIMIT ){ + zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg); + } + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ + sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx; + zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg, + pVtabIdx->idxNum, pVtabIdx->idxStr); + } +#endif + if( wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ){ + testcase( wctrlFlags & WHERE_ORDERBY_MIN ); + nRow = 1; + }else{ + nRow = (sqlite3_int64)pLevel->plan.nRow; + } + zMsg = sqlite3MAppendf(db, zMsg, "%s (~%lld rows)", zMsg, nRow); + sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC); + } +} +#else +# define explainOneScan(u,v,w,x,y,z) +#endif /* SQLITE_OMIT_EXPLAIN */ + + /* ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. @@ -90598,7 +104146,7 @@ static Bitmask codeOneLoopStart( pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; iCur = pTabItem->iCursor; bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0; - omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0 + omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0 && (wctrlFlags & WHERE_FORCE_TABLE)==0; /* Create labels for the "break" and "continue" instructions @@ -90680,6 +104228,7 @@ static Bitmask codeOneLoopStart( assert( pTerm->pExpr!=0 ); assert( pTerm->leftCursor==iCur ); assert( omitTable==0 ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, iReleaseReg); addrNxt = pLevel->addrNxt; sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); @@ -90707,7 +104256,7 @@ static Bitmask codeOneLoopStart( Expr *pX; /* The expression that defines the start bound */ int r1, rTemp; /* Registers for holding the start boundary */ - /* The following constant maps TK_xx codes into corresponding + /* The following constant maps TK_xx codes into corresponding ** seek opcodes. It depends on a particular ordering of TK_xx */ const u8 aMoveOp[] = { @@ -90720,6 +104269,7 @@ static Bitmask codeOneLoopStart( assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ assert( TK_GE==TK_GT+3 ); /* ... is correcct. */ + testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ pX = pStart->pExpr; assert( pX!=0 ); assert( pStart->leftCursor==iCur ); @@ -90737,6 +104287,7 @@ static Bitmask codeOneLoopStart( pX = pEnd->pExpr; assert( pX!=0 ); assert( pEnd->leftCursor==iCur ); + testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ memEndValue = ++pParse->nMem; sqlite3ExprCode(pParse, pX->pRight, memEndValue); if( pX->op==TK_LT || pX->op==TK_GT ){ @@ -90750,7 +104301,11 @@ static Bitmask codeOneLoopStart( pLevel->op = bRev ? OP_Prev : OP_Next; pLevel->p1 = iCur; pLevel->p2 = start; - pLevel->p5 = (pStart==0 && pEnd==0) ?1:0; + if( pStart==0 && pEnd==0 ){ + pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; + }else{ + assert( pLevel->p5==0 ); + } if( testOp!=OP_Noop ){ iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg); @@ -90761,14 +104316,14 @@ static Bitmask codeOneLoopStart( }else if( pLevel->plan.wsFlags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){ /* Case 3: A scan using an index. ** - ** The WHERE clause may contain zero or more equality + ** The WHERE clause may contain zero or more equality ** terms ("==" or "IN" operators) that refer to the N ** left-most columns of the index. It may also contain ** inequality constraints (>, <, >= or <=) on the indexed - ** column that immediately follows the N equalities. Only + ** column that immediately follows the N equalities. Only ** the right-most column can be an inequality - the rest must - ** use the "==" and "IN" operators. For example, if the - ** index is on (x,y,z), then the following clauses are all + ** use the "==" and "IN" operators. For example, if the + ** index is on (x,y,z), then the following clauses are all ** optimized: ** ** x=5 @@ -90789,8 +104344,8 @@ static Bitmask codeOneLoopStart( ** This case is also used when there are no WHERE clause ** constraints but an index is selected anyway, in order ** to force the output order to conform to an ORDER BY. - */ - int aStartOp[] = { + */ + static const u8 aStartOp[] = { 0, 0, OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */ @@ -90800,12 +104355,12 @@ static Bitmask codeOneLoopStart( OP_SeekGe, /* 6: (start_constraints && startEq && !bRev) */ OP_SeekLe /* 7: (start_constraints && startEq && bRev) */ }; - int aEndOp[] = { + static const u8 aEndOp[] = { OP_Noop, /* 0: (!end_constraints) */ OP_IdxGE, /* 1: (end_constraints && !bRev) */ OP_IdxLT /* 2: (end_constraints && bRev) */ }; - int nEq = pLevel->plan.nEq; + int nEq = pLevel->plan.nEq; /* Number of == or IN terms */ int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */ int regBase; /* Base register holding constraint values */ int r1; /* Temp register */ @@ -90815,18 +104370,19 @@ static Bitmask codeOneLoopStart( int endEq; /* True if range end uses ==, >= or <= */ int start_constraints; /* Start of range is constrained */ int nConstraint; /* Number of constraint terms */ - Index *pIdx; /* The index we will be using */ - int iIdxCur; /* The VDBE cursor for the index */ - int nExtraReg = 0; /* Number of extra registers needed */ - int op; /* Instruction opcode */ - char *zAff; + Index *pIdx; /* The index we will be using */ + int iIdxCur; /* The VDBE cursor for the index */ + int nExtraReg = 0; /* Number of extra registers needed */ + int op; /* Instruction opcode */ + char *zStartAff; /* Affinity for start of range constraint */ + char *zEndAff; /* Affinity for end of range constraint */ pIdx = pLevel->plan.u.pIdx; iIdxCur = pLevel->iIdxCur; k = pIdx->aiColumn[nEq]; /* Column for inequality constraints */ - /* If this loop satisfies a sort order (pOrderBy) request that - ** was passed to this function to implement a "SELECT min(x) ..." + /* If this loop satisfies a sort order (pOrderBy) request that + ** was passed to this function to implement a "SELECT min(x) ..." ** query, then the caller will only allow the loop to run for ** a single iteration. This means that the first row returned ** should not have a NULL value stored in 'x'. If column 'x' is @@ -90843,8 +104399,8 @@ static Bitmask codeOneLoopStart( nExtraReg = 1; } - /* Find any inequality constraint terms for the start and end - ** of the range. + /* Find any inequality constraint terms for the start and end + ** of the range. */ if( pLevel->plan.wsFlags & WHERE_TOP_LIMIT ){ pRangeEnd = findTerm(pWC, iCur, k, notReady, (WO_LT|WO_LE), pIdx); @@ -90860,15 +104416,16 @@ static Bitmask codeOneLoopStart( ** starting at regBase. */ regBase = codeAllEqualityTerms( - pParse, pLevel, pWC, notReady, nExtraReg, &zAff + pParse, pLevel, pWC, notReady, nExtraReg, &zStartAff ); + zEndAff = sqlite3DbStrDup(pParse->db, zStartAff); addrNxt = pLevel->addrNxt; /* If we are doing a reverse order scan on an ascending index, or - ** a forward order scan on a descending index, interchange the + ** a forward order scan on a descending index, interchange the ** start and end terms (pRangeStart and pRangeEnd). */ - if( bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){ + if( nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){ SWAP(WhereTerm *, pRangeEnd, pRangeStart); } @@ -90885,26 +104442,29 @@ static Bitmask codeOneLoopStart( if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; sqlite3ExprCode(pParse, pRight, regBase+nEq); - sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); - if( zAff ){ - if( sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE){ + if( (pRangeStart->wtFlags & TERM_VNULL)==0 ){ + sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); + } + if( zStartAff ){ + if( sqlite3CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_NONE){ /* Since the comparison is to be performed with no conversions - ** applied to the operands, set the affinity to apply to pRight to + ** applied to the operands, set the affinity to apply to pRight to ** SQLITE_AFF_NONE. */ - zAff[nConstraint] = SQLITE_AFF_NONE; + zStartAff[nEq] = SQLITE_AFF_NONE; } - if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[nConstraint]) ){ - zAff[nConstraint] = SQLITE_AFF_NONE; + if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){ + zStartAff[nEq] = SQLITE_AFF_NONE; } - } + } nConstraint++; + testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ }else if( isMinQuery ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); nConstraint++; startEq = 0; start_constraints = 1; } - codeApplyAffinity(pParse, regBase, nConstraint, zAff); + codeApplyAffinity(pParse, regBase, nConstraint, zStartAff); op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; assert( op!=0 ); testcase( op==OP_Rewind ); @@ -90923,22 +104483,26 @@ static Bitmask codeOneLoopStart( Expr *pRight = pRangeEnd->pExpr->pRight; sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); sqlite3ExprCode(pParse, pRight, regBase+nEq); - sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); - if( zAff ){ - if( sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE){ + if( (pRangeEnd->wtFlags & TERM_VNULL)==0 ){ + sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); + } + if( zEndAff ){ + if( sqlite3CompareAffinity(pRight, zEndAff[nEq])==SQLITE_AFF_NONE){ /* Since the comparison is to be performed with no conversions - ** applied to the operands, set the affinity to apply to pRight to + ** applied to the operands, set the affinity to apply to pRight to ** SQLITE_AFF_NONE. */ - zAff[nConstraint] = SQLITE_AFF_NONE; + zEndAff[nEq] = SQLITE_AFF_NONE; } - if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[nConstraint]) ){ - zAff[nConstraint] = SQLITE_AFF_NONE; + if( sqlite3ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){ + zEndAff[nEq] = SQLITE_AFF_NONE; } - } - codeApplyAffinity(pParse, regBase, nEq+1, zAff); + } + codeApplyAffinity(pParse, regBase, nEq+1, zEndAff); nConstraint++; + testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ } - sqlite3DbFree(pParse->db, zAff); + sqlite3DbFree(pParse->db, zStartAff); + sqlite3DbFree(pParse->db, zEndAff); /* Top of the loop body */ pLevel->p2 = sqlite3VdbeCurrentAddr(v); @@ -90960,7 +104524,7 @@ static Bitmask codeOneLoopStart( r1 = sqlite3GetTempReg(pParse); testcase( pLevel->plan.wsFlags & WHERE_BTM_LIMIT ); testcase( pLevel->plan.wsFlags & WHERE_TOP_LIMIT ); - if( pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT) ){ + if( (pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1); sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont); } @@ -90976,10 +104540,16 @@ static Bitmask codeOneLoopStart( sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */ } - /* Record the instruction used to terminate the loop. Disable + /* Record the instruction used to terminate the loop. Disable ** WHERE clause terms made redundant by the index range scan. */ - pLevel->op = bRev ? OP_Prev : OP_Next; + if( pLevel->plan.wsFlags & WHERE_UNIQUE ){ + pLevel->op = OP_Noop; + }else if( bRev ){ + pLevel->op = OP_Prev; + }else{ + pLevel->op = OP_Next; + } pLevel->p1 = iIdxCur; }else @@ -91025,7 +104595,6 @@ static Bitmask codeOneLoopStart( ** */ WhereClause *pOrWc; /* The OR-clause broken out into subterms */ - WhereTerm *pFinal; /* Final subterm within the OR-clause. */ SrcList *pOrTab; /* Shortened table list or OR-clause generation */ int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */ @@ -91035,13 +104604,12 @@ static Bitmask codeOneLoopStart( int iRetInit; /* Address of regReturn init */ int untestedTerms = 0; /* Some terms not completely tested */ int ii; - + pTerm = pLevel->plan.u.pTerm; assert( pTerm!=0 ); assert( pTerm->eOperator==WO_OR ); assert( (pTerm->wtFlags & TERM_ORINFO)!=0 ); pOrWc = &pTerm->u.pOrInfo->wc; - pFinal = &pOrWc->a[pOrWc->nTerm-1]; pLevel->op = OP_Return; pLevel->p1 = regReturn; @@ -91067,14 +104635,14 @@ static Bitmask codeOneLoopStart( pOrTab = pWInfo->pTabList; } - /* Initialize the rowset register to contain NULL. An SQL NULL is + /* Initialize the rowset register to contain NULL. An SQL NULL is ** equivalent to an empty rowset. ** - ** Also initialize regReturn to contain the address of the instruction + ** Also initialize regReturn to contain the address of the instruction ** immediately following the OP_Return at the bottom of the loop. This ** is required in a few obscure LEFT JOIN cases where control jumps - ** over the top of the loop into the body of it. In this case the - ** correct response for the end-of-loop code (the OP_Return) is to + ** over the top of the loop into the body of it. In this case the + ** correct response for the end-of-loop code (the OP_Return) is to ** fall through to the next instruction, just as an OP_Next does if ** called on an uninitialized cursor. */ @@ -91090,14 +104658,17 @@ static Bitmask codeOneLoopStart( if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){ WhereInfo *pSubWInfo; /* Info for single OR-term scan */ /* Loop through table entries that match term pOrTerm. */ - pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrTerm->pExpr, 0, + pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrTerm->pExpr, 0, 0, WHERE_OMIT_OPEN | WHERE_OMIT_CLOSE | WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY); if( pSubWInfo ){ + explainOneScan( + pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 + ); if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); int r; - r = sqlite3ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur, + r = sqlite3ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur, regRowid); sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, sqlite3VdbeCurrentAddr(v)+2, r, iSet); @@ -91142,11 +104713,14 @@ static Bitmask codeOneLoopStart( /* Insert code to test every subexpression that can be completely ** computed using the current set of tables. + ** + ** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through + ** the use of indices become tests that are evaluated against each row of + ** the relevant input tables. */ - k = 0; for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ Expr *pE; - testcase( pTerm->wtFlags & TERM_VIRTUAL ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */ testcase( pTerm->wtFlags & TERM_CODED ); if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( (pTerm->prereqAll & notReady)!=0 ){ @@ -91161,12 +104735,11 @@ static Bitmask codeOneLoopStart( continue; } sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); - k = 1; pTerm->wtFlags |= TERM_CODED; } /* For a LEFT OUTER JOIN, generate code that will record the fact that - ** at least one row of the right table has matched the left table. + ** at least one row of the right table has matched the left table. */ if( pLevel->iLeftJoin ){ pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); @@ -91174,7 +104747,7 @@ static Bitmask codeOneLoopStart( VdbeComment((v, "record LEFT JOIN hit")); sqlite3ExprCacheClear(pParse); for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){ - testcase( pTerm->wtFlags & TERM_VIRTUAL ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */ testcase( pTerm->wtFlags & TERM_CODED ); if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( (pTerm->prereqAll & notReady)!=0 ){ @@ -91208,7 +104781,7 @@ static int nQPlan = 0; /* Next free slow in _query_plan[] */ ** Free a WhereInfo structure */ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ - if( pWInfo ){ + if( ALWAYS(pWInfo) ){ int i; for(i=0; i<pWInfo->nLevel; i++){ sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo; @@ -91219,6 +104792,13 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ } sqlite3DbFree(db, pInfo); } + if( pWInfo->a[i].plan.wsFlags & WHERE_TEMP_INDEX ){ + Index *pIdx = pWInfo->a[i].plan.u.pIdx; + if( pIdx ){ + sqlite3DbFree(db, pIdx->zColAff); + sqlite3DbFree(db, pIdx); + } + } } whereClauseClear(pWInfo->pWC); sqlite3DbFree(db, pWInfo); @@ -91319,6 +104899,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( SrcList *pTabList, /* A list of all tables to be scanned */ Expr *pWhere, /* The WHERE clause */ ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */ + ExprList *pDistinct, /* The select-list for DISTINCT queries - or NULL */ u16 wctrlFlags /* One of the WHERE_* flags defined in sqliteInt.h */ ){ int i; /* Loop counter */ @@ -91336,14 +104917,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( sqlite3 *db; /* Database connection */ /* The number of tables in the FROM clause is limited by the number of - ** bits in a Bitmask + ** bits in a Bitmask */ + testcase( pTabList->nSrc==BMS ); if( pTabList->nSrc>BMS ){ sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS); return 0; } - /* This function normally generates a nested loop for all tables in + /* This function normally generates a nested loop for all tables in ** pTabList. But if the WHERE_ONETABLE_ONLY flag is set, then we should ** only generate code for the first table in pTabList and assume that ** any cursors associated with subsequent tables are uninitialized. @@ -91359,12 +104941,14 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( */ db = pParse->db; nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); - pWInfo = sqlite3DbMallocZero(db, - nByteWInfo + + pWInfo = sqlite3DbMallocZero(db, + nByteWInfo + sizeof(WhereClause) + sizeof(WhereMaskSet) ); if( db->mallocFailed ){ + sqlite3DbFree(db, pWInfo); + pWInfo = 0; goto whereBeginError; } pWInfo->nLevel = nTabList; @@ -91373,16 +104957,21 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( pWInfo->iBreak = sqlite3VdbeMakeLabel(v); pWInfo->pWC = pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo]; pWInfo->wctrlFlags = wctrlFlags; + pWInfo->savedNQueryLoop = pParse->nQueryLoop; pMaskSet = (WhereMaskSet*)&pWC[1]; + /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via + ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ + if( db->flags & SQLITE_DistinctOpt ) pDistinct = 0; + /* Split the WHERE clause into separate subexpressions where each ** subexpression is separated by an AND operator. */ initMaskSet(pMaskSet); whereClauseInit(pWC, pParse, pMaskSet); sqlite3ExprCodeConstants(pParse, pWhere); - whereSplit(pWC, pWhere, TK_AND); - + whereSplit(pWC, pWhere, TK_AND); /* IMP: R-15842-53296 */ + /* Special case: a WHERE clause that is constant. Evaluate the ** expression and either jump over all of the code or fall thru. */ @@ -91403,8 +104992,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** for all tables to the left of a left join is important. Ticket #3015. ** ** Configure the WhereClause.vmask variable so that bits that correspond - ** to virtual table cursors are set. This is used to selectively disable - ** the OR-to-IN transformation in exprAnalyzeOrTerm(). It is not helpful + ** to virtual table cursors are set. This is used to selectively disable + ** the OR-to-IN transformation in exprAnalyzeOrTerm(). It is not helpful ** with virtual tables. ** ** Note that bitmasks are created for all pTabList->nSrc tables in @@ -91442,6 +105031,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( goto whereBeginError; } + /* Check if the DISTINCT qualifier, if there is one, is redundant. + ** If it is, then set pDistinct to NULL and WhereInfo.eDistinct to + ** WHERE_DISTINCT_UNIQUE to tell the caller to ignore the DISTINCT. + */ + if( pDistinct && isDistinctRedundant(pParse, pTabList, pWC, pDistinct) ){ + pDistinct = 0; + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; + } + /* Chose the best index to use for each table in the FROM clause. ** ** This loop fills in the following fields: @@ -91458,8 +105056,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** clause. */ notReady = ~(Bitmask)0; - pTabItem = pTabList->a; - pLevel = pWInfo->a; andFlags = ~0; WHERETRACE(("*** Optimizer Start ***\n")); for(i=iFrom=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){ @@ -91469,50 +105065,66 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( int bestJ = -1; /* The value of j */ Bitmask m; /* Bitmask value for j or bestJ */ int isOptimal; /* Iterator for optimal/non-optimal search */ + int nUnconstrained; /* Number tables without INDEXED BY */ + Bitmask notIndexed; /* Mask of tables that cannot use an index */ memset(&bestPlan, 0, sizeof(bestPlan)); bestPlan.rCost = SQLITE_BIG_DBL; + WHERETRACE(("*** Begin search for loop %d ***\n", i)); /* Loop through the remaining entries in the FROM clause to find the - ** next nested loop. The FROM clause entries may be iterated through - ** either once or twice. + ** next nested loop. The loop tests all FROM clause entries + ** either once or twice. ** - ** The first iteration, which is always performed, searches for the - ** FROM clause entry that permits the lowest-cost, "optimal" scan. In + ** The first test is always performed if there are two or more entries + ** remaining and never performed if there is only one FROM clause entry + ** to choose from. The first test looks for an "optimal" scan. In ** this context an optimal scan is one that uses the same strategy ** for the given FROM clause entry as would be selected if the entry ** were used as the innermost nested loop. In other words, a table ** is chosen such that the cost of running that table cannot be reduced - ** by waiting for other tables to run first. + ** by waiting for other tables to run first. This "optimal" test works + ** by first assuming that the FROM clause is on the inner loop and finding + ** its query plan, then checking to see if that query plan uses any + ** other FROM clause terms that are notReady. If no notReady terms are + ** used then the "optimal" query plan works. + ** + ** Note that the WhereCost.nRow parameter for an optimal scan might + ** not be as small as it would be if the table really were the innermost + ** join. The nRow value can be reduced by WHERE clause constraints + ** that do not use indices. But this nRow reduction only happens if the + ** table really is the innermost join. ** - ** The second iteration is only performed if no optimal scan strategies - ** were found by the first. This iteration is used to search for the - ** lowest cost scan overall. + ** The second loop iteration is only performed if no optimal scan + ** strategies were found by the first iteration. This second iteration + ** is used to search for the lowest cost scan overall. ** ** Previous versions of SQLite performed only the second iteration - ** the next outermost loop was always that with the lowest overall ** cost. However, this meant that SQLite could select the wrong plan ** for scripts such as the following: - ** - ** CREATE TABLE t1(a, b); + ** + ** CREATE TABLE t1(a, b); ** CREATE TABLE t2(c, d); ** SELECT * FROM t2, t1 WHERE t2.rowid = t1.a; ** ** The best strategy is to iterate through table t1 first. However it ** is not possible to determine this with a simple greedy algorithm. - ** However, since the cost of a linear scan through table t2 is the same - ** as the cost of a linear scan through table t1, a simple greedy + ** Since the cost of a linear scan through table t2 is the same + ** as the cost of a linear scan through table t1, a simple greedy ** algorithm may choose to use t2 for the outer loop, which is a much ** costlier approach. */ - for(isOptimal=1; isOptimal>=0 && bestJ<0; isOptimal--){ - Bitmask mask = (isOptimal ? 0 : notReady); - assert( (nTabList-iFrom)>1 || isOptimal ); + nUnconstrained = 0; + notIndexed = 0; + for(isOptimal=(iFrom<nTabList-1); isOptimal>=0 && bestJ<0; isOptimal--){ + Bitmask mask; /* Mask of tables not yet ready */ for(j=iFrom, pTabItem=&pTabList->a[j]; j<nTabList; j++, pTabItem++){ int doNotReorder; /* True if this table should not be reordered */ WhereCost sCost; /* Cost information from best[Virtual]Index() */ ExprList *pOrderBy; /* ORDER BY clause for index to optimize */ - + ExprList *pDist; /* DISTINCT clause for index to optimize */ + doNotReorder = (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0; if( j!=iFrom && doNotReorder ) break; m = getMask(pMaskSet, pTabItem->iCursor); @@ -91520,23 +105132,70 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( j==iFrom ) iFrom++; continue; } + mask = (isOptimal ? m : notReady); pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0); - + pDist = (i==0 ? pDistinct : 0); + if( pTabItem->pIndex==0 ) nUnconstrained++; + + WHERETRACE(("=== trying table %d with isOptimal=%d ===\n", + j, isOptimal)); assert( pTabItem->pTab ); #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTabItem->pTab) ){ sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo; - bestVirtualIndex(pParse, pWC, pTabItem, mask, pOrderBy, &sCost, pp); - }else + bestVirtualIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy, + &sCost, pp); + }else #endif { - bestBtreeIndex(pParse, pWC, pTabItem, mask, pOrderBy, &sCost); + bestBtreeIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy, + pDist, &sCost); } assert( isOptimal || (sCost.used¬Ready)==0 ); - if( (sCost.used¬Ready)==0 - && (j==iFrom || sCost.rCost<bestPlan.rCost) + /* If an INDEXED BY clause is present, then the plan must use that + ** index if it uses any index at all */ + assert( pTabItem->pIndex==0 + || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 + || sCost.plan.u.pIdx==pTabItem->pIndex ); + + if( isOptimal && (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){ + notIndexed |= m; + } + + /* Conditions under which this table becomes the best so far: + ** + ** (1) The table must not depend on other tables that have not + ** yet run. + ** + ** (2) A full-table-scan plan cannot supercede indexed plan unless + ** the full-table-scan is an "optimal" plan as defined above. + ** + ** (3) All tables have an INDEXED BY clause or this table lacks an + ** INDEXED BY clause or this table uses the specific + ** index specified by its INDEXED BY clause. This rule ensures + ** that a best-so-far is always selected even if an impossible + ** combination of INDEXED BY clauses are given. The error + ** will be detected and relayed back to the application later. + ** The NEVER() comes about because rule (2) above prevents + ** An indexable full-table-scan from reaching rule (3). + ** + ** (4) The plan cost must be lower than prior plans or else the + ** cost must be the same and the number of rows must be lower. + */ + if( (sCost.used¬Ready)==0 /* (1) */ + && (bestJ<0 || (notIndexed&m)!=0 /* (2) */ + || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 + || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0) + && (nUnconstrained==0 || pTabItem->pIndex==0 /* (3) */ + || NEVER((sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)) + && (bestJ<0 || sCost.rCost<bestPlan.rCost /* (4) */ + || (sCost.rCost<=bestPlan.rCost + && sCost.plan.nRow<bestPlan.plan.nRow)) ){ + WHERETRACE(("=== table %d is best so far" + " with cost=%g and nRow=%g\n", + j, sCost.rCost, sCost.plan.nRow)); bestPlan = sCost; bestJ = j; } @@ -91545,20 +105204,30 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( } assert( bestJ>=0 ); assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) ); - WHERETRACE(("*** Optimizer selects table %d for loop %d\n", bestJ, - pLevel-pWInfo->a)); + WHERETRACE(("*** Optimizer selects table %d for loop %d" + " with cost=%g and nRow=%g\n", + bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow)); if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){ *ppOrderBy = 0; } + if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){ + assert( pWInfo->eDistinct==0 ); + pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; + } andFlags &= bestPlan.plan.wsFlags; pLevel->plan = bestPlan.plan; - if( bestPlan.plan.wsFlags & WHERE_INDEXED ){ + testcase( bestPlan.plan.wsFlags & WHERE_INDEXED ); + testcase( bestPlan.plan.wsFlags & WHERE_TEMP_INDEX ); + if( bestPlan.plan.wsFlags & (WHERE_INDEXED|WHERE_TEMP_INDEX) ){ pLevel->iIdxCur = pParse->nTab++; }else{ pLevel->iIdxCur = -1; } notReady &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor); pLevel->iFrom = (u8)bestJ; + if( bestPlan.plan.nRow>=(double)1 ){ + pParse->nQueryLoop *= bestPlan.plan.nRow; + } /* Check that if the table scanned by this loop iteration had an ** INDEXED BY clause attached to it, that the named index is being @@ -91605,43 +105274,20 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** searching those tables. */ sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */ + notReady = ~(Bitmask)0; + pWInfo->nRowOut = (double)1; for(i=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){ Table *pTab; /* Table to open */ int iDb; /* Index of database containing table/index */ -#ifndef SQLITE_OMIT_EXPLAIN - if( pParse->explain==2 ){ - char *zMsg; - struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; - zMsg = sqlite3MPrintf(db, "TABLE %s", pItem->zName); - if( pItem->zAlias ){ - zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias); - } - if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ - zMsg = sqlite3MAppendf(db, zMsg, "%s WITH INDEX %s", - zMsg, pLevel->plan.u.pIdx->zName); - }else if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){ - zMsg = sqlite3MAppendf(db, zMsg, "%s VIA MULTI-INDEX UNION", zMsg); - }else if( pLevel->plan.wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ - zMsg = sqlite3MAppendf(db, zMsg, "%s USING PRIMARY KEY", zMsg); - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - else if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){ - sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx; - zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg, - pVtabIdx->idxNum, pVtabIdx->idxStr); - } -#endif - if( pLevel->plan.wsFlags & WHERE_ORDERBY ){ - zMsg = sqlite3MAppendf(db, zMsg, "%s ORDER BY", zMsg); - } - sqlite3VdbeAddOp4(v, OP_Explain, i, pLevel->iFrom, 0, zMsg, P4_DYNAMIC); - } -#endif /* SQLITE_OMIT_EXPLAIN */ pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; + pLevel->iTabCur = pTabItem->iCursor; + pWInfo->nRowOut *= pLevel->plan.nRow; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ) continue; + if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){ + /* Do nothing */ + }else #ifndef SQLITE_OMIT_VIRTUALTABLE if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){ const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); @@ -91653,18 +105299,24 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( && (wctrlFlags & WHERE_OMIT_OPEN)==0 ){ int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead; sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op); + testcase( pTab->nCol==BMS-1 ); + testcase( pTab->nCol==BMS ); if( !pWInfo->okOnePass && pTab->nCol<BMS ){ Bitmask b = pTabItem->colUsed; int n = 0; for(; b; b=b>>1, n++){} - sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1, + sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1, SQLITE_INT_TO_PTR(n), P4_INT32); assert( n<=pTab->nCol ); } }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); } - pLevel->iTabCur = pTabItem->iCursor; +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX + if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){ + constructAutomaticIndex(pParse, pWC, pTabItem, notReady, pLevel); + }else +#endif if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ Index *pIx = pLevel->plan.u.pIdx; KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx); @@ -91676,8 +105328,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( VdbeComment((v, "%s", pIx->zName)); } sqlite3CodeVerifySchema(pParse, iDb); + notReady &= ~getMask(pWC->pMaskSet, pTabItem->iCursor); } pWInfo->iTop = sqlite3VdbeCurrentAddr(v); + if( db->mallocFailed ) goto whereBeginError; /* Generate the code to do the search. Each iteration of the for ** loop below generates code for a single nested loop of the VM @@ -91685,8 +105339,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( */ notReady = ~(Bitmask)0; for(i=0; i<nTabList; i++){ + pLevel = &pWInfo->a[i]; + explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags); notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady); - pWInfo->iContinue = pWInfo->a[i].addrCont; + pWInfo->iContinue = pLevel->addrCont; } #ifdef SQLITE_TEST /* For testing and debugging use only */ @@ -91745,12 +105401,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( /* Jump here if malloc fails */ whereBeginError: - whereInfoFree(db, pWInfo); + if( pWInfo ){ + pParse->nQueryLoop = pWInfo->savedNQueryLoop; + whereInfoFree(db, pWInfo); + } return 0; } /* -** Generate the end of the WHERE loop. See comments on +** Generate the end of the WHERE loop. See comments on ** sqlite3WhereBegin() for additional information. */ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ @@ -91815,12 +105474,15 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; Table *pTab = pTabItem->pTab; assert( pTab!=0 ); - if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ) continue; - if( (pWInfo->wctrlFlags & WHERE_OMIT_CLOSE)==0 ){ - if( !pWInfo->okOnePass && (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0 ){ + if( (pTab->tabFlags & TF_Ephemeral)==0 + && pTab->pSelect==0 + && (pWInfo->wctrlFlags & WHERE_OMIT_CLOSE)==0 + ){ + int ws = pLevel->plan.wsFlags; + if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){ sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); } - if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ + if( (ws & WHERE_INDEXED)!=0 && (ws & WHERE_TEMP_INDEX)==0 ){ sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); } } @@ -91831,7 +105493,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ ** as the vdbe level waits until the table is read before actually ** seeking the table cursor to the record corresponding to the current ** position in the index. - ** + ** ** Calls to the code generator in between sqlite3WhereBegin and ** sqlite3WhereEnd will have created code that references the table ** directly. This loop scans all that code looking for opcodes @@ -91868,6 +105530,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ /* Final cleanup */ + pParse->nQueryLoop = pWInfo->savedNQueryLoop; whereInfoFree(db, pWInfo); return; } @@ -91885,6 +105548,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ */ /* First off, code is included that follows the "include" declaration ** in the input grammar file. */ +/* #include <stdio.h> */ /* @@ -91979,7 +105643,7 @@ struct AttachKey { int type; Token key; }; pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0); pOut->zStart = pOperand->zStart; pOut->zEnd = &pPostOp->z[pPostOp->n]; - } + } /* A routine to convert a binary TK_IS or TK_ISNOT expression into a ** unary TK_ISNULL or TK_NOTNULL expression. */ @@ -92008,10 +105672,10 @@ struct AttachKey { int type; Token key; }; /* Next is all token values, in a form suitable for use by makeheaders. ** This section will be null unless lemon is run with the -m switch. */ -/* +/* ** These constants (all generated automatically by the parser generator) ** specify the various kinds of tokens (terminals) that the parser -** understands. +** understands. ** ** Each symbol here is a terminal symbol in the grammar. */ @@ -92028,7 +105692,7 @@ struct AttachKey { int type; Token key; }; ** and nonterminals. "int" is used otherwise. ** YYNOCODE is a number of type YYCODETYPE which corresponds ** to no legal terminal or nonterminal number. This -** number is used to fill in empty slots of the hash +** number is used to fill in empty slots of the hash ** table. ** YYFALLBACK If defined, this indicates that one or more tokens ** have fall-back values which should be used if the @@ -92037,7 +105701,7 @@ struct AttachKey { int type; Token key; }; ** and nonterminal numbers. "unsigned char" is ** used if there are fewer than 250 rules and ** states combined. "int" is used otherwise. -** sqlite3ParserTOKENTYPE is the data type used for minor tokens given +** sqlite3ParserTOKENTYPE is the data type used for minor tokens given ** directly to the parser from the tokenizer. ** YYMINORTYPE is the data type used for all minor tokens. ** This is typically a union of many types, one of @@ -92055,26 +105719,26 @@ struct AttachKey { int type; Token key; }; ** defined, then do no error processing. */ #define YYCODETYPE unsigned char -#define YYNOCODE 254 +#define YYNOCODE 253 #define YYACTIONTYPE unsigned short int #define YYWILDCARD 67 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; - Select* yy3; - ExprList* yy14; - SrcList* yy65; - struct LikeOp yy96; - Expr* yy132; - u8 yy186; - int yy328; - ExprSpan yy346; - struct TrigEvent yy378; - IdList* yy408; - struct {int value; int mask;} yy429; - TriggerStep* yy473; - struct LimitVal yy476; + int yy4; + struct TrigEvent yy90; + ExprSpan yy118; + TriggerStep* yy203; + u8 yy210; + struct {int value; int mask;} yy215; + SrcList* yy259; + struct LimitVal yy292; + Expr* yy314; + ExprList* yy322; + struct LikeOp yy342; + IdList* yy384; + Select* yy387; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -92083,8 +105747,8 @@ typedef union { #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse -#define YYNSTATE 631 -#define YYNRULE 330 +#define YYNSTATE 630 +#define YYNRULE 329 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) @@ -92110,7 +105774,7 @@ static const YYMINORTYPE yyzerominor = { 0 }; /* Next are the tables used to determine what action to take based on the ** current state and lookahead token. These tables are used to implement ** functions that take a state number and lookahead value and return an -** action integer. +** action integer. ** ** Suppose the action integer is N. Then the action is determined as ** follows @@ -92135,7 +105799,7 @@ static const YYMINORTYPE yyzerominor = { 0 }; ** If the index value yy_shift_ofst[S]+X is out of range or if the value ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. +** and that yy_default[S] should be used instead. ** ** The formula above is for computing the action when the lookahead is ** a terminal symbol. If the lookahead is a non-terminal (as occurs after @@ -92154,477 +105818,478 @@ static const YYMINORTYPE yyzerominor = { 0 }; ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. */ -#define YY_ACTTAB_COUNT (1550) +#define YY_ACTTAB_COUNT (1557) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 313, 49, 556, 46, 147, 172, 628, 598, 55, 55, - /* 10 */ 55, 55, 302, 53, 53, 53, 53, 52, 52, 51, - /* 20 */ 51, 51, 50, 238, 603, 66, 624, 623, 604, 598, - /* 30 */ 591, 585, 48, 53, 53, 53, 53, 52, 52, 51, - /* 40 */ 51, 51, 50, 238, 51, 51, 51, 50, 238, 56, - /* 50 */ 57, 47, 583, 582, 584, 584, 54, 54, 55, 55, - /* 60 */ 55, 55, 609, 53, 53, 53, 53, 52, 52, 51, - /* 70 */ 51, 51, 50, 238, 313, 598, 672, 330, 411, 217, + /* 0 */ 313, 960, 186, 419, 2, 172, 627, 597, 55, 55, + /* 10 */ 55, 55, 48, 53, 53, 53, 53, 52, 52, 51, + /* 20 */ 51, 51, 50, 238, 302, 283, 623, 622, 516, 515, + /* 30 */ 590, 584, 55, 55, 55, 55, 282, 53, 53, 53, + /* 40 */ 53, 52, 52, 51, 51, 51, 50, 238, 6, 56, + /* 50 */ 57, 47, 582, 581, 583, 583, 54, 54, 55, 55, + /* 60 */ 55, 55, 608, 53, 53, 53, 53, 52, 52, 51, + /* 70 */ 51, 51, 50, 238, 313, 597, 409, 330, 579, 579, /* 80 */ 32, 53, 53, 53, 53, 52, 52, 51, 51, 51, - /* 90 */ 50, 238, 330, 414, 621, 620, 166, 598, 673, 382, - /* 100 */ 379, 378, 602, 73, 591, 585, 307, 424, 166, 58, - /* 110 */ 377, 382, 379, 378, 516, 515, 624, 623, 254, 200, - /* 120 */ 199, 198, 377, 56, 57, 47, 583, 582, 584, 584, - /* 130 */ 54, 54, 55, 55, 55, 55, 581, 53, 53, 53, - /* 140 */ 53, 52, 52, 51, 51, 51, 50, 238, 313, 270, - /* 150 */ 226, 422, 283, 133, 177, 139, 284, 385, 279, 384, - /* 160 */ 169, 197, 251, 282, 253, 226, 411, 275, 440, 167, - /* 170 */ 139, 284, 385, 279, 384, 169, 571, 236, 591, 585, - /* 180 */ 240, 414, 275, 622, 621, 620, 674, 437, 441, 442, - /* 190 */ 602, 88, 352, 266, 439, 268, 438, 56, 57, 47, - /* 200 */ 583, 582, 584, 584, 54, 54, 55, 55, 55, 55, + /* 90 */ 50, 238, 330, 217, 620, 619, 166, 411, 624, 382, + /* 100 */ 379, 378, 7, 491, 590, 584, 200, 199, 198, 58, + /* 110 */ 377, 300, 414, 621, 481, 66, 623, 622, 621, 580, + /* 120 */ 254, 601, 94, 56, 57, 47, 582, 581, 583, 583, + /* 130 */ 54, 54, 55, 55, 55, 55, 671, 53, 53, 53, + /* 140 */ 53, 52, 52, 51, 51, 51, 50, 238, 313, 532, + /* 150 */ 226, 506, 507, 133, 177, 139, 284, 385, 279, 384, + /* 160 */ 169, 197, 342, 398, 251, 226, 253, 275, 388, 167, + /* 170 */ 139, 284, 385, 279, 384, 169, 570, 236, 590, 584, + /* 180 */ 672, 240, 275, 157, 620, 619, 554, 437, 51, 51, + /* 190 */ 51, 50, 238, 343, 439, 553, 438, 56, 57, 47, + /* 200 */ 582, 581, 583, 583, 54, 54, 55, 55, 55, 55, /* 210 */ 465, 53, 53, 53, 53, 52, 52, 51, 51, 51, - /* 220 */ 50, 238, 313, 471, 52, 52, 51, 51, 51, 50, - /* 230 */ 238, 234, 166, 491, 567, 382, 379, 378, 1, 440, - /* 240 */ 252, 176, 624, 623, 608, 67, 377, 513, 622, 443, - /* 250 */ 237, 577, 591, 585, 622, 172, 466, 598, 554, 441, - /* 260 */ 340, 409, 526, 580, 580, 349, 596, 553, 194, 482, - /* 270 */ 175, 56, 57, 47, 583, 582, 584, 584, 54, 54, - /* 280 */ 55, 55, 55, 55, 562, 53, 53, 53, 53, 52, - /* 290 */ 52, 51, 51, 51, 50, 238, 313, 594, 594, 594, - /* 300 */ 561, 578, 469, 65, 259, 351, 258, 411, 624, 623, - /* 310 */ 621, 620, 332, 576, 575, 240, 560, 568, 520, 411, - /* 320 */ 341, 237, 414, 624, 623, 598, 591, 585, 542, 519, - /* 330 */ 171, 602, 95, 68, 414, 624, 623, 624, 623, 38, - /* 340 */ 877, 506, 507, 602, 88, 56, 57, 47, 583, 582, - /* 350 */ 584, 584, 54, 54, 55, 55, 55, 55, 532, 53, + /* 220 */ 50, 238, 313, 390, 52, 52, 51, 51, 51, 50, + /* 230 */ 238, 391, 166, 491, 566, 382, 379, 378, 409, 440, + /* 240 */ 579, 579, 252, 440, 607, 66, 377, 513, 621, 49, + /* 250 */ 46, 147, 590, 584, 621, 16, 466, 189, 621, 441, + /* 260 */ 442, 673, 526, 441, 340, 577, 595, 64, 194, 482, + /* 270 */ 434, 56, 57, 47, 582, 581, 583, 583, 54, 54, + /* 280 */ 55, 55, 55, 55, 30, 53, 53, 53, 53, 52, + /* 290 */ 52, 51, 51, 51, 50, 238, 313, 593, 593, 593, + /* 300 */ 387, 578, 606, 493, 259, 351, 258, 411, 1, 623, + /* 310 */ 622, 496, 623, 622, 65, 240, 623, 622, 597, 443, + /* 320 */ 237, 239, 414, 341, 237, 602, 590, 584, 18, 603, + /* 330 */ 166, 601, 87, 382, 379, 378, 67, 623, 622, 38, + /* 340 */ 623, 622, 176, 270, 377, 56, 57, 47, 582, 581, + /* 350 */ 583, 583, 54, 54, 55, 55, 55, 55, 175, 53, /* 360 */ 53, 53, 53, 52, 52, 51, 51, 51, 50, 238, - /* 370 */ 313, 411, 579, 398, 531, 237, 621, 620, 388, 625, - /* 380 */ 500, 206, 167, 396, 233, 312, 414, 387, 569, 492, - /* 390 */ 216, 621, 620, 566, 622, 602, 74, 533, 210, 491, - /* 400 */ 591, 585, 548, 621, 620, 621, 620, 300, 598, 466, - /* 410 */ 481, 67, 603, 35, 622, 601, 604, 547, 6, 56, - /* 420 */ 57, 47, 583, 582, 584, 584, 54, 54, 55, 55, - /* 430 */ 55, 55, 601, 53, 53, 53, 53, 52, 52, 51, - /* 440 */ 51, 51, 50, 238, 313, 411, 184, 409, 528, 580, - /* 450 */ 580, 551, 962, 186, 419, 2, 353, 259, 351, 258, - /* 460 */ 414, 409, 411, 580, 580, 44, 411, 544, 240, 602, - /* 470 */ 94, 190, 7, 62, 591, 585, 598, 414, 350, 607, - /* 480 */ 493, 414, 409, 317, 580, 580, 602, 95, 496, 565, - /* 490 */ 602, 80, 203, 56, 57, 47, 583, 582, 584, 584, - /* 500 */ 54, 54, 55, 55, 55, 55, 535, 53, 53, 53, - /* 510 */ 53, 52, 52, 51, 51, 51, 50, 238, 313, 202, - /* 520 */ 564, 293, 511, 49, 562, 46, 147, 411, 394, 183, - /* 530 */ 563, 549, 505, 549, 174, 409, 322, 580, 580, 39, - /* 540 */ 561, 37, 414, 624, 623, 192, 473, 383, 591, 585, - /* 550 */ 474, 602, 80, 601, 504, 544, 560, 364, 402, 210, - /* 560 */ 421, 952, 361, 952, 365, 201, 144, 56, 57, 47, - /* 570 */ 583, 582, 584, 584, 54, 54, 55, 55, 55, 55, - /* 580 */ 559, 53, 53, 53, 53, 52, 52, 51, 51, 51, - /* 590 */ 50, 238, 313, 601, 232, 264, 272, 321, 374, 484, - /* 600 */ 510, 146, 342, 146, 328, 425, 485, 407, 576, 575, - /* 610 */ 622, 621, 620, 49, 168, 46, 147, 353, 546, 491, - /* 620 */ 204, 240, 591, 585, 421, 951, 549, 951, 549, 168, - /* 630 */ 429, 67, 390, 343, 622, 434, 307, 423, 338, 360, - /* 640 */ 391, 56, 57, 47, 583, 582, 584, 584, 54, 54, - /* 650 */ 55, 55, 55, 55, 601, 53, 53, 53, 53, 52, - /* 660 */ 52, 51, 51, 51, 50, 238, 313, 34, 318, 425, - /* 670 */ 237, 21, 359, 273, 411, 167, 411, 276, 411, 540, - /* 680 */ 411, 422, 13, 318, 619, 618, 617, 622, 275, 414, - /* 690 */ 336, 414, 622, 414, 622, 414, 591, 585, 602, 69, - /* 700 */ 602, 97, 602, 100, 602, 98, 631, 629, 334, 475, - /* 710 */ 475, 367, 319, 148, 327, 56, 57, 47, 583, 582, - /* 720 */ 584, 584, 54, 54, 55, 55, 55, 55, 411, 53, + /* 370 */ 313, 396, 233, 411, 531, 565, 317, 620, 619, 44, + /* 380 */ 620, 619, 240, 206, 620, 619, 597, 266, 414, 268, + /* 390 */ 409, 597, 579, 579, 352, 184, 505, 601, 73, 533, + /* 400 */ 590, 584, 466, 548, 190, 620, 619, 576, 620, 619, + /* 410 */ 547, 383, 551, 35, 332, 575, 574, 600, 504, 56, + /* 420 */ 57, 47, 582, 581, 583, 583, 54, 54, 55, 55, + /* 430 */ 55, 55, 567, 53, 53, 53, 53, 52, 52, 51, + /* 440 */ 51, 51, 50, 238, 313, 411, 561, 561, 528, 364, + /* 450 */ 259, 351, 258, 183, 361, 549, 524, 374, 411, 597, + /* 460 */ 414, 240, 560, 560, 409, 604, 579, 579, 328, 601, + /* 470 */ 93, 623, 622, 414, 590, 584, 237, 564, 559, 559, + /* 480 */ 520, 402, 601, 87, 409, 210, 579, 579, 168, 421, + /* 490 */ 950, 519, 950, 56, 57, 47, 582, 581, 583, 583, + /* 500 */ 54, 54, 55, 55, 55, 55, 192, 53, 53, 53, + /* 510 */ 53, 52, 52, 51, 51, 51, 50, 238, 313, 600, + /* 520 */ 293, 563, 511, 234, 357, 146, 475, 475, 367, 411, + /* 530 */ 562, 411, 358, 542, 425, 171, 411, 215, 144, 620, + /* 540 */ 619, 544, 318, 353, 414, 203, 414, 275, 590, 584, + /* 550 */ 549, 414, 174, 601, 94, 601, 79, 558, 471, 61, + /* 560 */ 601, 79, 421, 949, 350, 949, 34, 56, 57, 47, + /* 570 */ 582, 581, 583, 583, 54, 54, 55, 55, 55, 55, + /* 580 */ 535, 53, 53, 53, 53, 52, 52, 51, 51, 51, + /* 590 */ 50, 238, 313, 307, 424, 394, 272, 49, 46, 147, + /* 600 */ 349, 322, 4, 411, 491, 312, 321, 425, 568, 492, + /* 610 */ 216, 264, 407, 575, 574, 429, 66, 549, 414, 621, + /* 620 */ 540, 602, 590, 584, 13, 603, 621, 601, 72, 12, + /* 630 */ 618, 617, 616, 202, 210, 621, 546, 469, 422, 319, + /* 640 */ 148, 56, 57, 47, 582, 581, 583, 583, 54, 54, + /* 650 */ 55, 55, 55, 55, 338, 53, 53, 53, 53, 52, + /* 660 */ 52, 51, 51, 51, 50, 238, 313, 600, 600, 411, + /* 670 */ 39, 21, 37, 170, 237, 875, 411, 572, 572, 201, + /* 680 */ 144, 473, 538, 331, 414, 474, 143, 146, 630, 628, + /* 690 */ 334, 414, 353, 601, 68, 168, 590, 584, 132, 365, + /* 700 */ 601, 96, 307, 423, 530, 336, 49, 46, 147, 568, + /* 710 */ 406, 216, 549, 360, 529, 56, 57, 47, 582, 581, + /* 720 */ 583, 583, 54, 54, 55, 55, 55, 55, 411, 53, /* 730 */ 53, 53, 53, 52, 52, 51, 51, 51, 50, 238, - /* 740 */ 313, 411, 331, 414, 411, 49, 276, 46, 147, 569, - /* 750 */ 406, 216, 602, 106, 573, 573, 414, 354, 524, 414, - /* 760 */ 411, 622, 411, 224, 4, 602, 104, 605, 602, 108, - /* 770 */ 591, 585, 622, 20, 375, 414, 167, 414, 215, 144, - /* 780 */ 470, 239, 167, 225, 602, 109, 602, 134, 18, 56, - /* 790 */ 57, 47, 583, 582, 584, 584, 54, 54, 55, 55, + /* 740 */ 313, 411, 605, 414, 484, 510, 172, 422, 597, 318, + /* 750 */ 496, 485, 601, 99, 411, 142, 414, 411, 231, 411, + /* 760 */ 540, 411, 359, 629, 2, 601, 97, 426, 308, 414, + /* 770 */ 590, 584, 414, 20, 414, 621, 414, 621, 601, 106, + /* 780 */ 503, 601, 105, 601, 108, 601, 109, 204, 28, 56, + /* 790 */ 57, 47, 582, 581, 583, 583, 54, 54, 55, 55, /* 800 */ 55, 55, 411, 53, 53, 53, 53, 52, 52, 51, - /* 810 */ 51, 51, 50, 238, 313, 411, 276, 414, 12, 459, - /* 820 */ 276, 171, 411, 16, 223, 189, 602, 135, 354, 170, - /* 830 */ 414, 622, 630, 2, 411, 622, 540, 414, 143, 602, - /* 840 */ 61, 359, 132, 622, 591, 585, 602, 105, 458, 414, - /* 850 */ 23, 622, 446, 326, 23, 538, 622, 325, 602, 103, - /* 860 */ 427, 530, 309, 56, 57, 47, 583, 582, 584, 584, + /* 810 */ 51, 51, 50, 238, 313, 411, 597, 414, 411, 276, + /* 820 */ 214, 600, 411, 366, 213, 381, 601, 134, 274, 500, + /* 830 */ 414, 167, 130, 414, 621, 411, 354, 414, 376, 601, + /* 840 */ 135, 129, 601, 100, 590, 584, 601, 104, 522, 521, + /* 850 */ 414, 621, 224, 273, 600, 167, 327, 282, 600, 601, + /* 860 */ 103, 468, 521, 56, 57, 47, 582, 581, 583, 583, /* 870 */ 54, 54, 55, 55, 55, 55, 411, 53, 53, 53, /* 880 */ 53, 52, 52, 51, 51, 51, 50, 238, 313, 411, - /* 890 */ 264, 414, 411, 276, 359, 219, 157, 214, 357, 366, - /* 900 */ 602, 96, 522, 521, 414, 622, 358, 414, 622, 622, - /* 910 */ 411, 613, 612, 602, 102, 142, 602, 77, 591, 585, - /* 920 */ 529, 540, 231, 426, 308, 414, 622, 622, 468, 521, - /* 930 */ 324, 601, 257, 263, 602, 99, 622, 56, 45, 47, - /* 940 */ 583, 582, 584, 584, 54, 54, 55, 55, 55, 55, + /* 890 */ 27, 414, 411, 375, 276, 167, 359, 544, 50, 238, + /* 900 */ 601, 95, 128, 223, 414, 411, 165, 414, 411, 621, + /* 910 */ 411, 621, 612, 601, 102, 372, 601, 76, 590, 584, + /* 920 */ 414, 570, 236, 414, 470, 414, 167, 621, 188, 601, + /* 930 */ 98, 225, 601, 138, 601, 137, 232, 56, 45, 47, + /* 940 */ 582, 581, 583, 583, 54, 54, 55, 55, 55, 55, /* 950 */ 411, 53, 53, 53, 53, 52, 52, 51, 51, 51, - /* 960 */ 50, 238, 313, 264, 264, 414, 411, 213, 209, 544, - /* 970 */ 544, 207, 611, 28, 602, 138, 50, 238, 622, 622, - /* 980 */ 381, 414, 503, 140, 323, 222, 274, 622, 590, 589, - /* 990 */ 602, 137, 591, 585, 629, 334, 606, 30, 622, 571, - /* 1000 */ 236, 601, 601, 130, 496, 601, 453, 451, 288, 286, - /* 1010 */ 587, 586, 57, 47, 583, 582, 584, 584, 54, 54, + /* 960 */ 50, 238, 313, 276, 276, 414, 411, 276, 544, 459, + /* 970 */ 359, 171, 209, 479, 601, 136, 628, 334, 621, 621, + /* 980 */ 125, 414, 621, 368, 411, 621, 257, 540, 589, 588, + /* 990 */ 601, 75, 590, 584, 458, 446, 23, 23, 124, 414, + /* 1000 */ 326, 325, 621, 427, 324, 309, 600, 288, 601, 92, + /* 1010 */ 586, 585, 57, 47, 582, 581, 583, 583, 54, 54, /* 1020 */ 55, 55, 55, 55, 411, 53, 53, 53, 53, 52, - /* 1030 */ 52, 51, 51, 51, 50, 238, 313, 588, 411, 414, - /* 1040 */ 411, 264, 410, 129, 595, 400, 27, 376, 602, 136, - /* 1050 */ 128, 165, 479, 414, 282, 414, 622, 622, 411, 622, - /* 1060 */ 622, 411, 602, 76, 602, 93, 591, 585, 188, 372, - /* 1070 */ 368, 125, 476, 414, 261, 160, 414, 171, 124, 472, - /* 1080 */ 123, 15, 602, 92, 450, 602, 75, 47, 583, 582, - /* 1090 */ 584, 584, 54, 54, 55, 55, 55, 55, 464, 53, + /* 1030 */ 52, 51, 51, 51, 50, 238, 313, 587, 411, 414, + /* 1040 */ 411, 207, 611, 476, 171, 472, 160, 123, 601, 91, + /* 1050 */ 323, 261, 15, 414, 464, 414, 411, 621, 411, 354, + /* 1060 */ 222, 411, 601, 74, 601, 90, 590, 584, 159, 264, + /* 1070 */ 158, 414, 461, 414, 621, 600, 414, 121, 120, 25, + /* 1080 */ 601, 89, 601, 101, 621, 601, 88, 47, 582, 581, + /* 1090 */ 583, 583, 54, 54, 55, 55, 55, 55, 544, 53, /* 1100 */ 53, 53, 53, 52, 52, 51, 51, 51, 50, 238, - /* 1110 */ 43, 405, 264, 3, 558, 264, 545, 415, 623, 159, - /* 1120 */ 541, 158, 539, 278, 25, 461, 121, 622, 408, 622, - /* 1130 */ 622, 622, 24, 43, 405, 622, 3, 622, 622, 120, - /* 1140 */ 415, 623, 11, 456, 411, 156, 452, 403, 509, 277, - /* 1150 */ 118, 408, 489, 113, 205, 449, 271, 567, 221, 414, - /* 1160 */ 269, 267, 155, 622, 622, 111, 411, 622, 602, 95, - /* 1170 */ 403, 622, 411, 110, 10, 622, 622, 40, 41, 534, - /* 1180 */ 567, 414, 64, 264, 42, 413, 412, 414, 601, 596, - /* 1190 */ 602, 91, 445, 436, 150, 435, 602, 90, 622, 265, - /* 1200 */ 40, 41, 337, 242, 411, 191, 333, 42, 413, 412, - /* 1210 */ 398, 420, 596, 316, 622, 399, 260, 107, 230, 414, - /* 1220 */ 594, 594, 594, 593, 592, 14, 220, 411, 602, 101, - /* 1230 */ 240, 622, 43, 405, 362, 3, 149, 315, 626, 415, - /* 1240 */ 623, 127, 414, 594, 594, 594, 593, 592, 14, 622, - /* 1250 */ 408, 602, 89, 411, 181, 33, 405, 463, 3, 411, - /* 1260 */ 264, 462, 415, 623, 616, 615, 614, 355, 414, 403, - /* 1270 */ 417, 416, 622, 408, 414, 622, 622, 602, 87, 567, - /* 1280 */ 418, 627, 622, 602, 86, 8, 241, 180, 126, 255, - /* 1290 */ 600, 178, 403, 240, 208, 455, 395, 294, 444, 40, - /* 1300 */ 41, 297, 567, 248, 622, 296, 42, 413, 412, 247, - /* 1310 */ 622, 596, 244, 622, 30, 60, 31, 243, 430, 624, - /* 1320 */ 623, 292, 40, 41, 622, 295, 145, 622, 601, 42, - /* 1330 */ 413, 412, 622, 622, 596, 393, 622, 397, 599, 59, - /* 1340 */ 235, 622, 594, 594, 594, 593, 592, 14, 218, 291, - /* 1350 */ 622, 36, 344, 305, 304, 303, 179, 301, 411, 567, - /* 1360 */ 454, 557, 173, 185, 622, 594, 594, 594, 593, 592, - /* 1370 */ 14, 411, 29, 414, 151, 289, 246, 523, 411, 196, - /* 1380 */ 195, 335, 602, 85, 411, 245, 414, 526, 392, 543, - /* 1390 */ 411, 596, 287, 414, 285, 602, 72, 537, 153, 414, - /* 1400 */ 466, 411, 602, 71, 154, 414, 411, 152, 602, 84, - /* 1410 */ 386, 536, 329, 411, 602, 83, 414, 518, 280, 411, - /* 1420 */ 513, 414, 594, 594, 594, 602, 82, 517, 414, 311, - /* 1430 */ 602, 81, 411, 514, 414, 512, 131, 602, 70, 229, - /* 1440 */ 228, 227, 494, 602, 17, 411, 488, 414, 259, 346, - /* 1450 */ 249, 389, 487, 486, 314, 164, 602, 79, 310, 240, - /* 1460 */ 414, 373, 480, 163, 262, 371, 414, 162, 369, 602, - /* 1470 */ 78, 212, 478, 26, 477, 602, 9, 161, 467, 363, - /* 1480 */ 141, 122, 339, 187, 119, 457, 348, 347, 117, 116, - /* 1490 */ 115, 112, 114, 448, 182, 22, 320, 433, 432, 431, - /* 1500 */ 19, 428, 610, 597, 574, 193, 572, 63, 298, 404, - /* 1510 */ 555, 552, 290, 281, 510, 460, 498, 499, 495, 447, - /* 1520 */ 356, 497, 256, 380, 306, 570, 5, 250, 345, 238, - /* 1530 */ 299, 550, 527, 490, 508, 525, 502, 401, 501, 963, - /* 1540 */ 211, 963, 483, 963, 963, 963, 963, 963, 963, 370, + /* 1110 */ 43, 405, 263, 3, 610, 264, 140, 415, 622, 24, + /* 1120 */ 410, 11, 456, 594, 118, 155, 219, 452, 408, 621, + /* 1130 */ 621, 621, 156, 43, 405, 621, 3, 286, 621, 113, + /* 1140 */ 415, 622, 111, 445, 411, 400, 557, 403, 545, 10, + /* 1150 */ 411, 408, 264, 110, 205, 436, 541, 566, 453, 414, + /* 1160 */ 621, 621, 63, 621, 435, 414, 411, 621, 601, 94, + /* 1170 */ 403, 621, 411, 337, 601, 86, 150, 40, 41, 534, + /* 1180 */ 566, 414, 242, 264, 42, 413, 412, 414, 600, 595, + /* 1190 */ 601, 85, 191, 333, 107, 451, 601, 84, 621, 539, + /* 1200 */ 40, 41, 420, 230, 411, 149, 316, 42, 413, 412, + /* 1210 */ 398, 127, 595, 315, 621, 399, 278, 625, 181, 414, + /* 1220 */ 593, 593, 593, 592, 591, 14, 450, 411, 601, 71, + /* 1230 */ 240, 621, 43, 405, 264, 3, 615, 180, 264, 415, + /* 1240 */ 622, 614, 414, 593, 593, 593, 592, 591, 14, 621, + /* 1250 */ 408, 601, 70, 621, 417, 33, 405, 613, 3, 411, + /* 1260 */ 264, 411, 415, 622, 418, 626, 178, 509, 8, 403, + /* 1270 */ 241, 416, 126, 408, 414, 621, 414, 449, 208, 566, + /* 1280 */ 240, 221, 621, 601, 83, 601, 82, 599, 297, 277, + /* 1290 */ 296, 30, 403, 31, 395, 264, 295, 397, 489, 40, + /* 1300 */ 41, 411, 566, 220, 621, 294, 42, 413, 412, 271, + /* 1310 */ 621, 595, 600, 621, 59, 60, 414, 269, 267, 623, + /* 1320 */ 622, 36, 40, 41, 621, 601, 81, 598, 235, 42, + /* 1330 */ 413, 412, 621, 621, 595, 265, 344, 411, 248, 556, + /* 1340 */ 173, 185, 593, 593, 593, 592, 591, 14, 218, 29, + /* 1350 */ 621, 543, 414, 305, 304, 303, 179, 301, 411, 566, + /* 1360 */ 454, 601, 80, 289, 335, 593, 593, 593, 592, 591, + /* 1370 */ 14, 411, 287, 414, 151, 392, 246, 260, 411, 196, + /* 1380 */ 195, 523, 601, 69, 411, 245, 414, 526, 537, 285, + /* 1390 */ 389, 595, 621, 414, 536, 601, 17, 362, 153, 414, + /* 1400 */ 466, 463, 601, 78, 154, 414, 462, 152, 601, 77, + /* 1410 */ 355, 255, 621, 455, 601, 9, 621, 386, 444, 517, + /* 1420 */ 247, 621, 593, 593, 593, 621, 621, 244, 621, 243, + /* 1430 */ 430, 518, 292, 621, 329, 621, 145, 393, 280, 513, + /* 1440 */ 291, 131, 621, 514, 621, 621, 311, 621, 259, 346, + /* 1450 */ 249, 621, 621, 229, 314, 621, 228, 512, 227, 240, + /* 1460 */ 494, 488, 310, 164, 487, 486, 373, 480, 163, 262, + /* 1470 */ 369, 371, 162, 26, 212, 478, 477, 161, 141, 363, + /* 1480 */ 467, 122, 339, 187, 119, 348, 347, 117, 116, 115, + /* 1490 */ 114, 112, 182, 457, 320, 22, 433, 432, 448, 19, + /* 1500 */ 609, 431, 428, 62, 193, 596, 573, 298, 555, 552, + /* 1510 */ 571, 404, 290, 380, 498, 510, 495, 306, 281, 499, + /* 1520 */ 250, 5, 497, 460, 345, 447, 569, 550, 238, 299, + /* 1530 */ 527, 525, 508, 961, 502, 501, 961, 401, 961, 211, + /* 1540 */ 490, 356, 256, 961, 483, 961, 961, 961, 961, 961, + /* 1550 */ 961, 961, 961, 961, 961, 961, 370, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 19, 222, 223, 224, 225, 24, 1, 26, 77, 78, - /* 10 */ 79, 80, 15, 82, 83, 84, 85, 86, 87, 88, - /* 20 */ 89, 90, 91, 92, 113, 22, 26, 27, 117, 26, - /* 30 */ 49, 50, 81, 82, 83, 84, 85, 86, 87, 88, - /* 40 */ 89, 90, 91, 92, 88, 89, 90, 91, 92, 68, + /* 0 */ 19, 142, 143, 144, 145, 24, 1, 26, 77, 78, + /* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + /* 20 */ 89, 90, 91, 92, 15, 98, 26, 27, 7, 8, + /* 30 */ 49, 50, 77, 78, 79, 80, 109, 82, 83, 84, + /* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 22, 68, /* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, /* 60 */ 79, 80, 23, 82, 83, 84, 85, 86, 87, 88, - /* 70 */ 89, 90, 91, 92, 19, 94, 118, 19, 150, 22, + /* 70 */ 89, 90, 91, 92, 19, 94, 112, 19, 114, 115, /* 80 */ 25, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 90 */ 91, 92, 19, 165, 94, 95, 96, 94, 118, 99, - /* 100 */ 100, 101, 174, 175, 49, 50, 22, 23, 96, 54, - /* 110 */ 110, 99, 100, 101, 7, 8, 26, 27, 16, 105, - /* 120 */ 106, 107, 110, 68, 69, 70, 71, 72, 73, 74, - /* 130 */ 75, 76, 77, 78, 79, 80, 113, 82, 83, 84, - /* 140 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 16, - /* 150 */ 92, 67, 98, 24, 96, 97, 98, 99, 100, 101, - /* 160 */ 102, 25, 60, 109, 62, 92, 150, 109, 150, 25, + /* 90 */ 91, 92, 19, 22, 94, 95, 96, 150, 150, 99, + /* 100 */ 100, 101, 76, 150, 49, 50, 105, 106, 107, 54, + /* 110 */ 110, 158, 165, 165, 161, 162, 26, 27, 165, 113, + /* 120 */ 16, 174, 175, 68, 69, 70, 71, 72, 73, 74, + /* 130 */ 75, 76, 77, 78, 79, 80, 118, 82, 83, 84, + /* 140 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 23, + /* 150 */ 92, 97, 98, 24, 96, 97, 98, 99, 100, 101, + /* 160 */ 102, 25, 97, 216, 60, 92, 62, 109, 221, 25, /* 170 */ 97, 98, 99, 100, 101, 102, 86, 87, 49, 50, - /* 180 */ 116, 165, 109, 165, 94, 95, 118, 97, 170, 171, - /* 190 */ 174, 175, 128, 60, 104, 62, 106, 68, 69, 70, + /* 180 */ 118, 116, 109, 25, 94, 95, 32, 97, 88, 89, + /* 190 */ 90, 91, 92, 128, 104, 41, 106, 68, 69, 70, /* 200 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, /* 210 */ 11, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 220 */ 91, 92, 19, 21, 86, 87, 88, 89, 90, 91, - /* 230 */ 92, 215, 96, 150, 66, 99, 100, 101, 22, 150, - /* 240 */ 138, 118, 26, 27, 161, 162, 110, 103, 165, 231, - /* 250 */ 232, 23, 49, 50, 165, 24, 57, 26, 32, 170, - /* 260 */ 171, 112, 94, 114, 115, 63, 98, 41, 185, 186, - /* 270 */ 118, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 280 */ 77, 78, 79, 80, 12, 82, 83, 84, 85, 86, + /* 220 */ 91, 92, 19, 19, 86, 87, 88, 89, 90, 91, + /* 230 */ 92, 27, 96, 150, 66, 99, 100, 101, 112, 150, + /* 240 */ 114, 115, 138, 150, 161, 162, 110, 103, 165, 222, + /* 250 */ 223, 224, 49, 50, 165, 22, 57, 24, 165, 170, + /* 260 */ 171, 118, 94, 170, 171, 23, 98, 25, 185, 186, + /* 270 */ 243, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 280 */ 77, 78, 79, 80, 126, 82, 83, 84, 85, 86, /* 290 */ 87, 88, 89, 90, 91, 92, 19, 129, 130, 131, - /* 300 */ 28, 23, 100, 25, 105, 106, 107, 150, 26, 27, - /* 310 */ 94, 95, 169, 170, 171, 116, 44, 23, 46, 150, - /* 320 */ 231, 232, 165, 26, 27, 94, 49, 50, 23, 57, - /* 330 */ 25, 174, 175, 22, 165, 26, 27, 26, 27, 136, - /* 340 */ 138, 97, 98, 174, 175, 68, 69, 70, 71, 72, - /* 350 */ 73, 74, 75, 76, 77, 78, 79, 80, 23, 82, + /* 300 */ 88, 23, 172, 173, 105, 106, 107, 150, 22, 26, + /* 310 */ 27, 181, 26, 27, 22, 116, 26, 27, 26, 230, + /* 320 */ 231, 197, 165, 230, 231, 113, 49, 50, 204, 117, + /* 330 */ 96, 174, 175, 99, 100, 101, 22, 26, 27, 136, + /* 340 */ 26, 27, 118, 16, 110, 68, 69, 70, 71, 72, + /* 350 */ 73, 74, 75, 76, 77, 78, 79, 80, 118, 82, /* 360 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - /* 370 */ 19, 150, 23, 216, 23, 232, 94, 95, 221, 150, - /* 380 */ 23, 160, 25, 214, 215, 163, 165, 88, 166, 167, - /* 390 */ 168, 94, 95, 23, 165, 174, 175, 88, 160, 150, - /* 400 */ 49, 50, 120, 94, 95, 94, 95, 158, 26, 57, - /* 410 */ 161, 162, 113, 136, 165, 194, 117, 120, 22, 68, + /* 370 */ 19, 214, 215, 150, 23, 23, 155, 94, 95, 22, + /* 380 */ 94, 95, 116, 160, 94, 95, 94, 60, 165, 62, + /* 390 */ 112, 26, 114, 115, 128, 23, 36, 174, 175, 88, + /* 400 */ 49, 50, 57, 120, 22, 94, 95, 23, 94, 95, + /* 410 */ 120, 51, 25, 136, 169, 170, 171, 194, 58, 68, /* 420 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - /* 430 */ 79, 80, 194, 82, 83, 84, 85, 86, 87, 88, - /* 440 */ 89, 90, 91, 92, 19, 150, 23, 112, 23, 114, - /* 450 */ 115, 25, 142, 143, 144, 145, 218, 105, 106, 107, - /* 460 */ 165, 112, 150, 114, 115, 22, 150, 166, 116, 174, - /* 470 */ 175, 22, 76, 235, 49, 50, 94, 165, 240, 172, - /* 480 */ 173, 165, 112, 155, 114, 115, 174, 175, 181, 11, - /* 490 */ 174, 175, 22, 68, 69, 70, 71, 72, 73, 74, - /* 500 */ 75, 76, 77, 78, 79, 80, 205, 82, 83, 84, - /* 510 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 160, - /* 520 */ 23, 226, 23, 222, 12, 224, 225, 150, 216, 23, - /* 530 */ 23, 25, 36, 25, 25, 112, 220, 114, 115, 135, - /* 540 */ 28, 137, 165, 26, 27, 119, 30, 51, 49, 50, - /* 550 */ 34, 174, 175, 194, 58, 166, 44, 229, 46, 160, - /* 560 */ 22, 23, 234, 25, 48, 206, 207, 68, 69, 70, + /* 430 */ 79, 80, 23, 82, 83, 84, 85, 86, 87, 88, + /* 440 */ 89, 90, 91, 92, 19, 150, 12, 12, 23, 228, + /* 450 */ 105, 106, 107, 23, 233, 25, 165, 19, 150, 94, + /* 460 */ 165, 116, 28, 28, 112, 174, 114, 115, 108, 174, + /* 470 */ 175, 26, 27, 165, 49, 50, 231, 11, 44, 44, + /* 480 */ 46, 46, 174, 175, 112, 160, 114, 115, 50, 22, + /* 490 */ 23, 57, 25, 68, 69, 70, 71, 72, 73, 74, + /* 500 */ 75, 76, 77, 78, 79, 80, 119, 82, 83, 84, + /* 510 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 194, + /* 520 */ 225, 23, 23, 215, 19, 95, 105, 106, 107, 150, + /* 530 */ 23, 150, 27, 23, 67, 25, 150, 206, 207, 94, + /* 540 */ 95, 166, 104, 218, 165, 22, 165, 109, 49, 50, + /* 550 */ 120, 165, 25, 174, 175, 174, 175, 23, 21, 234, + /* 560 */ 174, 175, 22, 23, 239, 25, 25, 68, 69, 70, /* 570 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - /* 580 */ 23, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 590 */ 91, 92, 19, 194, 205, 150, 23, 220, 19, 181, - /* 600 */ 182, 95, 97, 95, 108, 67, 188, 169, 170, 171, - /* 610 */ 165, 94, 95, 222, 50, 224, 225, 218, 120, 150, - /* 620 */ 160, 116, 49, 50, 22, 23, 120, 25, 120, 50, - /* 630 */ 161, 162, 19, 128, 165, 244, 22, 23, 193, 240, - /* 640 */ 27, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 650 */ 77, 78, 79, 80, 194, 82, 83, 84, 85, 86, - /* 660 */ 87, 88, 89, 90, 91, 92, 19, 25, 104, 67, - /* 670 */ 232, 24, 150, 23, 150, 25, 150, 150, 150, 150, - /* 680 */ 150, 67, 25, 104, 7, 8, 9, 165, 109, 165, - /* 690 */ 245, 165, 165, 165, 165, 165, 49, 50, 174, 175, - /* 700 */ 174, 175, 174, 175, 174, 175, 0, 1, 2, 105, - /* 710 */ 106, 107, 248, 249, 187, 68, 69, 70, 71, 72, + /* 580 */ 205, 82, 83, 84, 85, 86, 87, 88, 89, 90, + /* 590 */ 91, 92, 19, 22, 23, 216, 23, 222, 223, 224, + /* 600 */ 63, 220, 35, 150, 150, 163, 220, 67, 166, 167, + /* 610 */ 168, 150, 169, 170, 171, 161, 162, 25, 165, 165, + /* 620 */ 150, 113, 49, 50, 25, 117, 165, 174, 175, 35, + /* 630 */ 7, 8, 9, 160, 160, 165, 120, 100, 67, 247, + /* 640 */ 248, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 650 */ 77, 78, 79, 80, 193, 82, 83, 84, 85, 86, + /* 660 */ 87, 88, 89, 90, 91, 92, 19, 194, 194, 150, + /* 670 */ 135, 24, 137, 35, 231, 138, 150, 129, 130, 206, + /* 680 */ 207, 30, 27, 213, 165, 34, 118, 95, 0, 1, + /* 690 */ 2, 165, 218, 174, 175, 50, 49, 50, 22, 48, + /* 700 */ 174, 175, 22, 23, 23, 244, 222, 223, 224, 166, + /* 710 */ 167, 168, 120, 239, 23, 68, 69, 70, 71, 72, /* 720 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82, /* 730 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - /* 740 */ 19, 150, 213, 165, 150, 222, 150, 224, 225, 166, - /* 750 */ 167, 168, 174, 175, 129, 130, 165, 150, 165, 165, - /* 760 */ 150, 165, 150, 241, 35, 174, 175, 174, 174, 175, - /* 770 */ 49, 50, 165, 52, 23, 165, 25, 165, 206, 207, - /* 780 */ 23, 197, 25, 187, 174, 175, 174, 175, 204, 68, + /* 740 */ 19, 150, 173, 165, 181, 182, 24, 67, 26, 104, + /* 750 */ 181, 188, 174, 175, 150, 39, 165, 150, 52, 150, + /* 760 */ 150, 150, 150, 144, 145, 174, 175, 249, 250, 165, + /* 770 */ 49, 50, 165, 52, 165, 165, 165, 165, 174, 175, + /* 780 */ 29, 174, 175, 174, 175, 174, 175, 160, 22, 68, /* 790 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, /* 800 */ 79, 80, 150, 82, 83, 84, 85, 86, 87, 88, - /* 810 */ 89, 90, 91, 92, 19, 150, 150, 165, 35, 23, - /* 820 */ 150, 25, 150, 22, 217, 24, 174, 175, 150, 35, - /* 830 */ 165, 165, 144, 145, 150, 165, 150, 165, 118, 174, - /* 840 */ 175, 150, 22, 165, 49, 50, 174, 175, 23, 165, - /* 850 */ 25, 165, 23, 187, 25, 27, 165, 187, 174, 175, - /* 860 */ 23, 23, 25, 68, 69, 70, 71, 72, 73, 74, + /* 810 */ 89, 90, 91, 92, 19, 150, 94, 165, 150, 150, + /* 820 */ 160, 194, 150, 213, 160, 52, 174, 175, 23, 23, + /* 830 */ 165, 25, 22, 165, 165, 150, 150, 165, 52, 174, + /* 840 */ 175, 22, 174, 175, 49, 50, 174, 175, 190, 191, + /* 850 */ 165, 165, 240, 23, 194, 25, 187, 109, 194, 174, + /* 860 */ 175, 190, 191, 68, 69, 70, 71, 72, 73, 74, /* 870 */ 75, 76, 77, 78, 79, 80, 150, 82, 83, 84, /* 880 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 150, - /* 890 */ 150, 165, 150, 150, 150, 217, 25, 160, 19, 213, - /* 900 */ 174, 175, 190, 191, 165, 165, 27, 165, 165, 165, - /* 910 */ 150, 150, 150, 174, 175, 39, 174, 175, 49, 50, - /* 920 */ 23, 150, 52, 250, 251, 165, 165, 165, 190, 191, - /* 930 */ 187, 194, 241, 193, 174, 175, 165, 68, 69, 70, + /* 890 */ 22, 165, 150, 23, 150, 25, 150, 166, 91, 92, + /* 900 */ 174, 175, 22, 217, 165, 150, 102, 165, 150, 165, + /* 910 */ 150, 165, 150, 174, 175, 19, 174, 175, 49, 50, + /* 920 */ 165, 86, 87, 165, 23, 165, 25, 165, 24, 174, + /* 930 */ 175, 187, 174, 175, 174, 175, 205, 68, 69, 70, /* 940 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, /* 950 */ 150, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 960 */ 91, 92, 19, 150, 150, 165, 150, 160, 160, 166, - /* 970 */ 166, 160, 150, 22, 174, 175, 91, 92, 165, 165, - /* 980 */ 52, 165, 29, 150, 213, 241, 23, 165, 49, 50, - /* 990 */ 174, 175, 49, 50, 1, 2, 173, 126, 165, 86, - /* 1000 */ 87, 194, 194, 22, 181, 194, 193, 193, 205, 205, + /* 960 */ 91, 92, 19, 150, 150, 165, 150, 150, 166, 23, + /* 970 */ 150, 25, 160, 20, 174, 175, 1, 2, 165, 165, + /* 980 */ 104, 165, 165, 43, 150, 165, 240, 150, 49, 50, + /* 990 */ 174, 175, 49, 50, 23, 23, 25, 25, 53, 165, + /* 1000 */ 187, 187, 165, 23, 187, 25, 194, 205, 174, 175, /* 1010 */ 71, 72, 69, 70, 71, 72, 73, 74, 75, 76, /* 1020 */ 77, 78, 79, 80, 150, 82, 83, 84, 85, 86, /* 1030 */ 87, 88, 89, 90, 91, 92, 19, 98, 150, 165, - /* 1040 */ 150, 150, 150, 22, 150, 150, 22, 52, 174, 175, - /* 1050 */ 22, 102, 20, 165, 109, 165, 165, 165, 150, 165, - /* 1060 */ 165, 150, 174, 175, 174, 175, 49, 50, 24, 19, - /* 1070 */ 43, 104, 59, 165, 138, 104, 165, 25, 53, 53, - /* 1080 */ 22, 5, 174, 175, 193, 174, 175, 70, 71, 72, - /* 1090 */ 73, 74, 75, 76, 77, 78, 79, 80, 1, 82, + /* 1040 */ 150, 160, 150, 59, 25, 53, 104, 22, 174, 175, + /* 1050 */ 213, 138, 5, 165, 1, 165, 150, 165, 150, 150, + /* 1060 */ 240, 150, 174, 175, 174, 175, 49, 50, 118, 150, + /* 1070 */ 35, 165, 27, 165, 165, 194, 165, 108, 127, 76, + /* 1080 */ 174, 175, 174, 175, 165, 174, 175, 70, 71, 72, + /* 1090 */ 73, 74, 75, 76, 77, 78, 79, 80, 166, 82, /* 1100 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - /* 1110 */ 19, 20, 150, 22, 150, 150, 150, 26, 27, 118, - /* 1120 */ 150, 35, 150, 150, 76, 27, 108, 165, 37, 165, - /* 1130 */ 165, 165, 76, 19, 20, 165, 22, 165, 165, 127, - /* 1140 */ 26, 27, 22, 1, 150, 16, 20, 56, 150, 150, - /* 1150 */ 119, 37, 150, 119, 160, 193, 150, 66, 193, 165, - /* 1160 */ 150, 150, 121, 165, 165, 108, 150, 165, 174, 175, - /* 1170 */ 56, 165, 150, 127, 22, 165, 165, 86, 87, 88, - /* 1180 */ 66, 165, 16, 150, 93, 94, 95, 165, 194, 98, - /* 1190 */ 174, 175, 128, 23, 15, 23, 174, 175, 165, 150, - /* 1200 */ 86, 87, 65, 140, 150, 22, 3, 93, 94, 95, - /* 1210 */ 216, 4, 98, 252, 165, 221, 150, 164, 180, 165, + /* 1110 */ 19, 20, 193, 22, 150, 150, 150, 26, 27, 76, + /* 1120 */ 150, 22, 1, 150, 119, 121, 217, 20, 37, 165, + /* 1130 */ 165, 165, 16, 19, 20, 165, 22, 205, 165, 119, + /* 1140 */ 26, 27, 108, 128, 150, 150, 150, 56, 150, 22, + /* 1150 */ 150, 37, 150, 127, 160, 23, 150, 66, 193, 165, + /* 1160 */ 165, 165, 16, 165, 23, 165, 150, 165, 174, 175, + /* 1170 */ 56, 165, 150, 65, 174, 175, 15, 86, 87, 88, + /* 1180 */ 66, 165, 140, 150, 93, 94, 95, 165, 194, 98, + /* 1190 */ 174, 175, 22, 3, 164, 193, 174, 175, 165, 150, + /* 1200 */ 86, 87, 4, 180, 150, 248, 251, 93, 94, 95, + /* 1210 */ 216, 180, 98, 251, 165, 221, 150, 149, 6, 165, /* 1220 */ 129, 130, 131, 132, 133, 134, 193, 150, 174, 175, - /* 1230 */ 116, 165, 19, 20, 150, 22, 249, 252, 149, 26, - /* 1240 */ 27, 180, 165, 129, 130, 131, 132, 133, 134, 165, - /* 1250 */ 37, 174, 175, 150, 6, 19, 20, 150, 22, 150, - /* 1260 */ 150, 150, 26, 27, 149, 149, 13, 150, 165, 56, - /* 1270 */ 149, 159, 165, 37, 165, 165, 165, 174, 175, 66, - /* 1280 */ 146, 147, 165, 174, 175, 25, 152, 151, 154, 150, - /* 1290 */ 194, 151, 56, 116, 160, 150, 123, 202, 150, 86, - /* 1300 */ 87, 199, 66, 193, 165, 200, 93, 94, 95, 150, - /* 1310 */ 165, 98, 150, 165, 126, 22, 124, 150, 150, 26, - /* 1320 */ 27, 150, 86, 87, 165, 201, 150, 165, 194, 93, - /* 1330 */ 94, 95, 165, 165, 98, 150, 165, 122, 203, 125, - /* 1340 */ 227, 165, 129, 130, 131, 132, 133, 134, 5, 150, - /* 1350 */ 165, 135, 218, 10, 11, 12, 13, 14, 150, 66, - /* 1360 */ 17, 157, 118, 157, 165, 129, 130, 131, 132, 133, - /* 1370 */ 134, 150, 104, 165, 31, 210, 33, 176, 150, 86, - /* 1380 */ 87, 247, 174, 175, 150, 42, 165, 94, 121, 211, - /* 1390 */ 150, 98, 210, 165, 210, 174, 175, 211, 55, 165, + /* 1230 */ 116, 165, 19, 20, 150, 22, 149, 151, 150, 26, + /* 1240 */ 27, 149, 165, 129, 130, 131, 132, 133, 134, 165, + /* 1250 */ 37, 174, 175, 165, 149, 19, 20, 13, 22, 150, + /* 1260 */ 150, 150, 26, 27, 146, 147, 151, 150, 25, 56, + /* 1270 */ 152, 159, 154, 37, 165, 165, 165, 193, 160, 66, + /* 1280 */ 116, 193, 165, 174, 175, 174, 175, 194, 199, 150, + /* 1290 */ 200, 126, 56, 124, 123, 150, 201, 122, 150, 86, + /* 1300 */ 87, 150, 66, 193, 165, 202, 93, 94, 95, 150, + /* 1310 */ 165, 98, 194, 165, 125, 22, 165, 150, 150, 26, + /* 1320 */ 27, 135, 86, 87, 165, 174, 175, 203, 226, 93, + /* 1330 */ 94, 95, 165, 165, 98, 150, 218, 150, 193, 157, + /* 1340 */ 118, 157, 129, 130, 131, 132, 133, 134, 5, 104, + /* 1350 */ 165, 211, 165, 10, 11, 12, 13, 14, 150, 66, + /* 1360 */ 17, 174, 175, 210, 246, 129, 130, 131, 132, 133, + /* 1370 */ 134, 150, 210, 165, 31, 121, 33, 150, 150, 86, + /* 1380 */ 87, 176, 174, 175, 150, 42, 165, 94, 211, 210, + /* 1390 */ 150, 98, 165, 165, 211, 174, 175, 150, 55, 165, /* 1400 */ 57, 150, 174, 175, 61, 165, 150, 64, 174, 175, - /* 1410 */ 104, 211, 47, 150, 174, 175, 165, 176, 176, 150, - /* 1420 */ 103, 165, 129, 130, 131, 174, 175, 184, 165, 179, - /* 1430 */ 174, 175, 150, 178, 165, 176, 22, 174, 175, 230, - /* 1440 */ 92, 230, 184, 174, 175, 150, 176, 165, 105, 106, - /* 1450 */ 107, 150, 176, 176, 111, 156, 174, 175, 179, 116, - /* 1460 */ 165, 18, 157, 156, 238, 157, 165, 156, 45, 174, - /* 1470 */ 175, 157, 157, 135, 239, 174, 175, 156, 189, 157, - /* 1480 */ 68, 189, 139, 219, 22, 199, 157, 18, 192, 192, - /* 1490 */ 192, 189, 192, 199, 219, 243, 157, 40, 157, 157, - /* 1500 */ 243, 38, 153, 166, 233, 196, 233, 246, 198, 228, - /* 1510 */ 177, 177, 209, 177, 182, 199, 166, 177, 166, 199, - /* 1520 */ 242, 177, 242, 178, 148, 166, 196, 209, 209, 92, - /* 1530 */ 195, 208, 174, 186, 183, 174, 183, 191, 183, 253, - /* 1540 */ 236, 253, 186, 253, 253, 253, 253, 253, 253, 237, + /* 1410 */ 150, 150, 165, 150, 174, 175, 165, 104, 150, 184, + /* 1420 */ 150, 165, 129, 130, 131, 165, 165, 150, 165, 150, + /* 1430 */ 150, 176, 150, 165, 47, 165, 150, 150, 176, 103, + /* 1440 */ 150, 22, 165, 178, 165, 165, 179, 165, 105, 106, + /* 1450 */ 107, 165, 165, 229, 111, 165, 92, 176, 229, 116, + /* 1460 */ 184, 176, 179, 156, 176, 176, 18, 157, 156, 237, + /* 1470 */ 45, 157, 156, 135, 157, 157, 238, 156, 68, 157, + /* 1480 */ 189, 189, 139, 219, 22, 157, 18, 192, 192, 192, + /* 1490 */ 192, 189, 219, 199, 157, 242, 40, 157, 199, 242, + /* 1500 */ 153, 157, 38, 245, 196, 166, 232, 198, 177, 177, + /* 1510 */ 232, 227, 209, 178, 166, 182, 166, 148, 177, 177, + /* 1520 */ 209, 196, 177, 199, 209, 199, 166, 208, 92, 195, + /* 1530 */ 174, 174, 183, 252, 183, 183, 252, 191, 252, 235, + /* 1540 */ 186, 241, 241, 252, 186, 252, 252, 252, 252, 252, + /* 1550 */ 252, 252, 252, 252, 252, 252, 236, }; -#define YY_SHIFT_USE_DFLT (-90) +#define YY_SHIFT_USE_DFLT (-74) #define YY_SHIFT_COUNT (418) -#define YY_SHIFT_MIN (-89) -#define YY_SHIFT_MAX (1469) +#define YY_SHIFT_MIN (-73) +#define YY_SHIFT_MAX (1468) static const short yy_shift_ofst[] = { - /* 0 */ 993, 1114, 1343, 1114, 1213, 1213, 90, 90, 0, -19, - /* 10 */ 1213, 1213, 1213, 1213, 1213, 352, 517, 721, 1091, 1213, + /* 0 */ 975, 1114, 1343, 1114, 1213, 1213, 90, 90, 0, -19, + /* 10 */ 1213, 1213, 1213, 1213, 1213, 345, 445, 721, 1091, 1213, /* 20 */ 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, /* 30 */ 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, /* 40 */ 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1236, 1213, 1213, /* 50 */ 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, - /* 60 */ 1213, -49, 199, 517, 517, 913, 913, 382, 1177, 55, - /* 70 */ 647, 573, 499, 425, 351, 277, 203, 129, 795, 795, + /* 60 */ 1213, 199, 445, 445, 835, 835, 365, 1164, 55, 647, + /* 70 */ 573, 499, 425, 351, 277, 203, 129, 795, 795, 795, /* 80 */ 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, - /* 90 */ 795, 795, 795, 795, 795, 795, 869, 795, 943, 1017, - /* 100 */ 1017, -69, -69, -69, -69, -1, -1, 58, 138, -44, - /* 110 */ 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, - /* 120 */ 517, 517, 517, 517, 517, 517, 202, 579, 517, 517, - /* 130 */ 517, 517, 517, 382, 885, 1437, -90, -90, -90, 1293, - /* 140 */ 73, 272, 272, 309, 311, 297, 282, 216, 602, 538, - /* 150 */ 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, - /* 160 */ 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, - /* 170 */ 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, - /* 180 */ 517, 517, 505, 231, 231, 231, 706, 64, 1177, 1177, - /* 190 */ 1177, -90, -90, -90, 136, 168, 168, 12, 496, 496, - /* 200 */ 496, 506, 423, 512, 370, 349, 335, 149, 149, 149, - /* 210 */ 149, 604, 516, 149, 149, 508, 3, 299, 677, 871, - /* 220 */ 613, 613, 879, 871, 879, 144, 382, 226, 382, 226, - /* 230 */ 564, 226, 613, 226, 226, 404, 625, 625, 382, 426, - /* 240 */ -89, 801, 1463, 1244, 1244, 1457, 1457, 1244, 1462, 1412, - /* 250 */ 1188, 1469, 1469, 1469, 1469, 1244, 1188, 1462, 1412, 1412, - /* 260 */ 1244, 1443, 1338, 1423, 1244, 1244, 1443, 1244, 1443, 1244, - /* 270 */ 1443, 1414, 1306, 1306, 1306, 1365, 1348, 1348, 1414, 1306, - /* 280 */ 1317, 1306, 1365, 1306, 1306, 1267, 1268, 1267, 1268, 1267, - /* 290 */ 1268, 1244, 1244, 1216, 1214, 1215, 1192, 1173, 1188, 1177, - /* 300 */ 1260, 1253, 1253, 1248, 1248, 1248, 1248, -90, -90, -90, - /* 310 */ -90, -90, -90, 939, 102, 614, 84, 133, 14, 837, - /* 320 */ 396, 829, 825, 796, 757, 751, 650, 357, 244, 107, - /* 330 */ 54, 305, 278, 1207, 1203, 1183, 1063, 1179, 1137, 1166, - /* 340 */ 1172, 1170, 1064, 1152, 1046, 1057, 1034, 1126, 1041, 1129, - /* 350 */ 1142, 1031, 1120, 1012, 1056, 1048, 1018, 1098, 1086, 1001, - /* 360 */ 1097, 1076, 1058, 971, 936, 1026, 1052, 1025, 1013, 1027, - /* 370 */ 967, 1044, 1032, 1050, 945, 949, 1028, 995, 1024, 1021, - /* 380 */ 963, 981, 928, 953, 951, 870, 876, 897, 838, 720, - /* 390 */ 828, 794, 820, 498, 642, 783, 657, 729, 642, 557, - /* 400 */ 507, 509, 497, 470, 478, 449, 294, 228, 443, 23, - /* 410 */ 152, 123, 68, -20, -42, 57, 39, -3, 5, + /* 90 */ 795, 795, 795, 795, 795, 869, 795, 943, 1017, 1017, + /* 100 */ -69, -45, -45, -45, -45, -45, -1, 58, 138, 100, + /* 110 */ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, + /* 120 */ 445, 445, 445, 445, 445, 445, 537, 438, 445, 445, + /* 130 */ 445, 445, 445, 365, 807, 1436, -74, -74, -74, 1293, + /* 140 */ 73, 434, 434, 311, 314, 290, 283, 286, 540, 467, + /* 150 */ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, + /* 160 */ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, + /* 170 */ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, + /* 180 */ 445, 445, 65, 722, 722, 722, 688, 266, 1164, 1164, + /* 190 */ 1164, -74, -74, -74, 136, 168, 168, 234, 360, 360, + /* 200 */ 360, 430, 372, 435, 352, 278, 126, -36, -36, -36, + /* 210 */ -36, 421, 651, -36, -36, 592, 292, 212, 623, 158, + /* 220 */ 204, 204, 505, 158, 505, 144, 365, 154, 365, 154, + /* 230 */ 645, 154, 204, 154, 154, 535, 548, 548, 365, 387, + /* 240 */ 508, 233, 1464, 1222, 1222, 1456, 1456, 1222, 1462, 1410, + /* 250 */ 1165, 1468, 1468, 1468, 1468, 1222, 1165, 1462, 1410, 1410, + /* 260 */ 1222, 1448, 1338, 1425, 1222, 1222, 1448, 1222, 1448, 1222, + /* 270 */ 1448, 1419, 1313, 1313, 1313, 1387, 1364, 1364, 1419, 1313, + /* 280 */ 1336, 1313, 1387, 1313, 1313, 1254, 1245, 1254, 1245, 1254, + /* 290 */ 1245, 1222, 1222, 1186, 1189, 1175, 1169, 1171, 1165, 1164, + /* 300 */ 1243, 1244, 1244, 1212, 1212, 1212, 1212, -74, -74, -74, + /* 310 */ -74, -74, -74, 939, 104, 680, 571, 327, 1, 980, + /* 320 */ 26, 972, 971, 946, 901, 870, 830, 806, 54, 21, + /* 330 */ -73, 510, 242, 1198, 1190, 1170, 1042, 1161, 1108, 1146, + /* 340 */ 1141, 1132, 1015, 1127, 1026, 1034, 1020, 1107, 1004, 1116, + /* 350 */ 1121, 1005, 1099, 951, 1043, 1003, 969, 1045, 1035, 950, + /* 360 */ 1053, 1047, 1025, 942, 913, 992, 1019, 945, 984, 940, + /* 370 */ 876, 904, 953, 896, 748, 804, 880, 786, 868, 819, + /* 380 */ 805, 810, 773, 751, 766, 706, 716, 691, 681, 568, + /* 390 */ 655, 638, 676, 516, 541, 594, 599, 567, 541, 534, + /* 400 */ 507, 527, 498, 523, 466, 382, 409, 384, 357, 6, + /* 410 */ 240, 224, 143, 62, 18, 71, 39, 9, 5, }; -#define YY_REDUCE_USE_DFLT (-222) +#define YY_REDUCE_USE_DFLT (-142) #define YY_REDUCE_COUNT (312) -#define YY_REDUCE_MIN (-221) -#define YY_REDUCE_MAX (1376) +#define YY_REDUCE_MIN (-141) +#define YY_REDUCE_MAX (1369) static const short yy_reduce_ofst[] = { - /* 0 */ 310, 994, 1134, 221, 169, 157, 89, 18, 83, 301, - /* 10 */ 377, 316, 312, 16, 295, 238, 249, 391, 1301, 1295, - /* 20 */ 1282, 1269, 1263, 1256, 1251, 1240, 1234, 1228, 1221, 1208, - /* 30 */ 1109, 1103, 1077, 1054, 1022, 1016, 911, 908, 890, 888, - /* 40 */ 874, 816, 800, 760, 742, 739, 726, 684, 672, 665, - /* 50 */ 652, 612, 610, 594, 591, 578, 530, 528, 526, 524, - /* 60 */ -72, -221, 399, 469, 445, 438, 143, 222, 359, 523, - /* 70 */ 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, - /* 80 */ 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, - /* 90 */ 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, - /* 100 */ 523, 523, 523, 523, 523, 523, 523, 307, 523, 523, - /* 110 */ 1110, 678, 1033, 965, 962, 891, 814, 813, 744, 771, - /* 120 */ 691, 607, 522, 743, 686, 740, 328, 418, 670, 666, - /* 130 */ 596, 527, 529, 583, 523, 523, 523, 523, 523, 593, - /* 140 */ 823, 738, 712, 892, 1199, 1185, 1176, 1171, 673, 673, - /* 150 */ 1168, 1167, 1162, 1159, 1148, 1145, 1139, 1117, 1111, 1107, - /* 160 */ 1084, 1066, 1049, 1011, 1010, 1006, 1002, 999, 998, 973, - /* 170 */ 972, 970, 966, 964, 895, 894, 892, 833, 822, 762, - /* 180 */ 761, 229, 811, 804, 803, 389, 688, 808, 807, 737, - /* 190 */ 460, 464, 572, 584, 1356, 1361, 1358, 1347, 1355, 1353, - /* 200 */ 1351, 1323, 1335, 1346, 1335, 1335, 1335, 1335, 1335, 1335, - /* 210 */ 1335, 1312, 1304, 1335, 1335, 1323, 1359, 1330, 1376, 1320, - /* 220 */ 1319, 1318, 1280, 1316, 1278, 1345, 1352, 1344, 1350, 1340, - /* 230 */ 1332, 1336, 1303, 1334, 1333, 1281, 1273, 1271, 1337, 1310, - /* 240 */ 1309, 1349, 1261, 1342, 1341, 1257, 1252, 1339, 1275, 1302, - /* 250 */ 1294, 1300, 1298, 1297, 1296, 1329, 1286, 1264, 1292, 1289, - /* 260 */ 1322, 1321, 1235, 1226, 1315, 1314, 1311, 1308, 1307, 1305, - /* 270 */ 1299, 1279, 1277, 1276, 1270, 1258, 1211, 1209, 1250, 1259, - /* 280 */ 1255, 1242, 1243, 1241, 1201, 1200, 1184, 1186, 1182, 1178, - /* 290 */ 1165, 1206, 1204, 1113, 1135, 1095, 1124, 1105, 1102, 1096, - /* 300 */ 1112, 1140, 1136, 1121, 1116, 1115, 1089, 985, 961, 987, - /* 310 */ 1061, 1038, 1053, + /* 0 */ -141, 994, 1118, 223, 157, -53, 93, 89, 83, 375, + /* 10 */ 386, 381, 379, 308, 295, 325, -47, 27, 1240, 1234, + /* 20 */ 1228, 1221, 1208, 1187, 1151, 1111, 1109, 1077, 1054, 1022, + /* 30 */ 1016, 1000, 911, 908, 906, 890, 888, 874, 834, 816, + /* 40 */ 800, 760, 758, 755, 742, 739, 726, 685, 672, 668, + /* 50 */ 665, 652, 611, 609, 607, 604, 591, 578, 526, 519, + /* 60 */ 453, 474, 454, 461, 443, 245, 442, 473, 484, 484, + /* 70 */ 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, + /* 80 */ 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, + /* 90 */ 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, + /* 100 */ 484, 484, 484, 484, 484, 484, 484, 130, 484, 484, + /* 110 */ 1145, 909, 1110, 1088, 1084, 1033, 1002, 965, 820, 837, + /* 120 */ 746, 686, 612, 817, 610, 919, 221, 563, 814, 813, + /* 130 */ 744, 669, 470, 543, 484, 484, 484, 484, 484, 291, + /* 140 */ 569, 671, 658, 970, 1290, 1287, 1286, 1282, 518, 518, + /* 150 */ 1280, 1279, 1277, 1270, 1268, 1263, 1261, 1260, 1256, 1251, + /* 160 */ 1247, 1227, 1185, 1168, 1167, 1159, 1148, 1139, 1117, 1066, + /* 170 */ 1049, 1006, 998, 996, 995, 973, 970, 966, 964, 892, + /* 180 */ 762, -52, 881, 932, 802, 731, 619, 812, 664, 660, + /* 190 */ 627, 392, 331, 124, 1358, 1357, 1356, 1354, 1352, 1351, + /* 200 */ 1349, 1319, 1334, 1346, 1334, 1334, 1334, 1334, 1334, 1334, + /* 210 */ 1334, 1320, 1304, 1334, 1334, 1319, 1360, 1325, 1369, 1326, + /* 220 */ 1315, 1311, 1301, 1324, 1300, 1335, 1350, 1345, 1348, 1342, + /* 230 */ 1333, 1341, 1303, 1332, 1331, 1284, 1278, 1274, 1339, 1309, + /* 240 */ 1308, 1347, 1258, 1344, 1340, 1257, 1253, 1337, 1273, 1302, + /* 250 */ 1299, 1298, 1297, 1296, 1295, 1328, 1294, 1264, 1292, 1291, + /* 260 */ 1322, 1321, 1238, 1232, 1318, 1317, 1316, 1314, 1312, 1310, + /* 270 */ 1307, 1283, 1289, 1288, 1285, 1276, 1229, 1224, 1267, 1281, + /* 280 */ 1265, 1262, 1235, 1255, 1205, 1183, 1179, 1177, 1162, 1140, + /* 290 */ 1153, 1184, 1182, 1102, 1124, 1103, 1095, 1090, 1089, 1093, + /* 300 */ 1112, 1115, 1086, 1105, 1092, 1087, 1068, 962, 955, 957, + /* 310 */ 1031, 1023, 1030, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 636, 872, 961, 961, 961, 872, 901, 901, 961, 760, - /* 10 */ 961, 961, 961, 961, 870, 961, 961, 935, 961, 961, - /* 20 */ 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, - /* 30 */ 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, - /* 40 */ 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, - /* 50 */ 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, - /* 60 */ 961, 844, 961, 961, 961, 901, 901, 675, 764, 795, - /* 70 */ 961, 961, 961, 961, 961, 961, 961, 961, 934, 936, - /* 80 */ 810, 809, 803, 802, 914, 775, 800, 793, 786, 797, - /* 90 */ 873, 866, 867, 865, 869, 874, 961, 796, 832, 850, - /* 100 */ 831, 849, 856, 848, 834, 843, 833, 667, 835, 836, - /* 110 */ 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, - /* 120 */ 961, 961, 961, 961, 961, 961, 662, 729, 961, 961, - /* 130 */ 961, 961, 961, 961, 837, 838, 853, 852, 851, 961, - /* 140 */ 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, - /* 150 */ 961, 941, 939, 961, 885, 961, 961, 961, 961, 961, - /* 160 */ 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, - /* 170 */ 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, - /* 180 */ 961, 642, 961, 760, 760, 760, 636, 961, 961, 961, - /* 190 */ 961, 953, 764, 754, 720, 961, 961, 961, 961, 961, - /* 200 */ 961, 961, 961, 961, 961, 961, 961, 805, 743, 924, - /* 210 */ 926, 961, 907, 741, 664, 762, 677, 752, 644, 799, - /* 220 */ 777, 777, 919, 799, 919, 701, 961, 789, 961, 789, - /* 230 */ 698, 789, 777, 789, 789, 868, 961, 961, 961, 761, - /* 240 */ 752, 961, 946, 768, 768, 938, 938, 768, 811, 733, - /* 250 */ 799, 740, 740, 740, 740, 768, 799, 811, 733, 733, - /* 260 */ 768, 659, 913, 911, 768, 768, 659, 768, 659, 768, - /* 270 */ 659, 878, 731, 731, 731, 716, 882, 882, 878, 731, - /* 280 */ 701, 731, 716, 731, 731, 781, 776, 781, 776, 781, - /* 290 */ 776, 768, 768, 961, 794, 782, 792, 790, 799, 961, - /* 300 */ 719, 652, 652, 641, 641, 641, 641, 958, 958, 953, - /* 310 */ 703, 703, 685, 961, 961, 961, 961, 961, 961, 961, - /* 320 */ 887, 961, 961, 961, 961, 961, 961, 961, 961, 961, - /* 330 */ 961, 961, 961, 961, 637, 948, 961, 961, 945, 961, - /* 340 */ 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, - /* 350 */ 961, 961, 961, 961, 961, 961, 961, 961, 961, 917, - /* 360 */ 961, 961, 961, 961, 961, 961, 910, 909, 961, 961, - /* 370 */ 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, - /* 380 */ 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, - /* 390 */ 961, 961, 961, 961, 791, 961, 783, 961, 871, 961, - /* 400 */ 961, 961, 961, 961, 961, 961, 961, 961, 961, 746, - /* 410 */ 820, 961, 819, 823, 818, 669, 961, 650, 961, 633, - /* 420 */ 638, 957, 960, 959, 956, 955, 954, 949, 947, 944, - /* 430 */ 943, 942, 940, 937, 933, 891, 889, 896, 895, 894, - /* 440 */ 893, 892, 890, 888, 886, 806, 804, 801, 798, 932, - /* 450 */ 884, 742, 739, 738, 658, 950, 916, 925, 923, 812, - /* 460 */ 922, 921, 920, 918, 915, 902, 808, 807, 734, 876, - /* 470 */ 875, 661, 906, 905, 904, 908, 912, 903, 770, 660, - /* 480 */ 657, 666, 723, 722, 730, 728, 727, 726, 725, 724, - /* 490 */ 721, 668, 676, 687, 715, 700, 699, 881, 883, 880, - /* 500 */ 879, 708, 707, 713, 712, 711, 710, 709, 706, 705, - /* 510 */ 704, 697, 696, 702, 695, 718, 717, 714, 694, 737, - /* 520 */ 736, 735, 732, 693, 692, 691, 823, 690, 689, 829, - /* 530 */ 828, 816, 860, 757, 756, 755, 767, 766, 779, 778, - /* 540 */ 814, 813, 780, 765, 759, 758, 774, 773, 772, 771, - /* 550 */ 763, 753, 785, 788, 787, 784, 845, 862, 769, 859, - /* 560 */ 931, 930, 929, 928, 927, 864, 863, 830, 827, 680, - /* 570 */ 681, 900, 898, 899, 897, 683, 682, 679, 678, 861, - /* 580 */ 748, 747, 857, 854, 846, 841, 858, 855, 847, 842, - /* 590 */ 840, 839, 825, 824, 822, 821, 817, 826, 671, 749, - /* 600 */ 745, 744, 815, 751, 750, 688, 686, 684, 665, 663, - /* 610 */ 656, 654, 653, 655, 651, 649, 648, 647, 646, 645, - /* 620 */ 674, 673, 672, 670, 669, 643, 640, 639, 635, 634, - /* 630 */ 632, + /* 0 */ 635, 870, 959, 959, 959, 870, 899, 899, 959, 759, + /* 10 */ 959, 959, 959, 959, 868, 959, 959, 933, 959, 959, + /* 20 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 30 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 40 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 50 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 60 */ 959, 959, 959, 959, 899, 899, 674, 763, 794, 959, + /* 70 */ 959, 959, 959, 959, 959, 959, 959, 932, 934, 809, + /* 80 */ 808, 802, 801, 912, 774, 799, 792, 785, 796, 871, + /* 90 */ 864, 865, 863, 867, 872, 959, 795, 831, 848, 830, + /* 100 */ 842, 847, 854, 846, 843, 833, 832, 666, 834, 835, + /* 110 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 120 */ 959, 959, 959, 959, 959, 959, 661, 728, 959, 959, + /* 130 */ 959, 959, 959, 959, 836, 837, 851, 850, 849, 959, + /* 140 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 150 */ 959, 939, 937, 959, 883, 959, 959, 959, 959, 959, + /* 160 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 170 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 180 */ 959, 641, 959, 759, 759, 759, 635, 959, 959, 959, + /* 190 */ 959, 951, 763, 753, 719, 959, 959, 959, 959, 959, + /* 200 */ 959, 959, 959, 959, 959, 959, 959, 804, 742, 922, + /* 210 */ 924, 959, 905, 740, 663, 761, 676, 751, 643, 798, + /* 220 */ 776, 776, 917, 798, 917, 700, 959, 788, 959, 788, + /* 230 */ 697, 788, 776, 788, 788, 866, 959, 959, 959, 760, + /* 240 */ 751, 959, 944, 767, 767, 936, 936, 767, 810, 732, + /* 250 */ 798, 739, 739, 739, 739, 767, 798, 810, 732, 732, + /* 260 */ 767, 658, 911, 909, 767, 767, 658, 767, 658, 767, + /* 270 */ 658, 876, 730, 730, 730, 715, 880, 880, 876, 730, + /* 280 */ 700, 730, 715, 730, 730, 780, 775, 780, 775, 780, + /* 290 */ 775, 767, 767, 959, 793, 781, 791, 789, 798, 959, + /* 300 */ 718, 651, 651, 640, 640, 640, 640, 956, 956, 951, + /* 310 */ 702, 702, 684, 959, 959, 959, 959, 959, 959, 959, + /* 320 */ 885, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 330 */ 959, 959, 959, 959, 636, 946, 959, 959, 943, 959, + /* 340 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 350 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 915, + /* 360 */ 959, 959, 959, 959, 959, 959, 908, 907, 959, 959, + /* 370 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 380 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 390 */ 959, 959, 959, 959, 790, 959, 782, 959, 869, 959, + /* 400 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 745, + /* 410 */ 819, 959, 818, 822, 817, 668, 959, 649, 959, 632, + /* 420 */ 637, 955, 958, 957, 954, 953, 952, 947, 945, 942, + /* 430 */ 941, 940, 938, 935, 931, 889, 887, 894, 893, 892, + /* 440 */ 891, 890, 888, 886, 884, 805, 803, 800, 797, 930, + /* 450 */ 882, 741, 738, 737, 657, 948, 914, 923, 921, 811, + /* 460 */ 920, 919, 918, 916, 913, 900, 807, 806, 733, 874, + /* 470 */ 873, 660, 904, 903, 902, 906, 910, 901, 769, 659, + /* 480 */ 656, 665, 722, 721, 729, 727, 726, 725, 724, 723, + /* 490 */ 720, 667, 675, 686, 714, 699, 698, 879, 881, 878, + /* 500 */ 877, 707, 706, 712, 711, 710, 709, 708, 705, 704, + /* 510 */ 703, 696, 695, 701, 694, 717, 716, 713, 693, 736, + /* 520 */ 735, 734, 731, 692, 691, 690, 822, 689, 688, 828, + /* 530 */ 827, 815, 858, 756, 755, 754, 766, 765, 778, 777, + /* 540 */ 813, 812, 779, 764, 758, 757, 773, 772, 771, 770, + /* 550 */ 762, 752, 784, 787, 786, 783, 860, 768, 857, 929, + /* 560 */ 928, 927, 926, 925, 862, 861, 829, 826, 679, 680, + /* 570 */ 898, 896, 897, 895, 682, 681, 678, 677, 859, 747, + /* 580 */ 746, 855, 852, 844, 840, 856, 853, 845, 841, 839, + /* 590 */ 838, 824, 823, 821, 820, 816, 825, 670, 748, 744, + /* 600 */ 743, 814, 750, 749, 687, 685, 683, 664, 662, 655, + /* 610 */ 653, 652, 654, 650, 648, 647, 646, 645, 644, 673, + /* 620 */ 672, 671, 669, 668, 642, 639, 638, 634, 633, 631, }; /* The next table maps tokens into fallback tokens. If a construct ** like the following: -** +** ** %fallback ID X Y Z. ** ** appears in the grammar, then ID becomes a fallback token for X, Y, @@ -92744,15 +106409,16 @@ struct yyParser { typedef struct yyParser yyParser; #ifndef NDEBUG +/* #include <stdio.h> */ static FILE *yyTraceFILE = 0; static char *yyTracePrompt = 0; #endif /* NDEBUG */ #ifndef NDEBUG -/* +/* ** Turn parser tracing on by giving a stream to which to write the trace ** and a prompt to preface each trace message. Tracing is turned off -** by making either argument NULL +** by making either argument NULL ** ** Inputs: ** <ul> @@ -92777,71 +106443,70 @@ SQLITE_PRIVATE void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){ #ifndef NDEBUG /* For tracing shifts, the names of all terminals and nonterminals ** are required. The following table supplies these names */ -static const char *const yyTokenName[] = { - "$", "SEMI", "EXPLAIN", "QUERY", - "PLAN", "BEGIN", "TRANSACTION", "DEFERRED", - "IMMEDIATE", "EXCLUSIVE", "COMMIT", "END", - "ROLLBACK", "SAVEPOINT", "RELEASE", "TO", - "TABLE", "CREATE", "IF", "NOT", - "EXISTS", "TEMP", "LP", "RP", - "AS", "COMMA", "ID", "INDEXED", - "ABORT", "ACTION", "AFTER", "ANALYZE", - "ASC", "ATTACH", "BEFORE", "BY", - "CASCADE", "CAST", "COLUMNKW", "CONFLICT", - "DATABASE", "DESC", "DETACH", "EACH", - "FAIL", "FOR", "IGNORE", "INITIALLY", - "INSTEAD", "LIKE_KW", "MATCH", "NO", - "KEY", "OF", "OFFSET", "PRAGMA", - "RAISE", "REPLACE", "RESTRICT", "ROW", - "TRIGGER", "VACUUM", "VIEW", "VIRTUAL", - "REINDEX", "RENAME", "CTIME_KW", "ANY", - "OR", "AND", "IS", "BETWEEN", - "IN", "ISNULL", "NOTNULL", "NE", - "EQ", "GT", "LE", "LT", - "GE", "ESCAPE", "BITAND", "BITOR", - "LSHIFT", "RSHIFT", "PLUS", "MINUS", - "STAR", "SLASH", "REM", "CONCAT", - "COLLATE", "BITNOT", "STRING", "JOIN_KW", - "CONSTRAINT", "DEFAULT", "NULL", "PRIMARY", - "UNIQUE", "CHECK", "REFERENCES", "AUTOINCR", - "ON", "INSERT", "DELETE", "UPDATE", - "SET", "DEFERRABLE", "FOREIGN", "DROP", - "UNION", "ALL", "EXCEPT", "INTERSECT", - "SELECT", "DISTINCT", "DOT", "FROM", - "JOIN", "USING", "ORDER", "GROUP", - "HAVING", "LIMIT", "WHERE", "INTO", - "VALUES", "INTEGER", "FLOAT", "BLOB", - "REGISTER", "VARIABLE", "CASE", "WHEN", - "THEN", "ELSE", "INDEX", "ALTER", - "ADD", "error", "input", "cmdlist", - "ecmd", "explain", "cmdx", "cmd", +static const char *const yyTokenName[] = { + "$", "SEMI", "EXPLAIN", "QUERY", + "PLAN", "BEGIN", "TRANSACTION", "DEFERRED", + "IMMEDIATE", "EXCLUSIVE", "COMMIT", "END", + "ROLLBACK", "SAVEPOINT", "RELEASE", "TO", + "TABLE", "CREATE", "IF", "NOT", + "EXISTS", "TEMP", "LP", "RP", + "AS", "COMMA", "ID", "INDEXED", + "ABORT", "ACTION", "AFTER", "ANALYZE", + "ASC", "ATTACH", "BEFORE", "BY", + "CASCADE", "CAST", "COLUMNKW", "CONFLICT", + "DATABASE", "DESC", "DETACH", "EACH", + "FAIL", "FOR", "IGNORE", "INITIALLY", + "INSTEAD", "LIKE_KW", "MATCH", "NO", + "KEY", "OF", "OFFSET", "PRAGMA", + "RAISE", "REPLACE", "RESTRICT", "ROW", + "TRIGGER", "VACUUM", "VIEW", "VIRTUAL", + "REINDEX", "RENAME", "CTIME_KW", "ANY", + "OR", "AND", "IS", "BETWEEN", + "IN", "ISNULL", "NOTNULL", "NE", + "EQ", "GT", "LE", "LT", + "GE", "ESCAPE", "BITAND", "BITOR", + "LSHIFT", "RSHIFT", "PLUS", "MINUS", + "STAR", "SLASH", "REM", "CONCAT", + "COLLATE", "BITNOT", "STRING", "JOIN_KW", + "CONSTRAINT", "DEFAULT", "NULL", "PRIMARY", + "UNIQUE", "CHECK", "REFERENCES", "AUTOINCR", + "ON", "INSERT", "DELETE", "UPDATE", + "SET", "DEFERRABLE", "FOREIGN", "DROP", + "UNION", "ALL", "EXCEPT", "INTERSECT", + "SELECT", "DISTINCT", "DOT", "FROM", + "JOIN", "USING", "ORDER", "GROUP", + "HAVING", "LIMIT", "WHERE", "INTO", + "VALUES", "INTEGER", "FLOAT", "BLOB", + "REGISTER", "VARIABLE", "CASE", "WHEN", + "THEN", "ELSE", "INDEX", "ALTER", + "ADD", "error", "input", "cmdlist", + "ecmd", "explain", "cmdx", "cmd", "transtype", "trans_opt", "nm", "savepoint_opt", - "create_table", "create_table_args", "createkw", "temp", + "create_table", "create_table_args", "createkw", "temp", "ifnotexists", "dbnm", "columnlist", "conslist_opt", - "select", "column", "columnid", "type", - "carglist", "id", "ids", "typetoken", - "typename", "signed", "plus_num", "minus_num", - "carg", "ccons", "term", "expr", - "onconf", "sortorder", "autoinc", "idxlist_opt", - "refargs", "defer_subclause", "refarg", "refact", - "init_deferred_pred_opt", "conslist", "tcons", "idxlist", - "defer_subclause_opt", "orconf", "resolvetype", "raisetype", + "select", "column", "columnid", "type", + "carglist", "id", "ids", "typetoken", + "typename", "signed", "plus_num", "minus_num", + "carg", "ccons", "term", "expr", + "onconf", "sortorder", "autoinc", "idxlist_opt", + "refargs", "defer_subclause", "refarg", "refact", + "init_deferred_pred_opt", "conslist", "tcons", "idxlist", + "defer_subclause_opt", "orconf", "resolvetype", "raisetype", "ifexists", "fullname", "oneselect", "multiselect_op", - "distinct", "selcollist", "from", "where_opt", - "groupby_opt", "having_opt", "orderby_opt", "limit_opt", - "sclp", "as", "seltablist", "stl_prefix", - "joinop", "indexed_opt", "on_opt", "using_opt", - "joinop2", "inscollist", "sortlist", "sortitem", + "distinct", "selcollist", "from", "where_opt", + "groupby_opt", "having_opt", "orderby_opt", "limit_opt", + "sclp", "as", "seltablist", "stl_prefix", + "joinop", "indexed_opt", "on_opt", "using_opt", + "joinop2", "inscollist", "sortlist", "sortitem", "nexprlist", "setlist", "insert_cmd", "inscollist_opt", - "itemlist", "exprlist", "likeop", "escape", - "between_op", "in_op", "case_operand", "case_exprlist", - "case_else", "uniqueflag", "collate", "nmnum", - "plus_opt", "number", "trigger_decl", "trigger_cmd_list", - "trigger_time", "trigger_event", "foreach_clause", "when_clause", - "trigger_cmd", "trnm", "tridxby", "database_kw_opt", - "key_opt", "add_column_fullname", "kwcolumn_opt", "create_vtab", - "vtabarglist", "vtabarg", "vtabargtoken", "lp", - "anylist", + "itemlist", "exprlist", "likeop", "between_op", + "in_op", "case_operand", "case_exprlist", "case_else", + "uniqueflag", "collate", "nmnum", "plus_opt", + "number", "trigger_decl", "trigger_cmd_list", "trigger_time", + "trigger_event", "foreach_clause", "when_clause", "trigger_cmd", + "trnm", "tridxby", "database_kw_opt", "key_opt", + "add_column_fullname", "kwcolumn_opt", "create_vtab", "vtabarglist", + "vtabarg", "vtabargtoken", "lp", "anylist", }; #endif /* NDEBUG */ @@ -93061,124 +106726,123 @@ static const char *const yyRuleName[] = { /* 209 */ "likeop ::= NOT LIKE_KW", /* 210 */ "likeop ::= MATCH", /* 211 */ "likeop ::= NOT MATCH", - /* 212 */ "escape ::= ESCAPE expr", - /* 213 */ "escape ::=", - /* 214 */ "expr ::= expr likeop expr escape", - /* 215 */ "expr ::= expr ISNULL|NOTNULL", - /* 216 */ "expr ::= expr NOT NULL", - /* 217 */ "expr ::= expr IS expr", - /* 218 */ "expr ::= expr IS NOT expr", - /* 219 */ "expr ::= NOT expr", - /* 220 */ "expr ::= BITNOT expr", - /* 221 */ "expr ::= MINUS expr", - /* 222 */ "expr ::= PLUS expr", - /* 223 */ "between_op ::= BETWEEN", - /* 224 */ "between_op ::= NOT BETWEEN", - /* 225 */ "expr ::= expr between_op expr AND expr", - /* 226 */ "in_op ::= IN", - /* 227 */ "in_op ::= NOT IN", - /* 228 */ "expr ::= expr in_op LP exprlist RP", - /* 229 */ "expr ::= LP select RP", - /* 230 */ "expr ::= expr in_op LP select RP", - /* 231 */ "expr ::= expr in_op nm dbnm", - /* 232 */ "expr ::= EXISTS LP select RP", - /* 233 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 234 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 235 */ "case_exprlist ::= WHEN expr THEN expr", - /* 236 */ "case_else ::= ELSE expr", - /* 237 */ "case_else ::=", - /* 238 */ "case_operand ::= expr", - /* 239 */ "case_operand ::=", - /* 240 */ "exprlist ::= nexprlist", - /* 241 */ "exprlist ::=", - /* 242 */ "nexprlist ::= nexprlist COMMA expr", - /* 243 */ "nexprlist ::= expr", - /* 244 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP", - /* 245 */ "uniqueflag ::= UNIQUE", - /* 246 */ "uniqueflag ::=", - /* 247 */ "idxlist_opt ::=", - /* 248 */ "idxlist_opt ::= LP idxlist RP", - /* 249 */ "idxlist ::= idxlist COMMA nm collate sortorder", - /* 250 */ "idxlist ::= nm collate sortorder", - /* 251 */ "collate ::=", - /* 252 */ "collate ::= COLLATE ids", - /* 253 */ "cmd ::= DROP INDEX ifexists fullname", - /* 254 */ "cmd ::= VACUUM", - /* 255 */ "cmd ::= VACUUM nm", - /* 256 */ "cmd ::= PRAGMA nm dbnm", - /* 257 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 258 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 259 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 260 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 261 */ "nmnum ::= plus_num", - /* 262 */ "nmnum ::= nm", - /* 263 */ "nmnum ::= ON", - /* 264 */ "nmnum ::= DELETE", - /* 265 */ "nmnum ::= DEFAULT", - /* 266 */ "plus_num ::= plus_opt number", - /* 267 */ "minus_num ::= MINUS number", - /* 268 */ "number ::= INTEGER|FLOAT", - /* 269 */ "plus_opt ::= PLUS", - /* 270 */ "plus_opt ::=", - /* 271 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 272 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 273 */ "trigger_time ::= BEFORE", - /* 274 */ "trigger_time ::= AFTER", - /* 275 */ "trigger_time ::= INSTEAD OF", - /* 276 */ "trigger_time ::=", - /* 277 */ "trigger_event ::= DELETE|INSERT", - /* 278 */ "trigger_event ::= UPDATE", - /* 279 */ "trigger_event ::= UPDATE OF inscollist", - /* 280 */ "foreach_clause ::=", - /* 281 */ "foreach_clause ::= FOR EACH ROW", - /* 282 */ "when_clause ::=", - /* 283 */ "when_clause ::= WHEN expr", - /* 284 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 285 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 286 */ "trnm ::= nm", - /* 287 */ "trnm ::= nm DOT nm", - /* 288 */ "tridxby ::=", - /* 289 */ "tridxby ::= INDEXED BY nm", - /* 290 */ "tridxby ::= NOT INDEXED", - /* 291 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt", - /* 292 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP", - /* 293 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select", - /* 294 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt", - /* 295 */ "trigger_cmd ::= select", - /* 296 */ "expr ::= RAISE LP IGNORE RP", - /* 297 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 298 */ "raisetype ::= ROLLBACK", - /* 299 */ "raisetype ::= ABORT", - /* 300 */ "raisetype ::= FAIL", - /* 301 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 302 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 303 */ "cmd ::= DETACH database_kw_opt expr", - /* 304 */ "key_opt ::=", - /* 305 */ "key_opt ::= KEY expr", - /* 306 */ "database_kw_opt ::= DATABASE", - /* 307 */ "database_kw_opt ::=", - /* 308 */ "cmd ::= REINDEX", - /* 309 */ "cmd ::= REINDEX nm dbnm", - /* 310 */ "cmd ::= ANALYZE", - /* 311 */ "cmd ::= ANALYZE nm dbnm", - /* 312 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 313 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", - /* 314 */ "add_column_fullname ::= fullname", - /* 315 */ "kwcolumn_opt ::=", - /* 316 */ "kwcolumn_opt ::= COLUMNKW", - /* 317 */ "cmd ::= create_vtab", - /* 318 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 319 */ "create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm", - /* 320 */ "vtabarglist ::= vtabarg", - /* 321 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 322 */ "vtabarg ::=", - /* 323 */ "vtabarg ::= vtabarg vtabargtoken", - /* 324 */ "vtabargtoken ::= ANY", - /* 325 */ "vtabargtoken ::= lp anylist RP", - /* 326 */ "lp ::= LP", - /* 327 */ "anylist ::=", - /* 328 */ "anylist ::= anylist LP anylist RP", - /* 329 */ "anylist ::= anylist ANY", + /* 212 */ "expr ::= expr likeop expr", + /* 213 */ "expr ::= expr likeop expr ESCAPE expr", + /* 214 */ "expr ::= expr ISNULL|NOTNULL", + /* 215 */ "expr ::= expr NOT NULL", + /* 216 */ "expr ::= expr IS expr", + /* 217 */ "expr ::= expr IS NOT expr", + /* 218 */ "expr ::= NOT expr", + /* 219 */ "expr ::= BITNOT expr", + /* 220 */ "expr ::= MINUS expr", + /* 221 */ "expr ::= PLUS expr", + /* 222 */ "between_op ::= BETWEEN", + /* 223 */ "between_op ::= NOT BETWEEN", + /* 224 */ "expr ::= expr between_op expr AND expr", + /* 225 */ "in_op ::= IN", + /* 226 */ "in_op ::= NOT IN", + /* 227 */ "expr ::= expr in_op LP exprlist RP", + /* 228 */ "expr ::= LP select RP", + /* 229 */ "expr ::= expr in_op LP select RP", + /* 230 */ "expr ::= expr in_op nm dbnm", + /* 231 */ "expr ::= EXISTS LP select RP", + /* 232 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 233 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 234 */ "case_exprlist ::= WHEN expr THEN expr", + /* 235 */ "case_else ::= ELSE expr", + /* 236 */ "case_else ::=", + /* 237 */ "case_operand ::= expr", + /* 238 */ "case_operand ::=", + /* 239 */ "exprlist ::= nexprlist", + /* 240 */ "exprlist ::=", + /* 241 */ "nexprlist ::= nexprlist COMMA expr", + /* 242 */ "nexprlist ::= expr", + /* 243 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP", + /* 244 */ "uniqueflag ::= UNIQUE", + /* 245 */ "uniqueflag ::=", + /* 246 */ "idxlist_opt ::=", + /* 247 */ "idxlist_opt ::= LP idxlist RP", + /* 248 */ "idxlist ::= idxlist COMMA nm collate sortorder", + /* 249 */ "idxlist ::= nm collate sortorder", + /* 250 */ "collate ::=", + /* 251 */ "collate ::= COLLATE ids", + /* 252 */ "cmd ::= DROP INDEX ifexists fullname", + /* 253 */ "cmd ::= VACUUM", + /* 254 */ "cmd ::= VACUUM nm", + /* 255 */ "cmd ::= PRAGMA nm dbnm", + /* 256 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 257 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 258 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 259 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 260 */ "nmnum ::= plus_num", + /* 261 */ "nmnum ::= nm", + /* 262 */ "nmnum ::= ON", + /* 263 */ "nmnum ::= DELETE", + /* 264 */ "nmnum ::= DEFAULT", + /* 265 */ "plus_num ::= plus_opt number", + /* 266 */ "minus_num ::= MINUS number", + /* 267 */ "number ::= INTEGER|FLOAT", + /* 268 */ "plus_opt ::= PLUS", + /* 269 */ "plus_opt ::=", + /* 270 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 271 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 272 */ "trigger_time ::= BEFORE", + /* 273 */ "trigger_time ::= AFTER", + /* 274 */ "trigger_time ::= INSTEAD OF", + /* 275 */ "trigger_time ::=", + /* 276 */ "trigger_event ::= DELETE|INSERT", + /* 277 */ "trigger_event ::= UPDATE", + /* 278 */ "trigger_event ::= UPDATE OF inscollist", + /* 279 */ "foreach_clause ::=", + /* 280 */ "foreach_clause ::= FOR EACH ROW", + /* 281 */ "when_clause ::=", + /* 282 */ "when_clause ::= WHEN expr", + /* 283 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 284 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 285 */ "trnm ::= nm", + /* 286 */ "trnm ::= nm DOT nm", + /* 287 */ "tridxby ::=", + /* 288 */ "tridxby ::= INDEXED BY nm", + /* 289 */ "tridxby ::= NOT INDEXED", + /* 290 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt", + /* 291 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP", + /* 292 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select", + /* 293 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt", + /* 294 */ "trigger_cmd ::= select", + /* 295 */ "expr ::= RAISE LP IGNORE RP", + /* 296 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 297 */ "raisetype ::= ROLLBACK", + /* 298 */ "raisetype ::= ABORT", + /* 299 */ "raisetype ::= FAIL", + /* 300 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 301 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 302 */ "cmd ::= DETACH database_kw_opt expr", + /* 303 */ "key_opt ::=", + /* 304 */ "key_opt ::= KEY expr", + /* 305 */ "database_kw_opt ::= DATABASE", + /* 306 */ "database_kw_opt ::=", + /* 307 */ "cmd ::= REINDEX", + /* 308 */ "cmd ::= REINDEX nm dbnm", + /* 309 */ "cmd ::= ANALYZE", + /* 310 */ "cmd ::= ANALYZE nm dbnm", + /* 311 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 312 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", + /* 313 */ "add_column_fullname ::= fullname", + /* 314 */ "kwcolumn_opt ::=", + /* 315 */ "kwcolumn_opt ::= COLUMNKW", + /* 316 */ "cmd ::= create_vtab", + /* 317 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 318 */ "create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm", + /* 319 */ "vtabarglist ::= vtabarg", + /* 320 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 321 */ "vtabarg ::=", + /* 322 */ "vtabarg ::= vtabarg vtabargtoken", + /* 323 */ "vtabargtoken ::= ANY", + /* 324 */ "vtabargtoken ::= lp anylist RP", + /* 325 */ "lp ::= LP", + /* 326 */ "anylist ::=", + /* 327 */ "anylist ::= anylist LP anylist RP", + /* 328 */ "anylist ::= anylist ANY", }; #endif /* NDEBUG */ @@ -93206,7 +106870,7 @@ static void yyGrowStack(yyParser *p){ } #endif -/* +/* ** This function allocates a new parser. ** The only argument is a pointer to a function which works like ** malloc. @@ -93250,7 +106914,7 @@ static void yy_destructor( /* Here is inserted the actions which take place when a ** terminal or non-terminal is destroyed. This can happen ** when the symbol is popped from the stack during a - ** reduce or during error processing or when a parser is + ** reduce or during error processing or when a parser is ** being destroyed before it is finished parsing. ** ** Note: during a reduce, the only symbols destroyed are those @@ -93260,14 +106924,13 @@ static void yy_destructor( case 160: /* select */ case 194: /* oneselect */ { -sqlite3SelectDelete(pParse->db, (yypminor->yy3)); +sqlite3SelectDelete(pParse->db, (yypminor->yy387)); } break; case 174: /* term */ case 175: /* expr */ - case 223: /* escape */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy346).pExpr); +sqlite3ExprDelete(pParse->db, (yypminor->yy118).pExpr); } break; case 179: /* idxlist_opt */ @@ -93281,9 +106944,9 @@ sqlite3ExprDelete(pParse->db, (yypminor->yy346).pExpr); case 217: /* setlist */ case 220: /* itemlist */ case 221: /* exprlist */ - case 227: /* case_exprlist */ + case 226: /* case_exprlist */ { -sqlite3ExprListDelete(pParse->db, (yypminor->yy14)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy322)); } break; case 193: /* fullname */ @@ -93291,37 +106954,37 @@ sqlite3ExprListDelete(pParse->db, (yypminor->yy14)); case 206: /* seltablist */ case 207: /* stl_prefix */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy65)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy259)); } break; case 199: /* where_opt */ case 201: /* having_opt */ case 210: /* on_opt */ case 215: /* sortitem */ - case 226: /* case_operand */ - case 228: /* case_else */ - case 239: /* when_clause */ - case 244: /* key_opt */ + case 225: /* case_operand */ + case 227: /* case_else */ + case 238: /* when_clause */ + case 243: /* key_opt */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy132)); +sqlite3ExprDelete(pParse->db, (yypminor->yy314)); } break; case 211: /* using_opt */ case 213: /* inscollist */ case 219: /* inscollist_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy408)); +sqlite3IdListDelete(pParse->db, (yypminor->yy384)); } break; - case 235: /* trigger_cmd_list */ - case 240: /* trigger_cmd */ + case 234: /* trigger_cmd_list */ + case 239: /* trigger_cmd */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy473)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy203)); } break; - case 237: /* trigger_event */ + case 236: /* trigger_event */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy378).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy90).b); } break; default: break; /* If no destructor action specified: do nothing */ @@ -93356,7 +107019,7 @@ static int yy_pop_parser_stack(yyParser *pParser){ return yymajor; } -/* +/* ** Deallocate and destroy a parser. Destructors are all called for ** all stack elements before shutting the parser down. ** @@ -93407,7 +107070,7 @@ static int yy_find_shift_action( ){ int i; int stateno = pParser->yystack[pParser->yyidx].stateno; - + if( stateno>YY_SHIFT_COUNT || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ return yy_default[stateno]; @@ -93432,7 +107095,7 @@ static int yy_find_shift_action( #ifdef YYWILDCARD { int j = i - iLookAhead + YYWILDCARD; - if( + if( #if YY_SHIFT_MIN+YYWILDCARD<0 j>=0 && #endif @@ -93530,7 +107193,7 @@ static void yy_shift( yypParser->yyidxMax = yypParser->yyidx; } #endif -#if YYSTACKDEPTH>0 +#if YYSTACKDEPTH>0 if( yypParser->yyidx>=YYSTACKDEPTH ){ yyStackOverflow(yypParser, yypMinor); return; @@ -93779,9 +107442,8 @@ static const struct { { 222, 2 }, { 222, 1 }, { 222, 2 }, - { 223, 2 }, - { 223, 0 }, - { 175, 4 }, + { 175, 3 }, + { 175, 5 }, { 175, 2 }, { 175, 3 }, { 175, 3 }, @@ -93790,36 +107452,36 @@ static const struct { { 175, 2 }, { 175, 2 }, { 175, 2 }, + { 223, 1 }, + { 223, 2 }, + { 175, 5 }, { 224, 1 }, { 224, 2 }, { 175, 5 }, - { 225, 1 }, - { 225, 2 }, - { 175, 5 }, { 175, 3 }, { 175, 5 }, { 175, 4 }, { 175, 4 }, { 175, 5 }, - { 227, 5 }, - { 227, 4 }, - { 228, 2 }, - { 228, 0 }, - { 226, 1 }, - { 226, 0 }, + { 226, 5 }, + { 226, 4 }, + { 227, 2 }, + { 227, 0 }, + { 225, 1 }, + { 225, 0 }, { 221, 1 }, { 221, 0 }, { 216, 3 }, { 216, 1 }, { 147, 11 }, - { 229, 1 }, - { 229, 0 }, + { 228, 1 }, + { 228, 0 }, { 179, 0 }, { 179, 3 }, { 187, 5 }, { 187, 3 }, - { 230, 0 }, - { 230, 2 }, + { 229, 0 }, + { 229, 2 }, { 147, 4 }, { 147, 1 }, { 147, 2 }, @@ -93828,41 +107490,41 @@ static const struct { { 147, 6 }, { 147, 5 }, { 147, 6 }, - { 231, 1 }, - { 231, 1 }, - { 231, 1 }, - { 231, 1 }, - { 231, 1 }, + { 230, 1 }, + { 230, 1 }, + { 230, 1 }, + { 230, 1 }, + { 230, 1 }, { 170, 2 }, { 171, 2 }, - { 233, 1 }, { 232, 1 }, - { 232, 0 }, + { 231, 1 }, + { 231, 0 }, { 147, 5 }, - { 234, 11 }, + { 233, 11 }, + { 235, 1 }, + { 235, 1 }, + { 235, 2 }, + { 235, 0 }, { 236, 1 }, { 236, 1 }, - { 236, 2 }, - { 236, 0 }, - { 237, 1 }, - { 237, 1 }, + { 236, 3 }, + { 237, 0 }, { 237, 3 }, { 238, 0 }, - { 238, 3 }, - { 239, 0 }, - { 239, 2 }, - { 235, 3 }, - { 235, 2 }, - { 241, 1 }, - { 241, 3 }, - { 242, 0 }, - { 242, 3 }, - { 242, 2 }, - { 240, 7 }, - { 240, 8 }, - { 240, 5 }, - { 240, 5 }, + { 238, 2 }, + { 234, 3 }, + { 234, 2 }, { 240, 1 }, + { 240, 3 }, + { 241, 0 }, + { 241, 3 }, + { 241, 2 }, + { 239, 7 }, + { 239, 8 }, + { 239, 5 }, + { 239, 5 }, + { 239, 1 }, { 175, 4 }, { 175, 6 }, { 191, 1 }, @@ -93871,32 +107533,32 @@ static const struct { { 147, 4 }, { 147, 6 }, { 147, 3 }, - { 244, 0 }, - { 244, 2 }, - { 243, 1 }, { 243, 0 }, + { 243, 2 }, + { 242, 1 }, + { 242, 0 }, { 147, 1 }, { 147, 3 }, { 147, 1 }, { 147, 3 }, { 147, 6 }, { 147, 6 }, + { 244, 1 }, + { 245, 0 }, { 245, 1 }, - { 246, 0 }, - { 246, 1 }, { 147, 1 }, { 147, 4 }, - { 247, 7 }, - { 248, 1 }, - { 248, 3 }, - { 249, 0 }, - { 249, 2 }, + { 246, 7 }, + { 247, 1 }, + { 247, 3 }, + { 248, 0 }, + { 248, 2 }, + { 249, 1 }, + { 249, 3 }, { 250, 1 }, - { 250, 3 }, - { 251, 1 }, - { 252, 0 }, - { 252, 4 }, - { 252, 2 }, + { 251, 0 }, + { 251, 4 }, + { 251, 2 }, }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -93917,7 +107579,7 @@ static void yy_reduce( sqlite3ParserARG_FETCH; yymsp = &yypParser->yystack[yypParser->yyidx]; #ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 + if( yyTraceFILE && yyruleno>=0 && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, yyRuleName[yyruleno]); @@ -93930,7 +107592,7 @@ static void yy_reduce( ** not set the value of its left-hand side nonterminal. Leaving the ** value of the nonterminal uninitialized is utterly harmless as long ** as the value is never used. So really the only thing this code - ** accomplishes is to quieten purify. + ** accomplishes is to quieten purify. ** ** 2007-01-16: The wireshark project (www.wireshark.org) reports that ** without this code, their parser segfaults. I'm not sure what there @@ -93964,17 +107626,17 @@ static void yy_reduce( { sqlite3FinishCoding(pParse); } break; case 9: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy328);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy4);} break; case 13: /* transtype ::= */ -{yygotominor.yy328 = TK_DEFERRED;} +{yygotominor.yy4 = TK_DEFERRED;} break; case 14: /* transtype ::= DEFERRED */ case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15); case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16); case 115: /* multiselect_op ::= UNION */ yytestcase(yyruleno==115); case 117: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==117); -{yygotominor.yy328 = yymsp[0].major;} +{yygotominor.yy4 = yymsp[0].major;} break; case 17: /* cmd ::= COMMIT trans_opt */ case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18); @@ -94000,7 +107662,7 @@ static void yy_reduce( break; case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { - sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy328,0,0,yymsp[-2].minor.yy328); + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy4,0,0,yymsp[-2].minor.yy4); } break; case 27: /* createkw ::= CREATE */ @@ -94019,9 +107681,9 @@ static void yy_reduce( case 109: /* ifexists ::= */ yytestcase(yyruleno==109); case 120: /* distinct ::= ALL */ yytestcase(yyruleno==120); case 121: /* distinct ::= */ yytestcase(yyruleno==121); - case 223: /* between_op ::= BETWEEN */ yytestcase(yyruleno==223); - case 226: /* in_op ::= IN */ yytestcase(yyruleno==226); -{yygotominor.yy328 = 0;} + case 222: /* between_op ::= BETWEEN */ yytestcase(yyruleno==222); + case 225: /* in_op ::= IN */ yytestcase(yyruleno==225); +{yygotominor.yy4 = 0;} break; case 29: /* ifnotexists ::= IF NOT EXISTS */ case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30); @@ -94029,9 +107691,9 @@ static void yy_reduce( case 86: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==86); case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108); case 119: /* distinct ::= DISTINCT */ yytestcase(yyruleno==119); - case 224: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==224); - case 227: /* in_op ::= NOT IN */ yytestcase(yyruleno==227); -{yygotominor.yy328 = 1;} + case 223: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==223); + case 226: /* in_op ::= NOT IN */ yytestcase(yyruleno==226); +{yygotominor.yy4 = 1;} break; case 32: /* create_table_args ::= LP columnlist conslist_opt RP */ { @@ -94040,8 +107702,8 @@ static void yy_reduce( break; case 33: /* create_table_args ::= AS select */ { - sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy3); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3); + sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy387); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387); } break; case 36: /* column ::= columnid type carglist */ @@ -94068,16 +107730,16 @@ static void yy_reduce( case 128: /* as ::= ids */ yytestcase(yyruleno==128); case 138: /* dbnm ::= DOT nm */ yytestcase(yyruleno==138); case 147: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==147); - case 252: /* collate ::= COLLATE ids */ yytestcase(yyruleno==252); - case 261: /* nmnum ::= plus_num */ yytestcase(yyruleno==261); - case 262: /* nmnum ::= nm */ yytestcase(yyruleno==262); - case 263: /* nmnum ::= ON */ yytestcase(yyruleno==263); - case 264: /* nmnum ::= DELETE */ yytestcase(yyruleno==264); - case 265: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==265); - case 266: /* plus_num ::= plus_opt number */ yytestcase(yyruleno==266); - case 267: /* minus_num ::= MINUS number */ yytestcase(yyruleno==267); - case 268: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==268); - case 286: /* trnm ::= nm */ yytestcase(yyruleno==286); + case 251: /* collate ::= COLLATE ids */ yytestcase(yyruleno==251); + case 260: /* nmnum ::= plus_num */ yytestcase(yyruleno==260); + case 261: /* nmnum ::= nm */ yytestcase(yyruleno==261); + case 262: /* nmnum ::= ON */ yytestcase(yyruleno==262); + case 263: /* nmnum ::= DELETE */ yytestcase(yyruleno==263); + case 264: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==264); + case 265: /* plus_num ::= plus_opt number */ yytestcase(yyruleno==265); + case 266: /* minus_num ::= MINUS number */ yytestcase(yyruleno==266); + case 267: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==267); + case 285: /* trnm ::= nm */ yytestcase(yyruleno==285); {yygotominor.yy0 = yymsp[0].minor.yy0;} break; case 45: /* type ::= typetoken */ @@ -94100,17 +107762,17 @@ static void yy_reduce( break; case 57: /* ccons ::= DEFAULT term */ case 59: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==59); -{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy346);} +{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy118);} break; case 58: /* ccons ::= DEFAULT LP expr RP */ -{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy346);} +{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy118);} break; case 60: /* ccons ::= DEFAULT MINUS term */ { ExprSpan v; - v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy346.pExpr, 0, 0); + v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy118.pExpr, 0, 0); v.zStart = yymsp[-1].minor.yy0.z; - v.zEnd = yymsp[0].minor.yy346.zEnd; + v.zEnd = yymsp[0].minor.yy118.zEnd; sqlite3AddDefaultValue(pParse,&v); } break; @@ -94122,62 +107784,62 @@ static void yy_reduce( } break; case 63: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy328);} +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy4);} break; case 64: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy328,yymsp[0].minor.yy328,yymsp[-2].minor.yy328);} +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy4,yymsp[0].minor.yy4,yymsp[-2].minor.yy4);} break; case 65: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy328,0,0,0,0);} +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy4,0,0,0,0);} break; case 66: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy346.pExpr);} +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy118.pExpr);} break; case 67: /* ccons ::= REFERENCES nm idxlist_opt refargs */ -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy328);} +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy4);} break; case 68: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy328);} +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy4);} break; case 69: /* ccons ::= COLLATE ids */ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; case 72: /* refargs ::= */ -{ yygotominor.yy328 = OE_None*0x0101; /* EV: R-19803-45884 */} +{ yygotominor.yy4 = OE_None*0x0101; /* EV: R-19803-45884 */} break; case 73: /* refargs ::= refargs refarg */ -{ yygotominor.yy328 = (yymsp[-1].minor.yy328 & ~yymsp[0].minor.yy429.mask) | yymsp[0].minor.yy429.value; } +{ yygotominor.yy4 = (yymsp[-1].minor.yy4 & ~yymsp[0].minor.yy215.mask) | yymsp[0].minor.yy215.value; } break; case 74: /* refarg ::= MATCH nm */ case 75: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==75); -{ yygotominor.yy429.value = 0; yygotominor.yy429.mask = 0x000000; } +{ yygotominor.yy215.value = 0; yygotominor.yy215.mask = 0x000000; } break; case 76: /* refarg ::= ON DELETE refact */ -{ yygotominor.yy429.value = yymsp[0].minor.yy328; yygotominor.yy429.mask = 0x0000ff; } +{ yygotominor.yy215.value = yymsp[0].minor.yy4; yygotominor.yy215.mask = 0x0000ff; } break; case 77: /* refarg ::= ON UPDATE refact */ -{ yygotominor.yy429.value = yymsp[0].minor.yy328<<8; yygotominor.yy429.mask = 0x00ff00; } +{ yygotominor.yy215.value = yymsp[0].minor.yy4<<8; yygotominor.yy215.mask = 0x00ff00; } break; case 78: /* refact ::= SET NULL */ -{ yygotominor.yy328 = OE_SetNull; /* EV: R-33326-45252 */} +{ yygotominor.yy4 = OE_SetNull; /* EV: R-33326-45252 */} break; case 79: /* refact ::= SET DEFAULT */ -{ yygotominor.yy328 = OE_SetDflt; /* EV: R-33326-45252 */} +{ yygotominor.yy4 = OE_SetDflt; /* EV: R-33326-45252 */} break; case 80: /* refact ::= CASCADE */ -{ yygotominor.yy328 = OE_Cascade; /* EV: R-33326-45252 */} +{ yygotominor.yy4 = OE_Cascade; /* EV: R-33326-45252 */} break; case 81: /* refact ::= RESTRICT */ -{ yygotominor.yy328 = OE_Restrict; /* EV: R-33326-45252 */} +{ yygotominor.yy4 = OE_Restrict; /* EV: R-33326-45252 */} break; case 82: /* refact ::= NO ACTION */ -{ yygotominor.yy328 = OE_None; /* EV: R-33326-45252 */} +{ yygotominor.yy4 = OE_None; /* EV: R-33326-45252 */} break; case 84: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ case 99: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==99); case 101: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==101); case 104: /* resolvetype ::= raisetype */ yytestcase(yyruleno==104); -{yygotominor.yy328 = yymsp[0].minor.yy328;} +{yygotominor.yy4 = yymsp[0].minor.yy4;} break; case 88: /* conslist_opt ::= */ {yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;} @@ -94186,101 +107848,101 @@ static void yy_reduce( {yygotominor.yy0 = yymsp[-1].minor.yy0;} break; case 94: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */ -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy328,yymsp[-2].minor.yy328,0);} +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy4,yymsp[-2].minor.yy4,0);} break; case 95: /* tcons ::= UNIQUE LP idxlist RP onconf */ -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy328,0,0,0,0);} +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy4,0,0,0,0);} break; case 96: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy346.pExpr);} +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy118.pExpr);} break; case 97: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */ { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy328); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy328); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy4); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy4); } break; case 100: /* onconf ::= */ -{yygotominor.yy328 = OE_Default;} +{yygotominor.yy4 = OE_Default;} break; case 102: /* orconf ::= */ -{yygotominor.yy186 = OE_Default;} +{yygotominor.yy210 = OE_Default;} break; case 103: /* orconf ::= OR resolvetype */ -{yygotominor.yy186 = (u8)yymsp[0].minor.yy328;} +{yygotominor.yy210 = (u8)yymsp[0].minor.yy4;} break; case 105: /* resolvetype ::= IGNORE */ -{yygotominor.yy328 = OE_Ignore;} +{yygotominor.yy4 = OE_Ignore;} break; case 106: /* resolvetype ::= REPLACE */ -{yygotominor.yy328 = OE_Replace;} +{yygotominor.yy4 = OE_Replace;} break; case 107: /* cmd ::= DROP TABLE ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy65, 0, yymsp[-1].minor.yy328); + sqlite3DropTable(pParse, yymsp[0].minor.yy259, 0, yymsp[-1].minor.yy4); } break; case 110: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */ { - sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy3, yymsp[-6].minor.yy328, yymsp[-4].minor.yy328); + sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy387, yymsp[-6].minor.yy4, yymsp[-4].minor.yy4); } break; case 111: /* cmd ::= DROP VIEW ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy65, 1, yymsp[-1].minor.yy328); + sqlite3DropTable(pParse, yymsp[0].minor.yy259, 1, yymsp[-1].minor.yy4); } break; case 112: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy3, &dest); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3); + sqlite3Select(pParse, yymsp[0].minor.yy387, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387); } break; case 113: /* select ::= oneselect */ -{yygotominor.yy3 = yymsp[0].minor.yy3;} +{yygotominor.yy387 = yymsp[0].minor.yy387;} break; case 114: /* select ::= select multiselect_op oneselect */ { - if( yymsp[0].minor.yy3 ){ - yymsp[0].minor.yy3->op = (u8)yymsp[-1].minor.yy328; - yymsp[0].minor.yy3->pPrior = yymsp[-2].minor.yy3; + if( yymsp[0].minor.yy387 ){ + yymsp[0].minor.yy387->op = (u8)yymsp[-1].minor.yy4; + yymsp[0].minor.yy387->pPrior = yymsp[-2].minor.yy387; }else{ - sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy3); + sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy387); } - yygotominor.yy3 = yymsp[0].minor.yy3; + yygotominor.yy387 = yymsp[0].minor.yy387; } break; case 116: /* multiselect_op ::= UNION ALL */ -{yygotominor.yy328 = TK_ALL;} +{yygotominor.yy4 = TK_ALL;} break; case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { - yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy65,yymsp[-4].minor.yy132,yymsp[-3].minor.yy14,yymsp[-2].minor.yy132,yymsp[-1].minor.yy14,yymsp[-7].minor.yy328,yymsp[0].minor.yy476.pLimit,yymsp[0].minor.yy476.pOffset); + yygotominor.yy387 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy259,yymsp[-4].minor.yy314,yymsp[-3].minor.yy322,yymsp[-2].minor.yy314,yymsp[-1].minor.yy322,yymsp[-7].minor.yy4,yymsp[0].minor.yy292.pLimit,yymsp[0].minor.yy292.pOffset); } break; case 122: /* sclp ::= selcollist COMMA */ - case 248: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==248); -{yygotominor.yy14 = yymsp[-1].minor.yy14;} + case 247: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==247); +{yygotominor.yy322 = yymsp[-1].minor.yy322;} break; case 123: /* sclp ::= */ case 151: /* orderby_opt ::= */ yytestcase(yyruleno==151); case 159: /* groupby_opt ::= */ yytestcase(yyruleno==159); - case 241: /* exprlist ::= */ yytestcase(yyruleno==241); - case 247: /* idxlist_opt ::= */ yytestcase(yyruleno==247); -{yygotominor.yy14 = 0;} + case 240: /* exprlist ::= */ yytestcase(yyruleno==240); + case 246: /* idxlist_opt ::= */ yytestcase(yyruleno==246); +{yygotominor.yy322 = 0;} break; case 124: /* selcollist ::= sclp expr as */ { - yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, yymsp[-1].minor.yy346.pExpr); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yygotominor.yy14,&yymsp[-1].minor.yy346); + yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, yymsp[-1].minor.yy118.pExpr); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yygotominor.yy322,&yymsp[-1].minor.yy118); } break; case 125: /* selcollist ::= sclp STAR */ { Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0); - yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy14, p); + yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy322, p); } break; case 126: /* selcollist ::= sclp nm DOT STAR */ @@ -94288,50 +107950,50 @@ static void yy_reduce( Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0); Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); - yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, pDot); + yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, pDot); } break; case 129: /* as ::= */ {yygotominor.yy0.n = 0;} break; case 130: /* from ::= */ -{yygotominor.yy65 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy65));} +{yygotominor.yy259 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy259));} break; case 131: /* from ::= FROM seltablist */ { - yygotominor.yy65 = yymsp[0].minor.yy65; - sqlite3SrcListShiftJoinType(yygotominor.yy65); + yygotominor.yy259 = yymsp[0].minor.yy259; + sqlite3SrcListShiftJoinType(yygotominor.yy259); } break; case 132: /* stl_prefix ::= seltablist joinop */ { - yygotominor.yy65 = yymsp[-1].minor.yy65; - if( ALWAYS(yygotominor.yy65 && yygotominor.yy65->nSrc>0) ) yygotominor.yy65->a[yygotominor.yy65->nSrc-1].jointype = (u8)yymsp[0].minor.yy328; + yygotominor.yy259 = yymsp[-1].minor.yy259; + if( ALWAYS(yygotominor.yy259 && yygotominor.yy259->nSrc>0) ) yygotominor.yy259->a[yygotominor.yy259->nSrc-1].jointype = (u8)yymsp[0].minor.yy4; } break; case 133: /* stl_prefix ::= */ -{yygotominor.yy65 = 0;} +{yygotominor.yy259 = 0;} break; case 134: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ { - yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy132,yymsp[0].minor.yy408); - sqlite3SrcListIndexedBy(pParse, yygotominor.yy65, &yymsp[-2].minor.yy0); + yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384); + sqlite3SrcListIndexedBy(pParse, yygotominor.yy259, &yymsp[-2].minor.yy0); } break; case 135: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ { - yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy3,yymsp[-1].minor.yy132,yymsp[0].minor.yy408); + yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy387,yymsp[-1].minor.yy314,yymsp[0].minor.yy384); } break; case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ { - if( yymsp[-6].minor.yy65==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy132==0 && yymsp[0].minor.yy408==0 ){ - yygotominor.yy65 = yymsp[-4].minor.yy65; + if( yymsp[-6].minor.yy259==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy314==0 && yymsp[0].minor.yy384==0 ){ + yygotominor.yy259 = yymsp[-4].minor.yy259; }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy65); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy65,0,0,0,0,0,0,0); - yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy132,yymsp[0].minor.yy408); + sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy259); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy259,0,0,0,0,0,0,0); + yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy314,yymsp[0].minor.yy384); } } break; @@ -94340,158 +108002,157 @@ static void yy_reduce( {yygotominor.yy0.z=0; yygotominor.yy0.n=0;} break; case 139: /* fullname ::= nm dbnm */ -{yygotominor.yy65 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} +{yygotominor.yy259 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} break; case 140: /* joinop ::= COMMA|JOIN */ -{ yygotominor.yy328 = JT_INNER; } +{ yygotominor.yy4 = JT_INNER; } break; case 141: /* joinop ::= JOIN_KW JOIN */ -{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } +{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } break; case 142: /* joinop ::= JOIN_KW nm JOIN */ -{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); } +{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); } break; case 143: /* joinop ::= JOIN_KW nm nm JOIN */ -{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); } +{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); } break; case 144: /* on_opt ::= ON expr */ case 155: /* sortitem ::= expr */ yytestcase(yyruleno==155); case 162: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==162); case 169: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==169); - case 236: /* case_else ::= ELSE expr */ yytestcase(yyruleno==236); - case 238: /* case_operand ::= expr */ yytestcase(yyruleno==238); -{yygotominor.yy132 = yymsp[0].minor.yy346.pExpr;} + case 235: /* case_else ::= ELSE expr */ yytestcase(yyruleno==235); + case 237: /* case_operand ::= expr */ yytestcase(yyruleno==237); +{yygotominor.yy314 = yymsp[0].minor.yy118.pExpr;} break; case 145: /* on_opt ::= */ case 161: /* having_opt ::= */ yytestcase(yyruleno==161); case 168: /* where_opt ::= */ yytestcase(yyruleno==168); - case 237: /* case_else ::= */ yytestcase(yyruleno==237); - case 239: /* case_operand ::= */ yytestcase(yyruleno==239); -{yygotominor.yy132 = 0;} + case 236: /* case_else ::= */ yytestcase(yyruleno==236); + case 238: /* case_operand ::= */ yytestcase(yyruleno==238); +{yygotominor.yy314 = 0;} break; case 148: /* indexed_opt ::= NOT INDEXED */ {yygotominor.yy0.z=0; yygotominor.yy0.n=1;} break; case 149: /* using_opt ::= USING LP inscollist RP */ case 181: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==181); -{yygotominor.yy408 = yymsp[-1].minor.yy408;} +{yygotominor.yy384 = yymsp[-1].minor.yy384;} break; case 150: /* using_opt ::= */ case 180: /* inscollist_opt ::= */ yytestcase(yyruleno==180); -{yygotominor.yy408 = 0;} +{yygotominor.yy384 = 0;} break; case 152: /* orderby_opt ::= ORDER BY sortlist */ case 160: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==160); - case 240: /* exprlist ::= nexprlist */ yytestcase(yyruleno==240); -{yygotominor.yy14 = yymsp[0].minor.yy14;} + case 239: /* exprlist ::= nexprlist */ yytestcase(yyruleno==239); +{yygotominor.yy322 = yymsp[0].minor.yy322;} break; case 153: /* sortlist ::= sortlist COMMA sortitem sortorder */ { - yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14,yymsp[-1].minor.yy132); - if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328; + yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322,yymsp[-1].minor.yy314); + if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4; } break; case 154: /* sortlist ::= sortitem sortorder */ { - yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy132); - if( yygotominor.yy14 && ALWAYS(yygotominor.yy14->a) ) yygotominor.yy14->a[0].sortOrder = (u8)yymsp[0].minor.yy328; + yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy314); + if( yygotominor.yy322 && ALWAYS(yygotominor.yy322->a) ) yygotominor.yy322->a[0].sortOrder = (u8)yymsp[0].minor.yy4; } break; case 156: /* sortorder ::= ASC */ case 158: /* sortorder ::= */ yytestcase(yyruleno==158); -{yygotominor.yy328 = SQLITE_SO_ASC;} +{yygotominor.yy4 = SQLITE_SO_ASC;} break; case 157: /* sortorder ::= DESC */ -{yygotominor.yy328 = SQLITE_SO_DESC;} +{yygotominor.yy4 = SQLITE_SO_DESC;} break; case 163: /* limit_opt ::= */ -{yygotominor.yy476.pLimit = 0; yygotominor.yy476.pOffset = 0;} +{yygotominor.yy292.pLimit = 0; yygotominor.yy292.pOffset = 0;} break; case 164: /* limit_opt ::= LIMIT expr */ -{yygotominor.yy476.pLimit = yymsp[0].minor.yy346.pExpr; yygotominor.yy476.pOffset = 0;} +{yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr; yygotominor.yy292.pOffset = 0;} break; case 165: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yygotominor.yy476.pLimit = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pOffset = yymsp[0].minor.yy346.pExpr;} +{yygotominor.yy292.pLimit = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pOffset = yymsp[0].minor.yy118.pExpr;} break; case 166: /* limit_opt ::= LIMIT expr COMMA expr */ -{yygotominor.yy476.pOffset = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pLimit = yymsp[0].minor.yy346.pExpr;} +{yygotominor.yy292.pOffset = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr;} break; case 167: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy65, &yymsp[-1].minor.yy0); - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy65,yymsp[0].minor.yy132); + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy259, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy259,yymsp[0].minor.yy314); } break; case 170: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy65, &yymsp[-3].minor.yy0); - sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy14,"set list"); - sqlite3Update(pParse,yymsp[-4].minor.yy65,yymsp[-1].minor.yy14,yymsp[0].minor.yy132,yymsp[-5].minor.yy186); + sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy259, &yymsp[-3].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy322,"set list"); + sqlite3Update(pParse,yymsp[-4].minor.yy259,yymsp[-1].minor.yy322,yymsp[0].minor.yy314,yymsp[-5].minor.yy210); } break; case 171: /* setlist ::= setlist COMMA nm EQ expr */ { - yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy346.pExpr); - sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1); + yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy118.pExpr); + sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1); } break; case 172: /* setlist ::= nm EQ expr */ { - yygotominor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy346.pExpr); - sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1); + yygotominor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy118.pExpr); + sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1); } break; case 173: /* cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP */ -{sqlite3Insert(pParse, yymsp[-5].minor.yy65, yymsp[-1].minor.yy14, 0, yymsp[-4].minor.yy408, yymsp[-7].minor.yy186);} +{sqlite3Insert(pParse, yymsp[-5].minor.yy259, yymsp[-1].minor.yy322, 0, yymsp[-4].minor.yy384, yymsp[-7].minor.yy210);} break; case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */ -{sqlite3Insert(pParse, yymsp[-2].minor.yy65, 0, yymsp[0].minor.yy3, yymsp[-1].minor.yy408, yymsp[-4].minor.yy186);} +{sqlite3Insert(pParse, yymsp[-2].minor.yy259, 0, yymsp[0].minor.yy387, yymsp[-1].minor.yy384, yymsp[-4].minor.yy210);} break; case 175: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */ -{sqlite3Insert(pParse, yymsp[-3].minor.yy65, 0, 0, yymsp[-2].minor.yy408, yymsp[-5].minor.yy186);} +{sqlite3Insert(pParse, yymsp[-3].minor.yy259, 0, 0, yymsp[-2].minor.yy384, yymsp[-5].minor.yy210);} break; case 176: /* insert_cmd ::= INSERT orconf */ -{yygotominor.yy186 = yymsp[0].minor.yy186;} +{yygotominor.yy210 = yymsp[0].minor.yy210;} break; case 177: /* insert_cmd ::= REPLACE */ -{yygotominor.yy186 = OE_Replace;} +{yygotominor.yy210 = OE_Replace;} break; case 178: /* itemlist ::= itemlist COMMA expr */ - case 242: /* nexprlist ::= nexprlist COMMA expr */ yytestcase(yyruleno==242); -{yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy346.pExpr);} + case 241: /* nexprlist ::= nexprlist COMMA expr */ yytestcase(yyruleno==241); +{yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy118.pExpr);} break; case 179: /* itemlist ::= expr */ - case 243: /* nexprlist ::= expr */ yytestcase(yyruleno==243); -{yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy346.pExpr);} + case 242: /* nexprlist ::= expr */ yytestcase(yyruleno==242); +{yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy118.pExpr);} break; case 182: /* inscollist ::= inscollist COMMA nm */ -{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy408,&yymsp[0].minor.yy0);} +{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy384,&yymsp[0].minor.yy0);} break; case 183: /* inscollist ::= nm */ -{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);} +{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);} break; case 184: /* expr ::= term */ - case 212: /* escape ::= ESCAPE expr */ yytestcase(yyruleno==212); -{yygotominor.yy346 = yymsp[0].minor.yy346;} +{yygotominor.yy118 = yymsp[0].minor.yy118;} break; case 185: /* expr ::= LP expr RP */ -{yygotominor.yy346.pExpr = yymsp[-1].minor.yy346.pExpr; spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);} +{yygotominor.yy118.pExpr = yymsp[-1].minor.yy118.pExpr; spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);} break; case 186: /* term ::= NULL */ case 191: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==191); case 192: /* term ::= STRING */ yytestcase(yyruleno==192); -{spanExpr(&yygotominor.yy346, pParse, yymsp[0].major, &yymsp[0].minor.yy0);} +{spanExpr(&yygotominor.yy118, pParse, yymsp[0].major, &yymsp[0].minor.yy0);} break; case 187: /* expr ::= id */ case 188: /* expr ::= JOIN_KW */ yytestcase(yyruleno==188); -{spanExpr(&yygotominor.yy346, pParse, TK_ID, &yymsp[0].minor.yy0);} +{spanExpr(&yygotominor.yy118, pParse, TK_ID, &yymsp[0].minor.yy0);} break; case 189: /* expr ::= nm DOT nm */ { Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0); - yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); - spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); + spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } break; case 190: /* expr ::= nm DOT nm DOT nm */ @@ -94500,8 +108161,8 @@ static void yy_reduce( Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0); Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0); - yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); - spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); + spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); } break; case 193: /* expr ::= REGISTER */ @@ -94511,61 +108172,61 @@ static void yy_reduce( ** in the virtual machine. #N is the N-th register. */ if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0); - yygotominor.yy346.pExpr = 0; + yygotominor.yy118.pExpr = 0; }else{ - yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0); - if( yygotominor.yy346.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy346.pExpr->iTable); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0); + if( yygotominor.yy118.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy118.pExpr->iTable); } - spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); + spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); } break; case 194: /* expr ::= VARIABLE */ { - spanExpr(&yygotominor.yy346, pParse, TK_VARIABLE, &yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yygotominor.yy346.pExpr); - spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); + spanExpr(&yygotominor.yy118, pParse, TK_VARIABLE, &yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yygotominor.yy118.pExpr); + spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); } break; case 195: /* expr ::= expr COLLATE ids */ { - yygotominor.yy346.pExpr = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy346.pExpr, &yymsp[0].minor.yy0); - yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart; - yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + yygotominor.yy118.pExpr = sqlite3ExprSetCollByToken(pParse, yymsp[-2].minor.yy118.pExpr, &yymsp[0].minor.yy0); + yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 196: /* expr ::= CAST LP expr AS typetoken RP */ { - yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy346.pExpr, 0, &yymsp[-1].minor.yy0); - spanSet(&yygotominor.yy346,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy118.pExpr, 0, &yymsp[-1].minor.yy0); + spanSet(&yygotominor.yy118,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); } break; case 197: /* expr ::= ID LP distinct exprlist RP */ { - if( yymsp[-1].minor.yy14 && yymsp[-1].minor.yy14->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ + if( yymsp[-1].minor.yy322 && yymsp[-1].minor.yy322->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0); } - yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0); - spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); - if( yymsp[-2].minor.yy328 && yygotominor.yy346.pExpr ){ - yygotominor.yy346.pExpr->flags |= EP_Distinct; + yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); + spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); + if( yymsp[-2].minor.yy4 && yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->flags |= EP_Distinct; } } break; case 198: /* expr ::= ID LP STAR RP */ { - yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); - spanSet(&yygotominor.yy346,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); + spanSet(&yygotominor.yy118,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); } break; case 199: /* term ::= CTIME_KW */ { /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are ** treated as functions that return constants */ - yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0); - if( yygotominor.yy346.pExpr ){ - yygotominor.yy346.pExpr->op = TK_CONST_FUNC; + yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->op = TK_CONST_FUNC; } - spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); + spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); } break; case 200: /* expr ::= expr AND expr */ @@ -94576,417 +108237,437 @@ static void yy_reduce( case 205: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==205); case 206: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==206); case 207: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==207); -{spanBinaryExpr(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy346);} +{spanBinaryExpr(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118);} break; case 208: /* likeop ::= LIKE_KW */ case 210: /* likeop ::= MATCH */ yytestcase(yyruleno==210); -{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.not = 0;} +{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.not = 0;} break; case 209: /* likeop ::= NOT LIKE_KW */ case 211: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==211); -{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.not = 1;} +{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.not = 1;} break; - case 213: /* escape ::= */ -{memset(&yygotominor.yy346,0,sizeof(yygotominor.yy346));} + case 212: /* expr ::= expr likeop expr */ +{ + ExprList *pList; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy118.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy118.pExpr); + yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy342.eOperator); + if( yymsp[-1].minor.yy342.not ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); + yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart; + yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd; + if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc; +} break; - case 214: /* expr ::= expr likeop expr escape */ + case 213: /* expr ::= expr likeop expr ESCAPE expr */ { ExprList *pList; - pList = sqlite3ExprListAppend(pParse,0, yymsp[-1].minor.yy346.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-3].minor.yy346.pExpr); - if( yymsp[0].minor.yy346.pExpr ){ - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr); - } - yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-2].minor.yy96.eOperator); - if( yymsp[-2].minor.yy96.not ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); - yygotominor.yy346.zStart = yymsp[-3].minor.yy346.zStart; - yygotominor.yy346.zEnd = yymsp[-1].minor.yy346.zEnd; - if( yygotominor.yy346.pExpr ) yygotominor.yy346.pExpr->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy118.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr); + yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy342.eOperator); + if( yymsp[-3].minor.yy342.not ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); + yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart; + yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd; + if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc; } break; - case 215: /* expr ::= expr ISNULL|NOTNULL */ -{spanUnaryPostfix(&yygotominor.yy346,pParse,yymsp[0].major,&yymsp[-1].minor.yy346,&yymsp[0].minor.yy0);} + case 214: /* expr ::= expr ISNULL|NOTNULL */ +{spanUnaryPostfix(&yygotominor.yy118,pParse,yymsp[0].major,&yymsp[-1].minor.yy118,&yymsp[0].minor.yy0);} break; - case 216: /* expr ::= expr NOT NULL */ -{spanUnaryPostfix(&yygotominor.yy346,pParse,TK_NOTNULL,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy0);} + case 215: /* expr ::= expr NOT NULL */ +{spanUnaryPostfix(&yygotominor.yy118,pParse,TK_NOTNULL,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy0);} break; - case 217: /* expr ::= expr IS expr */ + case 216: /* expr ::= expr IS expr */ { - spanBinaryExpr(&yygotominor.yy346,pParse,TK_IS,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy346); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy346.pExpr, yygotominor.yy346.pExpr, TK_ISNULL); + spanBinaryExpr(&yygotominor.yy118,pParse,TK_IS,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_ISNULL); } break; - case 218: /* expr ::= expr IS NOT expr */ + case 217: /* expr ::= expr IS NOT expr */ { - spanBinaryExpr(&yygotominor.yy346,pParse,TK_ISNOT,&yymsp[-3].minor.yy346,&yymsp[0].minor.yy346); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy346.pExpr, yygotominor.yy346.pExpr, TK_NOTNULL); + spanBinaryExpr(&yygotominor.yy118,pParse,TK_ISNOT,&yymsp[-3].minor.yy118,&yymsp[0].minor.yy118); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_NOTNULL); } break; - case 219: /* expr ::= NOT expr */ - case 220: /* expr ::= BITNOT expr */ yytestcase(yyruleno==220); -{spanUnaryPrefix(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);} + case 218: /* expr ::= NOT expr */ + case 219: /* expr ::= BITNOT expr */ yytestcase(yyruleno==219); +{spanUnaryPrefix(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);} break; - case 221: /* expr ::= MINUS expr */ -{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UMINUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);} + case 220: /* expr ::= MINUS expr */ +{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UMINUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);} break; - case 222: /* expr ::= PLUS expr */ -{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UPLUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);} + case 221: /* expr ::= PLUS expr */ +{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UPLUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);} break; - case 225: /* expr ::= expr between_op expr AND expr */ + case 224: /* expr ::= expr between_op expr AND expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr); - yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy346.pExpr, 0, 0); - if( yygotominor.yy346.pExpr ){ - yygotominor.yy346.pExpr->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy118.pExpr, 0, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); - } - if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); - yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart; - yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd; + } + if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); + yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart; + yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd; } break; - case 228: /* expr ::= expr in_op LP exprlist RP */ + case 227: /* expr ::= expr in_op LP exprlist RP */ { - yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0); - if( yygotominor.yy346.pExpr ){ - yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy14; - sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); + if( yymsp[-1].minor.yy322==0 ){ + /* Expressions of the form + ** + ** expr1 IN () + ** expr1 NOT IN () + ** + ** simplify to constants 0 (false) and 1 (true), respectively, + ** regardless of the value of expr1. + */ + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy4]); + sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy118.pExpr); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->x.pList = yymsp[-1].minor.yy322; + sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); + }else{ + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); + } + if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); } - if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); - yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart; - yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; - case 229: /* expr ::= LP select RP */ + case 228: /* expr ::= LP select RP */ { - yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); - if( yygotominor.yy346.pExpr ){ - yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3; - ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect); - sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387; + ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect); + sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); }else{ - sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3); + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387); } - yygotominor.yy346.zStart = yymsp[-2].minor.yy0.z; - yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + yygotominor.yy118.zStart = yymsp[-2].minor.yy0.z; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; - case 230: /* expr ::= expr in_op LP select RP */ + case 229: /* expr ::= expr in_op LP select RP */ { - yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0); - if( yygotominor.yy346.pExpr ){ - yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3; - ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect); - sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387; + ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect); + sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); }else{ - sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3); + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387); } - if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); - yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart; - yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); + yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; - case 231: /* expr ::= expr in_op nm dbnm */ + case 230: /* expr ::= expr in_op nm dbnm */ { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); - yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy346.pExpr, 0, 0); - if( yygotominor.yy346.pExpr ){ - yygotominor.yy346.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); - ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect); - sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy118.pExpr, 0, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); + ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect); + sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); }else{ sqlite3SrcListDelete(pParse->db, pSrc); } - if( yymsp[-2].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); - yygotominor.yy346.zStart = yymsp[-3].minor.yy346.zStart; - yygotominor.yy346.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]; + if( yymsp[-2].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); + yygotominor.yy118.zStart = yymsp[-3].minor.yy118.zStart; + yygotominor.yy118.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]; } break; - case 232: /* expr ::= EXISTS LP select RP */ + case 231: /* expr ::= EXISTS LP select RP */ { - Expr *p = yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); + Expr *p = yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); if( p ){ - p->x.pSelect = yymsp[-1].minor.yy3; + p->x.pSelect = yymsp[-1].minor.yy387; ExprSetProperty(p, EP_xIsSelect); sqlite3ExprSetHeight(pParse, p); }else{ - sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3); + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387); } - yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z; - yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; - case 233: /* expr ::= CASE case_operand case_exprlist case_else END */ + case 232: /* expr ::= CASE case_operand case_exprlist case_else END */ { - yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy132, yymsp[-1].minor.yy132, 0); - if( yygotominor.yy346.pExpr ){ - yygotominor.yy346.pExpr->x.pList = yymsp[-2].minor.yy14; - sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy314, yymsp[-1].minor.yy314, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->x.pList = yymsp[-2].minor.yy322; + sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322); } - yygotominor.yy346.zStart = yymsp[-4].minor.yy0.z; - yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + yygotominor.yy118.zStart = yymsp[-4].minor.yy0.z; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; - case 234: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + case 233: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { - yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy346.pExpr); - yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr); + yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy118.pExpr); + yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr); } break; - case 235: /* case_exprlist ::= WHEN expr THEN expr */ + case 234: /* case_exprlist ::= WHEN expr THEN expr */ { - yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr); - yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr); + yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr); + yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr); } break; - case 244: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */ + case 243: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */ { - sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, - sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy14, yymsp[-9].minor.yy328, - &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy328); + sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, + sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy322, yymsp[-9].minor.yy4, + &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy4); } break; - case 245: /* uniqueflag ::= UNIQUE */ - case 299: /* raisetype ::= ABORT */ yytestcase(yyruleno==299); -{yygotominor.yy328 = OE_Abort;} + case 244: /* uniqueflag ::= UNIQUE */ + case 298: /* raisetype ::= ABORT */ yytestcase(yyruleno==298); +{yygotominor.yy4 = OE_Abort;} break; - case 246: /* uniqueflag ::= */ -{yygotominor.yy328 = OE_None;} + case 245: /* uniqueflag ::= */ +{yygotominor.yy4 = OE_None;} break; - case 249: /* idxlist ::= idxlist COMMA nm collate sortorder */ + case 248: /* idxlist ::= idxlist COMMA nm collate sortorder */ { Expr *p = 0; if( yymsp[-1].minor.yy0.n>0 ){ p = sqlite3Expr(pParse->db, TK_COLUMN, 0); - sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0); + sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0); } - yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, p); - sqlite3ExprListSetName(pParse,yygotominor.yy14,&yymsp[-2].minor.yy0,1); - sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index"); - if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328; + yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, p); + sqlite3ExprListSetName(pParse,yygotominor.yy322,&yymsp[-2].minor.yy0,1); + sqlite3ExprListCheckLength(pParse, yygotominor.yy322, "index"); + if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4; } break; - case 250: /* idxlist ::= nm collate sortorder */ + case 249: /* idxlist ::= nm collate sortorder */ { Expr *p = 0; if( yymsp[-1].minor.yy0.n>0 ){ p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); - sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0); + sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0); } - yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, p); - sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1); - sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index"); - if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328; + yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, p); + sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1); + sqlite3ExprListCheckLength(pParse, yygotominor.yy322, "index"); + if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4; } break; - case 251: /* collate ::= */ + case 250: /* collate ::= */ {yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;} break; - case 253: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy65, yymsp[-1].minor.yy328);} + case 252: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy259, yymsp[-1].minor.yy4);} break; - case 254: /* cmd ::= VACUUM */ - case 255: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==255); + case 253: /* cmd ::= VACUUM */ + case 254: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==254); {sqlite3Vacuum(pParse);} break; - case 256: /* cmd ::= PRAGMA nm dbnm */ + case 255: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 257: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ + case 256: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; - case 258: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ + case 257: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; - case 259: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ + case 258: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; - case 260: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ + case 259: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} break; - case 271: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + case 270: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ { Token all; all.z = yymsp[-3].minor.yy0.z; all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy473, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy203, &all); } break; - case 272: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 271: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy328, yymsp[-4].minor.yy378.a, yymsp[-4].minor.yy378.b, yymsp[-2].minor.yy65, yymsp[0].minor.yy132, yymsp[-10].minor.yy328, yymsp[-8].minor.yy328); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy4, yymsp[-4].minor.yy90.a, yymsp[-4].minor.yy90.b, yymsp[-2].minor.yy259, yymsp[0].minor.yy314, yymsp[-10].minor.yy4, yymsp[-8].minor.yy4); yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); } break; - case 273: /* trigger_time ::= BEFORE */ - case 276: /* trigger_time ::= */ yytestcase(yyruleno==276); -{ yygotominor.yy328 = TK_BEFORE; } + case 272: /* trigger_time ::= BEFORE */ + case 275: /* trigger_time ::= */ yytestcase(yyruleno==275); +{ yygotominor.yy4 = TK_BEFORE; } break; - case 274: /* trigger_time ::= AFTER */ -{ yygotominor.yy328 = TK_AFTER; } + case 273: /* trigger_time ::= AFTER */ +{ yygotominor.yy4 = TK_AFTER; } break; - case 275: /* trigger_time ::= INSTEAD OF */ -{ yygotominor.yy328 = TK_INSTEAD;} + case 274: /* trigger_time ::= INSTEAD OF */ +{ yygotominor.yy4 = TK_INSTEAD;} break; - case 277: /* trigger_event ::= DELETE|INSERT */ - case 278: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==278); -{yygotominor.yy378.a = yymsp[0].major; yygotominor.yy378.b = 0;} + case 276: /* trigger_event ::= DELETE|INSERT */ + case 277: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==277); +{yygotominor.yy90.a = yymsp[0].major; yygotominor.yy90.b = 0;} break; - case 279: /* trigger_event ::= UPDATE OF inscollist */ -{yygotominor.yy378.a = TK_UPDATE; yygotominor.yy378.b = yymsp[0].minor.yy408;} + case 278: /* trigger_event ::= UPDATE OF inscollist */ +{yygotominor.yy90.a = TK_UPDATE; yygotominor.yy90.b = yymsp[0].minor.yy384;} break; - case 282: /* when_clause ::= */ - case 304: /* key_opt ::= */ yytestcase(yyruleno==304); -{ yygotominor.yy132 = 0; } + case 281: /* when_clause ::= */ + case 303: /* key_opt ::= */ yytestcase(yyruleno==303); +{ yygotominor.yy314 = 0; } break; - case 283: /* when_clause ::= WHEN expr */ - case 305: /* key_opt ::= KEY expr */ yytestcase(yyruleno==305); -{ yygotominor.yy132 = yymsp[0].minor.yy346.pExpr; } + case 282: /* when_clause ::= WHEN expr */ + case 304: /* key_opt ::= KEY expr */ yytestcase(yyruleno==304); +{ yygotominor.yy314 = yymsp[0].minor.yy118.pExpr; } break; - case 284: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 283: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { - assert( yymsp[-2].minor.yy473!=0 ); - yymsp[-2].minor.yy473->pLast->pNext = yymsp[-1].minor.yy473; - yymsp[-2].minor.yy473->pLast = yymsp[-1].minor.yy473; - yygotominor.yy473 = yymsp[-2].minor.yy473; + assert( yymsp[-2].minor.yy203!=0 ); + yymsp[-2].minor.yy203->pLast->pNext = yymsp[-1].minor.yy203; + yymsp[-2].minor.yy203->pLast = yymsp[-1].minor.yy203; + yygotominor.yy203 = yymsp[-2].minor.yy203; } break; - case 285: /* trigger_cmd_list ::= trigger_cmd SEMI */ -{ - assert( yymsp[-1].minor.yy473!=0 ); - yymsp[-1].minor.yy473->pLast = yymsp[-1].minor.yy473; - yygotominor.yy473 = yymsp[-1].minor.yy473; + case 284: /* trigger_cmd_list ::= trigger_cmd SEMI */ +{ + assert( yymsp[-1].minor.yy203!=0 ); + yymsp[-1].minor.yy203->pLast = yymsp[-1].minor.yy203; + yygotominor.yy203 = yymsp[-1].minor.yy203; } break; - case 287: /* trnm ::= nm DOT nm */ + case 286: /* trnm ::= nm DOT nm */ { yygotominor.yy0 = yymsp[0].minor.yy0; - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "qualified table names are not allowed on INSERT, UPDATE, and DELETE " "statements within triggers"); } break; - case 289: /* tridxby ::= INDEXED BY nm */ + case 288: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 290: /* tridxby ::= NOT INDEXED */ + case 289: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 291: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */ -{ yygotominor.yy473 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy14, yymsp[0].minor.yy132, yymsp[-5].minor.yy186); } + case 290: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */ +{ yygotominor.yy203 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy322, yymsp[0].minor.yy314, yymsp[-5].minor.yy210); } break; - case 292: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP */ -{yygotominor.yy473 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy408, yymsp[-1].minor.yy14, 0, yymsp[-7].minor.yy186);} + case 291: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP */ +{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy384, yymsp[-1].minor.yy322, 0, yymsp[-7].minor.yy210);} break; - case 293: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */ -{yygotominor.yy473 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy408, 0, yymsp[0].minor.yy3, yymsp[-4].minor.yy186);} + case 292: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */ +{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy384, 0, yymsp[0].minor.yy387, yymsp[-4].minor.yy210);} break; - case 294: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */ -{yygotominor.yy473 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy132);} + case 293: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */ +{yygotominor.yy203 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy314);} break; - case 295: /* trigger_cmd ::= select */ -{yygotominor.yy473 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy3); } + case 294: /* trigger_cmd ::= select */ +{yygotominor.yy203 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy387); } break; - case 296: /* expr ::= RAISE LP IGNORE RP */ + case 295: /* expr ::= RAISE LP IGNORE RP */ { - yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); - if( yygotominor.yy346.pExpr ){ - yygotominor.yy346.pExpr->affinity = OE_Ignore; + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->affinity = OE_Ignore; } - yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z; - yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; - case 297: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 296: /* expr ::= RAISE LP raisetype COMMA nm RP */ { - yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); - if( yygotominor.yy346.pExpr ) { - yygotominor.yy346.pExpr->affinity = (char)yymsp[-3].minor.yy328; + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); + if( yygotominor.yy118.pExpr ) { + yygotominor.yy118.pExpr->affinity = (char)yymsp[-3].minor.yy4; } - yygotominor.yy346.zStart = yymsp[-5].minor.yy0.z; - yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + yygotominor.yy118.zStart = yymsp[-5].minor.yy0.z; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; - case 298: /* raisetype ::= ROLLBACK */ -{yygotominor.yy328 = OE_Rollback;} + case 297: /* raisetype ::= ROLLBACK */ +{yygotominor.yy4 = OE_Rollback;} break; - case 300: /* raisetype ::= FAIL */ -{yygotominor.yy328 = OE_Fail;} + case 299: /* raisetype ::= FAIL */ +{yygotominor.yy4 = OE_Fail;} break; - case 301: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 300: /* cmd ::= DROP TRIGGER ifexists fullname */ { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy65,yymsp[-1].minor.yy328); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy259,yymsp[-1].minor.yy4); } break; - case 302: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 301: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { - sqlite3Attach(pParse, yymsp[-3].minor.yy346.pExpr, yymsp[-1].minor.yy346.pExpr, yymsp[0].minor.yy132); + sqlite3Attach(pParse, yymsp[-3].minor.yy118.pExpr, yymsp[-1].minor.yy118.pExpr, yymsp[0].minor.yy314); } break; - case 303: /* cmd ::= DETACH database_kw_opt expr */ + case 302: /* cmd ::= DETACH database_kw_opt expr */ { - sqlite3Detach(pParse, yymsp[0].minor.yy346.pExpr); + sqlite3Detach(pParse, yymsp[0].minor.yy118.pExpr); } break; - case 308: /* cmd ::= REINDEX */ + case 307: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 309: /* cmd ::= REINDEX nm dbnm */ + case 308: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 310: /* cmd ::= ANALYZE */ + case 309: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 311: /* cmd ::= ANALYZE nm dbnm */ + case 310: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 312: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 311: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy65,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy259,&yymsp[0].minor.yy0); } break; - case 313: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */ + case 312: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */ { sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0); } break; - case 314: /* add_column_fullname ::= fullname */ + case 313: /* add_column_fullname ::= fullname */ { pParse->db->lookaside.bEnabled = 0; - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy65); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy259); } break; - case 317: /* cmd ::= create_vtab */ + case 316: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 318: /* cmd ::= create_vtab LP vtabarglist RP */ + case 317: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 319: /* create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm */ + case 318: /* create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm */ { sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 322: /* vtabarg ::= */ + case 321: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 324: /* vtabargtoken ::= ANY */ - case 325: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==325); - case 326: /* lp ::= LP */ yytestcase(yyruleno==326); + case 323: /* vtabargtoken ::= ANY */ + case 324: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==324); + case 325: /* lp ::= LP */ yytestcase(yyruleno==325); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; default: @@ -95015,21 +108696,21 @@ static void yy_reduce( /* (91) conslist ::= conslist tcons */ yytestcase(yyruleno==91); /* (92) conslist ::= tcons */ yytestcase(yyruleno==92); /* (93) tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==93); - /* (269) plus_opt ::= PLUS */ yytestcase(yyruleno==269); - /* (270) plus_opt ::= */ yytestcase(yyruleno==270); - /* (280) foreach_clause ::= */ yytestcase(yyruleno==280); - /* (281) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==281); - /* (288) tridxby ::= */ yytestcase(yyruleno==288); - /* (306) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==306); - /* (307) database_kw_opt ::= */ yytestcase(yyruleno==307); - /* (315) kwcolumn_opt ::= */ yytestcase(yyruleno==315); - /* (316) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==316); - /* (320) vtabarglist ::= vtabarg */ yytestcase(yyruleno==320); - /* (321) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==321); - /* (323) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==323); - /* (327) anylist ::= */ yytestcase(yyruleno==327); - /* (328) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==328); - /* (329) anylist ::= anylist ANY */ yytestcase(yyruleno==329); + /* (268) plus_opt ::= PLUS */ yytestcase(yyruleno==268); + /* (269) plus_opt ::= */ yytestcase(yyruleno==269); + /* (279) foreach_clause ::= */ yytestcase(yyruleno==279); + /* (280) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==280); + /* (287) tridxby ::= */ yytestcase(yyruleno==287); + /* (305) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==305); + /* (306) database_kw_opt ::= */ yytestcase(yyruleno==306); + /* (314) kwcolumn_opt ::= */ yytestcase(yyruleno==314); + /* (315) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==315); + /* (319) vtabarglist ::= vtabarg */ yytestcase(yyruleno==319); + /* (320) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==320); + /* (322) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==322); + /* (326) anylist ::= */ yytestcase(yyruleno==326); + /* (327) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==327); + /* (328) anylist ::= anylist ANY */ yytestcase(yyruleno==328); break; }; yygoto = yyRuleInfo[yyruleno].lhs; @@ -95196,7 +108877,7 @@ SQLITE_PRIVATE void sqlite3Parser( #ifdef YYERRORSYMBOL /* A syntax error has occurred. ** The response to an error depends upon whether or not the - ** grammar defines an error token "ERROR". + ** grammar defines an error token "ERROR". ** ** This is what we do if the grammar does define ERROR: ** @@ -95259,7 +108940,7 @@ SQLITE_PRIVATE void sqlite3Parser( yy_syntax_error(yypParser,yymajor,yyminorunion); yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yymajor = YYNOCODE; - + #else /* YYERRORSYMBOL is not defined */ /* This is what we do if the grammar does not define ERROR: ** @@ -95304,6 +108985,7 @@ SQLITE_PRIVATE void sqlite3Parser( ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. */ +/* #include <stdlib.h> */ /* ** The charMap() macro maps alphabetic characters into their @@ -95340,7 +109022,7 @@ const unsigned char ebcdicToAscii[] = { /* ** The sqlite3KeywordCode function looks up an identifier to determine if -** it is a keyword. If it is a keyword, the token code of that keyword is +** it is a keyword. If it is a keyword, the token code of that keyword is ** returned. If the input is not a keyword, TK_ID is returned. ** ** The implementation of this routine was generated by a program, @@ -95458,31 +109140,31 @@ static int keywordCode(const char *z, int n){ 521, 527, 531, 536, }; static const unsigned char aCode[121] = { - TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, - TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, - TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, - TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_TABLE, - TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE, - TK_EXCEPT, TK_TRANSACTION,TK_ACTION, TK_ON, TK_JOIN_KW, - TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_SAVEPOINT, - TK_INTERSECT, TK_TRIGGER, TK_REFERENCES, TK_CONSTRAINT, TK_INTO, - TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP, - TK_OR, TK_UNIQUE, TK_QUERY, TK_ATTACH, TK_HAVING, - TK_GROUP, TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RELEASE, - TK_BETWEEN, TK_NOTNULL, TK_NOT, TK_NO, TK_NULL, - TK_LIKE_KW, TK_CASCADE, TK_ASC, TK_DELETE, TK_CASE, - TK_COLLATE, TK_CREATE, TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, - TK_JOIN, TK_INSERT, TK_MATCH, TK_PLAN, TK_ANALYZE, - TK_PRAGMA, TK_ABORT, TK_VALUES, TK_VIRTUAL, TK_LIMIT, - TK_WHEN, TK_WHERE, TK_RENAME, TK_AFTER, TK_REPLACE, - TK_AND, TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN, - TK_CAST, TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, - TK_CTIME_KW, TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, - TK_IS, TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW, - TK_LIKE_KW, TK_BY, TK_IF, TK_ISNULL, TK_ORDER, - TK_RESTRICT, TK_JOIN_KW, TK_JOIN_KW, TK_ROLLBACK, TK_ROW, - TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_INITIALLY, - TK_ALL, + TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, + TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, + TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, + TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_TABLE, + TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE, + TK_EXCEPT, TK_TRANSACTION,TK_ACTION, TK_ON, TK_JOIN_KW, + TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_SAVEPOINT, + TK_INTERSECT, TK_TRIGGER, TK_REFERENCES, TK_CONSTRAINT, TK_INTO, + TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP, + TK_OR, TK_UNIQUE, TK_QUERY, TK_ATTACH, TK_HAVING, + TK_GROUP, TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RELEASE, + TK_BETWEEN, TK_NOTNULL, TK_NOT, TK_NO, TK_NULL, + TK_LIKE_KW, TK_CASCADE, TK_ASC, TK_DELETE, TK_CASE, + TK_COLLATE, TK_CREATE, TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, + TK_JOIN, TK_INSERT, TK_MATCH, TK_PLAN, TK_ANALYZE, + TK_PRAGMA, TK_ABORT, TK_VALUES, TK_VIRTUAL, TK_LIMIT, + TK_WHEN, TK_WHERE, TK_RENAME, TK_AFTER, TK_REPLACE, + TK_AND, TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN, + TK_CAST, TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, + TK_CTIME_KW, TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, + TK_IS, TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW, + TK_LIKE_KW, TK_BY, TK_IF, TK_ISNULL, TK_ORDER, + TK_RESTRICT, TK_JOIN_KW, TK_JOIN_KW, TK_ROLLBACK, TK_ROW, + TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_INITIALLY, + TK_ALL, }; int h, i; if( n<2 ) return TK_ID; @@ -95631,14 +109313,14 @@ SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){ ** IdChar(X) will be true. Otherwise it is false. ** ** For ASCII, any character with the high-order bit set is -** allowed in an identifier. For 7-bit characters, +** allowed in an identifier. For 7-bit characters, ** sqlite3IsIdChar[X] must be 1. ** ** For EBCDIC, the rules are more complex but have the same ** end result. ** ** Ticket #1066. the SQL standard does not allow '$' in the -** middle of identfiers. But many SQL implementations do. +** middle of identfiers. But many SQL implementations do. ** SQLite will allow '$' in identifiers for compatibility. ** But the feature is undocumented. */ @@ -95666,7 +109348,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[] = { /* -** Return the length of the token that begins at z[0]. +** Return the length of the token that begins at z[0]. ** Store the token type in *tokenType before returning. */ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ @@ -95841,7 +109523,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ *tokenType = TK_FLOAT; } if( (z[i]=='e' || z[i]=='E') && - ( sqlite3Isdigit(z[i+1]) + ( sqlite3Isdigit(z[i+1]) || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2])) ) ){ @@ -95914,13 +109596,12 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ testcase( z[0]=='x' ); testcase( z[0]=='X' ); if( z[1]=='\'' ){ *tokenType = TK_BLOB; - for(i=2; (c=z[i])!=0 && c!='\''; i++){ - if( !sqlite3Isxdigit(c) ){ - *tokenType = TK_ILLEGAL; - } + for(i=2; sqlite3Isxdigit(z[i]); i++){} + if( z[i]!='\'' || i%2 ){ + *tokenType = TK_ILLEGAL; + while( z[i] && z[i]!='\'' ){ i++; } } - if( i%2 || !c ) *tokenType = TK_ILLEGAL; - if( c ) i++; + if( z[i] ) i++; return i; } /* Otherwise fall through to the next case */ @@ -95942,7 +109623,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ /* ** Run the parser on the given SQL string. The parser structure is ** passed in. An SQLITE_ status code is returned. If an error occurs -** then an and attempt is made to write an error message into +** then an and attempt is made to write an error message into ** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that ** error message. */ @@ -95973,9 +109654,8 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr assert( pParse->pNewTable==0 ); assert( pParse->pNewTrigger==0 ); assert( pParse->nVar==0 ); - assert( pParse->nVarExpr==0 ); - assert( pParse->nVarExprAlloc==0 ); - assert( pParse->apVarExpr==0 ); + assert( pParse->nzVar==0 ); + assert( pParse->azVar==0 ); enableLookaside = db->lookaside.bEnabled; if( db->lookaside.pStart ) db->lookaside.bEnabled = 1; while( !db->mallocFailed && zSql[i]!=0 ){ @@ -96057,19 +109737,20 @@ abort_parse: } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3DbFree(db, pParse->apVtabLock); + sqlite3_free(pParse->apVtabLock); #endif if( !IN_DECLARE_VTAB ){ - /* If the pParse->declareVtab flag is set, do not delete any table + /* If the pParse->declareVtab flag is set, do not delete any table ** structure built up in pParse->pNewTable. The calling code (see vtab.c) ** will take responsibility for freeing the Table structure. */ - sqlite3DeleteTable(pParse->pNewTable); + sqlite3DeleteTable(db, pParse->pNewTable); } sqlite3DeleteTrigger(db, pParse->pNewTrigger); - sqlite3DbFree(db, pParse->apVarExpr); + for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]); + sqlite3DbFree(db, pParse->azVar); sqlite3DbFree(db, pParse->aAlias); while( pParse->pAinc ){ AutoincInfo *p = pParse->pAinc; @@ -96079,7 +109760,7 @@ abort_parse: while( pParse->pZombieTab ){ Table *p = pParse->pZombieTab; pParse->pZombieTab = p->pNextZombie; - sqlite3DeleteTable(p); + sqlite3DeleteTable(db, p); } if( nErr>0 && pParse->rc==SQLITE_OK ){ pParse->rc = SQLITE_ERROR; @@ -96156,7 +109837,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[]; ** (2) NORMAL We are in the middle of statement which ends with a single ** semicolon. ** -** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of +** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of ** a statement. ** ** (4) CREATE The keyword CREATE has been seen at the beginning of a @@ -96489,15 +110170,33 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db); /************** Continuing where we left off in main.c ***********************/ #endif -/* -** The version of the library -*/ #ifndef SQLITE_AMALGAMATION +/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant +** contains the text of SQLITE_VERSION macro. +*/ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; #endif + +/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns +** a pointer to the to the sqlite3_version[] string constant. +*/ SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; } + +/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a +** pointer to a string constant whose value is the same as the +** SQLITE_SOURCE_ID C preprocessor macro. +*/ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } + +/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function +** returns an integer equal to SQLITE_VERSION_NUMBER. +*/ SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } + +/* IMPLEMENTATION-OF: R-54823-41343 The sqlite3_threadsafe() function returns +** zero if and only if SQLite was compiled mutexing code omitted due to +** the SQLITE_THREADSAFE compile-time option being set to 0. +*/ SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) @@ -96520,13 +110219,13 @@ SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*, ...) = 0; SQLITE_API char *sqlite3_temp_directory = 0; /* -** Initialize SQLite. +** Initialize SQLite. ** ** This routine must be called to initialize the memory allocation, ** VFS, and mutex subsystems prior to doing any serious work with ** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as -** sqlite3_open(). +** sqlite3_open(). ** ** This routine is a no-op except on its very first call for the process, ** or for the first call after a call to sqlite3_shutdown. @@ -96568,7 +110267,7 @@ SQLITE_API int sqlite3_initialize(void){ */ if( sqlite3GlobalConfig.isInit ) return SQLITE_OK; - /* Make sure the mutex subsystem is initialized. If unable to + /* Make sure the mutex subsystem is initialized. If unable to ** initialize the mutex subsystem, return early with the error. ** If the system is so sick that we are unable to allocate a mutex, ** there is not much SQLite is going to be able to do. @@ -96618,6 +110317,13 @@ SQLITE_API int sqlite3_initialize(void){ ** sqlite3_initialize(). The recursive calls normally come through ** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other ** recursive calls might also be possible. + ** + ** IMPLEMENTATION-OF: R-00140-37445 SQLite automatically serializes calls + ** to the xInit method, so the xInit method need not be threadsafe. + ** + ** The following mutex is what serializes access to the appdef pcache xInit + ** methods. The sqlite3_pcache_methods.xInit() all is embedded in the + ** call to sqlite3PcacheInitialize(). */ sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex); if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){ @@ -96633,7 +110339,7 @@ SQLITE_API int sqlite3_initialize(void){ rc = sqlite3OsInit(); } if( rc==SQLITE_OK ){ - sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, + sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); sqlite3GlobalConfig.isInit = 1; } @@ -96672,6 +110378,16 @@ SQLITE_API int sqlite3_initialize(void){ #endif #endif + /* Do extra initialization steps requested by the SQLITE_EXTRA_INIT + ** compile-time option. + */ +#ifdef SQLITE_EXTRA_INIT + if( rc==SQLITE_OK && sqlite3GlobalConfig.isInit ){ + int SQLITE_EXTRA_INIT(void); + rc = SQLITE_EXTRA_INIT(); + } +#endif + return rc; } @@ -96726,7 +110442,7 @@ SQLITE_API int sqlite3_config(int op, ...){ switch( op ){ /* Mutex configuration options are only available in a threadsafe - ** compile. + ** compile. */ #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 case SQLITE_CONFIG_SINGLETHREAD: { @@ -96813,6 +110529,13 @@ SQLITE_API int sqlite3_config(int op, ...){ sqlite3GlobalConfig.nHeap = va_arg(ap, int); sqlite3GlobalConfig.mnReq = va_arg(ap, int); + if( sqlite3GlobalConfig.mnReq<1 ){ + sqlite3GlobalConfig.mnReq = 1; + }else if( sqlite3GlobalConfig.mnReq>(1<<12) ){ + /* cap min request size at 2^12 */ + sqlite3GlobalConfig.mnReq = (1<<12); + } + if( sqlite3GlobalConfig.pHeap==0 ){ /* If the heap pointer is NULL, then restore the malloc implementation ** back to NULL pointers too. This will cause the malloc to go @@ -96841,7 +110564,7 @@ SQLITE_API int sqlite3_config(int op, ...){ sqlite3GlobalConfig.nLookaside = va_arg(ap, int); break; } - + /* Record a pointer to the logger funcction and its first argument. ** The default is NULL. Logging is disabled if the function pointer is ** NULL. @@ -96857,6 +110580,11 @@ SQLITE_API int sqlite3_config(int op, ...){ break; } + case SQLITE_CONFIG_URI: { + sqlite3GlobalConfig.bOpenUri = va_arg(ap, int); + break; + } + default: { rc = SQLITE_ERROR; break; @@ -96868,7 +110596,7 @@ SQLITE_API int sqlite3_config(int op, ...){ /* ** Set up the lookaside buffers for a database connection. -** Return SQLITE_OK on success. +** Return SQLITE_OK on success. ** If lookaside is already active, return SQLITE_BUSY. ** ** The sz parameter is the number of bytes in each lookaside slot. @@ -96883,7 +110611,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ return SQLITE_BUSY; } /* Free any existing lookaside buffer for this handle before - ** allocating a new one so we don't have to have space for + ** allocating a new one so we don't have to have space for ** both at the same time. */ if( db->lookaside.bMalloced ){ @@ -96898,12 +110626,12 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ sz = 0; pStart = 0; }else if( pBuf==0 ){ - sz = ROUND8(sz); + sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ sqlite3BeginBenignMalloc(); - pStart = sqlite3Malloc( sz*cnt ); + pStart = sqlite3Malloc( sz*cnt ); /* IMP: R-61949-35727 */ sqlite3EndBenignMalloc(); }else{ - sz = ROUNDDOWN8(sz); + sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ pStart = pBuf; } db->lookaside.pStart = pStart; @@ -96946,14 +110674,42 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ va_start(ap, op); switch( op ){ case SQLITE_DBCONFIG_LOOKASIDE: { - void *pBuf = va_arg(ap, void*); - int sz = va_arg(ap, int); - int cnt = va_arg(ap, int); + void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */ + int sz = va_arg(ap, int); /* IMP: R-47871-25994 */ + int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */ rc = setupLookaside(db, pBuf, sz, cnt); break; } default: { - rc = SQLITE_ERROR; + static const struct { + int op; /* The opcode */ + u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */ + } aFlagOp[] = { + { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, + { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger }, + }; + unsigned int i; + rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ + for(i=0; i<ArraySize(aFlagOp); i++){ + if( aFlagOp[i].op==op ){ + int onoff = va_arg(ap, int); + int *pRes = va_arg(ap, int*); + int oldFlags = db->flags; + if( onoff>0 ){ + db->flags |= aFlagOp[i].mask; + }else if( onoff==0 ){ + db->flags &= ~aFlagOp[i].mask; + } + if( oldFlags!=db->flags ){ + sqlite3ExpirePreparedStatements(db); + } + if( pRes ){ + *pRes = (db->flags & aFlagOp[i].mask)!=0; + } + rc = SQLITE_OK; + break; + } + } break; } } @@ -96999,7 +110755,7 @@ static int binCollFunc( } /* -** Another built-in collating sequence: NOCASE. +** Another built-in collating sequence: NOCASE. ** ** This collating sequence is intended to be used for "case independant ** comparison". SQLite's knowledge of upper and lower case equivalents @@ -97059,10 +110815,27 @@ SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *db){ } /* +** Invoke the destructor function associated with FuncDef p, if any. Except, +** if this is not the last copy of the function, do not invoke it. Multiple +** copies of a single function are created when create_function() is called +** with SQLITE_ANY as the encoding. +*/ +static void functionDestroy(sqlite3 *db, FuncDef *p){ + FuncDestructor *pDestructor = p->pDestructor; + if( pDestructor ){ + pDestructor->nRef--; + if( pDestructor->nRef==0 ){ + pDestructor->xDestroy(pDestructor->pUserData); + sqlite3DbFree(db, pDestructor); + } + } +} + +/* ** Close an existing SQLite database */ SQLITE_API int sqlite3_close(sqlite3 *db){ - HashElem *i; + HashElem *i; /* Hash table iterator */ int j; if( !db ){ @@ -97073,7 +110846,8 @@ SQLITE_API int sqlite3_close(sqlite3 *db){ } sqlite3_mutex_enter(db->mutex); - sqlite3ResetInternalSchema(db, 0); + /* Force xDestroy calls on all virtual tables */ + sqlite3ResetInternalSchema(db, -1); /* If a transaction is open, the ResetInternalSchema() call above ** will not have called the xDisconnect() method on any virtual @@ -97086,7 +110860,7 @@ SQLITE_API int sqlite3_close(sqlite3 *db){ /* If there are any outstanding VMs, return SQLITE_BUSY. */ if( db->pVdbe ){ - sqlite3Error(db, SQLITE_BUSY, + sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalised statements"); sqlite3_mutex_leave(db->mutex); return SQLITE_BUSY; @@ -97096,7 +110870,7 @@ SQLITE_API int sqlite3_close(sqlite3 *db){ for(j=0; j<db->nDb; j++){ Btree *pBt = db->aDb[j].pBt; if( pBt && sqlite3BtreeIsInBackup(pBt) ){ - sqlite3Error(db, SQLITE_BUSY, + sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinished backup operation"); sqlite3_mutex_leave(db->mutex); return SQLITE_BUSY; @@ -97116,7 +110890,7 @@ SQLITE_API int sqlite3_close(sqlite3 *db){ } } } - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); /* Tell the code in notify.c that the connection no longer holds any ** locks and does not require any further unlock-notify callbacks. @@ -97130,6 +110904,7 @@ SQLITE_API int sqlite3_close(sqlite3 *db){ for(p=db->aFunc.a[j]; p; p=pHash){ pHash = p->pHash; while( p ){ + functionDestroy(db, p); pNext = p->pNext; sqlite3DbFree(db, p); p = pNext; @@ -97169,7 +110944,7 @@ SQLITE_API int sqlite3_close(sqlite3 *db){ /* The temp-database schema is allocated differently from the other schema ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()). ** So it needs to be freed here. Todo: Why not roll the temp schema into - ** the same sqliteMalloc() as the one that allocates the database + ** the same sqliteMalloc() as the one that allocates the database ** structure? */ sqlite3DbFree(db, db->aDb[1].pSchema); @@ -97206,7 +110981,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db){ if( db->flags&SQLITE_InternChanges ){ sqlite3ExpirePreparedStatements(db); - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); } /* Any deferred constraint violations have now been resolved. */ @@ -97236,10 +111011,10 @@ SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){ /* SQLITE_INTERRUPT */ "interrupted", /* SQLITE_IOERR */ "disk I/O error", /* SQLITE_CORRUPT */ "database disk image is malformed", - /* SQLITE_NOTFOUND */ 0, + /* SQLITE_NOTFOUND */ "unknown operation", /* SQLITE_FULL */ "database or disk is full", /* SQLITE_CANTOPEN */ "unable to open database file", - /* SQLITE_PROTOCOL */ 0, + /* SQLITE_PROTOCOL */ "locking protocol", /* SQLITE_EMPTY */ "table contains no data", /* SQLITE_SCHEMA */ "database schema has changed", /* SQLITE_TOOBIG */ "string or blob too big", @@ -97275,7 +111050,7 @@ static int sqliteDefaultBusyCallback( { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; static const u8 totals[] = { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 }; -# define NDELAY (sizeof(delays)/sizeof(delays[0])) +# define NDELAY ArraySize(delays) sqlite3 *db = (sqlite3 *)ptr; int timeout = db->busyTimeout; int delay, prior; @@ -97321,7 +111096,7 @@ SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){ }else{ p->nBusy++; } - return rc; + return rc; } /* @@ -97348,9 +111123,9 @@ SQLITE_API int sqlite3_busy_handler( ** be invoked every nOps opcodes. */ SQLITE_API void sqlite3_progress_handler( - sqlite3 *db, + sqlite3 *db, int nOps, - int (*xProgress)(void*), + int (*xProgress)(void*), void *pArg ){ sqlite3_mutex_enter(db->mutex); @@ -97394,7 +111169,7 @@ SQLITE_API void sqlite3_interrupt(sqlite3 *db){ ** 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 -** is returned and the mallocFailed flag cleared. +** is returned and the mallocFailed flag cleared. */ SQLITE_PRIVATE int sqlite3CreateFunc( sqlite3 *db, @@ -97404,21 +111179,22 @@ SQLITE_PRIVATE int sqlite3CreateFunc( void *pUserData, void (*xFunc)(sqlite3_context*,int,sqlite3_value **), void (*xStep)(sqlite3_context*,int,sqlite3_value **), - void (*xFinal)(sqlite3_context*) + void (*xFinal)(sqlite3_context*), + FuncDestructor *pDestructor ){ FuncDef *p; int nName; assert( sqlite3_mutex_held(db->mutex) ); if( zFunctionName==0 || - (xFunc && (xFinal || xStep)) || + (xFunc && (xFinal || xStep)) || (!xFunc && (xFinal && !xStep)) || (!xFunc && (!xFinal && xStep)) || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) || (255<(nName = sqlite3Strlen30( zFunctionName))) ){ return SQLITE_MISUSE_BKPT; } - + #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 @@ -97432,10 +111208,10 @@ SQLITE_PRIVATE int sqlite3CreateFunc( }else if( enc==SQLITE_ANY ){ int rc; rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8, - pUserData, xFunc, xStep, xFinal); + pUserData, xFunc, xStep, xFinal, pDestructor); if( rc==SQLITE_OK ){ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE, - pUserData, xFunc, xStep, xFinal); + pUserData, xFunc, xStep, xFinal, pDestructor); } if( rc!=SQLITE_OK ){ return rc; @@ -97445,7 +111221,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc( #else enc = SQLITE_UTF8; #endif - + /* Check if an existing function is being overridden or deleted. If so, ** and there are active VMs, then return SQLITE_BUSY. If a function ** is being overridden/deleted but there are no active VMs, allow the @@ -97454,7 +111230,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc( p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0); if( p && p->iPrefEnc==enc && p->nArg==nArg ){ if( db->activeVdbeCnt ){ - sqlite3Error(db, SQLITE_BUSY, + sqlite3Error(db, SQLITE_BUSY, "unable to delete/modify user-function due to active statements"); assert( !db->mallocFailed ); return SQLITE_BUSY; @@ -97468,6 +111244,15 @@ SQLITE_PRIVATE int sqlite3CreateFunc( if( !p ){ return SQLITE_NOMEM; } + + /* If an older version of the function with a configured destructor is + ** being replaced invoke the destructor function here. */ + functionDestroy(db, p); + + if( pDestructor ){ + pDestructor->nRef++; + } + p->pDestructor = pDestructor; p->flags = 0; p->xFunc = xFunc; p->xStep = xStep; @@ -97482,7 +111267,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc( */ SQLITE_API int sqlite3_create_function( sqlite3 *db, - const char *zFunctionName, + const char *zFunc, int nArg, int enc, void *p, @@ -97490,9 +111275,41 @@ SQLITE_API int sqlite3_create_function( void (*xStep)(sqlite3_context*,int,sqlite3_value **), void (*xFinal)(sqlite3_context*) ){ - int rc; + return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xFunc, xStep, + xFinal, 0); +} + +SQLITE_API int sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xDestroy)(void *) +){ + int rc = SQLITE_ERROR; + FuncDestructor *pArg = 0; sqlite3_mutex_enter(db->mutex); - rc = sqlite3CreateFunc(db, zFunctionName, nArg, enc, p, xFunc, xStep, xFinal); + if( xDestroy ){ + pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor)); + if( !pArg ){ + xDestroy(p); + goto out; + } + pArg->xDestroy = xDestroy; + pArg->pUserData = p; + } + rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xFunc, xStep, xFinal, pArg); + if( pArg && pArg->nRef==0 ){ + assert( rc!=SQLITE_OK ); + xDestroy(p); + sqlite3DbFree(db, pArg); + } + + out: rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; @@ -97514,7 +111331,7 @@ SQLITE_API int sqlite3_create_function16( sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE); - rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal); + rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal,0); sqlite3DbFree(db, zFunc8); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); @@ -97528,7 +111345,7 @@ SQLITE_API int sqlite3_create_function16( ** ** If the function already exists as a regular global function, then ** this routine is a no-op. If the function does not exist, then create -** a new one that always throws a run-time error. +** a new one that always throws a run-time error. ** ** When virtual tables intend to provide an overloaded function, they ** should call this routine to make sure the global function exists. @@ -97545,7 +111362,7 @@ SQLITE_API int sqlite3_overload_function( sqlite3_mutex_enter(db->mutex); if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){ sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8, - 0, sqlite3InvalidFunction, 0, 0); + 0, sqlite3InvalidFunction, 0, 0, 0); } rc = sqlite3ApiExit(db, SQLITE_OK); sqlite3_mutex_leave(db->mutex); @@ -97555,7 +111372,7 @@ SQLITE_API int sqlite3_overload_function( #ifndef SQLITE_OMIT_TRACE /* ** Register a trace function. The pArg from the previously registered trace -** is returned. +** is returned. ** ** A NULL trace function means that no tracing is executes. A non-NULL ** trace is a pointer to a function that is invoked at the start of each @@ -97571,8 +111388,8 @@ SQLITE_API void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), v return pOld; } /* -** Register a profile function. The pArg from the previously registered -** profile function is returned. +** Register a profile function. The pArg from the previously registered +** profile function is returned. ** ** A NULL profile function means that no profiling is executes. A non-NULL ** profile is a pointer to a function that is invoked at the conclusion of @@ -97649,6 +111466,174 @@ SQLITE_API void *sqlite3_rollback_hook( return pRet; } +#ifndef SQLITE_OMIT_WAL +/* +** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint(). +** Invoke sqlite3_wal_checkpoint if the number of frames in the log file +** is greater than sqlite3.pWalArg cast to an integer (the value configured by +** wal_autocheckpoint()). +*/ +SQLITE_PRIVATE int sqlite3WalDefaultHook( + void *pClientData, /* Argument */ + sqlite3 *db, /* Connection */ + const char *zDb, /* Database */ + int nFrame /* Size of WAL */ +){ + if( nFrame>=SQLITE_PTR_TO_INT(pClientData) ){ + sqlite3BeginBenignMalloc(); + sqlite3_wal_checkpoint(db, zDb); + sqlite3EndBenignMalloc(); + } + return SQLITE_OK; +} +#endif /* SQLITE_OMIT_WAL */ + +/* +** Configure an sqlite3_wal_hook() callback to automatically checkpoint +** a database after committing a transaction if there are nFrame or +** more frames in the log file. Passing zero or a negative value as the +** nFrame parameter disables automatic checkpoints entirely. +** +** The callback registered by this function replaces any existing callback +** registered using sqlite3_wal_hook(). Likewise, registering a callback +** using sqlite3_wal_hook() disables the automatic checkpoint mechanism +** configured by this function. +*/ +SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){ +#ifdef SQLITE_OMIT_WAL + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(nFrame); +#else + if( nFrame>0 ){ + sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame)); + }else{ + sqlite3_wal_hook(db, 0, 0); + } +#endif + return SQLITE_OK; +} + +/* +** Register a callback to be invoked each time a transaction is written +** into the write-ahead-log by this database connection. +*/ +SQLITE_API void *sqlite3_wal_hook( + sqlite3 *db, /* Attach the hook to this db handle */ + int(*xCallback)(void *, sqlite3*, const char*, int), + void *pArg /* First argument passed to xCallback() */ +){ +#ifndef SQLITE_OMIT_WAL + void *pRet; + sqlite3_mutex_enter(db->mutex); + pRet = db->pWalArg; + db->xWalCallback = xCallback; + db->pWalArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +#else + return 0; +#endif +} + +/* +** Checkpoint database zDb. +*/ +SQLITE_API int sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLITE_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ +){ +#ifdef SQLITE_OMIT_WAL + return SQLITE_OK; +#else + int rc; /* Return code */ + int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */ + + /* Initialize the output variables to -1 in case an error occurs. */ + if( pnLog ) *pnLog = -1; + if( pnCkpt ) *pnCkpt = -1; + + assert( SQLITE_CHECKPOINT_FULL>SQLITE_CHECKPOINT_PASSIVE ); + assert( SQLITE_CHECKPOINT_FULL<SQLITE_CHECKPOINT_RESTART ); + assert( SQLITE_CHECKPOINT_PASSIVE+2==SQLITE_CHECKPOINT_RESTART ); + if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_RESTART ){ + return SQLITE_MISUSE; + } + + sqlite3_mutex_enter(db->mutex); + if( zDb && zDb[0] ){ + iDb = sqlite3FindDbName(db, zDb); + } + if( iDb<0 ){ + rc = SQLITE_ERROR; + sqlite3Error(db, SQLITE_ERROR, "unknown database: %s", zDb); + }else{ + rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt); + sqlite3Error(db, rc, 0); + } + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +#endif +} + + +/* +** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points +** to contains a zero-length string, all attached databases are +** checkpointed. +*/ +SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ + return sqlite3_wal_checkpoint_v2(db, zDb, SQLITE_CHECKPOINT_PASSIVE, 0, 0); +} + +#ifndef SQLITE_OMIT_WAL +/* +** Run a checkpoint on database iDb. This is a no-op if database iDb is +** not currently open in WAL mode. +** +** If a transaction is open on the database being checkpointed, this +** function returns SQLITE_LOCKED and a checkpoint is not attempted. If +** an error occurs while running the checkpoint, an SQLite error code is +** returned (i.e. SQLITE_IOERR). Otherwise, SQLITE_OK. +** +** The mutex on database handle db should be held by the caller. The mutex +** associated with the specific b-tree being checkpointed is taken by +** this function while the checkpoint is running. +** +** If iDb is passed SQLITE_MAX_ATTACHED, then all attached databases are +** checkpointed. If an error is encountered it is returned immediately - +** no attempt is made to checkpoint any remaining databases. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +*/ +SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){ + int rc = SQLITE_OK; /* Return code */ + int i; /* Used to iterate through attached dbs */ + int bBusy = 0; /* True if SQLITE_BUSY has been encountered */ + + assert( sqlite3_mutex_held(db->mutex) ); + assert( !pnLog || *pnLog==-1 ); + assert( !pnCkpt || *pnCkpt==-1 ); + + for(i=0; i<db->nDb && rc==SQLITE_OK; i++){ + if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){ + rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt); + pnLog = 0; + pnCkpt = 0; + if( rc==SQLITE_BUSY ){ + bBusy = 1; + rc = SQLITE_OK; + } + } + } + + return (rc==SQLITE_OK && bBusy) ? SQLITE_BUSY : rc; +} +#endif /* SQLITE_OMIT_WAL */ + /* ** This function returns true if main-memory should be used instead of ** a temporary file for transient pager files and statement journals. @@ -97684,60 +111669,6 @@ SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){ } /* -** This routine is called to create a connection to a database BTree -** driver. If zFilename is the name of a file, then that file is -** opened and used. If zFilename is the magic name ":memory:" then -** the database is stored in memory (and is thus forgotten as soon as -** the connection is closed.) If zFilename is NULL then the database -** is a "virtual" database for transient use only and is deleted as -** soon as the connection is closed. -** -** A virtual database can be either a disk file (that is automatically -** deleted when the file is closed) or it an be held entirely in memory. -** The sqlite3TempInMemory() function is used to determine which. -*/ -SQLITE_PRIVATE int sqlite3BtreeFactory( - sqlite3 *db, /* Main database when opening aux otherwise 0 */ - const char *zFilename, /* Name of the file containing the BTree database */ - int omitJournal, /* if TRUE then do not journal this file */ - int nCache, /* How many pages in the page cache */ - int vfsFlags, /* Flags passed through to vfsOpen */ - Btree **ppBtree /* Pointer to new Btree object written here */ -){ - int btFlags = 0; - int rc; - - assert( sqlite3_mutex_held(db->mutex) ); - assert( ppBtree != 0); - if( omitJournal ){ - btFlags |= BTREE_OMIT_JOURNAL; - } - if( db->flags & SQLITE_NoReadlock ){ - btFlags |= BTREE_NO_READLOCK; - } -#ifndef SQLITE_OMIT_MEMORYDB - if( zFilename==0 && sqlite3TempInMemory(db) ){ - zFilename = ":memory:"; - } -#endif - - if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (zFilename==0 || *zFilename==0) ){ - vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; - } - rc = sqlite3BtreeOpen(zFilename, (sqlite3 *)db, ppBtree, btFlags, vfsFlags); - - /* If the B-Tree was successfully opened, set the pager-cache size to the - ** default value. Except, if the call to BtreeOpen() returned a handle - ** open on an existing shared pager-cache, do not change the pager-cache - ** size. - */ - if( rc==SQLITE_OK && 0==sqlite3BtreeSchema(*ppBtree, 0, 0) ){ - sqlite3BtreeSetCacheSize(*ppBtree, nCache); - } - return rc; -} - -/* ** Return UTF-8 encoded English language explanation of the most recent ** error. */ @@ -97773,11 +111704,11 @@ SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){ 'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0 }; static const u16 misuse[] = { - 'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ', - 'r', 'o', 'u', 't', 'i', 'n', 'e', ' ', - 'c', 'a', 'l', 'l', 'e', 'd', ' ', - 'o', 'u', 't', ' ', - 'o', 'f', ' ', + 'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ', + 'r', 'o', 'u', 't', 'i', 'n', 'e', ' ', + 'c', 'a', 'l', 'l', 'e', 'd', ' ', + 'o', 'u', 't', ' ', + 'o', 'f', ' ', 's', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 0 }; @@ -97839,7 +111770,7 @@ SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){ */ static int createCollation( sqlite3* db, - const char *zName, + const char *zName, u8 enc, u8 collType, void* pCtx, @@ -97849,7 +111780,7 @@ static int createCollation( CollSeq *pColl; int enc2; int nName = sqlite3Strlen30(zName); - + assert( sqlite3_mutex_held(db->mutex) ); /* If SQLITE_UTF16 is specified as the encoding type, transform this @@ -97866,14 +111797,14 @@ static int createCollation( return SQLITE_MISUSE_BKPT; } - /* Check if this call is removing or replacing an existing collation + /* Check if this call is removing or replacing an existing collation ** sequence. If so, and there are active VMs, return busy. If there ** are no active VMs, invalidate any pre-compiled statements. */ pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0); if( pColl && pColl->xCmp ){ if( db->activeVdbeCnt ){ - sqlite3Error(db, SQLITE_BUSY, + sqlite3Error(db, SQLITE_BUSY, "unable to delete/modify collation sequence due to active statements"); return SQLITE_BUSY; } @@ -97884,7 +111815,7 @@ static int createCollation( ** then any copies made by synthCollSeq() need to be invalidated. ** Also, collation destructor - CollSeq.xDel() - function may need ** to be called. - */ + */ if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){ CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName, nName); int j; @@ -97901,13 +111832,12 @@ static int createCollation( } pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1); - if( pColl ){ - pColl->xCmp = xCompare; - pColl->pUser = pCtx; - pColl->xDel = xDel; - pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED)); - pColl->type = collType; - } + if( pColl==0 ) return SQLITE_NOMEM; + pColl->xCmp = xCompare; + pColl->pUser = pCtx; + pColl->xDel = xDel; + pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED)); + pColl->type = collType; sqlite3Error(db, SQLITE_OK, 0); return SQLITE_OK; } @@ -97953,8 +111883,8 @@ static const int aHardLimit[] = { #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 #endif -#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>30 -# error SQLITE_MAX_ATTACHED must be between 0 and 30 +#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62 +# error SQLITE_MAX_ATTACHED must be between 0 and 62 #endif #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 @@ -97979,33 +111909,287 @@ static const int aHardLimit[] = { */ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ int oldLimit; + + + /* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME + ** there is a hard upper bound set at compile-time by a C preprocessor + ** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to + ** "_MAX_".) + */ + assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN ); + assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH ); + assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT); + assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP ); + assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG ); + assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED ); + assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]== + SQLITE_MAX_LIKE_PATTERN_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER); + assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH ); + assert( SQLITE_LIMIT_TRIGGER_DEPTH==(SQLITE_N_LIMIT-1) ); + + if( limitId<0 || limitId>=SQLITE_N_LIMIT ){ return -1; } oldLimit = db->aLimit[limitId]; - if( newLimit>=0 ){ + if( newLimit>=0 ){ /* IMP: R-52476-28732 */ if( newLimit>aHardLimit[limitId] ){ - newLimit = aHardLimit[limitId]; + newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ } db->aLimit[limitId] = newLimit; } - return oldLimit; + return oldLimit; /* IMP: R-53341-35419 */ } /* +** This function is used to parse both URIs and non-URI filenames passed by the +** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database +** URIs specified as part of ATTACH statements. +** +** The first argument to this function is the name of the VFS to use (or +** a NULL to signify the default VFS) if the URI does not contain a "vfs=xxx" +** query parameter. The second argument contains the URI (or non-URI filename) +** itself. When this function is called the *pFlags variable should contain +** the default flags to open the database handle with. The value stored in +** *pFlags may be updated before returning if the URI filename contains +** "cache=xxx" or "mode=xxx" query parameters. +** +** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to +** the VFS that should be used to open the database file. *pzFile is set to +** point to a buffer containing the name of the file to open. It is the +** responsibility of the caller to eventually call sqlite3_free() to release +** this buffer. +** +** If an error occurs, then an SQLite error code is returned and *pzErrMsg +** may be set to point to a buffer containing an English language error +** message. It is the responsibility of the caller to eventually release +** this buffer by calling sqlite3_free(). +*/ +SQLITE_PRIVATE int sqlite3ParseUri( + const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ + const char *zUri, /* Nul-terminated URI to parse */ + unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ + sqlite3_vfs **ppVfs, /* OUT: VFS to use */ + char **pzFile, /* OUT: Filename component of URI */ + char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ +){ + int rc = SQLITE_OK; + unsigned int flags = *pFlags; + const char *zVfs = zDefaultVfs; + char *zFile; + char c; + int nUri = sqlite3Strlen30(zUri); + + assert( *pzErrMsg==0 ); + + if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri) + && nUri>=5 && memcmp(zUri, "file:", 5)==0 + ){ + char *zOpt; + int eState; /* Parser state when parsing URI */ + int iIn; /* Input character index */ + int iOut = 0; /* Output character index */ + int nByte = nUri+2; /* Bytes of space to allocate */ + + /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen + ** method that there may be extra parameters following the file-name. */ + flags |= SQLITE_OPEN_URI; + + for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&'); + zFile = sqlite3_malloc(nByte); + if( !zFile ) return SQLITE_NOMEM; + + /* Discard the scheme and authority segments of the URI. */ + if( zUri[5]=='/' && zUri[6]=='/' ){ + iIn = 7; + while( zUri[iIn] && zUri[iIn]!='/' ) iIn++; + + if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){ + *pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s", + iIn-7, &zUri[7]); + rc = SQLITE_ERROR; + goto parse_uri_out; + } + }else{ + iIn = 5; + } + + /* Copy the filename and any query parameters into the zFile buffer. + ** Decode %HH escape codes along the way. + ** + ** Within this loop, variable eState may be set to 0, 1 or 2, depending + ** on the parsing context. As follows: + ** + ** 0: Parsing file-name. + ** 1: Parsing name section of a name=value query parameter. + ** 2: Parsing value section of a name=value query parameter. + */ + eState = 0; + while( (c = zUri[iIn])!=0 && c!='#' ){ + iIn++; + if( c=='%' + && sqlite3Isxdigit(zUri[iIn]) + && sqlite3Isxdigit(zUri[iIn+1]) + ){ + int octet = (sqlite3HexToInt(zUri[iIn++]) << 4); + octet += sqlite3HexToInt(zUri[iIn++]); + + assert( octet>=0 && octet<256 ); + if( octet==0 ){ + /* This branch is taken when "%00" appears within the URI. In this + ** case we ignore all text in the remainder of the path, name or + ** value currently being parsed. So ignore the current character + ** and skip to the next "?", "=" or "&", as appropriate. */ + while( (c = zUri[iIn])!=0 && c!='#' + && (eState!=0 || c!='?') + && (eState!=1 || (c!='=' && c!='&')) + && (eState!=2 || c!='&') + ){ + iIn++; + } + continue; + } + c = octet; + }else if( eState==1 && (c=='&' || c=='=') ){ + if( zFile[iOut-1]==0 ){ + /* An empty option name. Ignore this option altogether. */ + while( zUri[iIn] && zUri[iIn]!='#' && zUri[iIn-1]!='&' ) iIn++; + continue; + } + if( c=='&' ){ + zFile[iOut++] = '\0'; + }else{ + eState = 2; + } + c = 0; + }else if( (eState==0 && c=='?') || (eState==2 && c=='&') ){ + c = 0; + eState = 1; + } + zFile[iOut++] = c; + } + if( eState==1 ) zFile[iOut++] = '\0'; + zFile[iOut++] = '\0'; + zFile[iOut++] = '\0'; + + /* Check if there were any options specified that should be interpreted + ** here. Options that are interpreted here include "vfs" and those that + ** correspond to flags that may be passed to the sqlite3_open_v2() + ** method. */ + zOpt = &zFile[sqlite3Strlen30(zFile)+1]; + while( zOpt[0] ){ + int nOpt = sqlite3Strlen30(zOpt); + char *zVal = &zOpt[nOpt+1]; + int nVal = sqlite3Strlen30(zVal); + + if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ + zVfs = zVal; + }else{ + struct OpenMode { + const char *z; + int mode; + } *aMode = 0; + char *zModeType = 0; + int mask = 0; + int limit = 0; + + if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ + static struct OpenMode aCacheMode[] = { + { "shared", SQLITE_OPEN_SHAREDCACHE }, + { "private", SQLITE_OPEN_PRIVATECACHE }, + { 0, 0 } + }; + + mask = SQLITE_OPEN_SHAREDCACHE|SQLITE_OPEN_PRIVATECACHE; + aMode = aCacheMode; + limit = mask; + zModeType = "cache"; + } + if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){ + static struct OpenMode aOpenMode[] = { + { "ro", SQLITE_OPEN_READONLY }, + { "rw", SQLITE_OPEN_READWRITE }, + { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE }, + { 0, 0 } + }; + + mask = SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; + aMode = aOpenMode; + limit = mask & flags; + zModeType = "access"; + } + + if( aMode ){ + int i; + int mode = 0; + for(i=0; aMode[i].z; i++){ + const char *z = aMode[i].z; + if( nVal==sqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){ + mode = aMode[i].mode; + break; + } + } + if( mode==0 ){ + *pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal); + rc = SQLITE_ERROR; + goto parse_uri_out; + } + if( mode>limit ){ + *pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s", + zModeType, zVal); + rc = SQLITE_PERM; + goto parse_uri_out; + } + flags = (flags & ~mask) | mode; + } + } + + zOpt = &zVal[nVal+1]; + } + + }else{ + zFile = sqlite3_malloc(nUri+2); + if( !zFile ) return SQLITE_NOMEM; + memcpy(zFile, zUri, nUri); + zFile[nUri] = '\0'; + zFile[nUri+1] = '\0'; + } + + *ppVfs = sqlite3_vfs_find(zVfs); + if( *ppVfs==0 ){ + *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs); + rc = SQLITE_ERROR; + } + parse_uri_out: + if( rc!=SQLITE_OK ){ + sqlite3_free(zFile); + zFile = 0; + } + *pFlags = flags; + *pzFile = zFile; + return rc; +} + + +/* ** This routine does the work of opening a database on behalf of -** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" +** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" ** is UTF-8 encoded. */ static int openDatabase( const char *zFilename, /* Database filename UTF-8 encoded */ sqlite3 **ppDb, /* OUT: Returned database handle */ - unsigned flags, /* Operational flags */ + unsigned int flags, /* Operational flags */ const char *zVfs /* Name of the VFS to use */ ){ - sqlite3 *db; - int rc; - int isThreadsafe; + sqlite3 *db; /* Store allocated handle here */ + int rc; /* Return code */ + int isThreadsafe; /* True for threadsafe connections */ + char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */ + char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */ *ppDb = 0; #ifndef SQLITE_OMIT_AUTOINIT @@ -98013,6 +112197,24 @@ static int openDatabase( if( rc ) return rc; #endif + /* 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 + ** assert() statements in deeper layers. Sensible combinations + ** are: + ** + ** 1: SQLITE_OPEN_READONLY + ** 2: SQLITE_OPEN_READWRITE + ** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE + */ + assert( SQLITE_OPEN_READONLY == 0x01 ); + assert( SQLITE_OPEN_READWRITE == 0x02 ); + assert( SQLITE_OPEN_CREATE == 0x04 ); + testcase( (1<<(flags&7))==0x02 ); /* READONLY */ + testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ + testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ + if( ((1<<(flags&7)) & 0x46)==0 ) return SQLITE_MISUSE_BKPT; + if( sqlite3GlobalConfig.bCoreMutex==0 ){ isThreadsafe = 0; }else if( flags & SQLITE_OPEN_NOMUTEX ){ @@ -98033,20 +112235,22 @@ static int openDatabase( ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were ** dealt with in the previous code block. Besides these, the only ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY, - ** SQLITE_OPEN_READWRITE, and SQLITE_OPEN_CREATE. Silently mask + ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE, + ** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask ** off all other flags. */ flags &= ~( SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_MAIN_DB | - SQLITE_OPEN_TEMP_DB | - SQLITE_OPEN_TRANSIENT_DB | - SQLITE_OPEN_MAIN_JOURNAL | - SQLITE_OPEN_TEMP_JOURNAL | - SQLITE_OPEN_SUBJOURNAL | + SQLITE_OPEN_TEMP_DB | + SQLITE_OPEN_TRANSIENT_DB | + SQLITE_OPEN_MAIN_JOURNAL | + SQLITE_OPEN_TEMP_JOURNAL | + SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_MASTER_JOURNAL | SQLITE_OPEN_NOMUTEX | - SQLITE_OPEN_FULLMUTEX + SQLITE_OPEN_FULLMUTEX | + SQLITE_OPEN_WAL ); /* Allocate the sqlite data structure */ @@ -98071,7 +112275,7 @@ static int openDatabase( db->autoCommit = 1; db->nextAutovac = -1; db->nextPagesize = 0; - db->flags |= SQLITE_ShortColNames + db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger #if SQLITE_DEFAULT_FILE_FORMAT<4 | SQLITE_LegacyFileFmt #endif @@ -98081,19 +112285,15 @@ static int openDatabase( #if SQLITE_DEFAULT_RECURSIVE_TRIGGERS | SQLITE_RecTriggers #endif +#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS + | SQLITE_ForeignKeys +#endif ; sqlite3HashInit(&db->aCollSeq); #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3HashInit(&db->aModule); #endif - db->pVfs = sqlite3_vfs_find(zVfs); - if( !db->pVfs ){ - rc = SQLITE_ERROR; - sqlite3Error(db, rc, "no such vfs: %s", zVfs); - goto opendb_out; - } - /* Add the default collation sequence BINARY. BINARY works for both UTF-8 ** and UTF-16, so add a version for each to avoid any unnecessary ** conversions. The only error that can occur here is a malloc() failure. @@ -98116,11 +112316,19 @@ static int openDatabase( createCollation(db, "NOCASE", SQLITE_UTF8, SQLITE_COLL_NOCASE, 0, nocaseCollatingFunc, 0); - /* Open the backend database driver */ + /* Parse the filename/URI argument. */ db->openFlags = flags; - rc = sqlite3BtreeFactory(db, zFilename, 0, SQLITE_DEFAULT_CACHE_SIZE, - flags | SQLITE_OPEN_MAIN_DB, - &db->aDb[0].pBt); + rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + sqlite3Error(db, rc, zErrMsg ? "%s" : 0, zErrMsg); + sqlite3_free(zErrMsg); + goto opendb_out; + } + + /* 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 ){ if( rc==SQLITE_IOERR_NOMEM ){ rc = SQLITE_NOMEM; @@ -98133,7 +112341,7 @@ static int openDatabase( /* The default safety_level for the main database is 'full'; for the temp - ** database it is 'NONE'. This matches the pager layer defaults. + ** database it is 'NONE'. This matches the pager layer defaults. */ db->aDb[0].zName = "main"; db->aDb[0].safety_level = 3; @@ -98209,7 +112417,10 @@ static int openDatabase( setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, sqlite3GlobalConfig.nLookaside); + sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); + opendb_out: + sqlite3_free(zOpen); if( db ){ assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 ); sqlite3_mutex_leave(db->mutex); @@ -98229,8 +112440,8 @@ opendb_out: ** Open a new database handle. */ SQLITE_API int sqlite3_open( - const char *zFilename, - sqlite3 **ppDb + const char *zFilename, + sqlite3 **ppDb ){ return openDatabase(zFilename, ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); @@ -98241,7 +112452,7 @@ SQLITE_API int sqlite3_open_v2( int flags, /* Flags */ const char *zVfs /* Name of VFS module to use */ ){ - return openDatabase(filename, ppDb, flags, zVfs); + return openDatabase(filename, ppDb, (unsigned int)flags, zVfs); } #ifndef SQLITE_OMIT_UTF16 @@ -98249,7 +112460,7 @@ SQLITE_API int sqlite3_open_v2( ** Open a new database handle. */ SQLITE_API int sqlite3_open16( - const void *zFilename, + const void *zFilename, sqlite3 **ppDb ){ char const *zFilename8; /* zFilename encoded in UTF-8 instead of UTF-16 */ @@ -98286,9 +112497,9 @@ SQLITE_API int sqlite3_open16( ** Register a new collation sequence with the database handle db. */ SQLITE_API int sqlite3_create_collation( - sqlite3* db, - const char *zName, - int enc, + sqlite3* db, + const char *zName, + int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*) ){ @@ -98305,9 +112516,9 @@ SQLITE_API int sqlite3_create_collation( ** Register a new collation sequence with the database handle db. */ SQLITE_API int sqlite3_create_collation_v2( - sqlite3* db, - const char *zName, - int enc, + sqlite3* db, + const char *zName, + int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*), void(*xDel)(void*) @@ -98326,9 +112537,9 @@ SQLITE_API int sqlite3_create_collation_v2( ** Register a new collation sequence with the database handle db. */ SQLITE_API int sqlite3_create_collation16( - sqlite3* db, + sqlite3* db, const void *zName, - int enc, + int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*) ){ @@ -98352,8 +112563,8 @@ SQLITE_API int sqlite3_create_collation16( ** db. Replace any previously installed collation sequence factory. */ SQLITE_API int sqlite3_collation_needed( - sqlite3 *db, - void *pCollNeededArg, + sqlite3 *db, + void *pCollNeededArg, void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*) ){ sqlite3_mutex_enter(db->mutex); @@ -98370,8 +112581,8 @@ SQLITE_API int sqlite3_collation_needed( ** db. Replace any previously installed collation sequence factory. */ SQLITE_API int sqlite3_collation_needed16( - sqlite3 *db, - void *pCollNeededArg, + sqlite3 *db, + void *pCollNeededArg, void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*) ){ sqlite3_mutex_enter(db->mutex); @@ -98383,7 +112594,6 @@ SQLITE_API int sqlite3_collation_needed16( } #endif /* SQLITE_OMIT_UTF16 */ -#ifndef SQLITE_OMIT_GLOBALRECOVER #ifndef SQLITE_OMIT_DEPRECATED /* ** This function is now an anachronism. It used to be used to recover from a @@ -98393,7 +112603,6 @@ SQLITE_API int sqlite3_global_recover(void){ return SQLITE_OK; } #endif -#endif /* ** Test to see whether or not the database connection is in autocommit @@ -98421,17 +112630,22 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){ SQLITE_PRIVATE int sqlite3CorruptError(int lineno){ testcase( sqlite3GlobalConfig.xLog!=0 ); sqlite3_log(SQLITE_CORRUPT, - "database corruption found by source line %d", lineno); + "database corruption at line %d of [%.10s]", + lineno, 20+sqlite3_sourceid()); return SQLITE_CORRUPT; } SQLITE_PRIVATE int sqlite3MisuseError(int lineno){ testcase( sqlite3GlobalConfig.xLog!=0 ); - sqlite3_log(SQLITE_MISUSE, "misuse detected by source line %d", lineno); + sqlite3_log(SQLITE_MISUSE, + "misuse at line %d of [%.10s]", + lineno, 20+sqlite3_sourceid()); return SQLITE_MISUSE; } SQLITE_PRIVATE int sqlite3CantopenError(int lineno){ testcase( sqlite3GlobalConfig.xLog!=0 ); - sqlite3_log(SQLITE_CANTOPEN, "cannot open file at source line %d", lineno); + sqlite3_log(SQLITE_CANTOPEN, + "cannot open file at line %d of [%.10s]", + lineno, 20+sqlite3_sourceid()); return SQLITE_CANTOPEN; } @@ -98513,13 +112727,13 @@ SQLITE_API int sqlite3_table_column_metadata( /* The following block stores the meta information that will be returned ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey ** and autoinc. At this point there are two possibilities: + ** + ** 1. The specified column name was rowid", "oid" or "_rowid_" + ** and there is no explicitly declared IPK column. ** - ** 1. The specified column name was rowid", "oid" or "_rowid_" - ** and there is no explicitly declared IPK column. - ** - ** 2. The table is not a view and the column name identified an + ** 2. The table is not a view and the column name identified an ** explicitly declared column. Copy meta information from *pCol. - */ + */ if( pCol ){ zDataType = pCol->zType; zCollSeq = pCol->zColl; @@ -98570,7 +112784,7 @@ SQLITE_API int sqlite3_sleep(int ms){ pVfs = sqlite3_vfs_find(0); if( pVfs==0 ) return 0; - /* This function works in milliseconds, but the underlying OsSleep() + /* This function works in milliseconds, but the underlying OsSleep() ** API uses microseconds. Hence the 1000's. */ rc = (sqlite3OsSleep(pVfs, 1000*ms)/1000); @@ -98611,14 +112825,19 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo assert( pPager!=0 ); fd = sqlite3PagerFile(pPager); assert( fd!=0 ); - if( fd->pMethods ){ + if( op==SQLITE_FCNTL_FILE_POINTER ){ + *(sqlite3_file**)pArg = fd; + rc = SQLITE_OK; + }else if( fd->pMethods ){ rc = sqlite3OsFileControl(fd, op, pArg); + }else{ + rc = SQLITE_NOTFOUND; } sqlite3BtreeLeave(pBtree); } } sqlite3_mutex_leave(db->mutex); - return rc; + return rc; } /* @@ -98677,7 +112896,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){ /* ** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) ** - ** Register hooks to call to indicate which malloc() failures + ** Register hooks to call to indicate which malloc() failures ** are benign. */ case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: { @@ -98703,9 +112922,13 @@ SQLITE_API int sqlite3_test_control(int op, ...){ ** dileterious behavior. */ case SQLITE_TESTCTRL_PENDING_BYTE: { - unsigned int newVal = va_arg(ap, unsigned int); - rc = sqlite3PendingByte; - if( newVal ) sqlite3PendingByte = newVal; + rc = PENDING_BYTE; +#ifndef SQLITE_OMIT_WSD + { + unsigned int newVal = va_arg(ap, unsigned int); + if( newVal ) sqlite3PendingByte = newVal; + } +#endif break; } @@ -98734,7 +112957,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){ ** This action provides a run-time test to see how the ALWAYS and ** NEVER macros were defined at compile-time. ** - ** The return value is ALWAYS(X). + ** The return value is ALWAYS(X). ** ** The recommended test is X==2. If the return value is 2, that means ** ALWAYS() and NEVER() are both no-op pass-through macros, which is the @@ -98777,7 +113000,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){ /* sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N) ** - ** Enable or disable various optimizations for testing purposes. The + ** Enable or disable various optimizations for testing purposes. The ** argument N is a bitmask of optimizations to be disabled. For normal ** operation N should be 0. The idea is that a test program (like the ** SQL Logic Test or SLT test module) can run the same SQL multiple times @@ -98796,7 +113019,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){ ** ** If zWord is a keyword recognized by the parser, then return the ** number of keywords. Or if zWord is not a keyword, return 0. - ** + ** ** This test feature is only available in the amalgamation since ** the SQLITE_N_KEYWORD macro is not defined in this file if SQLite ** is built using separate source files. @@ -98807,7 +113030,43 @@ SQLITE_API int sqlite3_test_control(int op, ...){ rc = (sqlite3KeywordCode((u8*)zWord, n)!=TK_ID) ? SQLITE_N_KEYWORD : 0; break; } -#endif +#endif + + /* sqlite3_test_control(SQLITE_TESTCTRL_PGHDRSZ) + ** + ** Return the size of a pcache header in bytes. + */ + case SQLITE_TESTCTRL_PGHDRSZ: { + rc = sizeof(PgHdr); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree); + ** + ** Pass pFree into sqlite3ScratchFree(). + ** If sz>0 then allocate a scratch buffer into pNew. + */ + case SQLITE_TESTCTRL_SCRATCHMALLOC: { + void *pFree, **ppNew; + int sz; + sz = va_arg(ap, int); + ppNew = va_arg(ap, void**); + pFree = va_arg(ap, void*); + if( sz ) *ppNew = sqlite3ScratchMalloc(sz); + sqlite3ScratchFree(pFree); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); + ** + ** If parameter onoff is non-zero, configure the wrappers so that all + ** subsequent calls to localtime() and variants fail. If onoff is zero, + ** undo this setting. + */ + case SQLITE_TESTCTRL_LOCALTIME_FAULT: { + sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); + break; + } } va_end(ap); @@ -98815,6 +113074,28 @@ SQLITE_API int sqlite3_test_control(int op, ...){ return rc; } +/* +** This is a utility routine, useful to VFS implementations, that checks +** to see if a database file was a URI that contained a specific query +** parameter, and if so obtains the value of the query parameter. +** +** The zFilename argument is the filename pointer passed into the xOpen() +** method of a VFS implementation. The zParam argument is the name of the +** query parameter we seek. This routine returns the value of the zParam +** parameter if it exists. If the parameter does not exist, this routine +** returns a NULL pointer. +*/ +SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ + zFilename += sqlite3Strlen30(zFilename) + 1; + while( zFilename[0] ){ + int x = strcmp(zFilename, zParam); + zFilename += sqlite3Strlen30(zFilename) + 1; + if( x==0 ) return zFilename; + zFilename += sqlite3Strlen30(zFilename) + 1; + } + return 0; +} + /************** End of main.c ************************************************/ /************** Begin file notify.c ******************************************/ /* @@ -98858,13 +113139,13 @@ static sqlite3 *SQLITE_WSD sqlite3BlockedList = 0; #ifndef NDEBUG /* -** This function is a complex assert() that verifies the following +** This function is a complex assert() that verifies the following ** properties of the blocked connections list: ** -** 1) Each entry in the list has a non-NULL value for either +** 1) Each entry in the list has a non-NULL value for either ** pUnlockConnection or pBlockingConnection, or both. ** -** 2) All entries in the list that share a common value for +** 2) All entries in the list that share a common value for ** xUnlockNotify are grouped together. ** ** 3) If the argument db is not NULL, then none of the entries in the @@ -98916,8 +113197,8 @@ static void addToBlockedList(sqlite3 *db){ sqlite3 **pp; assertMutexHeld(); for( - pp=&sqlite3BlockedList; - *pp && (*pp)->xUnlockNotify!=db->xUnlockNotify; + pp=&sqlite3BlockedList; + *pp && (*pp)->xUnlockNotify!=db->xUnlockNotify; pp=&(*pp)->pNextBlocked ); db->pNextBlocked = *pp; @@ -98974,13 +113255,14 @@ SQLITE_API int sqlite3_unlock_notify( if( xNotify==0 ){ removeFromBlockedList(db); + db->pBlockingConnection = 0; db->pUnlockConnection = 0; db->xUnlockNotify = 0; db->pUnlockArg = 0; }else if( 0==db->pBlockingConnection ){ - /* The blocking transaction has been concluded. Or there never was a + /* The blocking transaction has been concluded. Or there never was a ** blocking transaction. In either case, invoke the notify callback - ** immediately. + ** immediately. */ xNotify(&pArg, 1); }else{ @@ -99006,7 +113288,7 @@ SQLITE_API int sqlite3_unlock_notify( } /* -** This function is called while stepping or preparing a statement +** This function is called while stepping or preparing a statement ** associated with connection db. The operation will return SQLITE_LOCKED ** to the user because it requires a lock that will not be available ** until connection pBlocker concludes its current transaction. @@ -99022,7 +113304,7 @@ SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *db, sqlite3 *pBlocker){ /* ** This function is called when -** the transaction opened by database db has just finished. Locks held +** the transaction opened by database db has just finished. Locks held ** by database connection db have been released. ** ** This function loops through each entry in the blocked connections @@ -99071,7 +113353,7 @@ SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db){ assert( aArg==aDyn || (aDyn==0 && aArg==aStatic) ); assert( nArg<=(int)ArraySize(aStatic) || aArg==aDyn ); if( (!aDyn && nArg==(int)ArraySize(aStatic)) - || (aDyn && nArg==(int)(sqlite3DbMallocSize(db, aDyn)/sizeof(void*))) + || (aDyn && nArg==(int)(sqlite3MallocSize(aDyn)/sizeof(void*))) ){ /* The aArg[] array needs to grow. */ void **pNew = (void **)sqlite3Malloc(nArg*sizeof(void *)*2); @@ -99082,7 +113364,7 @@ SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db){ }else{ /* This occurs when the array of context pointers that need to ** be passed to the unlock-notify callback is larger than the - ** aStatic[] array allocated on the stack and the attempt to + ** aStatic[] array allocated on the stack and the attempt to ** allocate a larger array from the heap has failed. ** ** This is a difficult situation to handle. Returning an error @@ -99090,17 +113372,17 @@ SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db){ ** is returned the transaction on connection db will still be ** closed and the unlock-notify callbacks on blocked connections ** will go unissued. This might cause the application to wait - ** indefinitely for an unlock-notify callback that will never + ** indefinitely for an unlock-notify callback that will never ** arrive. ** ** Instead, invoke the unlock-notify callback with the context ** array already accumulated. We can then clear the array and - ** begin accumulating any further context pointers without + ** begin accumulating any further context pointers without ** requiring any dynamic allocation. This is sub-optimal because ** it means that instead of one callback with a large array of ** context pointers the application will receive two or more ** callbacks with smaller arrays of context pointers, which will - ** reduce the applications ability to prioritize multiple + ** reduce the applications ability to prioritize multiple ** connections. But it is the best that can be done under the ** circumstances. */ @@ -99135,7 +113417,7 @@ SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db){ } /* -** This is called when the database connection passed as an argument is +** This is called when the database connection passed as an argument is ** being closed. The connection is removed from the blocked list. */ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ @@ -99199,7 +113481,7 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ ** This is similar in concept to how sqlite encodes "varints" but ** the encoding is not the same. SQLite varints are big-endian ** are are limited to 9 bytes in length whereas FTS3 varints are -** little-endian and can be upt to 10 bytes in length (in theory). +** little-endian and can be up to 10 bytes in length (in theory). ** ** Example encodings: ** @@ -99210,26 +113492,26 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ ** **** Document lists **** ** A doclist (document list) holds a docid-sorted list of hits for a -** given term. Doclists hold docids, and can optionally associate -** token positions and offsets with docids. A position is the index -** of a word within the document. The first word of the document has -** a position of 0. +** given term. Doclists hold docids and associated token positions. +** A docid is the unique integer identifier for a single document. +** A position is the index of a word within the document. The first +** word of the document has a position of 0. ** ** FTS3 used to optionally store character offsets using a compile-time ** option. But that functionality is no longer supported. ** -** A DL_POSITIONS_OFFSETS doclist is stored like this: +** A doclist is stored like this: ** ** array { ** varint docid; ** array { (position list for column 0) -** varint position; (delta from previous position plus POS_BASE) +** varint position; (2 more than the delta from previous position) ** } ** array { ** varint POS_COLUMN; (marks start of position list for new column) ** varint column; (index of new column) ** array { -** varint position; (delta from previous position plus POS_BASE) +** varint position; (2 more than the delta from previous position) ** } ** } ** varint POS_END; (marks end of positions for this document. @@ -99237,11 +113519,11 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ ** ** Here, array { X } means zero or more occurrences of X, adjacent in ** memory. A "position" is an index of a token in the token stream -** generated by the tokenizer. Note that POS_END and POS_COLUMN occur +** generated by the tokenizer. Note that POS_END and POS_COLUMN occur ** in the same logical place as the position element, and act as sentinals ** ending a position list array. POS_END is 0. POS_COLUMN is 1. ** The positions numbers are not stored literally but rather as two more -** the difference from the prior position, or the just the position plus +** than the difference from the prior position, or the just the position plus ** 2 for the first position. Example: ** ** label: A B C D E F G H I J K @@ -99255,14 +113537,14 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ ** 234 at I is the next docid. It has one position 72 (72-2) and then ** terminates with the 0 at K. ** -** A DL_POSITIONS doclist omits the startOffset and endOffset -** information. A DL_DOCIDS doclist omits both the position and -** offset information, becoming an array of varint-encoded docids. -** -** On-disk data is stored as type DL_DEFAULT, so we don't serialize -** the type. Due to how deletion is implemented in the segmentation -** system, on-disk doclists MUST store at least positions. +** A "position-list" is the list of positions for multiple columns for +** a single docid. A "column-list" is the set of positions for a single +** column. Hence, a position-list consists of one or more column-lists, +** a document record consists of a docid followed by a position-list and +** a doclist consists of one or more document records. ** +** A bare doclist omits the position information, becoming an +** array of varint-encoded docids. ** **** Segment leaf nodes **** ** Segment leaf nodes store terms and doclists, ordered by term. Leaf @@ -99443,12 +113725,6 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ ** into a single segment. */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - -#if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE) -# define SQLITE_CORE 1 -#endif - /************** Include fts3Int.h in the middle of fts3.c ********************/ /************** Begin file fts3Int.h *****************************************/ /* @@ -99464,14 +113740,29 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ ****************************************************************************** ** */ - #ifndef _FTSINT_H #define _FTSINT_H -#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) # define NDEBUG 1 #endif +/* +** FTS4 is really an extension for FTS3. It is enabled using the +** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all +** the SQLITE_ENABLE_FTS4 macro to serve as an alisse for SQLITE_ENABLE_FTS3. +*/ +#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) +# define SQLITE_ENABLE_FTS3 +#endif + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* If not building as part of the core, include sqlite3ext.h. */ +#ifndef SQLITE_CORE +SQLITE_API extern const sqlite3_api_routines *sqlite3_api; +#endif + /************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/ /************** Begin file fts3_tokenizer.h **********************************/ /* @@ -99510,7 +113801,7 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ ** When an fts3 table is created, it passes any arguments passed to ** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the ** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer -** implementation. The xCreate() function in turn returns an +** implementation. The xCreate() function in turn returns an ** sqlite3_tokenizer structure representing the specific tokenizer to ** be used for the fts3 table (customized by the tokenizer clause arguments). ** @@ -99542,7 +113833,7 @@ struct sqlite3_tokenizer_module { ** then argc is set to 2, and the argv[] array contains pointers ** to the strings "arg1" and "arg2". ** - ** This method should return either SQLITE_OK (0), or an SQLite error + ** This method should return either SQLITE_OK (0), or an SQLite error ** code. If SQLITE_OK is returned, then *ppTokenizer should be set ** to point at the newly created tokenizer structure. The generic ** sqlite3_tokenizer.pModule variable should not be initialised by @@ -99563,7 +113854,7 @@ struct sqlite3_tokenizer_module { /* ** Create a tokenizer cursor to tokenize an input buffer. The caller ** is responsible for ensuring that the input buffer remains valid - ** until the cursor is closed (using the xClose() method). + ** until the cursor is closed (using the xClose() method). */ int (*xOpen)( sqlite3_tokenizer *pTokenizer, /* Tokenizer object */ @@ -99572,7 +113863,7 @@ struct sqlite3_tokenizer_module { ); /* - ** Destroy an existing tokenizer cursor. The fts3 module calls this + ** Destroy an existing tokenizer cursor. The fts3 module calls this ** method exactly once for each successful call to xOpen(). */ int (*xClose)(sqlite3_tokenizer_cursor *pCursor); @@ -99583,7 +113874,7 @@ struct sqlite3_tokenizer_module { ** "OUT" variables identified below, or SQLITE_DONE to indicate that ** the end of the buffer has been reached, or an SQLite error code. ** - ** *ppToken should be set to point at a buffer containing the + ** *ppToken should be set to point at a buffer containing the ** normalized version of the token (i.e. after any case-folding and/or ** stemming has been performed). *pnBytes should be set to the length ** of this buffer in bytes. The input text that generated the token is @@ -99595,7 +113886,7 @@ struct sqlite3_tokenizer_module { ** ** The buffer *ppToken is set to point at is managed by the tokenizer ** implementation. It is only required to be valid until the next call - ** to xNext() or xClose(). + ** to xNext() or xClose(). */ /* TODO(shess) current implementation requires pInput to be ** nul-terminated. This should either be fixed, or pInput/nBytes @@ -99673,7 +113964,7 @@ struct Fts3Hash { } *ht; }; -/* Each element in the hash table is an instance of the following +/* Each element in the hash table is an instance of the following ** structure. All elements are stored on a single doubly-linked list. ** ** Again, this structure is intended to be opaque, but it can't really @@ -99692,10 +113983,10 @@ struct Fts3HashElem { ** (including the null-terminator, if any). Case ** is respected in comparisons. ** -** FTS3_HASH_BINARY pKey points to binary data nKey bytes long. +** FTS3_HASH_BINARY pKey points to binary data nKey bytes long. ** memcmp() is used to compare keys. ** -** A copy of the key is made if the copyKey parameter to fts3HashInit is 1. +** A copy of the key is made if the copyKey parameter to fts3HashInit is 1. */ #define FTS3_HASH_STRING 1 #define FTS3_HASH_BINARY 2 @@ -99754,11 +114045,11 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi #define FTS3_MERGE_COUNT 16 /* -** This is the maximum amount of data (in bytes) to store in the +** This is the maximum amount of data (in bytes) to store in the ** Fts3Table.pendingTerms hash table. Normally, the hash table is ** populated as documents are inserted/updated/deleted in a transaction ** and used to create a new segment when the transaction is committed. -** However if this limit is reached midway through a transaction, a new +** However if this limit is reached midway through a transaction, a new ** segment is created and the hash table cleared immediately. */ #define FTS3_MAX_PENDING_DATA (1*1024*1024) @@ -99770,6 +114061,11 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi */ #define SizeofArray(X) ((int)(sizeof(X)/sizeof(X[0]))) + +#ifndef MIN +# define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + /* ** Maximum length of a varint encoded integer. The varint format is different ** from that used by SQLite, so the maximum length is 10, not 9. @@ -99777,8 +114073,40 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi #define FTS3_VARINT_MAX 10 /* +** FTS4 virtual tables may maintain multiple indexes - one index of all terms +** in the document set and zero or more prefix indexes. All indexes are stored +** as one or more b+-trees in the %_segments and %_segdir tables. +** +** It is possible to determine which index a b+-tree belongs to based on the +** value stored in the "%_segdir.level" column. Given this value L, the index +** that the b+-tree belongs to is (L<<10). In other words, all b+-trees with +** level values between 0 and 1023 (inclusive) belong to index 0, all levels +** between 1024 and 2047 to index 1, and so on. +** +** It is considered impossible for an index to use more than 1024 levels. In +** theory though this may happen, but only after at least +** (FTS3_MERGE_COUNT^1024) separate flushes of the pending-terms tables. +*/ +#define FTS3_SEGDIR_MAXLEVEL 1024 +#define FTS3_SEGDIR_MAXLEVEL_STR "1024" + +/* +** The testcase() macro is only used by the amalgamation. If undefined, +** make it a no-op. +*/ +#ifndef testcase +# define testcase(X) +#endif + +/* +** Terminator values for position-lists and column-lists. +*/ +#define POS_COLUMN (1) /* Column-list terminator */ +#define POS_END (0) /* Position-list terminator */ + +/* ** This section provides definitions to allow the -** FTS3 extension to be compiled outside of the +** FTS3 extension to be compiled outside of the ** amalgamation. */ #ifndef SQLITE_AMALGAMATION @@ -99786,8 +114114,14 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi ** Macros indicating that conditional expressions are always true or ** false. */ +#ifdef SQLITE_COVERAGE_TEST +# define ALWAYS(x) (1) +# define NEVER(X) (0) +#else # define ALWAYS(x) (x) # define NEVER(X) (x) +#endif + /* ** Internal types used by SQLite. */ @@ -99795,18 +114129,43 @@ typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */ typedef short int i16; /* 2-byte (or larger) signed integer */ typedef unsigned int u32; /* 4-byte unsigned integer */ typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */ + /* ** Macro used to suppress compiler warnings for unused parameters. */ #define UNUSED_PARAMETER(x) (void)(x) + +/* +** Activate assert() only if SQLITE_TEST is enabled. +*/ +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 #endif +/* +** The TESTONLY macro is used to enclose variable declarations or +** other bits of code that are needed to support the arguments +** within testcase() and assert() macros. +*/ +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) +# define TESTONLY(X) X +#else +# define TESTONLY(X) +#endif + +#endif /* SQLITE_AMALGAMATION */ + typedef struct Fts3Table Fts3Table; typedef struct Fts3Cursor Fts3Cursor; typedef struct Fts3Expr Fts3Expr; typedef struct Fts3Phrase Fts3Phrase; -typedef struct Fts3SegReader Fts3SegReader; +typedef struct Fts3PhraseToken Fts3PhraseToken; + +typedef struct Fts3Doclist Fts3Doclist; typedef struct Fts3SegFilter Fts3SegFilter; +typedef struct Fts3DeferredToken Fts3DeferredToken; +typedef struct Fts3SegReader Fts3SegReader; +typedef struct Fts3MultiSegReader Fts3MultiSegReader; /* ** A connection to a fulltext index is an instance of the following @@ -99824,37 +114183,54 @@ struct Fts3Table { char **azColumn; /* column names. malloced */ sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ - /* Precompiled statements used by the implementation. Each of these - ** statements is run and reset within a single virtual table API call. + /* Precompiled statements used by the implementation. Each of these + ** statements is run and reset within a single virtual table API call. */ - sqlite3_stmt *aStmt[25]; + sqlite3_stmt *aStmt[27]; - /* Pointer to string containing the SQL: - ** - ** "SELECT block FROM %_segments WHERE blockid BETWEEN ? AND ? - ** ORDER BY blockid" - */ - char *zSelectLeaves; - int nLeavesStmt; /* Valid statements in aLeavesStmt */ - int nLeavesTotal; /* Total number of prepared leaves stmts */ - int nLeavesAlloc; /* Allocated size of aLeavesStmt */ - sqlite3_stmt **aLeavesStmt; /* Array of prepared zSelectLeaves stmts */ + char *zReadExprlist; + char *zWriteExprlist; int nNodeSize; /* Soft limit for node size */ - u8 bHasContent; /* True if %_content table exists */ + u8 bHasStat; /* True if %_stat table exists */ u8 bHasDocsize; /* True if %_docsize table exists */ + u8 bDescIdx; /* True if doclists are in reverse order */ + int nPgsz; /* Page size for host database */ + char *zSegmentsTbl; /* Name of %_segments table */ + sqlite3_blob *pSegments; /* Blob handle open on %_segments table */ - /* The following hash table is used to buffer pending index updates during - ** transactions. Variable nPendingData estimates the memory size of the - ** pending data, including hash table overhead, but not malloc overhead. - ** When nPendingData exceeds nMaxPendingData, the buffer is flushed + /* TODO: Fix the first paragraph of this comment. + ** + ** The following hash table is used to buffer pending index updates during + ** transactions. Variable nPendingData estimates the memory size of the + ** pending data, including hash table overhead, but not malloc overhead. + ** When nPendingData exceeds nMaxPendingData, the buffer is flushed ** automatically. Variable iPrevDocid is the docid of the most recently ** inserted record. + ** + ** A single FTS4 table may have multiple full-text indexes. For each index + ** there is an entry in the aIndex[] array. Index 0 is an index of all the + ** terms that appear in the document set. Each subsequent index in aIndex[] + ** is an index of prefixes of a specific length. + */ + int nIndex; /* Size of aIndex[] */ + struct Fts3Index { + int nPrefix; /* Prefix length (0 for main terms index) */ + Fts3Hash hPending; /* Pending terms table for this index */ + } *aIndex; + int nMaxPendingData; /* Max pending data before flush to disk */ + int nPendingData; /* Current bytes of pending data */ + sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */ + +#if defined(SQLITE_DEBUG) + /* State variables used for validating that the transaction control + ** methods of the virtual table are called at appropriate times. These + ** values do not contribution to the FTS computation; they are used for + ** verifying the SQLite core. */ - int nMaxPendingData; - int nPendingData; - sqlite_int64 iPrevDocid; - Fts3Hash pendingTerms; + int inTransaction; /* True after xBegin but before xCommit/xRollback */ + int mxSavepoint; /* Largest valid xSavepoint integer */ +#endif }; /* @@ -99869,14 +114245,27 @@ struct Fts3Cursor { u8 isRequireSeek; /* True if must seek pStmt to %_content row */ sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ Fts3Expr *pExpr; /* Parsed MATCH query string */ + int nPhrase; /* Number of matchable phrases in query */ + Fts3DeferredToken *pDeferred; /* Deferred search tokens, if any */ sqlite3_int64 iPrevId; /* Previous id read from aDoclist */ char *pNextId; /* Pointer into the body of aDoclist */ char *aDoclist; /* List of docids for full-text queries */ int nDoclist; /* Size of buffer at aDoclist */ + u8 bDesc; /* True to sort in descending order */ + int eEvalmode; /* An FTS3_EVAL_XX constant */ + int nRowAvg; /* Average size of database rows, in pages */ + sqlite3_int64 nDoc; /* Documents in table */ + int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */ u32 *aMatchinfo; /* Information about most recent match */ + int nMatchinfo; /* Number of elements in aMatchinfo[] */ + char *zMatchinfo; /* Matchinfo specification */ }; +#define FTS3_EVAL_FILTER 0 +#define FTS3_EVAL_NEXT 1 +#define FTS3_EVAL_MATCHINFO 2 + /* ** The Fts3Cursor.eSearch member is always set to one of the following. ** Actualy, Fts3Cursor.eSearch can be greater than or equal to @@ -99885,10 +114274,10 @@ struct Fts3Cursor { ** ** CREATE VIRTUAL TABLE ex1 USING fts3(a,b,c,d); ** SELECT docid FROM ex1 WHERE b MATCH 'one two three'; -** +** ** Because the LHS of the MATCH operator is 2nd column "b", ** Fts3Cursor.eSearch will be set to FTS3_FULLTEXT_SEARCH+1. (+0 for a, -** +1 for b, +2 for c, +3 for d.) If the LHS of MATCH were "ex1" +** +1 for b, +2 for c, +3 for d.) If the LHS of MATCH were "ex1" ** indicating that all columns should be searched, ** then eSearch would be set to FTS3_FULLTEXT_SEARCH+4. */ @@ -99896,35 +114285,70 @@ struct Fts3Cursor { #define FTS3_DOCID_SEARCH 1 /* Lookup by rowid on %_content table */ #define FTS3_FULLTEXT_SEARCH 2 /* Full-text index search */ + +struct Fts3Doclist { + char *aAll; /* Array containing doclist (or NULL) */ + int nAll; /* Size of a[] in bytes */ + char *pNextDocid; /* Pointer to next docid */ + + sqlite3_int64 iDocid; /* Current docid (if pList!=0) */ + int bFreeList; /* True if pList should be sqlite3_free()d */ + char *pList; /* Pointer to position list following iDocid */ + int nList; /* Length of position list */ +}; + /* ** A "phrase" is a sequence of one or more tokens that must match in ** sequence. A single token is the base case and the most common case. -** For a sequence of tokens contained in "...", nToken will be the number -** of tokens in the string. -*/ +** For a sequence of tokens contained in double-quotes (i.e. "one two three") +** nToken will be the number of tokens in the string. +*/ +struct Fts3PhraseToken { + char *z; /* Text of the token */ + int n; /* Number of bytes in buffer z */ + int isPrefix; /* True if token ends with a "*" character */ + + /* Variables above this point are populated when the expression is + ** parsed (by code in fts3_expr.c). Below this point the variables are + ** used when evaluating the expression. */ + Fts3DeferredToken *pDeferred; /* Deferred token object for this token */ + Fts3MultiSegReader *pSegcsr; /* Segment-reader for this token */ +}; + struct Fts3Phrase { + /* Cache of doclist for this phrase. */ + Fts3Doclist doclist; + int bIncr; /* True if doclist is loaded incrementally */ + int iDoclistToken; + + /* Variables below this point are populated by fts3_expr.c when parsing + ** a MATCH expression. Everything above is part of the evaluation phase. + */ int nToken; /* Number of tokens in the phrase */ int iColumn; /* Index of column this phrase must match */ - int isNot; /* Phrase prefixed by unary not (-) operator */ - struct PhraseToken { - char *z; /* Text of the token */ - int n; /* Number of bytes in buffer pointed to by z */ - int isPrefix; /* True if token ends in with a "*" character */ - } aToken[1]; /* One entry for each token in the phrase */ + Fts3PhraseToken aToken[1]; /* One entry for each token in the phrase */ }; /* ** A tree of these objects forms the RHS of a MATCH operator. ** -** If Fts3Expr.eType is either FTSQUERY_NEAR or FTSQUERY_PHRASE and isLoaded -** is true, then aDoclist points to a malloced buffer, size nDoclist bytes, -** containing the results of the NEAR or phrase query in FTS3 doclist -** format. As usual, the initial "Length" field found in doclists stored -** on disk is omitted from this buffer. +** If Fts3Expr.eType is FTSQUERY_PHRASE and isLoaded is true, then aDoclist +** points to a malloced buffer, size nDoclist bytes, containing the results +** of this phrase query in FTS3 doclist format. As usual, the initial +** "Length" field found in doclists stored on disk is omitted from this +** buffer. +** +** Variable aMI is used only for FTSQUERY_NEAR nodes to store the global +** matchinfo data. If it is not NULL, it points to an array of size nCol*3, +** where nCol is the number of columns in the queried FTS table. The array +** is populated as follows: ** -** Variable pCurrent always points to the start of a docid field within -** aDoclist. Since the doclist is usually scanned in docid order, this can -** be used to accelerate seeking to the required docid within the doclist. +** aMI[iCol*3 + 0] = Undefined +** aMI[iCol*3 + 1] = Number of occurrences +** aMI[iCol*3 + 2] = Number of rows containing at least one instance +** +** The aMI array is allocated using sqlite3_malloc(). It should be freed +** when the expression node is. */ struct Fts3Expr { int eType; /* One of the FTSQUERY_XXX values defined below */ @@ -99934,17 +114358,18 @@ struct Fts3Expr { Fts3Expr *pRight; /* Right operand */ Fts3Phrase *pPhrase; /* Valid if eType==FTSQUERY_PHRASE */ - int isLoaded; /* True if aDoclist/nDoclist are initialized. */ - char *aDoclist; /* Buffer containing doclist */ - int nDoclist; /* Size of aDoclist in bytes */ + /* The following are used by the fts3_eval.c module. */ + sqlite3_int64 iDocid; /* Current docid */ + u8 bEof; /* True this expression is at EOF already */ + u8 bStart; /* True if iDocid is valid */ + u8 bDeferred; /* True if this expression is entirely deferred */ - sqlite3_int64 iCurrent; - char *pCurrent; + u32 *aMI; }; /* ** Candidate values for Fts3Query.eType. Note that the order of the first -** four values is in order of precedence when parsing expressions. For +** four values is in order of precedence when parsing expressions. For ** example, the following: ** ** "a OR b AND c NOT d NEAR e" @@ -99960,34 +114385,46 @@ struct Fts3Expr { #define FTSQUERY_PHRASE 5 -/* fts3_init.c */ -SQLITE_PRIVATE int sqlite3Fts3DeleteVtab(int, sqlite3_vtab *); -SQLITE_PRIVATE int sqlite3Fts3InitVtab(int, sqlite3*, void*, int, const char*const*, - sqlite3_vtab **, char **); - /* fts3_write.c */ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(sqlite3_vtab*,int,sqlite3_value**,sqlite3_int64*); SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *); SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *); SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *); -SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(Fts3Table *,int, sqlite3_int64, +SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(int, sqlite3_int64, sqlite3_int64, sqlite3_int64, const char *, int, Fts3SegReader**); -SQLITE_PRIVATE int sqlite3Fts3SegReaderPending(Fts3Table*,const char*,int,int,Fts3SegReader**); -SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3Table *, Fts3SegReader *); -SQLITE_PRIVATE int sqlite3Fts3SegReaderIterate( - Fts3Table *, Fts3SegReader **, int, Fts3SegFilter *, - int (*)(Fts3Table *, void *, char *, int, char *, int), void * -); -SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char const**, int*); -SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, sqlite3_stmt **); -SQLITE_PRIVATE int sqlite3Fts3MatchinfoDocsizeLocal(Fts3Cursor*, u32*); -SQLITE_PRIVATE int sqlite3Fts3MatchinfoDocsizeGlobal(Fts3Cursor*, u32*); +SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( + Fts3Table*,int,const char*,int,int,Fts3SegReader**); +SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *); +SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, sqlite3_stmt **); +SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *); +SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*); + +SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **); +SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **); + +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *); +SQLITE_PRIVATE int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int); +SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *); +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *); +SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *); + +/* Special values interpreted by sqlite3SegReaderCursor() */ +#define FTS3_SEGCURSOR_PENDING -1 +#define FTS3_SEGCURSOR_ALL -2 + +SQLITE_PRIVATE int sqlite3Fts3SegReaderStart(Fts3Table*, Fts3MultiSegReader*, Fts3SegFilter*); +SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(Fts3Table *, Fts3MultiSegReader *); +SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish(Fts3MultiSegReader *); + +SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor( + Fts3Table *, int, int, const char *, int, int, int, Fts3MultiSegReader *); /* Flags allowed as part of the 4th argument to SegmentReaderIterate() */ #define FTS3_SEGMENT_REQUIRE_POS 0x00000001 #define FTS3_SEGMENT_IGNORE_EMPTY 0x00000002 #define FTS3_SEGMENT_COLUMN_FILTER 0x00000004 #define FTS3_SEGMENT_PREFIX 0x00000008 +#define FTS3_SEGMENT_SCAN 0x00000010 /* Type passed as 4th argument to SegmentReaderIterate() */ struct Fts3SegFilter { @@ -99997,51 +114434,107 @@ struct Fts3SegFilter { int flags; }; +struct Fts3MultiSegReader { + /* Used internally by sqlite3Fts3SegReaderXXX() calls */ + 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 */ + int nBuffer; /* Allocated size of aBuffer[] in bytes */ + + int iColFilter; /* If >=0, filter for this column */ + int bRestart; + + /* Used by fts3.c only. */ + int nCost; /* Cost of running iterator */ + int bLookup; /* True if a lookup of a single entry. */ + + /* Output values. Valid only after Fts3SegReaderStep() returns SQLITE_ROW. */ + char *zTerm; /* Pointer to term buffer */ + int nTerm; /* Size of zTerm in bytes */ + char *aDoclist; /* Pointer to doclist buffer */ + int nDoclist; /* Size of aDoclist[] in bytes */ +}; + /* fts3.c */ SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64); SQLITE_PRIVATE void sqlite3Fts3Dequote(char *); +SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*); -SQLITE_PRIVATE char *sqlite3Fts3FindPositions(Fts3Expr *, sqlite3_int64, int); -SQLITE_PRIVATE int sqlite3Fts3ExprLoadDoclist(Fts3Table *, Fts3Expr *); -SQLITE_PRIVATE int sqlite3Fts3ExprNearTrim(Fts3Expr *, Fts3Expr *, int); +SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *); /* fts3_tokenizer.c */ SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *); SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *); -SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, - const char *, sqlite3_tokenizer **, const char **, char ** +SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, + sqlite3_tokenizer **, char ** ); +SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char); /* fts3_snippet.c */ SQLITE_PRIVATE void sqlite3Fts3Offsets(sqlite3_context*, Fts3Cursor*); SQLITE_PRIVATE void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *, const char *, const char *, int, int ); -SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *); +SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *); /* fts3_expr.c */ -SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, +SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, char **, int, int, const char *, int, Fts3Expr ** ); SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *); #ifdef SQLITE_TEST SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db); +SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db); #endif +/* fts3_aux.c */ +SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db); + +SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *); + +SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( + Fts3Table*, Fts3MultiSegReader*, int, const char*, int); +SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( + Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *); +SQLITE_PRIVATE char *sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol); +SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *); +SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); + +SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); + +#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ #endif /* _FTSINT_H */ /************** End of fts3Int.h *********************************************/ /************** Continuing where we left off in fts3.c ***********************/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +#if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE) +# define SQLITE_CORE 1 +#endif +/* #include <assert.h> */ +/* #include <stdlib.h> */ +/* #include <stddef.h> */ +/* #include <stdio.h> */ +/* #include <string.h> */ +/* #include <stdarg.h> */ -#ifndef SQLITE_CORE +#ifndef SQLITE_CORE SQLITE_EXTENSION_INIT1 #endif -/* +static int fts3EvalNext(Fts3Cursor *pCsr); +static int fts3EvalStart(Fts3Cursor *pCsr); +static int fts3TermSegReaderCursor( + Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **); + +/* ** Write a 64-bit variable-length integer to memory starting at p[0]. ** The length of data written will be between 1 and FTS3_VARINT_MAX bytes. ** The number of bytes written is returned. @@ -100058,7 +114551,7 @@ SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){ return (int) (q - (unsigned char *)p); } -/* +/* ** Read a 64-bit variable-length integer from memory starting at p[0]. ** Return the number of bytes read, or 0 on error. ** The value is stored in *v. @@ -100087,8 +114580,7 @@ SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){ } /* -** Return the number of bytes required to store the value passed as the -** first argument in varint form. +** Return the number of bytes required to encode v as a varint */ SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64 v){ int i = 0; @@ -100122,7 +114614,7 @@ SQLITE_PRIVATE void sqlite3Fts3Dequote(char *z){ int iOut = 0; /* Index of next byte to write to output */ /* If the first byte was a '[', then the close-quote character is a ']' */ - if( quote=='[' ) quote = ']'; + if( quote=='[' ) quote = ']'; while( ALWAYS(z[iIn]) ){ if( z[iIn]==quote ){ @@ -100139,7 +114631,7 @@ SQLITE_PRIVATE void sqlite3Fts3Dequote(char *z){ /* ** Read a single varint from the doclist at *pp and advance *pp to point -** to the next element of the varlist. Add the value of the varint +** to the first byte past the end of the varint. Add the value of the varint ** to *pVal. */ static void fts3GetDeltaVarint(char **pp, sqlite3_int64 *pVal){ @@ -100149,17 +114641,31 @@ static void fts3GetDeltaVarint(char **pp, sqlite3_int64 *pVal){ } /* -** As long as *pp has not reached its end (pEnd), then do the same -** as fts3GetDeltaVarint(): read a single varint and add it to *pVal. -** But if we have reached the end of the varint, just set *pp=0 and -** leave *pVal unchanged. +** When this function is called, *pp points to the first byte following a +** varint that is part of a doclist (or position-list, or any other list +** of varints). This function moves *pp to point to the start of that varint, +** and sets *pVal by the varint value. +** +** Argument pStart points to the first byte of the doclist that the +** varint is part of. */ -static void fts3GetDeltaVarint2(char **pp, char *pEnd, sqlite3_int64 *pVal){ - if( *pp>=pEnd ){ - *pp = 0; - }else{ - fts3GetDeltaVarint(pp, pVal); - } +static void fts3GetReverseVarint( + char **pp, + char *pStart, + sqlite3_int64 *pVal +){ + sqlite3_int64 iVal; + char *p = *pp; + + /* Pointer p now points at the first byte past the varint we are + ** interested in. So, unless the doclist is corrupt, the 0x80 bit is + ** clear on character p[-1]. */ + for(p = (*pp)-2; p>=pStart && *p&0x80; p--); + p++; + *pp = p; + + sqlite3Fts3GetVarint(p, &iVal); + *pVal = iVal; } /* @@ -100170,16 +114676,15 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){ int i; assert( p->nPendingData==0 ); + assert( p->pSegments==0 ); /* Free any prepared statements held */ for(i=0; i<SizeofArray(p->aStmt); i++){ sqlite3_finalize(p->aStmt[i]); } - for(i=0; i<p->nLeavesStmt; i++){ - sqlite3_finalize(p->aLeavesStmt[i]); - } - sqlite3_free(p->zSelectLeaves); - sqlite3_free(p->aLeavesStmt); + sqlite3_free(p->zSegmentsTbl); + sqlite3_free(p->zReadExprlist); + sqlite3_free(p->zWriteExprlist); /* Invoke the tokenizer destructor to free the tokenizer. */ p->pTokenizer->pModule->xDestroy(p->pTokenizer); @@ -100190,12 +114695,12 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){ /* ** Construct one or more SQL statements from the format string given -** and then evaluate those statements. The success code is writting +** and then evaluate those statements. The success code is written ** into *pRc. ** ** If *pRc is initially non-zero then this routine is a no-op. */ -void fts3DbExec( +static void fts3DbExec( int *pRc, /* Success code */ sqlite3 *db, /* Database in which to run SQL */ const char *zFormat, /* Format string for SQL */ @@ -100242,39 +114747,50 @@ static int fts3DestroyMethod(sqlite3_vtab *pVtab){ ** Invoke sqlite3_declare_vtab() to declare the schema for the FTS3 table ** passed as the first argument. This is done as part of the xConnect() ** and xCreate() methods. +** +** If *pRc is non-zero when this function is called, it is a no-op. +** Otherwise, if an error occurs, an SQLite error code is stored in *pRc +** before returning. */ -static int fts3DeclareVtab(Fts3Table *p){ - int i; /* Iterator variable */ - int rc; /* Return code */ - char *zSql; /* SQL statement passed to declare_vtab() */ - char *zCols; /* List of user defined columns */ +static void fts3DeclareVtab(int *pRc, Fts3Table *p){ + if( *pRc==SQLITE_OK ){ + int i; /* Iterator variable */ + int rc; /* Return code */ + char *zSql; /* SQL statement passed to declare_vtab() */ + char *zCols; /* List of user defined columns */ - /* Create a list of user columns for the virtual table */ - zCols = sqlite3_mprintf("%Q, ", p->azColumn[0]); - for(i=1; zCols && i<p->nColumn; i++){ - zCols = sqlite3_mprintf("%z%Q, ", zCols, p->azColumn[i]); - } + sqlite3_vtab_config(p->db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); - /* Create the whole "CREATE TABLE" statement to pass to SQLite */ - zSql = sqlite3_mprintf( - "CREATE TABLE x(%s %Q HIDDEN, docid HIDDEN)", zCols, p->zName - ); + /* Create a list of user columns for the virtual table */ + zCols = sqlite3_mprintf("%Q, ", p->azColumn[0]); + for(i=1; zCols && i<p->nColumn; i++){ + zCols = sqlite3_mprintf("%z%Q, ", zCols, p->azColumn[i]); + } - if( !zCols || !zSql ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_declare_vtab(p->db, zSql); - } + /* Create the whole "CREATE TABLE" statement to pass to SQLite */ + zSql = sqlite3_mprintf( + "CREATE TABLE x(%s %Q HIDDEN, docid HIDDEN)", zCols, p->zName + ); + if( !zCols || !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_declare_vtab(p->db, zSql); + } - sqlite3_free(zSql); - sqlite3_free(zCols); - return rc; + sqlite3_free(zSql); + sqlite3_free(zCols); + *pRc = rc; + } } /* ** Create the backing store tables (%_content, %_segments and %_segdir) ** required by the FTS3 table passed as the only argument. This is done ** as part of the vtab xCreate() method. +** +** If the p->bHasDocsize boolean is true (indicating that this is an +** FTS4 table, not an FTS3 table) then also create the %_docsize and +** %_stat tables required by FTS4. */ static int fts3CreateTables(Fts3Table *p){ int rc = SQLITE_OK; /* Return code */ @@ -100283,27 +114799,25 @@ static int fts3CreateTables(Fts3Table *p){ sqlite3 *db = p->db; /* The database connection */ /* Create a list of user columns for the content table */ - if( p->bHasContent ){ - zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY"); - for(i=0; zContentCols && i<p->nColumn; i++){ - char *z = p->azColumn[i]; - zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z); - } - if( zContentCols==0 ) rc = SQLITE_NOMEM; - - /* Create the content table */ - fts3DbExec(&rc, db, - "CREATE TABLE %Q.'%q_content'(%s)", - p->zDb, p->zName, zContentCols - ); - sqlite3_free(zContentCols); + zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY"); + for(i=0; zContentCols && i<p->nColumn; i++){ + char *z = p->azColumn[i]; + zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z); } + if( zContentCols==0 ) rc = SQLITE_NOMEM; + + /* Create the content table */ + fts3DbExec(&rc, db, + "CREATE TABLE %Q.'%q_content'(%s)", + p->zDb, p->zName, zContentCols + ); + sqlite3_free(zContentCols); /* Create other tables */ - fts3DbExec(&rc, db, + fts3DbExec(&rc, db, "CREATE TABLE %Q.'%q_segments'(blockid INTEGER PRIMARY KEY, block BLOB);", p->zDb, p->zName ); - fts3DbExec(&rc, db, + fts3DbExec(&rc, db, "CREATE TABLE %Q.'%q_segdir'(" "level INTEGER," "idx INTEGER," @@ -100316,11 +114830,13 @@ static int fts3CreateTables(Fts3Table *p){ p->zDb, p->zName ); if( p->bHasDocsize ){ - fts3DbExec(&rc, db, + fts3DbExec(&rc, db, "CREATE TABLE %Q.'%q_docsize'(docid INTEGER PRIMARY KEY, size BLOB);", p->zDb, p->zName ); - fts3DbExec(&rc, db, + } + if( p->bHasStat ){ + fts3DbExec(&rc, db, "CREATE TABLE %Q.'%q_stat'(id INTEGER PRIMARY KEY, value BLOB);", p->zDb, p->zName ); @@ -100329,36 +114845,282 @@ static int fts3CreateTables(Fts3Table *p){ } /* -** An sqlite3_exec() callback for fts3TableExists. +** Store the current database page-size in bytes in p->nPgsz. +** +** If *pRc is non-zero when this function is called, it is a no-op. +** Otherwise, if an error occurs, an SQLite error code is stored in *pRc +** before returning. */ -static int fts3TableExistsCallback(void *pArg, int n, char **pp1, char **pp2){ - *(int*)pArg = 1; +static void fts3DatabasePageSize(int *pRc, Fts3Table *p){ + if( *pRc==SQLITE_OK ){ + int rc; /* Return code */ + char *zSql; /* SQL text "PRAGMA %Q.page_size" */ + sqlite3_stmt *pStmt; /* Compiled "PRAGMA %Q.page_size" statement */ + + zSql = sqlite3_mprintf("PRAGMA %Q.page_size", p->zDb); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_step(pStmt); + p->nPgsz = sqlite3_column_int(pStmt, 0); + rc = sqlite3_finalize(pStmt); + }else if( rc==SQLITE_AUTH ){ + p->nPgsz = 1024; + rc = SQLITE_OK; + } + } + assert( p->nPgsz>0 || rc!=SQLITE_OK ); + sqlite3_free(zSql); + *pRc = rc; + } +} + +/* +** "Special" FTS4 arguments are column specifications of the following form: +** +** <key> = <value> +** +** There may not be whitespace surrounding the "=" character. The <value> +** term may be quoted, but the <key> may not. +*/ +static int fts3IsSpecialColumn( + const char *z, + int *pnKey, + char **pzValue +){ + char *zValue; + const char *zCsr = z; + + while( *zCsr!='=' ){ + if( *zCsr=='\0' ) return 0; + zCsr++; + } + + *pnKey = (int)(zCsr-z); + zValue = sqlite3_mprintf("%s", &zCsr[1]); + if( zValue ){ + sqlite3Fts3Dequote(zValue); + } + *pzValue = zValue; return 1; } /* -** Determine if a table currently exists in the database. +** Append the output of a printf() style formatting to an existing string. */ -static void fts3TableExists( - int *pRc, /* Success code */ - sqlite3 *db, /* The database connection to test */ - const char *zDb, /* ATTACHed database within the connection */ - const char *zName, /* Name of the FTS3 table */ - const char *zSuffix, /* Shadow table extension */ - u8 *pResult /* Write results here */ +static void fts3Appendf( + int *pRc, /* IN/OUT: Error code */ + char **pz, /* IN/OUT: Pointer to string buffer */ + const char *zFormat, /* Printf format string to append */ + ... /* Arguments for printf format string */ ){ - int rc = SQLITE_OK; - int res = 0; - char *zSql; - if( *pRc ) return; - zSql = sqlite3_mprintf( - "SELECT 1 FROM %Q.sqlite_master WHERE name='%q%s'", - zDb, zName, zSuffix - ); - rc = sqlite3_exec(db, zSql, fts3TableExistsCallback, &res, 0); - sqlite3_free(zSql); - *pResult = res & 0xff; - if( rc!=SQLITE_ABORT ) *pRc = rc; + if( *pRc==SQLITE_OK ){ + va_list ap; + char *z; + va_start(ap, zFormat); + z = sqlite3_vmprintf(zFormat, ap); + if( z && *pz ){ + char *z2 = sqlite3_mprintf("%s%s", *pz, z); + sqlite3_free(z); + z = z2; + } + if( z==0 ) *pRc = SQLITE_NOMEM; + sqlite3_free(*pz); + *pz = z; + } +} + +/* +** Return a copy of input string zInput enclosed in double-quotes (") and +** with all double quote characters escaped. For example: +** +** fts3QuoteId("un \"zip\"") -> "un \"\"zip\"\"" +** +** The pointer returned points to memory obtained from sqlite3_malloc(). It +** is the callers responsibility to call sqlite3_free() to release this +** memory. +*/ +static char *fts3QuoteId(char const *zInput){ + int nRet; + char *zRet; + nRet = 2 + strlen(zInput)*2 + 1; + zRet = sqlite3_malloc(nRet); + if( zRet ){ + int i; + char *z = zRet; + *(z++) = '"'; + for(i=0; zInput[i]; i++){ + if( zInput[i]=='"' ) *(z++) = '"'; + *(z++) = zInput[i]; + } + *(z++) = '"'; + *(z++) = '\0'; + } + return zRet; +} + +/* +** Return a list of comma separated SQL expressions that could be used +** in a SELECT statement such as the following: +** +** SELECT <list of expressions> FROM %_content AS x ... +** +** to return the docid, followed by each column of text data in order +** from left to write. If parameter zFunc is not NULL, then instead of +** being returned directly each column of text data is passed to an SQL +** function named zFunc first. For example, if zFunc is "unzip" and the +** table has the three user-defined columns "a", "b", and "c", the following +** string is returned: +** +** "docid, unzip(x.'a'), unzip(x.'b'), unzip(x.'c')" +** +** The pointer returned points to a buffer allocated by sqlite3_malloc(). It +** is the responsibility of the caller to eventually free it. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and +** a NULL pointer is returned). Otherwise, if an OOM error is encountered +** by this function, NULL is returned and *pRc is set to SQLITE_NOMEM. If +** no error occurs, *pRc is left unmodified. +*/ +static char *fts3ReadExprList(Fts3Table *p, const char *zFunc, int *pRc){ + char *zRet = 0; + char *zFree = 0; + char *zFunction; + int i; + + if( !zFunc ){ + zFunction = ""; + }else{ + zFree = zFunction = fts3QuoteId(zFunc); + } + fts3Appendf(pRc, &zRet, "docid"); + for(i=0; i<p->nColumn; i++){ + fts3Appendf(pRc, &zRet, ",%s(x.'c%d%q')", zFunction, i, p->azColumn[i]); + } + sqlite3_free(zFree); + return zRet; +} + +/* +** Return a list of N comma separated question marks, where N is the number +** of columns in the %_content table (one for the docid plus one for each +** user-defined text column). +** +** If argument zFunc is not NULL, then all but the first question mark +** is preceded by zFunc and an open bracket, and followed by a closed +** bracket. For example, if zFunc is "zip" and the FTS3 table has three +** user-defined text columns, the following string is returned: +** +** "?, zip(?), zip(?), zip(?)" +** +** The pointer returned points to a buffer allocated by sqlite3_malloc(). It +** is the responsibility of the caller to eventually free it. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and +** a NULL pointer is returned). Otherwise, if an OOM error is encountered +** by this function, NULL is returned and *pRc is set to SQLITE_NOMEM. If +** no error occurs, *pRc is left unmodified. +*/ +static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){ + char *zRet = 0; + char *zFree = 0; + char *zFunction; + int i; + + if( !zFunc ){ + zFunction = ""; + }else{ + zFree = zFunction = fts3QuoteId(zFunc); + } + fts3Appendf(pRc, &zRet, "?"); + for(i=0; i<p->nColumn; i++){ + fts3Appendf(pRc, &zRet, ",%s(?)", zFunction); + } + sqlite3_free(zFree); + return zRet; +} + +/* +** This function interprets the string at (*pp) as a non-negative integer +** value. It reads the integer and sets *pnOut to the value read, then +** sets *pp to point to the byte immediately following the last byte of +** the integer value. +** +** Only decimal digits ('0'..'9') may be part of an integer value. +** +** If *pp does not being with a decimal digit SQLITE_ERROR is returned and +** the output value undefined. Otherwise SQLITE_OK is returned. +** +** This function is used when parsing the "prefix=" FTS4 parameter. +*/ +static int fts3GobbleInt(const char **pp, int *pnOut){ + const char *p = *pp; /* Iterator pointer */ + int nInt = 0; /* Output value */ + + for(p=*pp; p[0]>='0' && p[0]<='9'; p++){ + nInt = nInt * 10 + (p[0] - '0'); + } + if( p==*pp ) return SQLITE_ERROR; + *pnOut = nInt; + *pp = p; + return SQLITE_OK; +} + +/* +** This function is called to allocate an array of Fts3Index structures +** representing the indexes maintained by the current FTS table. FTS tables +** always maintain the main "terms" index, but may also maintain one or +** more "prefix" indexes, depending on the value of the "prefix=" parameter +** (if any) specified as part of the CREATE VIRTUAL TABLE statement. +** +** Argument zParam is passed the value of the "prefix=" option if one was +** specified, or NULL otherwise. +** +** If no error occurs, SQLITE_OK is returned and *apIndex set to point to +** the allocated array. *pnIndex is set to the number of elements in the +** array. If an error does occur, an SQLite error code is returned. +** +** Regardless of whether or not an error is returned, it is the responsibility +** of the caller to call sqlite3_free() on the output array to free it. +*/ +static int fts3PrefixParameter( + const char *zParam, /* ABC in prefix=ABC parameter to parse */ + int *pnIndex, /* OUT: size of *apIndex[] array */ + struct Fts3Index **apIndex /* OUT: Array of indexes for this table */ +){ + struct Fts3Index *aIndex; /* Allocated array */ + int nIndex = 1; /* Number of entries in array */ + + if( zParam && zParam[0] ){ + const char *p; + nIndex++; + for(p=zParam; *p; p++){ + if( *p==',' ) nIndex++; + } + } + + aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex); + *apIndex = aIndex; + *pnIndex = nIndex; + if( !aIndex ){ + return SQLITE_NOMEM; + } + + memset(aIndex, 0, sizeof(struct Fts3Index) * nIndex); + if( zParam ){ + const char *p = zParam; + int i; + for(i=1; i<nIndex; i++){ + int nPrefix; + if( fts3GobbleInt(&p, &nPrefix) ) return SQLITE_ERROR; + aIndex[i].nPrefix = nPrefix; + p++; + } + } + + return SQLITE_OK; } /* @@ -100367,7 +115129,7 @@ static void fts3TableExists( ** ** The argv[] array contains the following: ** -** argv[0] -> module name +** argv[0] -> module name ("fts3" or "fts4") ** argv[1] -> database name ** argv[2] -> table name ** argv[...] -> "column name" and other module argument fields. @@ -100382,48 +115144,169 @@ static int fts3InitVtab( char **pzErr /* Write any error message here */ ){ Fts3Hash *pHash = (Fts3Hash *)pAux; - Fts3Table *p; /* Pointer to allocated vtab */ - int rc; /* Return code */ + Fts3Table *p = 0; /* Pointer to allocated vtab */ + int rc = SQLITE_OK; /* Return code */ int i; /* Iterator variable */ int nByte; /* Size of allocation used for *p */ - int iCol; - int nString = 0; - int nCol = 0; - char *zCsr; - int nDb; - int nName; - - const char *zTokenizer = 0; /* Name of tokenizer to use */ + int iCol; /* Column index */ + int nString = 0; /* Bytes required to hold all column names */ + int nCol = 0; /* Number of columns in the FTS table */ + char *zCsr; /* Space for holding column names */ + int nDb; /* Bytes required to hold database name */ + int nName; /* Bytes required to hold table name */ + int isFts4 = (argv[0][3]=='4'); /* True for FTS4, false for FTS3 */ + const char **aCol; /* Array of column names */ sqlite3_tokenizer *pTokenizer = 0; /* Tokenizer for this table */ + int nIndex; /* Size of aIndex[] array */ + struct Fts3Index *aIndex = 0; /* Array of indexes for this table */ + + /* The results of parsing supported FTS4 key=value options: */ + int bNoDocsize = 0; /* True to omit %_docsize table */ + int bDescIdx = 0; /* True to store descending indexes */ + char *zPrefix = 0; /* Prefix parameter value (or NULL) */ + char *zCompress = 0; /* compress=? parameter (or NULL) */ + char *zUncompress = 0; /* uncompress=? parameter (or NULL) */ + + assert( strlen(argv[0])==4 ); + assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4) + || (sqlite3_strnicmp(argv[0], "fts3", 4)==0 && !isFts4) + ); + nDb = (int)strlen(argv[1]) + 1; nName = (int)strlen(argv[2]) + 1; - for(i=3; i<argc; i++){ + + aCol = (const char **)sqlite3_malloc(sizeof(const char *) * (argc-2) ); + if( !aCol ) return SQLITE_NOMEM; + memset((void *)aCol, 0, sizeof(const char *) * (argc-2)); + + /* Loop through all of the arguments passed by the user to the FTS3/4 + ** module (i.e. all the column names and special arguments). This loop + ** does the following: + ** + ** + Figures out the number of columns the FTSX table will have, and + ** the number of bytes of space that must be allocated to store copies + ** of the column names. + ** + ** + If there is a tokenizer specification included in the arguments, + ** initializes the tokenizer pTokenizer. + */ + for(i=3; rc==SQLITE_OK && i<argc; i++){ char const *z = argv[i]; - rc = sqlite3Fts3InitTokenizer(pHash, z, &pTokenizer, &zTokenizer, pzErr); - if( rc!=SQLITE_OK ){ - return rc; + int nKey; + char *zVal; + + /* Check if this is a tokenizer specification */ + if( !pTokenizer + && strlen(z)>8 + && 0==sqlite3_strnicmp(z, "tokenize", 8) + && 0==sqlite3Fts3IsIdChar(z[8]) + ){ + rc = sqlite3Fts3InitTokenizer(pHash, &z[9], &pTokenizer, pzErr); + } + + /* Check if it is an FTS4 special argument. */ + else if( isFts4 && fts3IsSpecialColumn(z, &nKey, &zVal) ){ + struct Fts4Option { + const char *zOpt; + int nOpt; + char **pzVar; + } aFts4Opt[] = { + { "matchinfo", 9, 0 }, /* 0 -> MATCHINFO */ + { "prefix", 6, 0 }, /* 1 -> PREFIX */ + { "compress", 8, 0 }, /* 2 -> COMPRESS */ + { "uncompress", 10, 0 }, /* 3 -> UNCOMPRESS */ + { "order", 5, 0 } /* 4 -> ORDER */ + }; + + int iOpt; + if( !zVal ){ + rc = SQLITE_NOMEM; + }else{ + for(iOpt=0; iOpt<SizeofArray(aFts4Opt); iOpt++){ + struct Fts4Option *pOp = &aFts4Opt[iOpt]; + if( nKey==pOp->nOpt && !sqlite3_strnicmp(z, pOp->zOpt, pOp->nOpt) ){ + break; + } + } + if( iOpt==SizeofArray(aFts4Opt) ){ + *pzErr = sqlite3_mprintf("unrecognized parameter: %s", z); + rc = SQLITE_ERROR; + }else{ + switch( iOpt ){ + case 0: /* MATCHINFO */ + if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){ + *pzErr = sqlite3_mprintf("unrecognized matchinfo: %s", zVal); + rc = SQLITE_ERROR; + } + bNoDocsize = 1; + break; + + case 1: /* PREFIX */ + sqlite3_free(zPrefix); + zPrefix = zVal; + zVal = 0; + break; + + case 2: /* COMPRESS */ + sqlite3_free(zCompress); + zCompress = zVal; + zVal = 0; + break; + + case 3: /* UNCOMPRESS */ + sqlite3_free(zUncompress); + zUncompress = zVal; + zVal = 0; + break; + + case 4: /* ORDER */ + if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3)) + && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 3)) + ){ + *pzErr = sqlite3_mprintf("unrecognized order: %s", zVal); + rc = SQLITE_ERROR; + } + bDescIdx = (zVal[0]=='d' || zVal[0]=='D'); + break; + } + } + sqlite3_free(zVal); + } } - if( z!=zTokenizer ){ + + /* Otherwise, the argument is a column name. */ + else { nString += (int)(strlen(z) + 1); + aCol[nCol++] = z; } } - nCol = argc - 3 - (zTokenizer!=0); - if( zTokenizer==0 ){ - rc = sqlite3Fts3InitTokenizer(pHash, 0, &pTokenizer, 0, pzErr); - if( rc!=SQLITE_OK ){ - return rc; - } - assert( pTokenizer ); - } + if( rc!=SQLITE_OK ) goto fts3_init_out; if( nCol==0 ){ + assert( nString==0 ); + aCol[0] = "content"; + nString = 8; nCol = 1; } + if( pTokenizer==0 ){ + rc = sqlite3Fts3InitTokenizer(pHash, "simple", &pTokenizer, pzErr); + if( rc!=SQLITE_OK ) goto fts3_init_out; + } + assert( pTokenizer ); + + rc = fts3PrefixParameter(zPrefix, &nIndex, &aIndex); + if( rc==SQLITE_ERROR ){ + assert( zPrefix ); + *pzErr = sqlite3_mprintf("error parsing prefix parameter: %s", zPrefix); + } + if( rc!=SQLITE_OK ) goto fts3_init_out; + /* Allocate and populate the Fts3Table structure. */ - nByte = sizeof(Fts3Table) + /* Fts3Table */ + nByte = sizeof(Fts3Table) + /* Fts3Table */ nCol * sizeof(char *) + /* azColumn */ + nIndex * sizeof(struct Fts3Index) + /* aIndex */ nName + /* zName */ nDb + /* zDb */ nString; /* Space for azColumn strings */ @@ -100433,19 +115316,27 @@ static int fts3InitVtab( goto fts3_init_out; } memset(p, 0, nByte); - p->db = db; p->nColumn = nCol; p->nPendingData = 0; p->azColumn = (char **)&p[1]; p->pTokenizer = pTokenizer; - p->nNodeSize = 1000; p->nMaxPendingData = FTS3_MAX_PENDING_DATA; - zCsr = (char *)&p->azColumn[nCol]; + p->bHasDocsize = (isFts4 && bNoDocsize==0); + p->bHasStat = isFts4; + p->bDescIdx = bDescIdx; + TESTONLY( p->inTransaction = -1 ); + TESTONLY( p->mxSavepoint = -1 ); - fts3HashInit(&p->pendingTerms, FTS3_HASH_STRING, 1); + p->aIndex = (struct Fts3Index *)&p->azColumn[nCol]; + memcpy(p->aIndex, aIndex, sizeof(struct Fts3Index) * nIndex); + p->nIndex = nIndex; + for(i=0; i<nIndex; i++){ + fts3HashInit(&p->aIndex[i].hPending, FTS3_HASH_STRING, 1); + } /* Fill in the zName and zDb fields of the vtab structure. */ + zCsr = (char *)&p->aIndex[nIndex]; p->zName = zCsr; memcpy(zCsr, argv[2], nName); zCsr += nName; @@ -100454,52 +115345,57 @@ static int fts3InitVtab( zCsr += nDb; /* Fill in the azColumn array */ - iCol = 0; - for(i=3; i<argc; i++){ - if( argv[i]!=zTokenizer ){ - char *z; - int n; - z = (char *)sqlite3Fts3NextToken(argv[i], &n); - memcpy(zCsr, z, n); - zCsr[n] = '\0'; - sqlite3Fts3Dequote(zCsr); - p->azColumn[iCol++] = zCsr; - zCsr += n+1; - assert( zCsr <= &((char *)p)[nByte] ); - } - } - if( iCol==0 ){ - assert( nCol==1 ); - p->azColumn[0] = "content"; + for(iCol=0; iCol<nCol; iCol++){ + char *z; + int n = 0; + z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n); + memcpy(zCsr, z, n); + zCsr[n] = '\0'; + sqlite3Fts3Dequote(zCsr); + p->azColumn[iCol] = zCsr; + zCsr += n+1; + assert( zCsr <= &((char *)p)[nByte] ); + } + + if( (zCompress==0)!=(zUncompress==0) ){ + char const *zMiss = (zCompress==0 ? "compress" : "uncompress"); + rc = SQLITE_ERROR; + *pzErr = sqlite3_mprintf("missing %s parameter in fts4 constructor", zMiss); } + p->zReadExprlist = fts3ReadExprList(p, zUncompress, &rc); + p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc); + if( rc!=SQLITE_OK ) goto fts3_init_out; - /* If this is an xCreate call, create the underlying tables in the + /* If this is an xCreate call, create the underlying tables in the ** database. TODO: For xConnect(), it could verify that said tables exist. */ if( isCreate ){ - p->bHasContent = 1; - p->bHasDocsize = argv[0][3]=='4'; rc = fts3CreateTables(p); - }else{ - rc = SQLITE_OK; - fts3TableExists(&rc, db, argv[1], argv[2], "_content", &p->bHasContent); - fts3TableExists(&rc, db, argv[1], argv[2], "_docsize", &p->bHasDocsize); } - if( rc!=SQLITE_OK ) goto fts3_init_out; - rc = fts3DeclareVtab(p); - if( rc!=SQLITE_OK ) goto fts3_init_out; + /* Figure out the page-size for the database. This is required in order to + ** estimate the cost of loading large doclists from the database. */ + fts3DatabasePageSize(&rc, p); + p->nNodeSize = p->nPgsz-35; - *ppVTab = &p->base; + /* Declare the table schema to SQLite. */ + fts3DeclareVtab(&rc, p); fts3_init_out: - assert( p || (pTokenizer && rc!=SQLITE_OK) ); + sqlite3_free(zPrefix); + sqlite3_free(aIndex); + sqlite3_free(zCompress); + sqlite3_free(zUncompress); + sqlite3_free((void *)aCol); if( rc!=SQLITE_OK ){ if( p ){ fts3DisconnectMethod((sqlite3_vtab *)p); - }else{ + }else if( pTokenizer ){ pTokenizer->pModule->xDestroy(pTokenizer); } + }else{ + assert( p->pSegments==0 ); + *ppVTab = &p->base; } return rc; } @@ -100529,11 +115425,11 @@ static int fts3CreateMethod( return fts3InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr); } -/* +/* ** Implementation of the xBestIndex method for FTS3 tables. There ** are three possible strategies, in order of preference: ** -** 1. Direct lookup by rowid or docid. +** 1. Direct lookup by rowid or docid. ** 2. Full-text search using a MATCH operator on a non-docid column. ** 3. Linear scan of %_content table. */ @@ -100543,7 +115439,7 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ int iCons = -1; /* Index of constraint to use */ /* By default use a full table scan. This is an expensive option, - ** so search through the constraints to see if a more efficient + ** so search through the constraints to see if a more efficient ** strategy is possible. */ pInfo->idxNum = FTS3_FULLSCAN_SEARCH; @@ -100553,7 +115449,7 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ if( pCons->usable==0 ) continue; /* A direct lookup on the rowid or docid column. Assign a cost of 1.0. */ - if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ && (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1 ) ){ pInfo->idxNum = FTS3_DOCID_SEARCH; @@ -100565,12 +115461,12 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ ** ** If there is more than one MATCH constraint available, use the first ** one encountered. If there is both a MATCH constraint and a direct - ** rowid/docid lookup, prefer the MATCH strategy. This is done even + ** rowid/docid lookup, prefer the MATCH strategy. This is done even ** though the rowid/docid lookup is faster than a MATCH query, selecting - ** it would lead to an "unable to use function MATCH in the requested + ** it would lead to an "unable to use function MATCH in the requested ** context" error. */ - if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH + if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH && pCons->iColumn>=0 && pCons->iColumn<=p->nColumn ){ pInfo->idxNum = FTS3_FULLTEXT_SEARCH + pCons->iColumn; @@ -100583,7 +115479,24 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ if( iCons>=0 ){ pInfo->aConstraintUsage[iCons].argvIndex = 1; pInfo->aConstraintUsage[iCons].omit = 1; + } + + /* Regardless of the strategy selected, FTS can deliver rows in rowid (or + ** docid) order. Both ascending and descending are possible. + */ + if( pInfo->nOrderBy==1 ){ + struct sqlite3_index_orderby *pOrder = &pInfo->aOrderBy[0]; + if( pOrder->iColumn<0 || pOrder->iColumn==p->nColumn+1 ){ + if( pOrder->desc ){ + pInfo->idxStr = "DESC"; + }else{ + pInfo->idxStr = "ASC"; + } + pInfo->orderByConsumed = 1; + } } + + assert( p->pSegments==0 ); return SQLITE_OK; } @@ -100596,7 +115509,7 @@ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ UNUSED_PARAMETER(pVTab); /* Allocate a buffer large enough for an Fts3Cursor structure. If the - ** allocation succeeds, zero it and return SQLITE_OK. Otherwise, + ** allocation succeeds, zero it and return SQLITE_OK. Otherwise, ** if the allocation fails, return SQLITE_NOMEM. */ *ppCsr = pCsr = (sqlite3_vtab_cursor *)sqlite3_malloc(sizeof(Fts3Cursor)); @@ -100611,20 +115524,28 @@ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ ** Close the cursor. For additional information see the documentation ** on the xClose method of the virtual table interface. */ -static int fulltextClose(sqlite3_vtab_cursor *pCursor){ +static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){ Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); sqlite3_finalize(pCsr->pStmt); sqlite3Fts3ExprFree(pCsr->pExpr); + sqlite3Fts3FreeDeferredTokens(pCsr); sqlite3_free(pCsr->aDoclist); sqlite3_free(pCsr->aMatchinfo); + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); sqlite3_free(pCsr); return SQLITE_OK; } +/* +** Position the pCsr->pStmt statement so that it is on the row +** of the %_content table that contains the last match. Return +** SQLITE_OK on success. +*/ static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){ if( pCsr->isRequireSeek ){ - pCsr->isRequireSeek = 0; sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId); + pCsr->isRequireSeek = 0; if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){ return SQLITE_OK; }else{ @@ -100634,7 +115555,7 @@ static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){ ** table is missing a row that is present in the full-text index. ** The data structures are corrupt. */ - rc = SQLITE_CORRUPT; + rc = SQLITE_CORRUPT_VTAB; } pCsr->isEof = 1; if( pContext ){ @@ -100647,125 +115568,187 @@ static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){ } } -static int fts3NextMethod(sqlite3_vtab_cursor *pCursor){ +/* +** This function is used to process a single interior node when searching +** a b-tree for a term or term prefix. The node data is passed to this +** function via the zNode/nNode parameters. The term to search for is +** passed in zTerm/nTerm. +** +** If piFirst is not NULL, then this function sets *piFirst to the blockid +** of the child node that heads the sub-tree that may contain the term. +** +** If piLast is not NULL, then *piLast is set to the right-most child node +** that heads a sub-tree that may contain a term for which zTerm/nTerm is +** a prefix. +** +** If an OOM error occurs, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK. +*/ +static int fts3ScanInteriorNode( + const char *zTerm, /* Term to select leaves for */ + int nTerm, /* Size of term zTerm in bytes */ + const char *zNode, /* Buffer containing segment interior node */ + int nNode, /* Size of buffer at zNode */ + sqlite3_int64 *piFirst, /* OUT: Selected child node */ + sqlite3_int64 *piLast /* OUT: Selected child node */ +){ int rc = SQLITE_OK; /* Return code */ - Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; + const char *zCsr = zNode; /* Cursor to iterate through node */ + const char *zEnd = &zCsr[nNode];/* End of interior node buffer */ + char *zBuffer = 0; /* Buffer to load terms into */ + int nAlloc = 0; /* Size of allocated buffer */ + int isFirstTerm = 1; /* True when processing first term on page */ + sqlite3_int64 iChild; /* Block id of child node to descend to */ - if( pCsr->aDoclist==0 ){ - if( SQLITE_ROW!=sqlite3_step(pCsr->pStmt) ){ - pCsr->isEof = 1; - rc = sqlite3_reset(pCsr->pStmt); + /* Skip over the 'height' varint that occurs at the start of every + ** interior node. Then load the blockid of the left-child of the b-tree + ** node into variable iChild. + ** + ** Even if the data structure on disk is corrupted, this (reading two + ** varints from the buffer) does not risk an overread. If zNode is a + ** root node, then the buffer comes from a SELECT statement. SQLite does + ** not make this guarantee explicitly, but in practice there are always + ** either more than 20 bytes of allocated space following the nNode bytes of + ** contents, or two zero bytes. Or, if the node is read from the %_segments + ** table, then there are always 20 bytes of zeroed padding following the + ** nNode bytes of content (see sqlite3Fts3ReadBlock() for details). + */ + zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); + zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); + if( zCsr>zEnd ){ + return SQLITE_CORRUPT_VTAB; + } + + while( zCsr<zEnd && (piFirst || piLast) ){ + int cmp; /* memcmp() result */ + int nSuffix; /* Size of term suffix */ + int nPrefix = 0; /* Size of term prefix */ + int nBuffer; /* Total term size */ + + /* Load the next term on the node into zBuffer. Use realloc() to expand + ** the size of zBuffer if required. */ + if( !isFirstTerm ){ + zCsr += sqlite3Fts3GetVarint32(zCsr, &nPrefix); + } + isFirstTerm = 0; + zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix); + + if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){ + rc = SQLITE_CORRUPT_VTAB; + goto finish_scan; + } + if( nPrefix+nSuffix>nAlloc ){ + char *zNew; + nAlloc = (nPrefix+nSuffix) * 2; + zNew = (char *)sqlite3_realloc(zBuffer, nAlloc); + if( !zNew ){ + rc = SQLITE_NOMEM; + goto finish_scan; + } + zBuffer = zNew; } - }else if( pCsr->pNextId>=&pCsr->aDoclist[pCsr->nDoclist] ){ - pCsr->isEof = 1; - }else{ - sqlite3_reset(pCsr->pStmt); - fts3GetDeltaVarint(&pCsr->pNextId, &pCsr->iPrevId); - pCsr->isRequireSeek = 1; - pCsr->isMatchinfoNeeded = 1; - } + memcpy(&zBuffer[nPrefix], zCsr, nSuffix); + nBuffer = nPrefix + nSuffix; + zCsr += nSuffix; + + /* Compare the term we are searching for with the term just loaded from + ** the interior node. If the specified term is greater than or equal + ** to the term from the interior node, then all terms on the sub-tree + ** headed by node iChild are smaller than zTerm. No need to search + ** iChild. + ** + ** If the interior node term is larger than the specified term, then + ** the tree headed by iChild may contain the specified term. + */ + cmp = memcmp(zTerm, zBuffer, (nBuffer>nTerm ? nTerm : nBuffer)); + if( piFirst && (cmp<0 || (cmp==0 && nBuffer>nTerm)) ){ + *piFirst = iChild; + piFirst = 0; + } + + if( piLast && cmp<0 ){ + *piLast = iChild; + piLast = 0; + } + + iChild++; + }; + + if( piFirst ) *piFirst = iChild; + if( piLast ) *piLast = iChild; + + finish_scan: + sqlite3_free(zBuffer); return rc; } /* -** The buffer pointed to by argument zNode (size nNode bytes) contains the -** root node of a b-tree segment. The segment is guaranteed to be at least -** one level high (i.e. the root node is not also a leaf). If successful, -** this function locates the leaf node of the segment that may contain the -** term specified by arguments zTerm and nTerm and writes its block number -** to *piLeaf. +** The buffer pointed to by argument zNode (size nNode bytes) contains an +** interior node of a b-tree segment. The zTerm buffer (size nTerm bytes) +** contains a term. This function searches the sub-tree headed by the zNode +** node for the range of leaf nodes that may contain the specified term +** or terms for which the specified term is a prefix. +** +** If piLeaf is not NULL, then *piLeaf is set to the blockid of the +** left-most leaf node in the tree that may contain the specified term. +** If piLeaf2 is not NULL, then *piLeaf2 is set to the blockid of the +** right-most leaf node that may contain a term for which the specified +** term is a prefix. ** -** It is possible that the returned leaf node does not contain the specified -** term. However, if the segment does contain said term, it is stored on -** the identified leaf node. Because this function only inspects interior -** segment nodes (and never loads leaf nodes into memory), it is not possible -** to be sure. +** It is possible that the range of returned leaf nodes does not contain +** the specified term or any terms for which it is a prefix. However, if the +** segment does contain any such terms, they are stored within the identified +** range. Because this function only inspects interior segment nodes (and +** never loads leaf nodes into memory), it is not possible to be sure. ** ** If an error occurs, an error code other than SQLITE_OK is returned. -*/ +*/ static int fts3SelectLeaf( Fts3Table *p, /* Virtual table handle */ const char *zTerm, /* Term to select leaves for */ int nTerm, /* Size of term zTerm in bytes */ const char *zNode, /* Buffer containing segment interior node */ int nNode, /* Size of buffer at zNode */ - sqlite3_int64 *piLeaf /* Selected leaf node */ + sqlite3_int64 *piLeaf, /* Selected leaf node */ + sqlite3_int64 *piLeaf2 /* Selected leaf node */ ){ - int rc = SQLITE_OK; /* Return code */ - const char *zCsr = zNode; /* Cursor to iterate through node */ - const char *zEnd = &zCsr[nNode];/* End of interior node buffer */ - char *zBuffer = 0; /* Buffer to load terms into */ - int nAlloc = 0; /* Size of allocated buffer */ + int rc; /* Return code */ + int iHeight; /* Height of this node in tree */ - while( 1 ){ - int isFirstTerm = 1; /* True when processing first term on page */ - int iHeight; /* Height of this node in tree */ - sqlite3_int64 iChild; /* Block id of child node to descend to */ - int nBlock; /* Size of child node in bytes */ - - zCsr += sqlite3Fts3GetVarint32(zCsr, &iHeight); - zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); - - while( zCsr<zEnd ){ - int cmp; /* memcmp() result */ - int nSuffix; /* Size of term suffix */ - int nPrefix = 0; /* Size of term prefix */ - int nBuffer; /* Total term size */ - - /* Load the next term on the node into zBuffer */ - if( !isFirstTerm ){ - zCsr += sqlite3Fts3GetVarint32(zCsr, &nPrefix); - } - isFirstTerm = 0; - zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix); - if( nPrefix+nSuffix>nAlloc ){ - char *zNew; - nAlloc = (nPrefix+nSuffix) * 2; - zNew = (char *)sqlite3_realloc(zBuffer, nAlloc); - if( !zNew ){ - sqlite3_free(zBuffer); - return SQLITE_NOMEM; - } - zBuffer = zNew; - } - memcpy(&zBuffer[nPrefix], zCsr, nSuffix); - nBuffer = nPrefix + nSuffix; - zCsr += nSuffix; + assert( piLeaf || piLeaf2 ); - /* Compare the term we are searching for with the term just loaded from - ** the interior node. If the specified term is greater than or equal - ** to the term from the interior node, then all terms on the sub-tree - ** headed by node iChild are smaller than zTerm. No need to search - ** iChild. - ** - ** If the interior node term is larger than the specified term, then - ** the tree headed by iChild may contain the specified term. - */ - cmp = memcmp(zTerm, zBuffer, (nBuffer>nTerm ? nTerm : nBuffer)); - if( cmp<0 || (cmp==0 && nBuffer>nTerm) ) break; - iChild++; - }; + sqlite3Fts3GetVarint32(zNode, &iHeight); + rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); + assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); - /* If (iHeight==1), the children of this interior node are leaves. The - ** specified term may be present on leaf node iChild. - */ - if( iHeight==1 ){ - *piLeaf = iChild; - break; + if( rc==SQLITE_OK && iHeight>1 ){ + char *zBlob = 0; /* Blob read from %_segments table */ + int nBlob; /* Size of zBlob in bytes */ + + if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){ + rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0); + if( rc==SQLITE_OK ){ + rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0); + } + sqlite3_free(zBlob); + piLeaf = 0; + zBlob = 0; } - /* Descend to interior node iChild. */ - rc = sqlite3Fts3ReadBlock(p, iChild, &zCsr, &nBlock); - if( rc!=SQLITE_OK ) break; - zEnd = &zCsr[nBlock]; + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3ReadBlock(p, piLeaf?*piLeaf:*piLeaf2, &zBlob, &nBlob, 0); + } + if( rc==SQLITE_OK ){ + rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2); + } + sqlite3_free(zBlob); } - sqlite3_free(zBuffer); + return rc; } /* -** This function is used to create delta-encoded serialized lists of FTS3 +** This function is used to create delta-encoded serialized lists of FTS3 ** varints. Each call to this function appends a single varint to a list. */ static void fts3PutDeltaVarint( @@ -100779,10 +115762,15 @@ static void fts3PutDeltaVarint( } /* -** When this function is called, *ppPoslist is assumed to point to the +** When this function is called, *ppPoslist is assumed to point to the ** start of a position-list. After it returns, *ppPoslist points to the ** first byte after the position-list. ** +** A position list is list of positions (delta encoded) and columns for +** a single document record of a doclist. So, in other words, this +** routine advances *ppPoslist so that it points to the next docid in +** the doclist, or to the first byte past the end of the doclist. +** ** If pp is not NULL, then the contents of the position list are copied ** to *pp. *pp is set to point to the first byte past the last byte copied ** before this function returns. @@ -100791,18 +115779,21 @@ static void fts3PoslistCopy(char **pp, char **ppPoslist){ char *pEnd = *ppPoslist; char c = 0; - /* The end of a position list is marked by a zero encoded as an FTS3 - ** varint. A single 0x00 byte. Except, if the 0x00 byte is preceded by + /* The end of a position list is marked by a zero encoded as an FTS3 + ** varint. A single POS_END (0) byte. Except, if the 0 byte is preceded by ** a byte with the 0x80 bit set, then it is not a varint 0, but the tail ** of some other, multi-byte, value. ** - ** The following block moves pEnd to point to the first byte that is not + ** The following while-loop moves pEnd to point to the first byte that is not ** immediately preceded by a byte with the 0x80 bit set. Then increments ** pEnd once more so that it points to the byte immediately following the ** last byte in the position-list. */ - while( *pEnd | c ) c = *pEnd++ & 0x80; - pEnd++; + while( *pEnd | c ){ + c = *pEnd++ & 0x80; + testcase( c!=0 && (*pEnd)==0 ); + } + pEnd++; /* Advance past the POS_END terminator byte */ if( pp ){ int n = (int)(pEnd - *ppPoslist); @@ -100814,12 +115805,34 @@ static void fts3PoslistCopy(char **pp, char **ppPoslist){ *ppPoslist = pEnd; } +/* +** When this function is called, *ppPoslist is assumed to point to the +** start of a column-list. After it returns, *ppPoslist points to the +** to the terminator (POS_COLUMN or POS_END) byte of the column-list. +** +** A column-list is list of delta-encoded positions for a single column +** within a single document within a doclist. +** +** The column-list is terminated either by a POS_COLUMN varint (1) or +** a POS_END varint (0). This routine leaves *ppPoslist pointing to +** the POS_COLUMN or POS_END that terminates the column-list. +** +** If pp is not NULL, then the contents of the column-list are copied +** to *pp. *pp is set to point to the first byte past the last byte copied +** before this function returns. The POS_COLUMN or POS_END terminator +** is not copied into *pp. +*/ static void fts3ColumnlistCopy(char **pp, char **ppPoslist){ char *pEnd = *ppPoslist; char c = 0; - /* A column-list is terminated by either a 0x01 or 0x00. */ - while( 0xFE & (*pEnd | c) ) c = *pEnd++ & 0x80; + /* A column-list is terminated by either a 0x01 or 0x00 byte that is + ** not part of a multi-byte varint. + */ + while( 0xFE & (*pEnd | c) ){ + c = *pEnd++ & 0x80; + testcase( c!=0 && ((*pEnd)&0xfe)==0 ); + } if( pp ){ int n = (int)(pEnd - *ppPoslist); char *p = *pp; @@ -100831,39 +115844,47 @@ static void fts3ColumnlistCopy(char **pp, char **ppPoslist){ } /* -** Value used to signify the end of an offset-list. This is safe because +** Value used to signify the end of an position-list. This is safe because ** it is not possible to have a document with 2^31 terms. */ -#define OFFSET_LIST_END 0x7fffffff +#define POSITION_LIST_END 0x7fffffff /* -** This function is used to help parse offset-lists. When this function is -** called, *pp may point to the start of the next varint in the offset-list -** being parsed, or it may point to 1 byte past the end of the offset-list -** (in which case **pp will be 0x00 or 0x01). +** This function is used to help parse position-lists. When this function is +** called, *pp may point to the start of the next varint in the position-list +** being parsed, or it may point to 1 byte past the end of the position-list +** (in which case **pp will be a terminator bytes POS_END (0) or +** (1)). ** -** If *pp points past the end of the current offset list, set *pi to -** OFFSET_LIST_END and return. Otherwise, read the next varint from *pp, +** If *pp points past the end of the current position-list, set *pi to +** POSITION_LIST_END and return. Otherwise, read the next varint from *pp, ** increment the current value of *pi by the value read, and set *pp to ** point to the next value before returning. +** +** Before calling this routine *pi must be initialized to the value of +** the previous position, or zero if we are reading the first position +** in the position-list. Because positions are delta-encoded, the value +** of the previous position is needed in order to compute the value of +** the next position. */ static void fts3ReadNextPos( - char **pp, /* IN/OUT: Pointer into offset-list buffer */ - sqlite3_int64 *pi /* IN/OUT: Value read from offset-list */ + char **pp, /* IN/OUT: Pointer into position-list buffer */ + sqlite3_int64 *pi /* IN/OUT: Value read from position-list */ ){ - if( **pp&0xFE ){ + if( (**pp)&0xFE ){ fts3GetDeltaVarint(pp, pi); *pi -= 2; }else{ - *pi = OFFSET_LIST_END; + *pi = POSITION_LIST_END; } } /* -** If parameter iCol is not 0, write an 0x01 byte followed by the value of -** iCol encoded as a varint to *pp. +** If parameter iCol is not 0, write an POS_COLUMN (1) byte followed by +** the value of iCol encoded as a varint to *pp. This will start a new +** column list. ** -** Set *pp to point to the byte just after the last byte written before +** Set *pp to point to the byte just after the last byte written before ** returning (do not modify it if iCol==0). Return the total number of bytes ** written (0 if iCol==0). */ @@ -100879,7 +115900,11 @@ static int fts3PutColNumber(char **pp, int iCol){ } /* -** +** Compute the union of two position lists. The output written +** into *pp contains all positions of both *pp1 and *pp2 in sorted +** order and with any duplicates removed. All pointers are +** updated appropriately. The caller is responsible for insuring +** that there is enough space in *pp to hold the complete output. */ static void fts3PoslistMerge( char **pp, /* Output buffer */ @@ -100891,37 +115916,38 @@ static void fts3PoslistMerge( char *p2 = *pp2; while( *p1 || *p2 ){ - int iCol1; - int iCol2; + int iCol1; /* The current column index in pp1 */ + int iCol2; /* The current column index in pp2 */ - if( *p1==0x01 ) sqlite3Fts3GetVarint32(&p1[1], &iCol1); - else if( *p1==0x00 ) iCol1 = OFFSET_LIST_END; + if( *p1==POS_COLUMN ) sqlite3Fts3GetVarint32(&p1[1], &iCol1); + else if( *p1==POS_END ) iCol1 = POSITION_LIST_END; else iCol1 = 0; - if( *p2==0x01 ) sqlite3Fts3GetVarint32(&p2[1], &iCol2); - else if( *p2==0x00 ) iCol2 = OFFSET_LIST_END; + if( *p2==POS_COLUMN ) sqlite3Fts3GetVarint32(&p2[1], &iCol2); + else if( *p2==POS_END ) iCol2 = POSITION_LIST_END; else iCol2 = 0; if( iCol1==iCol2 ){ - sqlite3_int64 i1 = 0; - sqlite3_int64 i2 = 0; + sqlite3_int64 i1 = 0; /* Last position from pp1 */ + sqlite3_int64 i2 = 0; /* Last position from pp2 */ sqlite3_int64 iPrev = 0; int n = fts3PutColNumber(&p, iCol1); p1 += n; p2 += n; - /* At this point, both p1 and p2 point to the start of offset-lists. - ** An offset-list is a list of non-negative delta-encoded varints, each - ** incremented by 2 before being stored. Each list is terminated by a 0 - ** or 1 value (0x00 or 0x01). The following block merges the two lists + /* At this point, both p1 and p2 point to the start of column-lists + ** for the same column (the column with index iCol1 and iCol2). + ** A column-list is a list of non-negative delta-encoded varints, each + ** incremented by 2 before being stored. Each list is terminated by a + ** POS_END (0) or POS_COLUMN (1). The following block merges the two lists ** and writes the results to buffer p. p is left pointing to the byte - ** after the list written. No terminator (0x00 or 0x01) is written to - ** the output. + ** after the list written. No terminator (POS_END or POS_COLUMN) is + ** written to the output. */ fts3GetDeltaVarint(&p1, &i1); fts3GetDeltaVarint(&p2, &i2); do { - fts3PutDeltaVarint(&p, &iPrev, (i1<i2) ? i1 : i2); + fts3PutDeltaVarint(&p, &iPrev, (i1<i2) ? i1 : i2); iPrev -= 2; if( i1==i2 ){ fts3ReadNextPos(&p1, &i1); @@ -100931,7 +115957,7 @@ static void fts3PoslistMerge( }else{ fts3ReadNextPos(&p2, &i2); } - }while( i1!=OFFSET_LIST_END || i2!=OFFSET_LIST_END ); + }while( i1!=POSITION_LIST_END || i2!=POSITION_LIST_END ); }else if( iCol1<iCol2 ){ p1 += fts3PutColNumber(&p, iCol1); fts3ColumnlistCopy(&p, &p1); @@ -100941,34 +115967,58 @@ static void fts3PoslistMerge( } } - *p++ = '\0'; + *p++ = POS_END; *pp = p; *pp1 = p1 + 1; *pp2 = p2 + 1; } /* -** nToken==1 searches for adjacent positions. +** This function is used to merge two position lists into one. When it is +** called, *pp1 and *pp2 must both point to position lists. A position-list is +** the part of a doclist that follows each document id. For example, if a row +** contains: +** +** 'a b c'|'x y z'|'a b b a' +** +** Then the position list for this row for token 'b' would consist of: +** +** 0x02 0x01 0x02 0x03 0x03 0x00 +** +** When this function returns, both *pp1 and *pp2 are left pointing to the +** byte following the 0x00 terminator of their respective position lists. +** +** If isSaveLeft is 0, an entry is added to the output position list for +** each position in *pp2 for which there exists one or more positions in +** *pp1 so that (pos(*pp2)>pos(*pp1) && pos(*pp2)-pos(*pp1)<=nToken). i.e. +** when the *pp1 token appears before the *pp2 token, but not more than nToken +** slots before it. +** +** e.g. nToken==1 searches for adjacent positions. */ static int fts3PoslistPhraseMerge( - char **pp, /* Output buffer */ + char **pp, /* IN/OUT: Preallocated output buffer */ int nToken, /* Maximum difference in token positions */ int isSaveLeft, /* Save the left position */ - char **pp1, /* Left input list */ - char **pp2 /* Right input list */ + int isExact, /* If *pp1 is exactly nTokens before *pp2 */ + char **pp1, /* IN/OUT: Left input list */ + char **pp2 /* IN/OUT: Right input list */ ){ char *p = (pp ? *pp : 0); char *p1 = *pp1; char *p2 = *pp2; - int iCol1 = 0; int iCol2 = 0; + + /* Never set both isSaveLeft and isExact for the same invocation. */ + assert( isSaveLeft==0 || isExact==0 ); + assert( *p1!=0 && *p2!=0 ); - if( *p1==0x01 ){ + if( *p1==POS_COLUMN ){ p1++; p1 += sqlite3Fts3GetVarint32(p1, &iCol1); } - if( *p2==0x01 ){ + if( *p2==POS_COLUMN ){ p2++; p2 += sqlite3Fts3GetVarint32(p2, &iCol2); } @@ -100981,16 +116031,19 @@ static int fts3PoslistPhraseMerge( sqlite3_int64 iPos2 = 0; if( pp && iCol1 ){ - *p++ = 0x01; + *p++ = POS_COLUMN; p += sqlite3Fts3PutVarint(p, iCol1); } - assert( *p1!=0x00 && *p2!=0x00 && *p1!=0x01 && *p2!=0x01 ); + assert( *p1!=POS_END && *p1!=POS_COLUMN ); + assert( *p2!=POS_END && *p2!=POS_COLUMN ); fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2; fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2; while( 1 ){ - if( iPos2>iPos1 && iPos2<=iPos1+nToken ){ + if( iPos2==iPos1+nToken + || (isExact==0 && iPos2>iPos1 && iPos2<=iPos1+nToken) + ){ sqlite3_int64 iSave; if( !pp ){ fts3PoslistCopy(0, &p2); @@ -101030,8 +116083,8 @@ static int fts3PoslistPhraseMerge( /* Advance pointer p1 or p2 (whichever corresponds to the smaller of ** iCol1 and iCol2) so that it points to either the 0x00 that marks the - ** end of the position list, or the 0x01 that precedes the next - ** column-number in the position list. + ** end of the position list, or the 0x01 that precedes the next + ** column-number in the position list. */ else if( iCol1<iCol2 ){ fts3ColumnlistCopy(0, &p1); @@ -101059,7 +116112,19 @@ static int fts3PoslistPhraseMerge( } /* -** Merge two position-lists as required by the NEAR operator. +** Merge two position-lists as required by the NEAR operator. The argument +** position lists correspond to the left and right phrases of an expression +** like: +** +** "phrase 1" NEAR "phrase number 2" +** +** Position list *pp1 corresponds to the left-hand side of the NEAR +** expression and *pp2 to the right. As usual, the indexes in the position +** lists are the offsets of the last token in each phrase (tokens "1" and "2" +** in the example above). +** +** The output position list - written to *pp - is a copy of *pp2 with those +** entries that are not sufficiently NEAR entries in *pp1 removed. */ static int fts3PoslistNearMerge( char **pp, /* Output buffer */ @@ -101072,629 +116137,711 @@ static int fts3PoslistNearMerge( char *p1 = *pp1; char *p2 = *pp2; - if( !pp ){ - if( fts3PoslistPhraseMerge(0, nRight, 0, pp1, pp2) ) return 1; - *pp1 = p1; - *pp2 = p2; - return fts3PoslistPhraseMerge(0, nLeft, 0, pp2, pp1); + char *pTmp1 = aTmp; + char *pTmp2; + char *aTmp2; + int res = 1; + + fts3PoslistPhraseMerge(&pTmp1, nRight, 0, 0, pp1, pp2); + aTmp2 = pTmp2 = pTmp1; + *pp1 = p1; + *pp2 = p2; + fts3PoslistPhraseMerge(&pTmp2, nLeft, 1, 0, pp2, pp1); + if( pTmp1!=aTmp && pTmp2!=aTmp2 ){ + fts3PoslistMerge(pp, &aTmp, &aTmp2); + }else if( pTmp1!=aTmp ){ + fts3PoslistCopy(pp, &aTmp); + }else if( pTmp2!=aTmp2 ){ + fts3PoslistCopy(pp, &aTmp2); + }else{ + res = 0; + } + + return res; +} + +/* +** An instance of this function is used to merge together the (potentially +** large number of) doclists for each term that matches a prefix query. +** See function fts3TermSelectMerge() for details. +*/ +typedef struct TermSelect TermSelect; +struct TermSelect { + char *aaOutput[16]; /* Malloc'd output buffers */ + int anOutput[16]; /* Size each output buffer in bytes */ +}; + +/* +** This function is used to read a single varint from a buffer. Parameter +** pEnd points 1 byte past the end of the buffer. When this function is +** called, if *pp points to pEnd or greater, then the end of the buffer +** has been reached. In this case *pp is set to 0 and the function returns. +** +** If *pp does not point to or past pEnd, then a single varint is read +** from *pp. *pp is then set to point 1 byte past the end of the read varint. +** +** If bDescIdx is false, the value read is added to *pVal before returning. +** If it is true, the value read is subtracted from *pVal before this +** function returns. +*/ +static void fts3GetDeltaVarint3( + char **pp, /* IN/OUT: Point to read varint from */ + char *pEnd, /* End of buffer */ + int bDescIdx, /* True if docids are descending */ + sqlite3_int64 *pVal /* IN/OUT: Integer value */ +){ + if( *pp>=pEnd ){ + *pp = 0; }else{ - char *pTmp1 = aTmp; - char *pTmp2; - char *aTmp2; - int res = 1; - - fts3PoslistPhraseMerge(&pTmp1, nRight, 0, pp1, pp2); - aTmp2 = pTmp2 = pTmp1; - *pp1 = p1; - *pp2 = p2; - fts3PoslistPhraseMerge(&pTmp2, nLeft, 1, pp2, pp1); - if( pTmp1!=aTmp && pTmp2!=aTmp2 ){ - fts3PoslistMerge(pp, &aTmp, &aTmp2); - }else if( pTmp1!=aTmp ){ - fts3PoslistCopy(pp, &aTmp); - }else if( pTmp2!=aTmp2 ){ - fts3PoslistCopy(pp, &aTmp2); + sqlite3_int64 iVal; + *pp += sqlite3Fts3GetVarint(*pp, &iVal); + if( bDescIdx ){ + *pVal -= iVal; }else{ - res = 0; + *pVal += iVal; } + } +} - return res; +/* +** This function is used to write a single varint to a buffer. The varint +** is written to *pp. Before returning, *pp is set to point 1 byte past the +** end of the value written. +** +** If *pbFirst is zero when this function is called, the value written to +** the buffer is that of parameter iVal. +** +** If *pbFirst is non-zero when this function is called, then the value +** written is either (iVal-*piPrev) (if bDescIdx is zero) or (*piPrev-iVal) +** (if bDescIdx is non-zero). +** +** Before returning, this function always sets *pbFirst to 1 and *piPrev +** to the value of parameter iVal. +*/ +static void fts3PutDeltaVarint3( + char **pp, /* IN/OUT: Output pointer */ + int bDescIdx, /* True for descending docids */ + sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ + int *pbFirst, /* IN/OUT: True after first int written */ + sqlite3_int64 iVal /* Write this value to the list */ +){ + sqlite3_int64 iWrite; + if( bDescIdx==0 || *pbFirst==0 ){ + iWrite = iVal - *piPrev; + }else{ + iWrite = *piPrev - iVal; } + assert( *pbFirst || *piPrev==0 ); + assert( *pbFirst==0 || iWrite>0 ); + *pp += sqlite3Fts3PutVarint(*pp, iWrite); + *piPrev = iVal; + *pbFirst = 1; } + /* -** Values that may be used as the first parameter to fts3DoclistMerge(). +** This macro is used by various functions that merge doclists. The two +** arguments are 64-bit docid values. If the value of the stack variable +** bDescDoclist is 0 when this macro is invoked, then it returns (i1-i2). +** Otherwise, (i2-i1). +** +** Using this makes it easier to write code that can merge doclists that are +** sorted in either ascending or descending order. */ -#define MERGE_NOT 2 /* D + D -> D */ -#define MERGE_AND 3 /* D + D -> D */ -#define MERGE_OR 4 /* D + D -> D */ -#define MERGE_POS_OR 5 /* P + P -> P */ -#define MERGE_PHRASE 6 /* P + P -> D */ -#define MERGE_POS_PHRASE 7 /* P + P -> P */ -#define MERGE_NEAR 8 /* P + P -> D */ -#define MERGE_POS_NEAR 9 /* P + P -> P */ +#define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i1-i2)) /* -** Merge the two doclists passed in buffer a1 (size n1 bytes) and a2 -** (size n2 bytes). The output is written to pre-allocated buffer aBuffer, -** which is guaranteed to be large enough to hold the results. The number -** of bytes written to aBuffer is stored in *pnBuffer before returning. +** This function does an "OR" merge of two doclists (output contains all +** positions contained in either argument doclist). If the docids in the +** input doclists are sorted in ascending order, parameter bDescDoclist +** should be false. If they are sorted in ascending order, it should be +** passed a non-zero value. ** -** If successful, SQLITE_OK is returned. Otherwise, if a malloc error -** occurs while allocating a temporary buffer as part of the merge operation, -** SQLITE_NOMEM is returned. +** If no error occurs, *paOut is set to point at an sqlite3_malloc'd buffer +** containing the output doclist and SQLITE_OK is returned. In this case +** *pnOut is set to the number of bytes in the output doclist. +** +** If an error occurs, an SQLite error code is returned. The output values +** are undefined in this case. */ -static int fts3DoclistMerge( - int mergetype, /* One of the MERGE_XXX constants */ - int nParam1, /* Used by MERGE_NEAR and MERGE_POS_NEAR */ - int nParam2, /* Used by MERGE_NEAR and MERGE_POS_NEAR */ - char *aBuffer, /* Pre-allocated output buffer */ - int *pnBuffer, /* OUT: Bytes written to aBuffer */ - char *a1, /* Buffer containing first doclist */ - int n1, /* Size of buffer a1 */ - char *a2, /* Buffer containing second doclist */ - int n2 /* Size of buffer a2 */ +static int fts3DoclistOrMerge( + int bDescDoclist, /* True if arguments are desc */ + char *a1, int n1, /* First doclist */ + char *a2, int n2, /* Second doclist */ + char **paOut, int *pnOut /* OUT: Malloc'd doclist */ ){ sqlite3_int64 i1 = 0; sqlite3_int64 i2 = 0; sqlite3_int64 iPrev = 0; - - char *p = aBuffer; - char *p1 = a1; - char *p2 = a2; char *pEnd1 = &a1[n1]; char *pEnd2 = &a2[n2]; + char *p1 = a1; + char *p2 = a2; + char *p; + char *aOut; + int bFirstOut = 0; - assert( mergetype==MERGE_OR || mergetype==MERGE_POS_OR - || mergetype==MERGE_AND || mergetype==MERGE_NOT - || mergetype==MERGE_PHRASE || mergetype==MERGE_POS_PHRASE - || mergetype==MERGE_NEAR || mergetype==MERGE_POS_NEAR - ); + *paOut = 0; + *pnOut = 0; - if( !aBuffer ){ - *pnBuffer = 0; - return SQLITE_NOMEM; + /* Allocate space for the output. Both the input and output doclists + ** are delta encoded. If they are in ascending order (bDescDoclist==0), + ** then the first docid in each list is simply encoded as a varint. For + ** each subsequent docid, the varint stored is the difference between the + ** current and previous docid (a positive number - since the list is in + ** ascending order). + ** + ** The first docid written to the output is therefore encoded using the + ** same number of bytes as it is in whichever of the input lists it is + ** read from. And each subsequent docid read from the same input list + ** consumes either the same or less bytes as it did in the input (since + ** the difference between it and the previous value in the output must + ** be a positive value less than or equal to the delta value read from + ** the input list). The same argument applies to all but the first docid + ** read from the 'other' list. And to the contents of all position lists + ** that will be copied and merged from the input to the output. + ** + ** However, if the first docid copied to the output is a negative number, + ** then the encoding of the first docid from the 'other' input list may + ** be larger in the output than it was in the input (since the delta value + ** may be a larger positive integer than the actual docid). + ** + ** The space required to store the output is therefore the sum of the + ** sizes of the two inputs, plus enough space for exactly one of the input + ** docids to grow. + ** + ** A symetric argument may be made if the doclists are in descending + ** order. + */ + aOut = sqlite3_malloc(n1+n2+FTS3_VARINT_MAX-1); + if( !aOut ) return SQLITE_NOMEM; + + p = aOut; + fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); + while( p1 || p2 ){ + sqlite3_int64 iDiff = DOCID_CMP(i1, i2); + + if( p2 && p1 && iDiff==0 ){ + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); + fts3PoslistMerge(&p, &p1, &p2); + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + }else if( !p2 || (p1 && iDiff<0) ){ + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); + fts3PoslistCopy(&p, &p1); + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + }else{ + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i2); + fts3PoslistCopy(&p, &p2); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + } } - /* Read the first docid from each doclist */ - fts3GetDeltaVarint2(&p1, pEnd1, &i1); - fts3GetDeltaVarint2(&p2, pEnd2, &i2); - - switch( mergetype ){ - case MERGE_OR: - case MERGE_POS_OR: - while( p1 || p2 ){ - if( p2 && p1 && i1==i2 ){ - fts3PutDeltaVarint(&p, &iPrev, i1); - if( mergetype==MERGE_POS_OR ) fts3PoslistMerge(&p, &p1, &p2); - fts3GetDeltaVarint2(&p1, pEnd1, &i1); - fts3GetDeltaVarint2(&p2, pEnd2, &i2); - }else if( !p2 || (p1 && i1<i2) ){ - fts3PutDeltaVarint(&p, &iPrev, i1); - if( mergetype==MERGE_POS_OR ) fts3PoslistCopy(&p, &p1); - fts3GetDeltaVarint2(&p1, pEnd1, &i1); - }else{ - fts3PutDeltaVarint(&p, &iPrev, i2); - if( mergetype==MERGE_POS_OR ) fts3PoslistCopy(&p, &p2); - fts3GetDeltaVarint2(&p2, pEnd2, &i2); - } - } - break; - - case MERGE_AND: - while( p1 && p2 ){ - if( i1==i2 ){ - fts3PutDeltaVarint(&p, &iPrev, i1); - fts3GetDeltaVarint2(&p1, pEnd1, &i1); - fts3GetDeltaVarint2(&p2, pEnd2, &i2); - }else if( i1<i2 ){ - fts3GetDeltaVarint2(&p1, pEnd1, &i1); - }else{ - fts3GetDeltaVarint2(&p2, pEnd2, &i2); - } - } - break; + *paOut = aOut; + *pnOut = (p-aOut); + assert( *pnOut<=n1+n2+FTS3_VARINT_MAX-1 ); + return SQLITE_OK; +} - case MERGE_NOT: - while( p1 ){ - if( p2 && i1==i2 ){ - fts3GetDeltaVarint2(&p1, pEnd1, &i1); - fts3GetDeltaVarint2(&p2, pEnd2, &i2); - }else if( !p2 || i1<i2 ){ - fts3PutDeltaVarint(&p, &iPrev, i1); - fts3GetDeltaVarint2(&p1, pEnd1, &i1); - }else{ - fts3GetDeltaVarint2(&p2, pEnd2, &i2); - } - } - break; +/* +** This function does a "phrase" merge of two doclists. In a phrase merge, +** the output contains a copy of each position from the right-hand input +** doclist for which there is a position in the left-hand input doclist +** exactly nDist tokens before it. +** +** If the docids in the input doclists are sorted in ascending order, +** parameter bDescDoclist should be false. If they are sorted in ascending +** order, it should be passed a non-zero value. +** +** The right-hand input doclist is overwritten by this function. +*/ +static void fts3DoclistPhraseMerge( + int bDescDoclist, /* True if arguments are desc */ + int nDist, /* Distance from left to right (1=adjacent) */ + char *aLeft, int nLeft, /* Left doclist */ + char *aRight, int *pnRight /* IN/OUT: Right/output doclist */ +){ + sqlite3_int64 i1 = 0; + sqlite3_int64 i2 = 0; + sqlite3_int64 iPrev = 0; + char *pEnd1 = &aLeft[nLeft]; + char *pEnd2 = &aRight[*pnRight]; + char *p1 = aLeft; + char *p2 = aRight; + char *p; + int bFirstOut = 0; + char *aOut = aRight; + + assert( nDist>0 ); + + p = aOut; + fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); + + while( p1 && p2 ){ + sqlite3_int64 iDiff = DOCID_CMP(i1, i2); + if( iDiff==0 ){ + char *pSave = p; + sqlite3_int64 iPrevSave = iPrev; + int bFirstOutSave = bFirstOut; - case MERGE_POS_PHRASE: - case MERGE_PHRASE: { - char **ppPos = (mergetype==MERGE_PHRASE ? 0 : &p); - while( p1 && p2 ){ - if( i1==i2 ){ - char *pSave = p; - sqlite3_int64 iPrevSave = iPrev; - fts3PutDeltaVarint(&p, &iPrev, i1); - if( 0==fts3PoslistPhraseMerge(ppPos, 1, 0, &p1, &p2) ){ - p = pSave; - iPrev = iPrevSave; - } - fts3GetDeltaVarint2(&p1, pEnd1, &i1); - fts3GetDeltaVarint2(&p2, pEnd2, &i2); - }else if( i1<i2 ){ - fts3PoslistCopy(0, &p1); - fts3GetDeltaVarint2(&p1, pEnd1, &i1); - }else{ - fts3PoslistCopy(0, &p2); - fts3GetDeltaVarint2(&p2, pEnd2, &i2); - } - } - break; + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); + if( 0==fts3PoslistPhraseMerge(&p, nDist, 0, 1, &p1, &p2) ){ + p = pSave; + iPrev = iPrevSave; + bFirstOut = bFirstOutSave; + } + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + }else if( iDiff<0 ){ + fts3PoslistCopy(0, &p1); + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + }else{ + fts3PoslistCopy(0, &p2); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); } + } - default: assert( mergetype==MERGE_POS_NEAR || mergetype==MERGE_NEAR ); { - char *aTmp = 0; - char **ppPos = 0; - if( mergetype==MERGE_POS_NEAR ){ - ppPos = &p; - aTmp = sqlite3_malloc(2*(n1+n2+1)); - if( !aTmp ){ - return SQLITE_NOMEM; - } - } + *pnRight = p - aOut; +} - while( p1 && p2 ){ - if( i1==i2 ){ - char *pSave = p; - sqlite3_int64 iPrevSave = iPrev; - fts3PutDeltaVarint(&p, &iPrev, i1); - if( !fts3PoslistNearMerge(ppPos, aTmp, nParam1, nParam2, &p1, &p2) ){ - iPrev = iPrevSave; - p = pSave; - } +/* +** Merge all doclists in the TermSelect.aaOutput[] array into a single +** doclist stored in TermSelect.aaOutput[0]. If successful, delete all +** other doclists (except the aaOutput[0] one) and return SQLITE_OK. +** +** If an OOM error occurs, return SQLITE_NOMEM. In this case it is +** the responsibility of the caller to free any doclists left in the +** TermSelect.aaOutput[] array. +*/ +static int fts3TermSelectFinishMerge(Fts3Table *p, TermSelect *pTS){ + char *aOut = 0; + int nOut = 0; + int i; - fts3GetDeltaVarint2(&p1, pEnd1, &i1); - fts3GetDeltaVarint2(&p2, pEnd2, &i2); - }else if( i1<i2 ){ - fts3PoslistCopy(0, &p1); - fts3GetDeltaVarint2(&p1, pEnd1, &i1); - }else{ - fts3PoslistCopy(0, &p2); - fts3GetDeltaVarint2(&p2, pEnd2, &i2); + /* Loop through the doclists in the aaOutput[] array. Merge them all + ** into a single doclist. + */ + for(i=0; i<SizeofArray(pTS->aaOutput); i++){ + if( pTS->aaOutput[i] ){ + if( !aOut ){ + aOut = pTS->aaOutput[i]; + nOut = pTS->anOutput[i]; + pTS->aaOutput[i] = 0; + }else{ + int nNew; + char *aNew; + + int rc = fts3DoclistOrMerge(p->bDescIdx, + pTS->aaOutput[i], pTS->anOutput[i], aOut, nOut, &aNew, &nNew + ); + if( rc!=SQLITE_OK ){ + sqlite3_free(aOut); + return rc; } + + sqlite3_free(pTS->aaOutput[i]); + sqlite3_free(aOut); + pTS->aaOutput[i] = 0; + aOut = aNew; + nOut = nNew; } - sqlite3_free(aTmp); - break; } } - *pnBuffer = (int)(p-aBuffer); + pTS->aaOutput[0] = aOut; + pTS->anOutput[0] = nOut; return SQLITE_OK; } /* -** A pointer to an instance of this structure is used as the context -** argument to sqlite3Fts3SegReaderIterate() -*/ -typedef struct TermSelect TermSelect; -struct TermSelect { - int isReqPos; - char *aOutput; /* Malloc'd output buffer */ - int nOutput; /* Size of output in bytes */ -}; - -/* -** This function is used as the sqlite3Fts3SegReaderIterate() callback when -** querying the full-text index for a doclist associated with a term or -** term-prefix. +** Merge the doclist aDoclist/nDoclist into the TermSelect object passed +** as the first argument. The merge is an "OR" merge (see function +** fts3DoclistOrMerge() for details). +** +** This function is called with the doclist for each term that matches +** a queried prefix. It merges all these doclists into one, the doclist +** for the specified prefix. Since there can be a very large number of +** doclists to merge, the merging is done pair-wise using the TermSelect +** object. +** +** This function returns SQLITE_OK if the merge is successful, or an +** SQLite error code (SQLITE_NOMEM) if an error occurs. */ -static int fts3TermSelectCb( - Fts3Table *p, /* Virtual table object */ - void *pContext, /* Pointer to TermSelect structure */ - char *zTerm, - int nTerm, - char *aDoclist, - int nDoclist +static int fts3TermSelectMerge( + Fts3Table *p, /* FTS table handle */ + TermSelect *pTS, /* TermSelect object to merge into */ + char *aDoclist, /* Pointer to doclist */ + int nDoclist /* Size of aDoclist in bytes */ ){ - TermSelect *pTS = (TermSelect *)pContext; - int nNew = pTS->nOutput + nDoclist; - char *aNew = sqlite3_malloc(nNew); + if( pTS->aaOutput[0]==0 ){ + /* If this is the first term selected, copy the doclist to the output + ** buffer using memcpy(). */ + pTS->aaOutput[0] = sqlite3_malloc(nDoclist); + pTS->anOutput[0] = nDoclist; + if( pTS->aaOutput[0] ){ + memcpy(pTS->aaOutput[0], aDoclist, nDoclist); + }else{ + return SQLITE_NOMEM; + } + }else{ + char *aMerge = aDoclist; + int nMerge = nDoclist; + int iOut; + + for(iOut=0; iOut<SizeofArray(pTS->aaOutput); iOut++){ + if( pTS->aaOutput[iOut]==0 ){ + assert( iOut>0 ); + pTS->aaOutput[iOut] = aMerge; + pTS->anOutput[iOut] = nMerge; + break; + }else{ + char *aNew; + int nNew; - UNUSED_PARAMETER(p); - UNUSED_PARAMETER(zTerm); - UNUSED_PARAMETER(nTerm); + int rc = fts3DoclistOrMerge(p->bDescIdx, aMerge, nMerge, + pTS->aaOutput[iOut], pTS->anOutput[iOut], &aNew, &nNew + ); + if( rc!=SQLITE_OK ){ + if( aMerge!=aDoclist ) sqlite3_free(aMerge); + return rc; + } - if( !aNew ){ - return SQLITE_NOMEM; + if( aMerge!=aDoclist ) sqlite3_free(aMerge); + sqlite3_free(pTS->aaOutput[iOut]); + pTS->aaOutput[iOut] = 0; + + aMerge = aNew; + nMerge = nNew; + if( (iOut+1)==SizeofArray(pTS->aaOutput) ){ + pTS->aaOutput[iOut] = aMerge; + pTS->anOutput[iOut] = nMerge; + } + } + } } + return SQLITE_OK; +} - if( pTS->nOutput==0 ){ - /* If this is the first term selected, copy the doclist to the output - ** buffer using memcpy(). TODO: Add a way to transfer control of the - ** aDoclist buffer from the caller so as to avoid the memcpy(). - */ - memcpy(aNew, aDoclist, nDoclist); - }else{ - /* The output buffer is not empty. Merge doclist aDoclist with the - ** existing output. This can only happen with prefix-searches (as - ** searches for exact terms return exactly one doclist). - */ - int mergetype = (pTS->isReqPos ? MERGE_POS_OR : MERGE_OR); - fts3DoclistMerge(mergetype, 0, 0, - aNew, &nNew, pTS->aOutput, pTS->nOutput, aDoclist, nDoclist - ); +/* +** Append SegReader object pNew to the end of the pCsr->apSegment[] array. +*/ +static int fts3SegReaderCursorAppend( + Fts3MultiSegReader *pCsr, + Fts3SegReader *pNew +){ + if( (pCsr->nSegment%16)==0 ){ + Fts3SegReader **apNew; + int nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*); + apNew = (Fts3SegReader **)sqlite3_realloc(pCsr->apSegment, nByte); + if( !apNew ){ + sqlite3Fts3SegReaderFree(pNew); + return SQLITE_NOMEM; + } + pCsr->apSegment = apNew; } - - sqlite3_free(pTS->aOutput); - pTS->aOutput = aNew; - pTS->nOutput = nNew; - + pCsr->apSegment[pCsr->nSegment++] = pNew; return SQLITE_OK; } /* -** This function retreives the doclist for the specified term (or term -** prefix) from the database. +** Add seg-reader objects to the Fts3MultiSegReader object passed as the +** 8th argument. ** -** The returned doclist may be in one of two formats, depending on the -** value of parameter isReqPos. If isReqPos is zero, then the doclist is -** a sorted list of delta-compressed docids. If isReqPos is non-zero, -** then the returned list is in the same format as is stored in the -** database without the found length specifier at the start of on-disk -** doclists. +** This function returns SQLITE_OK if successful, or an SQLite error code +** otherwise. */ -static int fts3TermSelect( - Fts3Table *p, /* Virtual table handle */ - int iColumn, /* Column to query (or -ve for all columns) */ +static int fts3SegReaderCursor( + Fts3Table *p, /* FTS3 table handle */ + int iIndex, /* Index to search (from 0 to p->nIndex-1) */ + int iLevel, /* Level of segments to scan */ const char *zTerm, /* Term to query for */ int nTerm, /* Size of zTerm in bytes */ int isPrefix, /* True for a prefix search */ - int isReqPos, /* True to include position lists in output */ - int *pnOut, /* OUT: Size of buffer at *ppOut */ - char **ppOut /* OUT: Malloced result buffer */ + int isScan, /* True to scan from zTerm to EOF */ + Fts3MultiSegReader *pCsr /* Cursor object to populate */ ){ - int i; - TermSelect tsc; - Fts3SegFilter filter; /* Segment term filter configuration */ - Fts3SegReader **apSegment; /* Array of segments to read data from */ - int nSegment = 0; /* Size of apSegment array */ - int nAlloc = 16; /* Allocated size of segment array */ - int rc; /* Return code */ - sqlite3_stmt *pStmt = 0; /* SQL statement to scan %_segdir table */ - int iAge = 0; /* Used to assign ages to segments */ + int rc = SQLITE_OK; /* Error code */ + sqlite3_stmt *pStmt = 0; /* Statement to iterate through segments */ + int rc2; /* Result of sqlite3_reset() */ - apSegment = (Fts3SegReader **)sqlite3_malloc(sizeof(Fts3SegReader*)*nAlloc); - if( !apSegment ) return SQLITE_NOMEM; - rc = sqlite3Fts3SegReaderPending(p, zTerm, nTerm, isPrefix, &apSegment[0]); - if( rc!=SQLITE_OK ) goto finished; - if( apSegment[0] ){ - nSegment = 1; + /* If iLevel is less than 0 and this is not a scan, include a seg-reader + ** for the pending-terms. If this is a scan, then this call must be being + ** made by an fts4aux module, not an FTS table. In this case calling + ** Fts3SegReaderPending might segfault, as the data structures used by + ** fts4aux are not completely populated. So it's easiest to filter these + ** calls out here. */ + if( iLevel<0 && p->aIndex ){ + Fts3SegReader *pSeg = 0; + rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix, &pSeg); + if( rc==SQLITE_OK && pSeg ){ + rc = fts3SegReaderCursorAppend(pCsr, pSeg); + } } - /* Loop through the entire %_segdir table. For each segment, create a - ** Fts3SegReader to iterate through the subset of the segment leaves - ** that may contain a term that matches zTerm/nTerm. For non-prefix - ** searches, this is always a single leaf. For prefix searches, this - ** may be a contiguous block of leaves. - ** - ** The code in this loop does not actually load any leaves into memory - ** (unless the root node happens to be a leaf). It simply examines the - ** b-tree structure to determine which leaves need to be inspected. - */ - rc = sqlite3Fts3AllSegdirs(p, &pStmt); - while( rc==SQLITE_OK && SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ - Fts3SegReader *pNew = 0; - int nRoot = sqlite3_column_bytes(pStmt, 4); - char const *zRoot = sqlite3_column_blob(pStmt, 4); - if( sqlite3_column_int64(pStmt, 1)==0 ){ - /* The entire segment is stored on the root node (which must be a - ** leaf). Do not bother inspecting any data in this case, just - ** create a Fts3SegReader to scan the single leaf. - */ - rc = sqlite3Fts3SegReaderNew(p, iAge, 0, 0, 0, zRoot, nRoot, &pNew); - }else{ - int rc2; /* Return value of sqlite3Fts3ReadBlock() */ - sqlite3_int64 i1; /* Blockid of leaf that may contain zTerm */ - rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &i1); - if( rc==SQLITE_OK ){ - sqlite3_int64 i2 = sqlite3_column_int64(pStmt, 2); - rc = sqlite3Fts3SegReaderNew(p, iAge, i1, i2, 0, 0, 0, &pNew); - } - - /* The following call to ReadBlock() serves to reset the SQL statement - ** used to retrieve blocks of data from the %_segments table. If it is - ** not reset here, then it may remain classified as an active statement - ** by SQLite, which may lead to "DROP TABLE" or "DETACH" commands - ** failing. - */ - rc2 = sqlite3Fts3ReadBlock(p, 0, 0, 0); - if( rc==SQLITE_OK ){ - rc = rc2; - } + if( iLevel!=FTS3_SEGCURSOR_PENDING ){ + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3AllSegdirs(p, iIndex, iLevel, &pStmt); } - iAge++; - /* If a new Fts3SegReader was allocated, add it to the apSegment array. */ - assert( pNew!=0 || rc!=SQLITE_OK ); - if( pNew ){ - if( nSegment==nAlloc ){ - Fts3SegReader **pArray; - nAlloc += 16; - pArray = (Fts3SegReader **)sqlite3_realloc( - apSegment, nAlloc*sizeof(Fts3SegReader *) - ); - if( !pArray ){ - sqlite3Fts3SegReaderFree(p, pNew); - rc = SQLITE_NOMEM; - goto finished; - } - apSegment = pArray; + while( rc==SQLITE_OK && SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ + Fts3SegReader *pSeg = 0; + + /* Read the values returned by the SELECT into local variables. */ + sqlite3_int64 iStartBlock = sqlite3_column_int64(pStmt, 1); + sqlite3_int64 iLeavesEndBlock = sqlite3_column_int64(pStmt, 2); + sqlite3_int64 iEndBlock = sqlite3_column_int64(pStmt, 3); + int nRoot = sqlite3_column_bytes(pStmt, 4); + char const *zRoot = sqlite3_column_blob(pStmt, 4); + + /* If zTerm is not NULL, and this segment is not stored entirely on its + ** root node, the range of leaves scanned can be reduced. Do this. */ + if( iStartBlock && zTerm ){ + sqlite3_int64 *pi = (isPrefix ? &iLeavesEndBlock : 0); + rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &iStartBlock, pi); + if( rc!=SQLITE_OK ) goto finished; + if( isPrefix==0 && isScan==0 ) iLeavesEndBlock = iStartBlock; } - apSegment[nSegment++] = pNew; + + rc = sqlite3Fts3SegReaderNew(pCsr->nSegment+1, + iStartBlock, iLeavesEndBlock, iEndBlock, zRoot, nRoot, &pSeg + ); + if( rc!=SQLITE_OK ) goto finished; + rc = fts3SegReaderCursorAppend(pCsr, pSeg); } } - if( rc!=SQLITE_DONE ){ - assert( rc!=SQLITE_OK ); - goto finished; - } - memset(&tsc, 0, sizeof(TermSelect)); - tsc.isReqPos = isReqPos; + finished: + rc2 = sqlite3_reset(pStmt); + if( rc==SQLITE_DONE ) rc = rc2; - filter.flags = FTS3_SEGMENT_IGNORE_EMPTY - | (isPrefix ? FTS3_SEGMENT_PREFIX : 0) - | (isReqPos ? FTS3_SEGMENT_REQUIRE_POS : 0) - | (iColumn<p->nColumn ? FTS3_SEGMENT_COLUMN_FILTER : 0); - filter.iCol = iColumn; - filter.zTerm = zTerm; - filter.nTerm = nTerm; + return rc; +} - rc = sqlite3Fts3SegReaderIterate(p, apSegment, nSegment, &filter, - fts3TermSelectCb, (void *)&tsc +/* +** Set up a cursor object for iterating through a full-text index or a +** single level therein. +*/ +SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor( + Fts3Table *p, /* FTS3 table handle */ + int iIndex, /* Index to search (from 0 to p->nIndex-1) */ + int iLevel, /* Level of segments to scan */ + const char *zTerm, /* Term to query for */ + int nTerm, /* Size of zTerm in bytes */ + int isPrefix, /* True for a prefix search */ + int isScan, /* True to scan from zTerm to EOF */ + Fts3MultiSegReader *pCsr /* Cursor object to populate */ +){ + assert( iIndex>=0 && iIndex<p->nIndex ); + assert( iLevel==FTS3_SEGCURSOR_ALL + || iLevel==FTS3_SEGCURSOR_PENDING + || iLevel>=0 ); + assert( iLevel<FTS3_SEGDIR_MAXLEVEL ); + assert( FTS3_SEGCURSOR_ALL<0 && FTS3_SEGCURSOR_PENDING<0 ); + assert( isPrefix==0 || isScan==0 ); - if( rc==SQLITE_OK ){ - *ppOut = tsc.aOutput; - *pnOut = tsc.nOutput; - }else{ - sqlite3_free(tsc.aOutput); - } + /* "isScan" is only set to true by the ft4aux module, an ordinary + ** full-text tables. */ + assert( isScan==0 || p->aIndex==0 ); -finished: - sqlite3_reset(pStmt); - for(i=0; i<nSegment; i++){ - sqlite3Fts3SegReaderFree(p, apSegment[i]); - } - sqlite3_free(apSegment); - return rc; + memset(pCsr, 0, sizeof(Fts3MultiSegReader)); + + return fts3SegReaderCursor( + p, iIndex, iLevel, zTerm, nTerm, isPrefix, isScan, pCsr + ); } +/* +** In addition to its current configuration, have the Fts3MultiSegReader +** passed as the 4th argument also scan the doclist for term zTerm/nTerm. +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +*/ +static int fts3SegReaderCursorAddZero( + Fts3Table *p, /* FTS virtual table handle */ + const char *zTerm, /* Term to scan doclist of */ + int nTerm, /* Number of bytes in zTerm */ + Fts3MultiSegReader *pCsr /* Fts3MultiSegReader to modify */ +){ + return fts3SegReaderCursor(p, 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0,pCsr); +} /* -** Return a DocList corresponding to the phrase *pPhrase. +** Open an Fts3MultiSegReader to scan the doclist for term zTerm/nTerm. Or, +** if isPrefix is true, to scan the doclist for all terms for which +** zTerm/nTerm is a prefix. If successful, return SQLITE_OK and write +** a pointer to the new Fts3MultiSegReader to *ppSegcsr. Otherwise, return +** an SQLite error code. +** +** It is the responsibility of the caller to free this object by eventually +** passing it to fts3SegReaderCursorFree() +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +** Output parameter *ppSegcsr is set to 0 if an error occurs. */ -static int fts3PhraseSelect( - Fts3Table *p, /* Virtual table handle */ - Fts3Phrase *pPhrase, /* Phrase to return a doclist for */ - int isReqPos, /* True if output should contain positions */ - char **paOut, /* OUT: Pointer to malloc'd result buffer */ - int *pnOut /* OUT: Size of buffer at *paOut */ +static int fts3TermSegReaderCursor( + Fts3Cursor *pCsr, /* Virtual table cursor handle */ + const char *zTerm, /* Term to query for */ + int nTerm, /* Size of zTerm in bytes */ + int isPrefix, /* True for a prefix search */ + Fts3MultiSegReader **ppSegcsr /* OUT: Allocated seg-reader cursor */ ){ - char *pOut = 0; - int nOut = 0; - int rc = SQLITE_OK; - int ii; - int iCol = pPhrase->iColumn; - int isTermPos = (pPhrase->nToken>1 || isReqPos); - - for(ii=0; ii<pPhrase->nToken; ii++){ - struct PhraseToken *pTok = &pPhrase->aToken[ii]; - char *z = pTok->z; /* Next token of the phrase */ - int n = pTok->n; /* Size of z in bytes */ - int isPrefix = pTok->isPrefix;/* True if token is a prefix */ - char *pList; /* Pointer to token doclist */ - int nList; /* Size of buffer at pList */ - - rc = fts3TermSelect(p, iCol, z, n, isPrefix, isTermPos, &nList, &pList); - if( rc!=SQLITE_OK ) break; - - if( ii==0 ){ - pOut = pList; - nOut = nList; - }else{ - /* Merge the new term list and the current output. If this is the - ** last term in the phrase, and positions are not required in the - ** output of this function, the positions can be dropped as part - ** of this merge. Either way, the result of this merge will be - ** smaller than nList bytes. The code in fts3DoclistMerge() is written - ** so that it is safe to use pList as the output as well as an input - ** in this case. - */ - int mergetype = MERGE_POS_PHRASE; - if( ii==pPhrase->nToken-1 && !isReqPos ){ - mergetype = MERGE_PHRASE; + Fts3MultiSegReader *pSegcsr; /* Object to allocate and return */ + int rc = SQLITE_NOMEM; /* Return code */ + + pSegcsr = sqlite3_malloc(sizeof(Fts3MultiSegReader)); + if( pSegcsr ){ + int i; + int bFound = 0; /* True once an index has been found */ + Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; + + if( isPrefix ){ + for(i=1; bFound==0 && i<p->nIndex; i++){ + if( p->aIndex[i].nPrefix==nTerm ){ + bFound = 1; + rc = sqlite3Fts3SegReaderCursor( + p, i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0, pSegcsr); + pSegcsr->bLookup = 1; + } + } + + for(i=1; bFound==0 && i<p->nIndex; i++){ + if( p->aIndex[i].nPrefix==nTerm+1 ){ + bFound = 1; + rc = sqlite3Fts3SegReaderCursor( + p, i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 1, 0, pSegcsr + ); + if( rc==SQLITE_OK ){ + rc = fts3SegReaderCursorAddZero(p, zTerm, nTerm, pSegcsr); + } + } } - fts3DoclistMerge(mergetype, 0, 0, pList, &nOut, pOut, nOut, pList, nList); - sqlite3_free(pOut); - pOut = pList; } - assert( nOut==0 || pOut!=0 ); - } - if( rc==SQLITE_OK ){ - *paOut = pOut; - *pnOut = nOut; - }else{ - sqlite3_free(pOut); + if( bFound==0 ){ + rc = sqlite3Fts3SegReaderCursor( + p, 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, isPrefix, 0, pSegcsr + ); + pSegcsr->bLookup = !isPrefix; + } } + + *ppSegcsr = pSegcsr; return rc; } -static int fts3NearMerge( - int mergetype, /* MERGE_POS_NEAR or MERGE_NEAR */ - int nNear, /* Parameter to NEAR operator */ - int nTokenLeft, /* Number of tokens in LHS phrase arg */ - char *aLeft, /* Doclist for LHS (incl. positions) */ - int nLeft, /* Size of LHS doclist in bytes */ - int nTokenRight, /* As nTokenLeft */ - char *aRight, /* As aLeft */ - int nRight, /* As nRight */ - char **paOut, /* OUT: Results of merge (malloced) */ - int *pnOut /* OUT: Sized of output buffer */ +/* +** Free an Fts3MultiSegReader allocated by fts3TermSegReaderCursor(). +*/ +static void fts3SegReaderCursorFree(Fts3MultiSegReader *pSegcsr){ + sqlite3Fts3SegReaderFinish(pSegcsr); + sqlite3_free(pSegcsr); +} + +/* +** This function retreives the doclist for the specified term (or term +** prefix) from the database. +*/ +static int fts3TermSelect( + Fts3Table *p, /* Virtual table handle */ + Fts3PhraseToken *pTok, /* Token to query for */ + int iColumn, /* Column to query (or -ve for all columns) */ + int *pnOut, /* OUT: Size of buffer at *ppOut */ + char **ppOut /* OUT: Malloced result buffer */ ){ - char *aOut; - int rc; + int rc; /* Return code */ + Fts3MultiSegReader *pSegcsr; /* Seg-reader cursor for this term */ + TermSelect tsc; /* Object for pair-wise doclist merging */ + Fts3SegFilter filter; /* Segment term filter configuration */ - assert( mergetype==MERGE_POS_NEAR || MERGE_NEAR ); + pSegcsr = pTok->pSegcsr; + memset(&tsc, 0, sizeof(TermSelect)); - aOut = sqlite3_malloc(nLeft+nRight+1); - if( aOut==0 ){ - rc = SQLITE_NOMEM; + filter.flags = FTS3_SEGMENT_IGNORE_EMPTY | FTS3_SEGMENT_REQUIRE_POS + | (pTok->isPrefix ? FTS3_SEGMENT_PREFIX : 0) + | (iColumn<p->nColumn ? FTS3_SEGMENT_COLUMN_FILTER : 0); + filter.iCol = iColumn; + filter.zTerm = pTok->z; + filter.nTerm = pTok->n; + + rc = sqlite3Fts3SegReaderStart(p, pSegcsr, &filter); + while( SQLITE_OK==rc + && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pSegcsr)) + ){ + rc = fts3TermSelectMerge(p, &tsc, pSegcsr->aDoclist, pSegcsr->nDoclist); + } + + if( rc==SQLITE_OK ){ + rc = fts3TermSelectFinishMerge(p, &tsc); + } + if( rc==SQLITE_OK ){ + *ppOut = tsc.aaOutput[0]; + *pnOut = tsc.anOutput[0]; }else{ - rc = fts3DoclistMerge(mergetype, nNear+nTokenRight, nNear+nTokenLeft, - aOut, pnOut, aLeft, nLeft, aRight, nRight - ); - if( rc!=SQLITE_OK ){ - sqlite3_free(aOut); - aOut = 0; + int i; + for(i=0; i<SizeofArray(tsc.aaOutput); i++){ + sqlite3_free(tsc.aaOutput[i]); } } - *paOut = aOut; + fts3SegReaderCursorFree(pSegcsr); + pTok->pSegcsr = 0; return rc; } -SQLITE_PRIVATE int sqlite3Fts3ExprNearTrim(Fts3Expr *pLeft, Fts3Expr *pRight, int nNear){ - int rc; - if( pLeft->aDoclist==0 || pRight->aDoclist==0 ){ - sqlite3_free(pLeft->aDoclist); - sqlite3_free(pRight->aDoclist); - pRight->aDoclist = 0; - pLeft->aDoclist = 0; - rc = SQLITE_OK; - }else{ - char *aOut; - int nOut; - - rc = fts3NearMerge(MERGE_POS_NEAR, nNear, - pLeft->pPhrase->nToken, pLeft->aDoclist, pLeft->nDoclist, - pRight->pPhrase->nToken, pRight->aDoclist, pRight->nDoclist, - &aOut, &nOut - ); - if( rc!=SQLITE_OK ) return rc; - sqlite3_free(pRight->aDoclist); - pRight->aDoclist = aOut; - pRight->nDoclist = nOut; - - rc = fts3NearMerge(MERGE_POS_NEAR, nNear, - pRight->pPhrase->nToken, pRight->aDoclist, pRight->nDoclist, - pLeft->pPhrase->nToken, pLeft->aDoclist, pLeft->nDoclist, - &aOut, &nOut - ); - sqlite3_free(pLeft->aDoclist); - pLeft->aDoclist = aOut; - pLeft->nDoclist = nOut; +/* +** This function counts the total number of docids in the doclist stored +** in buffer aList[], size nList bytes. +** +** If the isPoslist argument is true, then it is assumed that the doclist +** contains a position-list following each docid. Otherwise, it is assumed +** that the doclist is simply a list of docids stored as delta encoded +** varints. +*/ +static int fts3DoclistCountDocids(char *aList, int nList){ + int nDoc = 0; /* Return value */ + if( aList ){ + char *aEnd = &aList[nList]; /* Pointer to one byte after EOF */ + char *p = aList; /* Cursor */ + while( p<aEnd ){ + nDoc++; + while( (*p++)&0x80 ); /* Skip docid varint */ + fts3PoslistCopy(0, &p); /* Skip over position list */ + } } - return rc; + + return nDoc; } /* -** Evaluate the full-text expression pExpr against fts3 table pTab. Store -** the resulting doclist in *paOut and *pnOut. +** Advance the cursor to the next row in the %_content table that +** matches the search criteria. For a MATCH search, this will be +** the next row that matches. For a full-table scan, this will be +** simply the next row in the %_content table. For a docid lookup, +** this routine simply sets the EOF flag. +** +** Return SQLITE_OK if nothing goes wrong. SQLITE_OK is returned +** even if we reach end-of-file. The fts3EofMethod() will be called +** subsequently to determine whether or not an EOF was hit. */ -static int evalFts3Expr( - Fts3Table *p, /* Virtual table handle */ - Fts3Expr *pExpr, /* Parsed fts3 expression */ - char **paOut, /* OUT: Pointer to malloc'd result buffer */ - int *pnOut, /* OUT: Size of buffer at *paOut */ - int isReqPos /* Require positions in output buffer */ -){ - int rc = SQLITE_OK; /* Return code */ - - /* Zero the output parameters. */ - *paOut = 0; - *pnOut = 0; - - if( pExpr ){ - assert( pExpr->eType==FTSQUERY_PHRASE - || pExpr->eType==FTSQUERY_NEAR - || isReqPos==0 - ); - if( pExpr->eType==FTSQUERY_PHRASE ){ - rc = fts3PhraseSelect(p, pExpr->pPhrase, - isReqPos || (pExpr->pParent && pExpr->pParent->eType==FTSQUERY_NEAR), - paOut, pnOut - ); +static int fts3NextMethod(sqlite3_vtab_cursor *pCursor){ + int rc; + Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; + if( pCsr->eSearch==FTS3_DOCID_SEARCH || pCsr->eSearch==FTS3_FULLSCAN_SEARCH ){ + if( SQLITE_ROW!=sqlite3_step(pCsr->pStmt) ){ + pCsr->isEof = 1; + rc = sqlite3_reset(pCsr->pStmt); }else{ - char *aLeft; - char *aRight; - int nLeft; - int nRight; - - if( 0==(rc = evalFts3Expr(p, pExpr->pRight, &aRight, &nRight, isReqPos)) - && 0==(rc = evalFts3Expr(p, pExpr->pLeft, &aLeft, &nLeft, isReqPos)) - ){ - assert( pExpr->eType==FTSQUERY_NEAR || pExpr->eType==FTSQUERY_OR - || pExpr->eType==FTSQUERY_AND || pExpr->eType==FTSQUERY_NOT - ); - switch( pExpr->eType ){ - case FTSQUERY_NEAR: { - Fts3Expr *pLeft; - Fts3Expr *pRight; - int mergetype = isReqPos ? MERGE_POS_NEAR : MERGE_NEAR; - - if( pExpr->pParent && pExpr->pParent->eType==FTSQUERY_NEAR ){ - mergetype = MERGE_POS_NEAR; - } - pLeft = pExpr->pLeft; - while( pLeft->eType==FTSQUERY_NEAR ){ - pLeft=pLeft->pRight; - } - pRight = pExpr->pRight; - assert( pRight->eType==FTSQUERY_PHRASE ); - assert( pLeft->eType==FTSQUERY_PHRASE ); - - rc = fts3NearMerge(mergetype, pExpr->nNear, - pLeft->pPhrase->nToken, aLeft, nLeft, - pRight->pPhrase->nToken, aRight, nRight, - paOut, pnOut - ); - sqlite3_free(aLeft); - break; - } - - case FTSQUERY_OR: { - /* Allocate a buffer for the output. The maximum size is the - ** sum of the sizes of the two input buffers. The +1 term is - ** so that a buffer of zero bytes is never allocated - this can - ** cause fts3DoclistMerge() to incorrectly return SQLITE_NOMEM. - */ - char *aBuffer = sqlite3_malloc(nRight+nLeft+1); - rc = fts3DoclistMerge(MERGE_OR, 0, 0, aBuffer, pnOut, - aLeft, nLeft, aRight, nRight - ); - *paOut = aBuffer; - sqlite3_free(aLeft); - break; - } - - default: { - assert( FTSQUERY_NOT==MERGE_NOT && FTSQUERY_AND==MERGE_AND ); - fts3DoclistMerge(pExpr->eType, 0, 0, aLeft, pnOut, - aLeft, nLeft, aRight, nRight - ); - *paOut = aLeft; - break; - } - } - } - sqlite3_free(aRight); + pCsr->iPrevId = sqlite3_column_int64(pCsr->pStmt, 0); + rc = SQLITE_OK; } + }else{ + rc = fts3EvalNext((Fts3Cursor *)pCursor); } - + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); return rc; } @@ -101714,11 +116861,6 @@ static int evalFts3Expr( ** number idxNum-FTS3_FULLTEXT_SEARCH, 0 indexed. argv[0] is the right-hand ** side of the MATCH operator. */ -/* TODO(shess) Upgrade the cursor initialization and destruction to -** account for fts3FilterMethod() being called multiple times on the -** same cursor. The current solution is very fragile. Apply fix to -** fts3 as appropriate. -*/ static int fts3FilterMethod( sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ int idxNum, /* Strategy index */ @@ -101726,11 +116868,7 @@ static int fts3FilterMethod( int nVal, /* Number of elements in apVal */ sqlite3_value **apVal /* Arguments for the indexing scheme */ ){ - const char *azSql[] = { - "SELECT * FROM %Q.'%q_content' WHERE docid = ?", /* non-full-table-scan */ - "SELECT * FROM %Q.'%q_content'", /* full-table-scan */ - }; - int rc; /* Return code */ + int rc; char *zSql; /* SQL statement used to access %_content */ Fts3Table *p = (Fts3Table *)pCursor->pVtab; Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; @@ -101741,6 +116879,7 @@ static int fts3FilterMethod( assert( idxNum>=0 && idxNum<=(FTS3_FULLTEXT_SEARCH+p->nColumn) ); assert( nVal==0 || nVal==1 ); assert( (nVal==0)==(idxNum==FTS3_FULLSCAN_SEARCH) ); + assert( p->pSegments==0 ); /* In case the cursor has been used before, clear it now. */ sqlite3_finalize(pCsr->pStmt); @@ -101748,24 +116887,14 @@ static int fts3FilterMethod( sqlite3Fts3ExprFree(pCsr->pExpr); memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor)); - /* Compile a SELECT statement for this cursor. For a full-table-scan, the - ** statement loops through all rows of the %_content table. For a - ** full-text query or docid lookup, the statement retrieves a single - ** row by docid. - */ - zSql = sqlite3_mprintf(azSql[idxNum==FTS3_FULLSCAN_SEARCH], p->zDb, p->zName); - if( !zSql ){ - rc = SQLITE_NOMEM; + if( idxStr ){ + pCsr->bDesc = (idxStr[0]=='D'); }else{ - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0); - sqlite3_free(zSql); + pCsr->bDesc = p->bDescIdx; } - if( rc!=SQLITE_OK ) return rc; pCsr->eSearch = (i16)idxNum; - if( idxNum==FTS3_DOCID_SEARCH ){ - rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]); - }else if( idxNum!=FTS3_FULLSCAN_SEARCH ){ + if( idxNum!=FTS3_DOCID_SEARCH && idxNum!=FTS3_FULLSCAN_SEARCH ){ int iCol = idxNum-FTS3_FULLTEXT_SEARCH; const char *zQuery = (const char *)sqlite3_value_text(apVal[0]); @@ -101773,35 +116902,63 @@ static int fts3FilterMethod( return SQLITE_NOMEM; } - rc = sqlite3Fts3ExprParse(p->pTokenizer, p->azColumn, p->nColumn, + rc = sqlite3Fts3ExprParse(p->pTokenizer, p->azColumn, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr ); if( rc!=SQLITE_OK ){ if( rc==SQLITE_ERROR ){ - p->base.zErrMsg = sqlite3_mprintf("malformed MATCH expression: [%s]", - zQuery); + static const char *zErr = "malformed MATCH expression: [%s]"; + p->base.zErrMsg = sqlite3_mprintf(zErr, zQuery); } return rc; } - rc = evalFts3Expr(p, pCsr->pExpr, &pCsr->aDoclist, &pCsr->nDoclist, 0); + rc = sqlite3Fts3ReadLock(p); + if( rc!=SQLITE_OK ) return rc; + + rc = fts3EvalStart(pCsr); + + sqlite3Fts3SegmentsClose(p); + if( rc!=SQLITE_OK ) return rc; pCsr->pNextId = pCsr->aDoclist; pCsr->iPrevId = 0; } + /* Compile a SELECT statement for this cursor. For a full-table-scan, the + ** statement loops through all rows of the %_content table. For a + ** full-text query or docid lookup, the statement retrieves a single + ** row by docid. + */ + if( idxNum==FTS3_FULLSCAN_SEARCH ){ + const char *zSort = (pCsr->bDesc ? "DESC" : "ASC"); + const char *zTmpl = "SELECT %s FROM %Q.'%q_content' AS x ORDER BY docid %s"; + zSql = sqlite3_mprintf(zTmpl, p->zReadExprlist, p->zDb, p->zName, zSort); + }else{ + const char *zTmpl = "SELECT %s FROM %Q.'%q_content' AS x WHERE docid = ?"; + zSql = sqlite3_mprintf(zTmpl, p->zReadExprlist, p->zDb, p->zName); + } + if( !zSql ) return SQLITE_NOMEM; + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0); + sqlite3_free(zSql); if( rc!=SQLITE_OK ) return rc; + + if( idxNum==FTS3_DOCID_SEARCH ){ + rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]); + if( rc!=SQLITE_OK ) return rc; + } + return fts3NextMethod(pCursor); } -/* -** This is the xEof method of the virtual table. SQLite calls this +/* +** This is the xEof method of the virtual table. SQLite calls this ** routine to find out if it has reached the end of a result set. */ static int fts3EofMethod(sqlite3_vtab_cursor *pCursor){ return ((Fts3Cursor *)pCursor)->isEof; } -/* +/* ** This is the xRowid method. The SQLite core calls this routine to ** retrieve the rowid for the current row of the result set. fts3 ** exposes %_content.docid as the rowid for the virtual table. The @@ -101809,15 +116966,11 @@ static int fts3EofMethod(sqlite3_vtab_cursor *pCursor){ */ static int fts3RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ Fts3Cursor *pCsr = (Fts3Cursor *) pCursor; - if( pCsr->aDoclist ){ - *pRowid = pCsr->iPrevId; - }else{ - *pRowid = sqlite3_column_int64(pCsr->pStmt, 0); - } + *pRowid = pCsr->iPrevId; return SQLITE_OK; } -/* +/* ** This is the xColumn method, called by SQLite to request a value from ** the row that the supplied cursor currently points to. */ @@ -101826,7 +116979,7 @@ static int fts3ColumnMethod( sqlite3_context *pContext, /* Context for sqlite3_result_xxx() calls */ int iCol /* Index of column to read value from */ ){ - int rc; /* Return Code */ + int rc = SQLITE_OK; /* Return Code */ Fts3Cursor *pCsr = (Fts3Cursor *) pCursor; Fts3Table *p = (Fts3Table *)pCursor->pVtab; @@ -101834,29 +116987,28 @@ static int fts3ColumnMethod( assert( iCol>=0 && iCol<=p->nColumn+1 ); if( iCol==p->nColumn+1 ){ - /* This call is a request for the "docid" column. Since "docid" is an + /* This call is a request for the "docid" column. Since "docid" is an ** alias for "rowid", use the xRowid() method to obtain the value. */ - sqlite3_int64 iRowid; - rc = fts3RowidMethod(pCursor, &iRowid); - sqlite3_result_int64(pContext, iRowid); + sqlite3_result_int64(pContext, pCsr->iPrevId); }else if( iCol==p->nColumn ){ /* The extra column whose name is the same as the table. ** Return a blob which is a pointer to the cursor. */ sqlite3_result_blob(pContext, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT); - rc = SQLITE_OK; }else{ rc = fts3CursorSeek(0, pCsr); if( rc==SQLITE_OK ){ sqlite3_result_value(pContext, sqlite3_column_value(pCsr->pStmt, iCol+1)); } } + + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); return rc; } -/* -** This function is the implementation of the xUpdate callback used by +/* +** This function is the implementation of the xUpdate callback used by ** FTS3 virtual tables. It is invoked by SQLite each time a row is to be ** inserted, updated or deleted. */ @@ -101874,15 +117026,22 @@ static int fts3UpdateMethod( ** hash-table to the database. */ static int fts3SyncMethod(sqlite3_vtab *pVtab){ - return sqlite3Fts3PendingTermsFlush((Fts3Table *)pVtab); + int rc = sqlite3Fts3PendingTermsFlush((Fts3Table *)pVtab); + sqlite3Fts3SegmentsClose((Fts3Table *)pVtab); + return rc; } /* ** Implementation of xBegin() method. This is a no-op. */ static int fts3BeginMethod(sqlite3_vtab *pVtab){ + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); UNUSED_PARAMETER(pVtab); - assert( ((Fts3Table *)pVtab)->nPendingData==0 ); + assert( p->pSegments==0 ); + assert( p->nPendingData==0 ); + assert( p->inTransaction!=1 ); + TESTONLY( p->inTransaction = 1 ); + TESTONLY( p->mxSavepoint = -1; ); return SQLITE_OK; } @@ -101892,8 +117051,13 @@ static int fts3BeginMethod(sqlite3_vtab *pVtab){ ** by fts3SyncMethod(). */ static int fts3CommitMethod(sqlite3_vtab *pVtab){ + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); UNUSED_PARAMETER(pVtab); - assert( ((Fts3Table *)pVtab)->nPendingData==0 ); + assert( p->nPendingData==0 ); + assert( p->inTransaction!=0 ); + assert( p->pSegments==0 ); + TESTONLY( p->inTransaction = 0 ); + TESTONLY( p->mxSavepoint = -1; ); return SQLITE_OK; } @@ -101902,67 +117066,31 @@ static int fts3CommitMethod(sqlite3_vtab *pVtab){ ** hash-table. Any changes made to the database are reverted by SQLite. */ static int fts3RollbackMethod(sqlite3_vtab *pVtab){ - sqlite3Fts3PendingTermsClear((Fts3Table *)pVtab); + Fts3Table *p = (Fts3Table*)pVtab; + sqlite3Fts3PendingTermsClear(p); + assert( p->inTransaction!=0 ); + TESTONLY( p->inTransaction = 0 ); + TESTONLY( p->mxSavepoint = -1; ); return SQLITE_OK; } /* -** Load the doclist associated with expression pExpr to pExpr->aDoclist. -** The loaded doclist contains positions as well as the document ids. -** This is used by the matchinfo(), snippet() and offsets() auxillary -** functions. -*/ -SQLITE_PRIVATE int sqlite3Fts3ExprLoadDoclist(Fts3Table *pTab, Fts3Expr *pExpr){ - return evalFts3Expr(pTab, pExpr, &pExpr->aDoclist, &pExpr->nDoclist, 1); -} - -/* -** After ExprLoadDoclist() (see above) has been called, this function is -** used to iterate/search through the position lists that make up the doclist -** stored in pExpr->aDoclist. +** When called, *ppPoslist must point to the byte immediately following the +** end of a position-list. i.e. ( (*ppPoslist)[-1]==POS_END ). This function +** moves *ppPoslist so that it instead points to the first byte of the +** same position list. */ -SQLITE_PRIVATE char *sqlite3Fts3FindPositions( - Fts3Expr *pExpr, /* Access this expressions doclist */ - sqlite3_int64 iDocid, /* Docid associated with requested pos-list */ - int iCol /* Column of requested pos-list */ -){ - assert( pExpr->isLoaded ); - if( pExpr->aDoclist ){ - char *pEnd = &pExpr->aDoclist[pExpr->nDoclist]; - char *pCsr = pExpr->pCurrent; +static void fts3ReversePoslist(char *pStart, char **ppPoslist){ + char *p = &(*ppPoslist)[-2]; + char c; - assert( pCsr ); - while( pCsr<pEnd ){ - if( pExpr->iCurrent<iDocid ){ - fts3PoslistCopy(0, &pCsr); - if( pCsr<pEnd ){ - fts3GetDeltaVarint(&pCsr, &pExpr->iCurrent); - } - pExpr->pCurrent = pCsr; - }else{ - if( pExpr->iCurrent==iDocid ){ - int iThis = 0; - if( iCol<0 ){ - /* If iCol is negative, return a pointer to the start of the - ** position-list (instead of a pointer to the start of a list - ** of offsets associated with a specific column). - */ - return pCsr; - } - while( iThis<iCol ){ - fts3ColumnlistCopy(0, &pCsr); - if( *pCsr==0x00 ) return 0; - pCsr++; - pCsr += sqlite3Fts3GetVarint32(pCsr, &iThis); - } - if( iCol==iThis && (*pCsr&0xFE) ) return pCsr; - } - return 0; - } - } + while( p>pStart && (c=*p--)==0 ); + while( p>pStart && (*p & 0x80) | c ){ + c = *p--; } - - return 0; + if( p>pStart ){ p = &p[2]; } + while( *p++&0x80 ); + *ppPoslist = p; } /* @@ -101970,7 +117098,7 @@ SQLITE_PRIVATE char *sqlite3Fts3FindPositions( ** offsets() and optimize() SQL functions. ** ** If the value passed as the third argument is a blob of size -** sizeof(Fts3Cursor*), then the blob contents are copied to the +** sizeof(Fts3Cursor*), then the blob contents are copied to the ** output variable *ppCsr and SQLITE_OK is returned. Otherwise, an error ** message is written to context pContext and SQLITE_ERROR returned. The ** string passed via zFunc is used as part of the error message. @@ -101979,10 +117107,10 @@ static int fts3FunctionArg( sqlite3_context *pContext, /* SQL function call context */ const char *zFunc, /* Function name */ sqlite3_value *pVal, /* argv[0] passed to function */ - Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ + Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ ){ Fts3Cursor *pRet; - if( sqlite3_value_type(pVal)!=SQLITE_BLOB + if( sqlite3_value_type(pVal)!=SQLITE_BLOB || sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *) ){ char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); @@ -102016,7 +117144,7 @@ static void fts3SnippetFunc( assert( nVal>=1 ); if( nVal>6 ){ - sqlite3_result_error(pContext, + sqlite3_result_error(pContext, "wrong number of arguments to function snippet()", -1); return; } @@ -102056,8 +117184,8 @@ static void fts3OffsetsFunc( } } -/* -** Implementation of the special optimize() function for FTS3. This +/* +** Implementation of the special optimize() function for FTS3. This ** function merges all segments in the database to a single segment. ** Example usage is: ** @@ -102105,15 +117233,13 @@ static void fts3MatchinfoFunc( sqlite3_value **apVal /* Array of arguments */ ){ Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ - - if( nVal!=1 ){ - sqlite3_result_error(pContext, - "wrong number of arguments to function matchinfo()", -1); - return; - } - + assert( nVal==1 || nVal==2 ); if( SQLITE_OK==fts3FunctionArg(pContext, "matchinfo", apVal[0], &pCsr) ){ - sqlite3Fts3Matchinfo(pContext, pCsr); + const char *zArg = 0; + if( nVal>1 ){ + zArg = (const char *)sqlite3_value_text(apVal[1]); + } + sqlite3Fts3Matchinfo(pContext, pCsr, zArg); } } @@ -102162,21 +117288,25 @@ static int fts3RenameMethod( const char *zName /* New name of table */ ){ Fts3Table *p = (Fts3Table *)pVtab; - sqlite3 *db; /* Database connection */ + sqlite3 *db = p->db; /* Database connection */ int rc; /* Return Code */ - db = p->db; - rc = SQLITE_OK; + rc = sqlite3Fts3PendingTermsFlush(p); + if( rc!=SQLITE_OK ){ + return rc; + } + fts3DbExec(&rc, db, "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';", p->zDb, p->zName, zName ); - if( rc==SQLITE_ERROR ) rc = SQLITE_OK; if( p->bHasDocsize ){ fts3DbExec(&rc, db, "ALTER TABLE %Q.'%q_docsize' RENAME TO '%q_docsize';", p->zDb, p->zName, zName ); + } + if( p->bHasStat ){ fts3DbExec(&rc, db, "ALTER TABLE %Q.'%q_stat' RENAME TO '%q_stat';", p->zDb, p->zName, zName @@ -102193,15 +117323,58 @@ static int fts3RenameMethod( return rc; } +/* +** The xSavepoint() method. +** +** Flush the contents of the pending-terms table to disk. +*/ +static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ + UNUSED_PARAMETER(iSavepoint); + assert( ((Fts3Table *)pVtab)->inTransaction ); + assert( ((Fts3Table *)pVtab)->mxSavepoint < iSavepoint ); + TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint ); + return fts3SyncMethod(pVtab); +} + +/* +** The xRelease() method. +** +** This is a no-op. +*/ +static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); + UNUSED_PARAMETER(iSavepoint); + UNUSED_PARAMETER(pVtab); + assert( p->inTransaction ); + assert( p->mxSavepoint >= iSavepoint ); + TESTONLY( p->mxSavepoint = iSavepoint-1 ); + return SQLITE_OK; +} + +/* +** The xRollbackTo() method. +** +** Discard the contents of the pending terms table. +*/ +static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ + Fts3Table *p = (Fts3Table*)pVtab; + UNUSED_PARAMETER(iSavepoint); + assert( p->inTransaction ); + assert( p->mxSavepoint >= iSavepoint ); + TESTONLY( p->mxSavepoint = iSavepoint ); + sqlite3Fts3PendingTermsClear(p); + return SQLITE_OK; +} + static const sqlite3_module fts3Module = { - /* iVersion */ 0, + /* iVersion */ 2, /* xCreate */ fts3CreateMethod, /* xConnect */ fts3ConnectMethod, /* xBestIndex */ fts3BestIndexMethod, /* xDisconnect */ fts3DisconnectMethod, /* xDestroy */ fts3DestroyMethod, /* xOpen */ fts3OpenMethod, - /* xClose */ fulltextClose, + /* xClose */ fts3CloseMethod, /* xFilter */ fts3FilterMethod, /* xNext */ fts3NextMethod, /* xEof */ fts3EofMethod, @@ -102214,6 +117387,9 @@ static const sqlite3_module fts3Module = { /* xRollback */ fts3RollbackMethod, /* xFindFunction */ fts3FindFunctionMethod, /* xRename */ fts3RenameMethod, + /* xSavepoint */ fts3SavepointMethod, + /* xRelease */ fts3ReleaseMethod, + /* xRollbackTo */ fts3RollbackToMethod, }; /* @@ -102228,19 +117404,20 @@ static void hashDestroy(void *p){ } /* -** The fts3 built-in tokenizers - "simple" and "porter" - are implemented -** in files fts3_tokenizer1.c and fts3_porter.c respectively. The following -** two forward declarations are for functions declared in these files -** used to retrieve the respective implementations. +** The fts3 built-in tokenizers - "simple", "porter" and "icu"- are +** implemented in files fts3_tokenizer1.c, fts3_porter.c and fts3_icu.c +** respectively. The following three forward declarations are for functions +** declared in these files used to retrieve the respective implementations. ** ** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed -** to by the argument to point a the "simple" tokenizer implementation. -** Function ...PorterTokenizerModule() sets *pModule to point to the -** porter tokenizer/stemmer implementation. +** to by the argument to point to the "simple" tokenizer implementation. +** And so on. */ SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); +#ifdef SQLITE_ENABLE_ICU SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); +#endif /* ** Initialise the fts3 extension. If this extension is built as part @@ -102259,6 +117436,14 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ sqlite3Fts3IcuTokenizerModule(&pIcu); #endif +#ifdef SQLITE_TEST + rc = sqlite3Fts3InitTerm(db); + if( rc!=SQLITE_OK ) return rc; +#endif + + rc = sqlite3Fts3InitAux(db); + if( rc!=SQLITE_OK ) return rc; + sqlite3Fts3SimpleTokenizerModule(&pSimple); sqlite3Fts3PorterTokenizerModule(&pPorter); @@ -102273,7 +117458,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ /* Load the built-in tokenizers into the hash table */ if( rc==SQLITE_OK ){ if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) - || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) + || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) #ifdef SQLITE_ENABLE_ICU || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) #endif @@ -102288,15 +117473,16 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ } #endif - /* Create the virtual table wrapper around the hash-table and overload + /* Create the virtual table wrapper around the hash-table and overload ** the two scalar functions. If this is successful, register the ** module with sqlite. */ - if( SQLITE_OK==rc + if( SQLITE_OK==rc && SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer")) && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1)) && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", 1)) - && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", -1)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 1)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 2)) && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", 1)) ){ rc = sqlite3_create_module_v2( @@ -102319,9 +117505,1550 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ return rc; } +/* +** Allocate an Fts3MultiSegReader for each token in the expression headed +** by pExpr. +** +** An Fts3SegReader object is a cursor that can seek or scan a range of +** entries within a single segment b-tree. An Fts3MultiSegReader uses multiple +** Fts3SegReader objects internally to provide an interface to seek or scan +** within the union of all segments of a b-tree. Hence the name. +** +** If the allocated Fts3MultiSegReader just seeks to a single entry in a +** segment b-tree (if the term is not a prefix or it is a prefix for which +** there exists prefix b-tree of the right length) then it may be traversed +** and merged incrementally. Otherwise, it has to be merged into an in-memory +** doclist and then traversed. +*/ +static void fts3EvalAllocateReaders( + Fts3Cursor *pCsr, /* FTS cursor handle */ + Fts3Expr *pExpr, /* Allocate readers for this expression */ + int *pnToken, /* OUT: Total number of tokens in phrase. */ + int *pnOr, /* OUT: Total number of OR nodes in expr. */ + int *pRc /* IN/OUT: Error code */ +){ + if( pExpr && SQLITE_OK==*pRc ){ + if( pExpr->eType==FTSQUERY_PHRASE ){ + int i; + int nToken = pExpr->pPhrase->nToken; + *pnToken += nToken; + for(i=0; i<nToken; i++){ + Fts3PhraseToken *pToken = &pExpr->pPhrase->aToken[i]; + int rc = fts3TermSegReaderCursor(pCsr, + pToken->z, pToken->n, pToken->isPrefix, &pToken->pSegcsr + ); + if( rc!=SQLITE_OK ){ + *pRc = rc; + return; + } + } + assert( pExpr->pPhrase->iDoclistToken==0 ); + pExpr->pPhrase->iDoclistToken = -1; + }else{ + *pnOr += (pExpr->eType==FTSQUERY_OR); + fts3EvalAllocateReaders(pCsr, pExpr->pLeft, pnToken, pnOr, pRc); + fts3EvalAllocateReaders(pCsr, pExpr->pRight, pnToken, pnOr, pRc); + } + } +} + +/* +** Arguments pList/nList contain the doclist for token iToken of phrase p. +** It is merged into the main doclist stored in p->doclist.aAll/nAll. +** +** This function assumes that pList points to a buffer allocated using +** sqlite3_malloc(). This function takes responsibility for eventually +** freeing the buffer. +*/ +static void fts3EvalPhraseMergeToken( + Fts3Table *pTab, /* FTS Table pointer */ + Fts3Phrase *p, /* Phrase to merge pList/nList into */ + int iToken, /* Token pList/nList corresponds to */ + char *pList, /* Pointer to doclist */ + int nList /* Number of bytes in pList */ +){ + assert( iToken!=p->iDoclistToken ); + + if( pList==0 ){ + sqlite3_free(p->doclist.aAll); + p->doclist.aAll = 0; + p->doclist.nAll = 0; + } + + else if( p->iDoclistToken<0 ){ + p->doclist.aAll = pList; + p->doclist.nAll = nList; + } + + else if( p->doclist.aAll==0 ){ + sqlite3_free(pList); + } + + else { + char *pLeft; + char *pRight; + int nLeft; + int nRight; + int nDiff; + + if( p->iDoclistToken<iToken ){ + pLeft = p->doclist.aAll; + nLeft = p->doclist.nAll; + pRight = pList; + nRight = nList; + nDiff = iToken - p->iDoclistToken; + }else{ + pRight = p->doclist.aAll; + nRight = p->doclist.nAll; + pLeft = pList; + nLeft = nList; + nDiff = p->iDoclistToken - iToken; + } + + fts3DoclistPhraseMerge(pTab->bDescIdx, nDiff, pLeft, nLeft, pRight,&nRight); + sqlite3_free(pLeft); + p->doclist.aAll = pRight; + p->doclist.nAll = nRight; + } + + if( iToken>p->iDoclistToken ) p->iDoclistToken = iToken; +} + +/* +** Load the doclist for phrase p into p->doclist.aAll/nAll. The loaded doclist +** does not take deferred tokens into account. +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +*/ +static int fts3EvalPhraseLoad( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Phrase *p /* Phrase object */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int iToken; + int rc = SQLITE_OK; + + for(iToken=0; rc==SQLITE_OK && iToken<p->nToken; iToken++){ + Fts3PhraseToken *pToken = &p->aToken[iToken]; + assert( pToken->pDeferred==0 || pToken->pSegcsr==0 ); + + if( pToken->pSegcsr ){ + int nThis = 0; + char *pThis = 0; + rc = fts3TermSelect(pTab, pToken, p->iColumn, &nThis, &pThis); + if( rc==SQLITE_OK ){ + fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis); + } + } + assert( pToken->pSegcsr==0 ); + } + + return rc; +} + +/* +** This function is called on each phrase after the position lists for +** any deferred tokens have been loaded into memory. It updates the phrases +** current position list to include only those positions that are really +** instances of the phrase (after considering deferred tokens). If this +** means that the phrase does not appear in the current row, doclist.pList +** and doclist.nList are both zeroed. +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +*/ +static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ + int iToken; /* Used to iterate through phrase tokens */ + int rc = SQLITE_OK; /* Return code */ + 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 */ + + assert( pPhrase->doclist.bFreeList==0 ); + + for(iToken=0; rc==SQLITE_OK && iToken<pPhrase->nToken; iToken++){ + Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; + Fts3DeferredToken *pDeferred = pToken->pDeferred; + + if( pDeferred ){ + char *pList; + int nList; + rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList); + if( rc!=SQLITE_OK ) return rc; + + if( pList==0 ){ + sqlite3_free(aPoslist); + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + return SQLITE_OK; + + }else if( aPoslist==0 ){ + aPoslist = pList; + nPoslist = nList; + + }else{ + char *aOut = pList; + char *p1 = aPoslist; + char *p2 = aOut; + + assert( iPrev>=0 ); + fts3PoslistPhraseMerge(&aOut, iToken-iPrev, 0, 1, &p1, &p2); + sqlite3_free(aPoslist); + aPoslist = pList; + nPoslist = aOut - aPoslist; + if( nPoslist==0 ){ + sqlite3_free(aPoslist); + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + return SQLITE_OK; + } + } + iPrev = iToken; + } + } + + if( iPrev>=0 ){ + int nMaxUndeferred = pPhrase->iDoclistToken; + if( nMaxUndeferred<0 ){ + pPhrase->doclist.pList = aPoslist; + pPhrase->doclist.nList = nPoslist; + pPhrase->doclist.iDocid = pCsr->iPrevId; + pPhrase->doclist.bFreeList = 1; + }else{ + int nDistance; + char *p1; + char *p2; + char *aOut; + + if( nMaxUndeferred>iPrev ){ + p1 = aPoslist; + p2 = pPhrase->doclist.pList; + nDistance = nMaxUndeferred - iPrev; + }else{ + p1 = pPhrase->doclist.pList; + p2 = aPoslist; + nDistance = iPrev - nMaxUndeferred; + } + + aOut = (char *)sqlite3_malloc(nPoslist+8); + if( !aOut ){ + sqlite3_free(aPoslist); + return SQLITE_NOMEM; + } + + pPhrase->doclist.pList = aOut; + if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){ + pPhrase->doclist.bFreeList = 1; + pPhrase->doclist.nList = (aOut - pPhrase->doclist.pList); + }else{ + sqlite3_free(aOut); + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + } + sqlite3_free(aPoslist); + } + } + + return SQLITE_OK; +} + +/* +** This function is called for each Fts3Phrase in a full-text query +** expression to initialize the mechanism for returning rows. Once this +** function has been called successfully on an Fts3Phrase, it may be +** used with fts3EvalPhraseNext() to iterate through the matching docids. +** +** If parameter bOptOk is true, then the phrase may (or may not) use the +** incremental loading strategy. Otherwise, the entire doclist is loaded into +** memory within this call. +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +*/ +static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ + int rc; /* Error code */ + Fts3PhraseToken *pFirst = &p->aToken[0]; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + + if( pCsr->bDesc==pTab->bDescIdx + && bOptOk==1 + && p->nToken==1 + && pFirst->pSegcsr + && pFirst->pSegcsr->bLookup + ){ + /* Use the incremental approach. */ + int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn); + rc = sqlite3Fts3MsrIncrStart( + pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n); + p->bIncr = 1; + + }else{ + /* Load the full doclist for the phrase into memory. */ + rc = fts3EvalPhraseLoad(pCsr, p); + p->bIncr = 0; + } + + assert( rc!=SQLITE_OK || p->nToken<1 || p->aToken[0].pSegcsr==0 || p->bIncr ); + return rc; +} + +/* +** This function is used to iterate backwards (from the end to start) +** through doclists. It is used by this module to iterate through phrase +** doclists in reverse and by the fts3_write.c module to iterate through +** pending-terms lists when writing to databases with "order=desc". +** +** The doclist may be sorted in ascending (parameter bDescIdx==0) or +** descending (parameter bDescIdx==1) order of docid. Regardless, this +** function iterates from the end of the doclist to the beginning. +*/ +SQLITE_PRIVATE void sqlite3Fts3DoclistPrev( + int bDescIdx, /* True if the doclist is desc */ + char *aDoclist, /* Pointer to entire doclist */ + int nDoclist, /* Length of aDoclist in bytes */ + char **ppIter, /* IN/OUT: Iterator pointer */ + sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */ + int *pnList, /* IN/OUT: List length pointer */ + u8 *pbEof /* OUT: End-of-file flag */ +){ + char *p = *ppIter; + + assert( nDoclist>0 ); + assert( *pbEof==0 ); + assert( p || *piDocid==0 ); + assert( !p || (p>aDoclist && p<&aDoclist[nDoclist]) ); + + if( p==0 ){ + sqlite3_int64 iDocid = 0; + char *pNext = 0; + char *pDocid = aDoclist; + char *pEnd = &aDoclist[nDoclist]; + int iMul = 1; + + while( pDocid<pEnd ){ + sqlite3_int64 iDelta; + pDocid += sqlite3Fts3GetVarint(pDocid, &iDelta); + iDocid += (iMul * iDelta); + pNext = pDocid; + fts3PoslistCopy(0, &pDocid); + while( pDocid<pEnd && *pDocid==0 ) pDocid++; + iMul = (bDescIdx ? -1 : 1); + } + + *pnList = pEnd - pNext; + *ppIter = pNext; + *piDocid = iDocid; + }else{ + int iMul = (bDescIdx ? -1 : 1); + sqlite3_int64 iDelta; + fts3GetReverseVarint(&p, aDoclist, &iDelta); + *piDocid -= (iMul * iDelta); + + if( p==aDoclist ){ + *pbEof = 1; + }else{ + char *pSave = p; + fts3ReversePoslist(aDoclist, &p); + *pnList = (pSave - p); + } + *ppIter = p; + } +} + +/* +** Attempt to move the phrase iterator to point to the next matching docid. +** If an error occurs, return an SQLite error code. Otherwise, return +** SQLITE_OK. +** +** If there is no "next" entry and no error occurs, then *pbEof is set to +** 1 before returning. Otherwise, if no error occurs and the iterator is +** successfully advanced, *pbEof is set to 0. +*/ +static int fts3EvalPhraseNext( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Phrase *p, /* Phrase object to advance to next docid */ + u8 *pbEof /* OUT: Set to 1 if EOF */ +){ + int rc = SQLITE_OK; + Fts3Doclist *pDL = &p->doclist; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + + if( p->bIncr ){ + assert( p->nToken==1 ); + assert( pDL->pNextDocid==0 ); + rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr, + &pDL->iDocid, &pDL->pList, &pDL->nList + ); + if( rc==SQLITE_OK && !pDL->pList ){ + *pbEof = 1; + } + }else if( pCsr->bDesc!=pTab->bDescIdx && pDL->nAll ){ + sqlite3Fts3DoclistPrev(pTab->bDescIdx, pDL->aAll, pDL->nAll, + &pDL->pNextDocid, &pDL->iDocid, &pDL->nList, pbEof + ); + pDL->pList = pDL->pNextDocid; + }else{ + char *pIter; /* Used to iterate through aAll */ + char *pEnd = &pDL->aAll[pDL->nAll]; /* 1 byte past end of aAll */ + if( pDL->pNextDocid ){ + pIter = pDL->pNextDocid; + }else{ + pIter = pDL->aAll; + } + + if( pIter>=pEnd ){ + /* We have already reached the end of this doclist. EOF. */ + *pbEof = 1; + }else{ + sqlite3_int64 iDelta; + pIter += sqlite3Fts3GetVarint(pIter, &iDelta); + if( pTab->bDescIdx==0 || pDL->pNextDocid==0 ){ + pDL->iDocid += iDelta; + }else{ + pDL->iDocid -= iDelta; + } + pDL->pList = pIter; + fts3PoslistCopy(0, &pIter); + pDL->nList = (pIter - pDL->pList); + + /* pIter now points just past the 0x00 that terminates the position- + ** list for document pDL->iDocid. However, if this position-list was + ** edited in place by fts3EvalNearTrim(), then pIter may not actually + ** point to the start of the next docid value. The following line deals + ** with this case by advancing pIter past the zero-padding added by + ** fts3EvalNearTrim(). */ + while( pIter<pEnd && *pIter==0 ) pIter++; + + pDL->pNextDocid = pIter; + assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter ); + *pbEof = 0; + } + } + + return rc; +} + +/* +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, fts3EvalPhraseStart() is called on all phrases within the +** expression. Also the Fts3Expr.bDeferred variable is set to true for any +** expressions for which all descendent tokens are deferred. +** +** If parameter bOptOk is zero, then it is guaranteed that the +** Fts3Phrase.doclist.aAll/nAll variables contain the entire doclist for +** each phrase in the expression (subject to deferred token processing). +** Or, if bOptOk is non-zero, then one or more tokens within the expression +** may be loaded incrementally, meaning doclist.aAll/nAll is not available. +** +** If an error occurs within this function, *pRc is set to an SQLite error +** code before returning. +*/ +static void fts3EvalStartReaders( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pExpr, /* Expression to initialize phrases in */ + int bOptOk, /* True to enable incremental loading */ + int *pRc /* IN/OUT: Error code */ +){ + if( pExpr && SQLITE_OK==*pRc ){ + if( pExpr->eType==FTSQUERY_PHRASE ){ + int i; + int nToken = pExpr->pPhrase->nToken; + for(i=0; i<nToken; i++){ + if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break; + } + pExpr->bDeferred = (i==nToken); + *pRc = fts3EvalPhraseStart(pCsr, bOptOk, pExpr->pPhrase); + }else{ + fts3EvalStartReaders(pCsr, pExpr->pLeft, bOptOk, pRc); + fts3EvalStartReaders(pCsr, pExpr->pRight, bOptOk, pRc); + pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred); + } + } +} + +/* +** An array of the following structures is assembled as part of the process +** of selecting tokens to defer before the query starts executing (as part +** of the xFilter() method). There is one element in the array for each +** token in the FTS expression. +** +** Tokens are divided into AND/NEAR clusters. All tokens in a cluster belong +** to phrases that are connected only by AND and NEAR operators (not OR or +** NOT). When determining tokens to defer, each AND/NEAR cluster is considered +** separately. The root of a tokens AND/NEAR cluster is stored in +** Fts3TokenAndCost.pRoot. +*/ +typedef struct Fts3TokenAndCost Fts3TokenAndCost; +struct Fts3TokenAndCost { + Fts3Phrase *pPhrase; /* The phrase the token belongs to */ + int iToken; /* Position of token in phrase */ + Fts3PhraseToken *pToken; /* The token itself */ + Fts3Expr *pRoot; /* Root of NEAR/AND cluster */ + int nOvfl; /* Number of overflow pages to load doclist */ + int iCol; /* The column the token must match */ +}; + +/* +** This function is used to populate an allocated Fts3TokenAndCost array. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, if an error occurs during execution, *pRc is set to an +** SQLite error code. +*/ +static void fts3EvalTokenCosts( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pRoot, /* Root of current AND/NEAR cluster */ + Fts3Expr *pExpr, /* Expression to consider */ + Fts3TokenAndCost **ppTC, /* Write new entries to *(*ppTC)++ */ + Fts3Expr ***ppOr, /* Write new OR root to *(*ppOr)++ */ + int *pRc /* IN/OUT: Error code */ +){ + if( *pRc==SQLITE_OK && pExpr ){ + if( pExpr->eType==FTSQUERY_PHRASE ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + int i; + for(i=0; *pRc==SQLITE_OK && i<pPhrase->nToken; i++){ + Fts3TokenAndCost *pTC = (*ppTC)++; + pTC->pPhrase = pPhrase; + pTC->iToken = i; + pTC->pRoot = pRoot; + pTC->pToken = &pPhrase->aToken[i]; + pTC->iCol = pPhrase->iColumn; + *pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl); + } + }else if( pExpr->eType!=FTSQUERY_NOT ){ + if( pExpr->eType==FTSQUERY_OR ){ + pRoot = pExpr->pLeft; + **ppOr = pRoot; + (*ppOr)++; + } + fts3EvalTokenCosts(pCsr, pRoot, pExpr->pLeft, ppTC, ppOr, pRc); + if( pExpr->eType==FTSQUERY_OR ){ + pRoot = pExpr->pRight; + **ppOr = pRoot; + (*ppOr)++; + } + fts3EvalTokenCosts(pCsr, pRoot, pExpr->pRight, ppTC, ppOr, pRc); + } + } +} + +/* +** Determine the average document (row) size in pages. If successful, +** write this value to *pnPage and return SQLITE_OK. Otherwise, return +** an SQLite error code. +** +** The average document size in pages is calculated by first calculating +** determining the average size in bytes, B. If B is less than the amount +** of data that will fit on a single leaf page of an intkey table in +** this database, then the average docsize is 1. Otherwise, it is 1 plus +** the number of overflow pages consumed by a record B bytes in size. +*/ +static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){ + if( pCsr->nRowAvg==0 ){ + /* The average document size, which is required to calculate the cost + ** of each doclist, has not yet been determined. Read the required + ** data from the %_stat table to calculate it. + ** + ** Entry 0 of the %_stat table is a blob containing (nCol+1) FTS3 + ** varints, where nCol is the number of columns in the FTS3 table. + ** The first varint is the number of documents currently stored in + ** the table. The following nCol varints contain the total amount of + ** data stored in all rows of each column of the table, from left + ** to right. + */ + int rc; + Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; + sqlite3_stmt *pStmt; + sqlite3_int64 nDoc = 0; + sqlite3_int64 nByte = 0; + const char *pEnd; + const char *a; + + rc = sqlite3Fts3SelectDoctotal(p, &pStmt); + if( rc!=SQLITE_OK ) return rc; + a = sqlite3_column_blob(pStmt, 0); + assert( a ); + + pEnd = &a[sqlite3_column_bytes(pStmt, 0)]; + a += sqlite3Fts3GetVarint(a, &nDoc); + while( a<pEnd ){ + a += sqlite3Fts3GetVarint(a, &nByte); + } + if( nDoc==0 || nByte==0 ){ + sqlite3_reset(pStmt); + return SQLITE_CORRUPT_VTAB; + } + + pCsr->nDoc = nDoc; + pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz); + assert( pCsr->nRowAvg>0 ); + rc = sqlite3_reset(pStmt); + if( rc!=SQLITE_OK ) return rc; + } + + *pnPage = pCsr->nRowAvg; + return SQLITE_OK; +} + +/* +** This function is called to select the tokens (if any) that will be +** deferred. The array aTC[] has already been populated when this is +** called. +** +** This function is called once for each AND/NEAR cluster in the +** expression. Each invocation determines which tokens to defer within +** the cluster with root node pRoot. See comments above the definition +** of struct Fts3TokenAndCost for more details. +** +** If no error occurs, SQLITE_OK is returned and sqlite3Fts3DeferToken() +** called on each token to defer. Otherwise, an SQLite error code is +** returned. +*/ +static int fts3EvalSelectDeferred( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pRoot, /* Consider tokens with this root node */ + Fts3TokenAndCost *aTC, /* Array of expression tokens and costs */ + int nTC /* Number of entries in aTC[] */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int nDocSize = 0; /* Number of pages per doc loaded */ + int rc = SQLITE_OK; /* Return code */ + int ii; /* Iterator variable for various purposes */ + int nOvfl = 0; /* Total overflow pages used by doclists */ + int nToken = 0; /* Total number of tokens in cluster */ + + int nMinEst = 0; /* The minimum count for any phrase so far. */ + int nLoad4 = 1; /* (Phrases that will be loaded)^4. */ + + /* Count the tokens in this AND/NEAR cluster. If none of the doclists + ** associated with the tokens spill onto overflow pages, or if there is + ** only 1 token, exit early. No tokens to defer in this case. */ + for(ii=0; ii<nTC; ii++){ + if( aTC[ii].pRoot==pRoot ){ + nOvfl += aTC[ii].nOvfl; + nToken++; + } + } + if( nOvfl==0 || nToken<2 ) return SQLITE_OK; + + /* Obtain the average docsize (in pages). */ + rc = fts3EvalAverageDocsize(pCsr, &nDocSize); + assert( rc!=SQLITE_OK || nDocSize>0 ); + + + /* Iterate through all tokens in this AND/NEAR cluster, in ascending order + ** of the number of overflow pages that will be loaded by the pager layer + ** to retrieve the entire doclist for the token from the full-text index. + ** Load the doclists for tokens that are either: + ** + ** a. The cheapest token in the entire query (i.e. the one visited by the + ** first iteration of this loop), or + ** + ** b. Part of a multi-token phrase. + ** + ** After each token doclist is loaded, merge it with the others from the + ** same phrase and count the number of documents that the merged doclist + ** contains. Set variable "nMinEst" to the smallest number of documents in + ** any phrase doclist for which 1 or more token doclists have been loaded. + ** Let nOther be the number of other phrases for which it is certain that + ** one or more tokens will not be deferred. + ** + ** Then, for each token, defer it if loading the doclist would result in + ** loading N or more overflow pages into memory, where N is computed as: + ** + ** (nMinEst + 4^nOther - 1) / (4^nOther) + */ + for(ii=0; ii<nToken && rc==SQLITE_OK; ii++){ + int iTC; /* Used to iterate through aTC[] array. */ + Fts3TokenAndCost *pTC = 0; /* Set to cheapest remaining token. */ + + /* Set pTC to point to the cheapest remaining token. */ + for(iTC=0; iTC<nTC; iTC++){ + if( aTC[iTC].pToken && aTC[iTC].pRoot==pRoot + && (!pTC || aTC[iTC].nOvfl<pTC->nOvfl) + ){ + pTC = &aTC[iTC]; + } + } + assert( pTC ); + + if( ii && pTC->nOvfl>=((nMinEst+(nLoad4/4)-1)/(nLoad4/4))*nDocSize ){ + /* The number of overflow pages to load for this (and therefore all + ** subsequent) tokens is greater than the estimated number of pages + ** that will be loaded if all subsequent tokens are deferred. + */ + Fts3PhraseToken *pToken = pTC->pToken; + rc = sqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol); + fts3SegReaderCursorFree(pToken->pSegcsr); + pToken->pSegcsr = 0; + }else{ + nLoad4 = nLoad4*4; + if( ii==0 || pTC->pPhrase->nToken>1 ){ + /* Either this is the cheapest token in the entire query, or it is + ** part of a multi-token phrase. Either way, the entire doclist will + ** (eventually) be loaded into memory. It may as well be now. */ + Fts3PhraseToken *pToken = pTC->pToken; + int nList = 0; + char *pList = 0; + rc = fts3TermSelect(pTab, pToken, pTC->iCol, &nList, &pList); + assert( rc==SQLITE_OK || pList==0 ); + if( rc==SQLITE_OK ){ + int nCount; + fts3EvalPhraseMergeToken(pTab, pTC->pPhrase, pTC->iToken,pList,nList); + nCount = fts3DoclistCountDocids( + pTC->pPhrase->doclist.aAll, pTC->pPhrase->doclist.nAll + ); + if( ii==0 || nCount<nMinEst ) nMinEst = nCount; + } + } + } + pTC->pToken = 0; + } + + return rc; +} + +/* +** This function is called from within the xFilter method. It initializes +** the full-text query currently stored in pCsr->pExpr. To iterate through +** the results of a query, the caller does: +** +** fts3EvalStart(pCsr); +** while( 1 ){ +** fts3EvalNext(pCsr); +** if( pCsr->bEof ) break; +** ... return row pCsr->iPrevId to the caller ... +** } +*/ +static int fts3EvalStart(Fts3Cursor *pCsr){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int nToken = 0; + int nOr = 0; + + /* Allocate a MultiSegReader for each token in the expression. */ + fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc); + + /* Determine which, if any, tokens in the expression should be deferred. */ + if( rc==SQLITE_OK && nToken>1 && pTab->bHasStat ){ + Fts3TokenAndCost *aTC; + Fts3Expr **apOr; + aTC = (Fts3TokenAndCost *)sqlite3_malloc( + sizeof(Fts3TokenAndCost) * nToken + + sizeof(Fts3Expr *) * nOr * 2 + ); + apOr = (Fts3Expr **)&aTC[nToken]; + + if( !aTC ){ + rc = SQLITE_NOMEM; + }else{ + int ii; + Fts3TokenAndCost *pTC = aTC; + Fts3Expr **ppOr = apOr; + + fts3EvalTokenCosts(pCsr, 0, pCsr->pExpr, &pTC, &ppOr, &rc); + nToken = pTC-aTC; + nOr = ppOr-apOr; + + if( rc==SQLITE_OK ){ + rc = fts3EvalSelectDeferred(pCsr, 0, aTC, nToken); + for(ii=0; rc==SQLITE_OK && ii<nOr; ii++){ + rc = fts3EvalSelectDeferred(pCsr, apOr[ii], aTC, nToken); + } + } + + sqlite3_free(aTC); + } + } + + fts3EvalStartReaders(pCsr, pCsr->pExpr, 1, &rc); + return rc; +} + +/* +** Invalidate the current position list for phrase pPhrase. +*/ +static void fts3EvalInvalidatePoslist(Fts3Phrase *pPhrase){ + if( pPhrase->doclist.bFreeList ){ + sqlite3_free(pPhrase->doclist.pList); + } + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + pPhrase->doclist.bFreeList = 0; +} + +/* +** This function is called to edit the position list associated with +** the phrase object passed as the fifth argument according to a NEAR +** condition. For example: +** +** abc NEAR/5 "def ghi" +** +** Parameter nNear is passed the NEAR distance of the expression (5 in +** the example above). When this function is called, *paPoslist points to +** the position list, and *pnToken is the number of phrase tokens in, the +** phrase on the other side of the NEAR operator to pPhrase. For example, +** if pPhrase refers to the "def ghi" phrase, then *paPoslist points to +** the position list associated with phrase "abc". +** +** All positions in the pPhrase position list that are not sufficiently +** close to a position in the *paPoslist position list are removed. If this +** leaves 0 positions, zero is returned. Otherwise, non-zero. +** +** Before returning, *paPoslist is set to point to the position lsit +** associated with pPhrase. And *pnToken is set to the number of tokens in +** pPhrase. +*/ +static int fts3EvalNearTrim( + int nNear, /* NEAR distance. As in "NEAR/nNear". */ + char *aTmp, /* Temporary space to use */ + char **paPoslist, /* IN/OUT: Position list */ + int *pnToken, /* IN/OUT: Tokens in phrase of *paPoslist */ + Fts3Phrase *pPhrase /* The phrase object to trim the doclist of */ +){ + int nParam1 = nNear + pPhrase->nToken; + int nParam2 = nNear + *pnToken; + int nNew; + char *p2; + char *pOut; + int res; + + assert( pPhrase->doclist.pList ); + + p2 = pOut = pPhrase->doclist.pList; + res = fts3PoslistNearMerge( + &pOut, aTmp, nParam1, nParam2, paPoslist, &p2 + ); + if( res ){ + nNew = (pOut - pPhrase->doclist.pList) - 1; + assert( pPhrase->doclist.pList[nNew]=='\0' ); + assert( nNew<=pPhrase->doclist.nList && nNew>0 ); + memset(&pPhrase->doclist.pList[nNew], 0, pPhrase->doclist.nList - nNew); + pPhrase->doclist.nList = nNew; + *paPoslist = pPhrase->doclist.pList; + *pnToken = pPhrase->nToken; + } + + return res; +} + +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is called. +** Otherwise, it advances the expression passed as the second argument to +** point to the next matching row in the database. Expressions iterate through +** matching rows in docid order. Ascending order if Fts3Cursor.bDesc is zero, +** or descending if it is non-zero. +** +** If an error occurs, *pRc is set to an SQLite error code. Otherwise, if +** successful, the following variables in pExpr are set: +** +** Fts3Expr.bEof (non-zero if EOF - there is no next row) +** Fts3Expr.iDocid (valid if bEof==0. The docid of the next row) +** +** If the expression is of type FTSQUERY_PHRASE, and the expression is not +** at EOF, then the following variables are populated with the position list +** for the phrase for the visited row: +** +** FTs3Expr.pPhrase->doclist.nList (length of pList in bytes) +** FTs3Expr.pPhrase->doclist.pList (pointer to position list) +** +** It says above that this function advances the expression to the next +** matching row. This is usually true, but there are the following exceptions: +** +** 1. Deferred tokens are not taken into account. If a phrase consists +** entirely of deferred tokens, it is assumed to match every row in +** the db. In this case the position-list is not populated at all. +** +** Or, if a phrase contains one or more deferred tokens and one or +** more non-deferred tokens, then the expression is advanced to the +** next possible match, considering only non-deferred tokens. In other +** words, if the phrase is "A B C", and "B" is deferred, the expression +** is advanced to the next row that contains an instance of "A * C", +** where "*" may match any single token. The position list in this case +** is populated as for "A * C" before returning. +** +** 2. NEAR is treated as AND. If the expression is "x NEAR y", it is +** advanced to point to the next row that matches "x AND y". +** +** See fts3EvalTestDeferredAndNear() for details on testing if a row is +** really a match, taking into account deferred tokens and NEAR operators. +*/ +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 ){ + 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: { + Fts3Expr *pLeft = pExpr->pLeft; + Fts3Expr *pRight = pExpr->pRight; + assert( !pLeft->bDeferred || !pRight->bDeferred ); + + if( pLeft->bDeferred ){ + /* LHS is entirely deferred. So we assume it matches every row. + ** Advance the RHS iterator to find the next row visited. */ + fts3EvalNextRow(pCsr, pRight, pRc); + pExpr->iDocid = pRight->iDocid; + pExpr->bEof = pRight->bEof; + }else if( pRight->bDeferred ){ + /* RHS is entirely deferred. So we assume it matches every row. + ** Advance the LHS iterator to find the next row visited. */ + fts3EvalNextRow(pCsr, pLeft, pRc); + pExpr->iDocid = pLeft->iDocid; + pExpr->bEof = pLeft->bEof; + }else{ + /* Neither the RHS or LHS are deferred. */ + fts3EvalNextRow(pCsr, pLeft, pRc); + fts3EvalNextRow(pCsr, pRight, pRc); + while( !pLeft->bEof && !pRight->bEof && *pRc==SQLITE_OK ){ + sqlite3_int64 iDiff = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + if( iDiff==0 ) break; + if( iDiff<0 ){ + fts3EvalNextRow(pCsr, pLeft, pRc); + }else{ + fts3EvalNextRow(pCsr, pRight, pRc); + } + } + pExpr->iDocid = pLeft->iDocid; + pExpr->bEof = (pLeft->bEof || pRight->bEof); + } + break; + } + + case FTSQUERY_OR: { + Fts3Expr *pLeft = pExpr->pLeft; + Fts3Expr *pRight = pExpr->pRight; + sqlite3_int64 iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + + assert( pLeft->bStart || pLeft->iDocid==pRight->iDocid ); + assert( pRight->bStart || pLeft->iDocid==pRight->iDocid ); + + if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){ + fts3EvalNextRow(pCsr, pLeft, pRc); + }else if( pLeft->bEof || (pRight->bEof==0 && iCmp>0) ){ + fts3EvalNextRow(pCsr, pRight, pRc); + }else{ + fts3EvalNextRow(pCsr, pLeft, pRc); + fts3EvalNextRow(pCsr, pRight, pRc); + } + + pExpr->bEof = (pLeft->bEof && pRight->bEof); + iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){ + pExpr->iDocid = pLeft->iDocid; + }else{ + pExpr->iDocid = pRight->iDocid; + } + + break; + } + + case FTSQUERY_NOT: { + Fts3Expr *pLeft = pExpr->pLeft; + Fts3Expr *pRight = pExpr->pRight; + + if( pRight->bStart==0 ){ + fts3EvalNextRow(pCsr, pRight, pRc); + assert( *pRc!=SQLITE_OK || pRight->bStart ); + } + + fts3EvalNextRow(pCsr, pLeft, pRc); + if( pLeft->bEof==0 ){ + while( !*pRc + && !pRight->bEof + && DOCID_CMP(pLeft->iDocid, pRight->iDocid)>0 + ){ + fts3EvalNextRow(pCsr, pRight, pRc); + } + } + pExpr->iDocid = pLeft->iDocid; + pExpr->bEof = pLeft->bEof; + break; + } + + default: { + Fts3Phrase *pPhrase = pExpr->pPhrase; + fts3EvalInvalidatePoslist(pPhrase); + *pRc = fts3EvalPhraseNext(pCsr, pPhrase, &pExpr->bEof); + pExpr->iDocid = pPhrase->doclist.iDocid; + break; + } + } + } +} + +/* +** If *pRc is not SQLITE_OK, or if pExpr is not the root node of a NEAR +** cluster, then this function returns 1 immediately. +** +** Otherwise, it checks if the current row really does match the NEAR +** expression, using the data currently stored in the position lists +** (Fts3Expr->pPhrase.doclist.pList/nList) for each phrase in the expression. +** +** If the current row is a match, the position list associated with each +** phrase in the NEAR expression is edited in place to contain only those +** phrase instances sufficiently close to their peers to satisfy all NEAR +** constraints. In this case it returns 1. If the NEAR expression does not +** match the current row, 0 is returned. The position lists may or may not +** be edited if 0 is returned. +*/ +static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ + int res = 1; + + /* The following block runs if pExpr is the root of a NEAR query. + ** For example, the query: + ** + ** "w" NEAR "x" NEAR "y" NEAR "z" + ** + ** which is represented in tree form as: + ** + ** | + ** +--NEAR--+ <-- root of NEAR query + ** | | + ** +--NEAR--+ "z" + ** | | + ** +--NEAR--+ "y" + ** | | + ** "w" "x" + ** + ** The right-hand child of a NEAR node is always a phrase. The + ** left-hand child may be either a phrase or a NEAR node. There are + ** no exceptions to this - it's the way the parser in fts3_expr.c works. + */ + if( *pRc==SQLITE_OK + && pExpr->eType==FTSQUERY_NEAR + && pExpr->bEof==0 + && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR) + ){ + Fts3Expr *p; + int nTmp = 0; /* Bytes of temp space */ + char *aTmp; /* Temp space for PoslistNearMerge() */ + + /* Allocate temporary working space. */ + for(p=pExpr; p->pLeft; p=p->pLeft){ + nTmp += p->pRight->pPhrase->doclist.nList; + } + nTmp += p->pPhrase->doclist.nList; + aTmp = sqlite3_malloc(nTmp*2); + if( !aTmp ){ + *pRc = SQLITE_NOMEM; + res = 0; + }else{ + char *aPoslist = p->pPhrase->doclist.pList; + int nToken = p->pPhrase->nToken; + + for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){ + Fts3Phrase *pPhrase = p->pRight->pPhrase; + int nNear = p->nNear; + res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); + } + + aPoslist = pExpr->pRight->pPhrase->doclist.pList; + nToken = pExpr->pRight->pPhrase->nToken; + for(p=pExpr->pLeft; p && res; p=p->pLeft){ + int nNear = p->pParent->nNear; + Fts3Phrase *pPhrase = ( + p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase + ); + res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); + } + } + + sqlite3_free(aTmp); + } + + return res; +} + +/* +** This function is a helper function for fts3EvalTestDeferredAndNear(). +** Assuming no error occurs or has occurred, It returns non-zero if the +** expression passed as the second argument matches the row that pCsr +** currently points to, or zero if it does not. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** If an error occurs during execution of this function, *pRc is set to +** the appropriate SQLite error code. In this case the returned value is +** undefined. +*/ +static int fts3EvalTestExpr( + Fts3Cursor *pCsr, /* FTS cursor handle */ + Fts3Expr *pExpr, /* Expr to test. May or may not be root. */ + int *pRc /* IN/OUT: Error code */ +){ + int bHit = 1; /* Return value */ + if( *pRc==SQLITE_OK ){ + switch( pExpr->eType ){ + case FTSQUERY_NEAR: + case FTSQUERY_AND: + bHit = ( + fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc) + && fts3EvalTestExpr(pCsr, pExpr->pRight, pRc) + && fts3EvalNearTest(pExpr, pRc) + ); + + /* If the NEAR expression does not match any rows, zero the doclist for + ** all phrases involved in the NEAR. This is because the snippet(), + ** offsets() and matchinfo() functions are not supposed to recognize + ** any instances of phrases that are part of unmatched NEAR queries. + ** For example if this expression: + ** + ** ... MATCH 'a OR (b NEAR c)' + ** + ** is matched against a row containing: + ** + ** 'a b d e' + ** + ** then any snippet() should ony highlight the "a" term, not the "b" + ** (as "b" is part of a non-matching NEAR clause). + */ + if( bHit==0 + && pExpr->eType==FTSQUERY_NEAR + && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR) + ){ + Fts3Expr *p; + for(p=pExpr; p->pPhrase==0; p=p->pLeft){ + if( p->pRight->iDocid==pCsr->iPrevId ){ + fts3EvalInvalidatePoslist(p->pRight->pPhrase); + } + } + if( p->iDocid==pCsr->iPrevId ){ + fts3EvalInvalidatePoslist(p->pPhrase); + } + } + + break; + + case FTSQUERY_OR: { + int bHit1 = fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc); + int bHit2 = fts3EvalTestExpr(pCsr, pExpr->pRight, pRc); + bHit = bHit1 || bHit2; + break; + } + + case FTSQUERY_NOT: + bHit = ( + fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc) + && !fts3EvalTestExpr(pCsr, pExpr->pRight, pRc) + ); + break; + + default: { + 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); + pExpr->iDocid = pCsr->iPrevId; + }else{ + bHit = (pExpr->bEof==0 && pExpr->iDocid==pCsr->iPrevId); + } + break; + } + } + } + return bHit; +} + +/* +** This function is called as the second part of each xNext operation when +** iterating through the results of a full-text query. At this point the +** cursor points to a row that matches the query expression, with the +** following caveats: +** +** * Up until this point, "NEAR" operators in the expression have been +** treated as "AND". +** +** * Deferred tokens have not yet been considered. +** +** If *pRc is not SQLITE_OK when this function is called, it immediately +** returns 0. Otherwise, it tests whether or not after considering NEAR +** operators and deferred tokens the current row is still a match for the +** expression. It returns 1 if both of the following are true: +** +** 1. *pRc is SQLITE_OK when this function returns, and +** +** 2. After scanning the current FTS table row for the deferred tokens, +** it is determined that the row does *not* match the query. +** +** Or, if no error occurs and it seems the current row does match the FTS +** query, return 0. +*/ +static int fts3EvalTestDeferredAndNear(Fts3Cursor *pCsr, int *pRc){ + int rc = *pRc; + int bMiss = 0; + if( rc==SQLITE_OK ){ + + /* If there are one or more deferred tokens, load the current row into + ** memory and scan it to determine the position list for each deferred + ** token. Then, see if this row is really a match, considering deferred + ** tokens and NEAR operators (neither of which were taken into account + ** earlier, by fts3EvalNextRow()). + */ + if( pCsr->pDeferred ){ + rc = fts3CursorSeek(0, pCsr); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3CacheDeferredDoclists(pCsr); + } + } + bMiss = (0==fts3EvalTestExpr(pCsr, pCsr->pExpr, &rc)); + + /* Free the position-lists accumulated for each deferred token above. */ + sqlite3Fts3FreeDeferredDoclists(pCsr); + *pRc = rc; + } + return (rc==SQLITE_OK && bMiss); +} + +/* +** Advance to the next document that matches the FTS expression in +** Fts3Cursor.pExpr. +*/ +static int fts3EvalNext(Fts3Cursor *pCsr){ + int rc = SQLITE_OK; /* Return Code */ + Fts3Expr *pExpr = pCsr->pExpr; + assert( pCsr->isEof==0 ); + if( pExpr==0 ){ + pCsr->isEof = 1; + }else{ + do { + if( pCsr->isRequireSeek==0 ){ + sqlite3_reset(pCsr->pStmt); + } + assert( sqlite3_data_count(pCsr->pStmt)==0 ); + fts3EvalNextRow(pCsr, pExpr, &rc); + pCsr->isEof = pExpr->bEof; + pCsr->isRequireSeek = 1; + pCsr->isMatchinfoNeeded = 1; + pCsr->iPrevId = pExpr->iDocid; + }while( pCsr->isEof==0 && fts3EvalTestDeferredAndNear(pCsr, &rc) ); + } + return rc; +} + +/* +** Restart interation for expression pExpr so that the next call to +** fts3EvalNext() visits the first row. Do not allow incremental +** loading or merging of phrase doclists for this iteration. +** +** If *pRc is other than SQLITE_OK when this function is called, it is +** a no-op. If an error occurs within this function, *pRc is set to an +** SQLite error code before returning. +*/ +static void fts3EvalRestart( + Fts3Cursor *pCsr, + Fts3Expr *pExpr, + int *pRc +){ + if( pExpr && *pRc==SQLITE_OK ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + + if( pPhrase ){ + fts3EvalInvalidatePoslist(pPhrase); + if( pPhrase->bIncr ){ + assert( pPhrase->nToken==1 ); + assert( pPhrase->aToken[0].pSegcsr ); + sqlite3Fts3MsrIncrRestart(pPhrase->aToken[0].pSegcsr); + *pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase); + } + + pPhrase->doclist.pNextDocid = 0; + pPhrase->doclist.iDocid = 0; + } + + pExpr->iDocid = 0; + pExpr->bEof = 0; + pExpr->bStart = 0; + + fts3EvalRestart(pCsr, pExpr->pLeft, pRc); + fts3EvalRestart(pCsr, pExpr->pRight, pRc); + } +} + +/* +** After allocating the Fts3Expr.aMI[] array for each phrase in the +** expression rooted at pExpr, the cursor iterates through all rows matched +** by pExpr, calling this function for each row. This function increments +** the values in Fts3Expr.aMI[] according to the position-list currently +** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase +** expression nodes. +*/ +static void fts3EvalUpdateCounts(Fts3Expr *pExpr){ + if( pExpr ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + if( pPhrase && pPhrase->doclist.pList ){ + int iCol = 0; + char *p = pPhrase->doclist.pList; + + assert( *p ); + while( 1 ){ + u8 c = 0; + int iCnt = 0; + while( 0xFE & (*p | c) ){ + if( (c&0x80)==0 ) iCnt++; + c = *p++ & 0x80; + } + + /* aMI[iCol*3 + 1] = Number of occurrences + ** aMI[iCol*3 + 2] = Number of rows containing at least one instance + */ + pExpr->aMI[iCol*3 + 1] += iCnt; + pExpr->aMI[iCol*3 + 2] += (iCnt>0); + if( *p==0x00 ) break; + p++; + p += sqlite3Fts3GetVarint32(p, &iCol); + } + } + + fts3EvalUpdateCounts(pExpr->pLeft); + fts3EvalUpdateCounts(pExpr->pRight); + } +} + +/* +** 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 +** of a NEAR expression, then it also allocates and populates the same array +** for all other phrases that are part of the NEAR expression. +** +** SQLITE_OK is returned if the aMI[] array is successfully allocated and +** populated. Otherwise, if an error occurs, an SQLite error code is returned. +*/ +static int fts3EvalGatherStats( + Fts3Cursor *pCsr, /* Cursor object */ + Fts3Expr *pExpr /* FTSQUERY_PHRASE expression */ +){ + int rc = SQLITE_OK; /* Return code */ + + 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 = pRoot->pParent; + } + iDocid = pRoot->iDocid; + bEof = pRoot->bEof; + assert( pRoot->bStart ); + + /* Allocate space for the aMSI[] array of each FTSQUERY_PHRASE node */ + for(p=pRoot; p; p=p->pLeft){ + Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight); + assert( pE->aMI==0 ); + pE->aMI = (u32 *)sqlite3_malloc(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 { + /* Ensure the %_content statement is reset. */ + if( pCsr->isRequireSeek==0 ) sqlite3_reset(pCsr->pStmt); + assert( sqlite3_data_count(pCsr->pStmt)==0 ); + + /* Advance to the next document */ + fts3EvalNextRow(pCsr, pRoot, &rc); + pCsr->isEof = pRoot->bEof; + pCsr->isRequireSeek = 1; + pCsr->isMatchinfoNeeded = 1; + pCsr->iPrevId = pRoot->iDocid; + }while( pCsr->isEof==0 + && pRoot->eType==FTSQUERY_NEAR + && fts3EvalTestDeferredAndNear(pCsr, &rc) + ); + + if( rc==SQLITE_OK && pCsr->isEof==0 ){ + fts3EvalUpdateCounts(pRoot); + } + } + + pCsr->isEof = 0; + pCsr->iPrevId = iPrevId; + + if( bEof ){ + pRoot->bEof = bEof; + }else{ + /* Caution: pRoot may iterate through docids in ascending or descending + ** order. For this reason, even though it seems more defensive, the + ** do loop can not be written: + ** + ** do {...} while( pRoot->iDocid<iDocid && rc==SQLITE_OK ); + */ + fts3EvalRestart(pCsr, pRoot, &rc); + do { + fts3EvalNextRow(pCsr, pRoot, &rc); + assert( pRoot->bEof==0 ); + }while( pRoot->iDocid!=iDocid && rc==SQLITE_OK ); + fts3EvalTestDeferredAndNear(pCsr, &rc); + } + } + return rc; +} + +/* +** This function is used by the matchinfo() module to query a phrase +** expression node for the following information: +** +** 1. The total number of occurrences of the phrase in each column of +** the FTS table (considering all rows), and +** +** 2. For each column, the number of rows in the table for which the +** column contains at least one instance of the phrase. +** +** If no error occurs, SQLITE_OK is returned and the values for each column +** written into the array aiOut as follows: +** +** aiOut[iCol*3 + 1] = Number of occurrences +** aiOut[iCol*3 + 2] = Number of rows containing at least one instance +** +** Caveats: +** +** * If a phrase consists entirely of deferred tokens, then all output +** values are set to the number of documents in the table. In other +** words we assume that very common tokens occur exactly once in each +** column of each row of the table. +** +** * If a phrase contains some deferred tokens (and some non-deferred +** tokens), count the potential occurrence identified by considering +** the non-deferred tokens instead of actual phrase occurrences. +** +** * If the phrase is part of a NEAR expression, then only phrase instances +** that meet the NEAR constraint are included in the counts. +*/ +SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats( + Fts3Cursor *pCsr, /* FTS cursor handle */ + Fts3Expr *pExpr, /* Phrase expression */ + u32 *aiOut /* Array to write results into (see above) */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int iCol; + + if( pExpr->bDeferred && pExpr->pParent->eType!=FTSQUERY_NEAR ){ + assert( pCsr->nDoc>0 ); + for(iCol=0; iCol<pTab->nColumn; iCol++){ + aiOut[iCol*3 + 1] = (u32)pCsr->nDoc; + aiOut[iCol*3 + 2] = (u32)pCsr->nDoc; + } + }else{ + rc = fts3EvalGatherStats(pCsr, pExpr); + if( rc==SQLITE_OK ){ + assert( pExpr->aMI ); + for(iCol=0; iCol<pTab->nColumn; iCol++){ + aiOut[iCol*3 + 1] = pExpr->aMI[iCol*3 + 1]; + aiOut[iCol*3 + 2] = pExpr->aMI[iCol*3 + 2]; + } + } + } + + return rc; +} + +/* +** The expression pExpr passed as the second argument to this function +** must be of type FTSQUERY_PHRASE. +** +** The returned value is either NULL or a pointer to a buffer containing +** a position-list indicating the occurrences of the phrase in column iCol +** of the current row. +** +** More specifically, the returned buffer contains 1 varint for each +** occurence of the phrase in the column, stored using the normal (delta+2) +** compression and is terminated by either an 0x01 or 0x00 byte. For example, +** if the requested column contains "a b X c d X X" and the position-list +** for 'X' is requested, the buffer returned may contain: +** +** 0x04 0x05 0x03 0x01 or 0x04 0x05 0x03 0x00 +** +** This function works regardless of whether or not the phrase is deferred, +** incremental, or neither. +*/ +SQLITE_PRIVATE char *sqlite3Fts3EvalPhrasePoslist( + Fts3Cursor *pCsr, /* FTS3 cursor object */ + Fts3Expr *pExpr, /* Phrase to return doclist for */ + int iCol /* Column to return position list for */ +){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + char *pIter = pPhrase->doclist.pList; + int iThis; + + assert( iCol>=0 && iCol<pTab->nColumn ); + if( !pIter + || pExpr->bEof + || pExpr->iDocid!=pCsr->iPrevId + || (pPhrase->iColumn<pTab->nColumn && pPhrase->iColumn!=iCol) + ){ + return 0; + } + + assert( pPhrase->doclist.nList>0 ); + if( *pIter==0x01 ){ + pIter++; + pIter += sqlite3Fts3GetVarint32(pIter, &iThis); + }else{ + iThis = 0; + } + while( iThis<iCol ){ + fts3ColumnlistCopy(0, &pIter); + if( *pIter==0x00 ) return 0; + pIter++; + pIter += sqlite3Fts3GetVarint32(pIter, &iThis); + } + + return ((iCol==iThis)?pIter:0); +} + +/* +** Free all components of the Fts3Phrase structure that were allocated by +** the eval module. Specifically, this means to free: +** +** * the contents of pPhrase->doclist, and +** * any Fts3MultiSegReader objects held by phrase tokens. +*/ +SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *pPhrase){ + if( pPhrase ){ + int i; + sqlite3_free(pPhrase->doclist.aAll); + fts3EvalInvalidatePoslist(pPhrase); + memset(&pPhrase->doclist, 0, sizeof(Fts3Doclist)); + for(i=0; i<pPhrase->nToken; i++){ + fts3SegReaderCursorFree(pPhrase->aToken[i].pSegcsr); + pPhrase->aToken[i].pSegcsr = 0; + } + } +} + #if !SQLITE_CORE +/* +** Initialize API pointer table, if required. +*/ SQLITE_API int sqlite3_extension_init( - sqlite3 *db, + sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ @@ -102333,6 +119060,482 @@ SQLITE_API int sqlite3_extension_init( #endif /************** End of fts3.c ************************************************/ +/************** Begin file fts3_aux.c ****************************************/ +/* +** 2011 Jan 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. +** +****************************************************************************** +** +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include <string.h> */ +/* #include <assert.h> */ + +typedef struct Fts3auxTable Fts3auxTable; +typedef struct Fts3auxCursor Fts3auxCursor; + +struct Fts3auxTable { + sqlite3_vtab base; /* Base class used by SQLite core */ + Fts3Table *pFts3Tab; +}; + +struct Fts3auxCursor { + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ + Fts3MultiSegReader csr; /* Must be right after "base" */ + Fts3SegFilter filter; + char *zStop; + int nStop; /* Byte-length of string zStop */ + int isEof; /* True if cursor is at EOF */ + sqlite3_int64 iRowid; /* Current rowid */ + + int iCol; /* Current value of 'col' column */ + int nStat; /* Size of aStat[] array */ + struct Fts3auxColstats { + sqlite3_int64 nDoc; /* 'documents' values for current csr row */ + sqlite3_int64 nOcc; /* 'occurrences' values for current csr row */ + } *aStat; +}; + +/* +** Schema of the terms table. +*/ +#define FTS3_TERMS_SCHEMA "CREATE TABLE x(term, col, documents, occurrences)" + +/* +** This function does all the work for both the xConnect and xCreate methods. +** These tables have no persistent representation of their own, so xConnect +** and xCreate are identical operations. +*/ +static int fts3auxConnectMethod( + sqlite3 *db, /* Database connection */ + void *pUnused, /* Unused */ + int argc, /* Number of elements in argv array */ + const char * const *argv, /* xCreate/xConnect argument array */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ +){ + char const *zDb; /* Name of database (e.g. "main") */ + char const *zFts3; /* Name of fts3 table */ + int nDb; /* Result of strlen(zDb) */ + int nFts3; /* Result of strlen(zFts3) */ + int nByte; /* Bytes of space to allocate here */ + int rc; /* value returned by declare_vtab() */ + Fts3auxTable *p; /* Virtual table object to return */ + + UNUSED_PARAMETER(pUnused); + + /* The user should specify a single argument - the name of an fts3 table. */ + if( argc!=4 ){ + *pzErr = sqlite3_mprintf( + "wrong number of arguments to fts4aux constructor" + ); + return SQLITE_ERROR; + } + + zDb = argv[1]; + nDb = strlen(zDb); + zFts3 = argv[3]; + nFts3 = strlen(zFts3); + + rc = sqlite3_declare_vtab(db, FTS3_TERMS_SCHEMA); + if( rc!=SQLITE_OK ) return rc; + + nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2; + p = (Fts3auxTable *)sqlite3_malloc(nByte); + if( !p ) return SQLITE_NOMEM; + memset(p, 0, nByte); + + p->pFts3Tab = (Fts3Table *)&p[1]; + p->pFts3Tab->zDb = (char *)&p->pFts3Tab[1]; + p->pFts3Tab->zName = &p->pFts3Tab->zDb[nDb+1]; + p->pFts3Tab->db = db; + p->pFts3Tab->nIndex = 1; + + memcpy((char *)p->pFts3Tab->zDb, zDb, nDb); + memcpy((char *)p->pFts3Tab->zName, zFts3, nFts3); + sqlite3Fts3Dequote((char *)p->pFts3Tab->zName); + + *ppVtab = (sqlite3_vtab *)p; + return SQLITE_OK; +} + +/* +** This function does the work for both the xDisconnect and xDestroy methods. +** These tables have no persistent representation of their own, so xDisconnect +** and xDestroy are identical operations. +*/ +static int fts3auxDisconnectMethod(sqlite3_vtab *pVtab){ + Fts3auxTable *p = (Fts3auxTable *)pVtab; + Fts3Table *pFts3 = p->pFts3Tab; + int i; + + /* Free any prepared statements held */ + for(i=0; i<SizeofArray(pFts3->aStmt); i++){ + sqlite3_finalize(pFts3->aStmt[i]); + } + sqlite3_free(pFts3->zSegmentsTbl); + sqlite3_free(p); + return SQLITE_OK; +} + +#define FTS4AUX_EQ_CONSTRAINT 1 +#define FTS4AUX_GE_CONSTRAINT 2 +#define FTS4AUX_LE_CONSTRAINT 4 + +/* +** xBestIndex - Analyze a WHERE and ORDER BY clause. +*/ +static int fts3auxBestIndexMethod( + sqlite3_vtab *pVTab, + sqlite3_index_info *pInfo +){ + int i; + int iEq = -1; + int iGe = -1; + int iLe = -1; + + UNUSED_PARAMETER(pVTab); + + /* This vtab delivers always results in "ORDER BY term ASC" order. */ + if( pInfo->nOrderBy==1 + && pInfo->aOrderBy[0].iColumn==0 + && pInfo->aOrderBy[0].desc==0 + ){ + pInfo->orderByConsumed = 1; + } + + /* Search for equality and range constraints on the "term" column. */ + for(i=0; i<pInfo->nConstraint; i++){ + if( pInfo->aConstraint[i].usable && pInfo->aConstraint[i].iColumn==0 ){ + int op = pInfo->aConstraint[i].op; + if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iEq = i; + if( op==SQLITE_INDEX_CONSTRAINT_LT ) iLe = i; + if( op==SQLITE_INDEX_CONSTRAINT_LE ) iLe = i; + if( op==SQLITE_INDEX_CONSTRAINT_GT ) iGe = i; + if( op==SQLITE_INDEX_CONSTRAINT_GE ) iGe = i; + } + } + + if( iEq>=0 ){ + pInfo->idxNum = FTS4AUX_EQ_CONSTRAINT; + pInfo->aConstraintUsage[iEq].argvIndex = 1; + pInfo->estimatedCost = 5; + }else{ + pInfo->idxNum = 0; + pInfo->estimatedCost = 20000; + if( iGe>=0 ){ + pInfo->idxNum += FTS4AUX_GE_CONSTRAINT; + pInfo->aConstraintUsage[iGe].argvIndex = 1; + pInfo->estimatedCost /= 2; + } + if( iLe>=0 ){ + pInfo->idxNum += FTS4AUX_LE_CONSTRAINT; + pInfo->aConstraintUsage[iLe].argvIndex = 1 + (iGe>=0); + pInfo->estimatedCost /= 2; + } + } + + return SQLITE_OK; +} + +/* +** xOpen - Open a cursor. +*/ +static int fts3auxOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ + Fts3auxCursor *pCsr; /* Pointer to cursor object to return */ + + UNUSED_PARAMETER(pVTab); + + pCsr = (Fts3auxCursor *)sqlite3_malloc(sizeof(Fts3auxCursor)); + if( !pCsr ) return SQLITE_NOMEM; + memset(pCsr, 0, sizeof(Fts3auxCursor)); + + *ppCsr = (sqlite3_vtab_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** xClose - Close a cursor. +*/ +static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){ + Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + + sqlite3Fts3SegmentsClose(pFts3); + sqlite3Fts3SegReaderFinish(&pCsr->csr); + sqlite3_free((void *)pCsr->filter.zTerm); + sqlite3_free(pCsr->zStop); + sqlite3_free(pCsr->aStat); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){ + if( nSize>pCsr->nStat ){ + struct Fts3auxColstats *aNew; + aNew = (struct Fts3auxColstats *)sqlite3_realloc(pCsr->aStat, + sizeof(struct Fts3auxColstats) * nSize + ); + if( aNew==0 ) return SQLITE_NOMEM; + memset(&aNew[pCsr->nStat], 0, + sizeof(struct Fts3auxColstats) * (nSize - pCsr->nStat) + ); + pCsr->aStat = aNew; + pCsr->nStat = nSize; + } + return SQLITE_OK; +} + +/* +** xNext - Advance the cursor to the next row, if any. +*/ +static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; + int rc; + + /* Increment our pretend rowid value. */ + pCsr->iRowid++; + + for(pCsr->iCol++; pCsr->iCol<pCsr->nStat; pCsr->iCol++){ + if( pCsr->aStat[pCsr->iCol].nDoc>0 ) return SQLITE_OK; + } + + rc = sqlite3Fts3SegReaderStep(pFts3, &pCsr->csr); + if( rc==SQLITE_ROW ){ + int i = 0; + int nDoclist = pCsr->csr.nDoclist; + char *aDoclist = pCsr->csr.aDoclist; + int iCol; + + int eState = 0; + + if( pCsr->zStop ){ + int n = (pCsr->nStop<pCsr->csr.nTerm) ? pCsr->nStop : pCsr->csr.nTerm; + int mc = memcmp(pCsr->zStop, pCsr->csr.zTerm, n); + if( mc<0 || (mc==0 && pCsr->csr.nTerm>pCsr->nStop) ){ + pCsr->isEof = 1; + return SQLITE_OK; + } + } + + if( fts3auxGrowStatArray(pCsr, 2) ) return SQLITE_NOMEM; + memset(pCsr->aStat, 0, sizeof(struct Fts3auxColstats) * pCsr->nStat); + iCol = 0; + + while( i<nDoclist ){ + sqlite3_int64 v = 0; + + i += sqlite3Fts3GetVarint(&aDoclist[i], &v); + switch( eState ){ + /* State 0. In this state the integer just read was a docid. */ + case 0: + pCsr->aStat[0].nDoc++; + eState = 1; + iCol = 0; + break; + + /* State 1. In this state we are expecting either a 1, indicating + ** that the following integer will be a column number, or the + ** start of a position list for column 0. + ** + ** The only difference between state 1 and state 2 is that if the + ** integer encountered in state 1 is not 0 or 1, then we need to + ** increment the column 0 "nDoc" count for this term. + */ + case 1: + assert( iCol==0 ); + if( v>1 ){ + pCsr->aStat[1].nDoc++; + } + eState = 2; + /* fall through */ + + case 2: + if( v==0 ){ /* 0x00. Next integer will be a docid. */ + eState = 0; + }else if( v==1 ){ /* 0x01. Next integer will be a column number. */ + eState = 3; + }else{ /* 2 or greater. A position. */ + pCsr->aStat[iCol+1].nOcc++; + pCsr->aStat[0].nOcc++; + } + break; + + /* State 3. The integer just read is a column number. */ + default: assert( eState==3 ); + iCol = (int)v; + if( fts3auxGrowStatArray(pCsr, iCol+2) ) return SQLITE_NOMEM; + pCsr->aStat[iCol+1].nDoc++; + eState = 2; + break; + } + } + + pCsr->iCol = 0; + rc = SQLITE_OK; + }else{ + pCsr->isEof = 1; + } + return rc; +} + +/* +** xFilter - Initialize a cursor to point at the start of its data. +*/ +static int fts3auxFilterMethod( + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + int idxNum, /* Strategy index */ + const char *idxStr, /* Unused */ + int nVal, /* Number of elements in apVal */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ +){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; + int rc; + int isScan; + + UNUSED_PARAMETER(nVal); + UNUSED_PARAMETER(idxStr); + + assert( idxStr==0 ); + assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0 + || idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT + || idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) + ); + isScan = (idxNum!=FTS4AUX_EQ_CONSTRAINT); + + /* In case this cursor is being reused, close and zero it. */ + testcase(pCsr->filter.zTerm); + sqlite3Fts3SegReaderFinish(&pCsr->csr); + sqlite3_free((void *)pCsr->filter.zTerm); + sqlite3_free(pCsr->aStat); + memset(&pCsr->csr, 0, ((u8*)&pCsr[1]) - (u8*)&pCsr->csr); + + pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; + if( isScan ) pCsr->filter.flags |= FTS3_SEGMENT_SCAN; + + if( idxNum&(FTS4AUX_EQ_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) ){ + const unsigned char *zStr = sqlite3_value_text(apVal[0]); + if( zStr ){ + pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr); + pCsr->filter.nTerm = sqlite3_value_bytes(apVal[0]); + if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM; + } + } + if( idxNum&FTS4AUX_LE_CONSTRAINT ){ + int iIdx = (idxNum&FTS4AUX_GE_CONSTRAINT) ? 1 : 0; + pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iIdx])); + pCsr->nStop = sqlite3_value_bytes(apVal[iIdx]); + if( pCsr->zStop==0 ) return SQLITE_NOMEM; + } + + rc = sqlite3Fts3SegReaderCursor(pFts3, 0, FTS3_SEGCURSOR_ALL, + pCsr->filter.zTerm, pCsr->filter.nTerm, 0, isScan, &pCsr->csr + ); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3SegReaderStart(pFts3, &pCsr->csr, &pCsr->filter); + } + + if( rc==SQLITE_OK ) rc = fts3auxNextMethod(pCursor); + return rc; +} + +/* +** xEof - Return true if the cursor is at EOF, or false otherwise. +*/ +static int fts3auxEofMethod(sqlite3_vtab_cursor *pCursor){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + return pCsr->isEof; +} + +/* +** xColumn - Return a column value. +*/ +static int fts3auxColumnMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pContext, /* Context for sqlite3_result_xxx() calls */ + int iCol /* Index of column to read value from */ +){ + Fts3auxCursor *p = (Fts3auxCursor *)pCursor; + + assert( p->isEof==0 ); + if( iCol==0 ){ /* Column "term" */ + sqlite3_result_text(pContext, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT); + }else if( iCol==1 ){ /* Column "col" */ + if( p->iCol ){ + sqlite3_result_int(pContext, p->iCol-1); + }else{ + sqlite3_result_text(pContext, "*", -1, SQLITE_STATIC); + } + }else if( iCol==2 ){ /* Column "documents" */ + sqlite3_result_int64(pContext, p->aStat[p->iCol].nDoc); + }else{ /* Column "occurrences" */ + sqlite3_result_int64(pContext, p->aStat[p->iCol].nOcc); + } + + return SQLITE_OK; +} + +/* +** xRowid - Return the current rowid for the cursor. +*/ +static int fts3auxRowidMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite_int64 *pRowid /* OUT: Rowid value */ +){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + *pRowid = pCsr->iRowid; + return SQLITE_OK; +} + +/* +** Register the fts3aux module with database connection db. Return SQLITE_OK +** if successful or an error code if sqlite3_create_module() fails. +*/ +SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db){ + static const sqlite3_module fts3aux_module = { + 0, /* iVersion */ + fts3auxConnectMethod, /* xCreate */ + fts3auxConnectMethod, /* xConnect */ + fts3auxBestIndexMethod, /* xBestIndex */ + fts3auxDisconnectMethod, /* xDisconnect */ + fts3auxDisconnectMethod, /* xDestroy */ + fts3auxOpenMethod, /* xOpen */ + fts3auxCloseMethod, /* xClose */ + fts3auxFilterMethod, /* xFilter */ + fts3auxNextMethod, /* xNext */ + fts3auxEofMethod, /* xEof */ + fts3auxColumnMethod, /* xColumn */ + fts3auxRowidMethod, /* xRowid */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindFunction */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ + }; + int rc; /* Return code */ + + rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0); + return rc; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_aux.c ********************************************/ /************** Begin file fts3_expr.c ***************************************/ /* ** 2008 Nov 28 @@ -102347,14 +119550,14 @@ SQLITE_API int sqlite3_extension_init( ****************************************************************************** ** ** This module contains code that implements a parser for fts3 query strings -** (the right-hand argument to the MATCH operator). Because the supported +** (the right-hand argument to the MATCH operator). Because the supported ** syntax is relatively simple, the whole tokenizer/parser system is -** hand-coded. +** hand-coded. */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* -** By default, this module parses the legacy syntax that has been +** By default, this module parses the legacy syntax that has been ** traditionally used by fts3. Or, if SQLITE_ENABLE_FTS3_PARENTHESIS ** is defined, then it uses the new syntax. The differences between ** the new and the old syntaxes are: @@ -102363,7 +119566,7 @@ SQLITE_API int sqlite3_extension_init( ** ** b) The new syntax supports the AND and NOT operators. The old does not. ** -** c) The old syntax supports the "-" token qualifier. This is not +** c) The old syntax supports the "-" token qualifier. This is not ** supported by the new syntax (it is replaced by the NOT operator). ** ** d) When using the old syntax, the OR operator has a greater precedence @@ -102372,7 +119575,7 @@ SQLITE_API int sqlite3_extension_init( ** ** If compiled with SQLITE_TEST defined, then this module exports the ** symbol "int sqlite3_fts3_enable_parentheses". Setting this variable -** to zero causes the module to use the old syntax. If it is set to +** to zero causes the module to use the old syntax. If it is set to ** non-zero the new syntax is activated. This is so both syntaxes can ** be tested using a single build of testfixture. ** @@ -102401,7 +119604,7 @@ SQLITE_API int sqlite3_extension_init( #ifdef SQLITE_TEST SQLITE_API int sqlite3_fts3_enable_parentheses = 0; #else -# ifdef SQLITE_ENABLE_FTS3_PARENTHESIS +# ifdef SQLITE_ENABLE_FTS3_PARENTHESIS # define sqlite3_fts3_enable_parentheses 1 # else # define sqlite3_fts3_enable_parentheses 0 @@ -102413,19 +119616,30 @@ SQLITE_API int sqlite3_fts3_enable_parentheses = 0; */ #define SQLITE_FTS3_DEFAULT_NEAR_PARAM 10 +/* #include <string.h> */ +/* #include <assert.h> */ +/* +** isNot: +** This variable is used by function getNextNode(). When getNextNode() is +** called, it sets ParseContext.isNot to true if the 'next node' is a +** FTSQUERY_PHRASE with a unary "-" attached to it. i.e. "mysql" in the +** FTS3 query "sqlite -mysql". Otherwise, ParseContext.isNot is set to +** zero. +*/ typedef struct ParseContext ParseContext; struct ParseContext { sqlite3_tokenizer *pTokenizer; /* Tokenizer module */ const char **azCol; /* Array of column names for fts3 table */ int nCol; /* Number of entries in azCol[] */ int iDefaultCol; /* Default column to query */ + int isNot; /* True if getNextNode() sees a unary - */ sqlite3_context *pCtx; /* Write error message here */ int nNest; /* Number of nested brackets */ }; /* -** This function is equivalent to the standard isspace() function. +** This function is equivalent to the standard isspace() function. ** ** The standard isspace() can be awkward to use safely, because although it ** is defined to accept an argument of type int, its behaviour when passed @@ -102436,16 +119650,28 @@ struct ParseContext { ** negative values). */ static int fts3isspace(char c){ - return (c&0x80)==0 ? isspace(c) : 0; + return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f'; +} + +/* +** Allocate nByte bytes of memory using sqlite3_malloc(). If successful, +** zero the memory before returning a pointer to it. If unsuccessful, +** return NULL. +*/ +static void *fts3MallocZero(int nByte){ + void *pRet = sqlite3_malloc(nByte); + if( pRet ) memset(pRet, 0, nByte); + return pRet; } + /* ** Extract the next token from buffer z (length n) using the tokenizer ** and other information (column names etc.) in pParse. Create an Fts3Expr ** structure of type FTSQUERY_PHRASE containing a phrase consisting of this ** single token and set *ppExpr to point to it. If the end of the buffer is ** reached before a token is found, set *ppExpr to zero. It is the -** responsibility of the caller to eventually deallocate the allocated +** responsibility of the caller to eventually deallocate the allocated ** Fts3Expr structure (if any) by passing it to sqlite3_free(). ** ** Return SQLITE_OK if successful, or SQLITE_NOMEM if a memory allocation @@ -102476,11 +119702,10 @@ static int getNextToken( if( rc==SQLITE_OK ){ nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; - pRet = (Fts3Expr *)sqlite3_malloc(nByte); + pRet = (Fts3Expr *)fts3MallocZero(nByte); if( !pRet ){ rc = SQLITE_NOMEM; }else{ - memset(pRet, 0, nByte); pRet->eType = FTSQUERY_PHRASE; pRet->pPhrase = (Fts3Phrase *)&pRet[1]; pRet->pPhrase->nToken = 1; @@ -102494,7 +119719,7 @@ static int getNextToken( iEnd++; } if( !sqlite3_fts3_enable_parentheses && iStart>0 && z[iStart-1]=='-' ){ - pRet->pPhrase->isNot = 1; + pParse->isNot = 1; } } nConsumed = iEnd; @@ -102502,7 +119727,7 @@ static int getNextToken( pModule->xClose(pCursor); } - + *pnConsumed = nConsumed; *ppExpr = pRet; return rc; @@ -102525,7 +119750,7 @@ static void *fts3ReallocOrFree(void *pOrig, int nNew){ ** Buffer zInput, length nInput, contains the contents of a quoted string ** that appeared as part of an fts3 query expression. Neither quote character ** is included in the buffer. This function attempts to tokenize the entire -** input buffer and create an Fts3Expr structure of type FTSQUERY_PHRASE +** input buffer and create an Fts3Expr structure of type FTSQUERY_PHRASE ** containing the results. ** ** If successful, SQLITE_OK is returned and *ppExpr set to point at the @@ -102546,35 +119771,55 @@ static int getNextString( char *zTemp = 0; int nTemp = 0; + const int nSpace = sizeof(Fts3Expr) + sizeof(Fts3Phrase); + int nToken = 0; + + /* The final Fts3Expr data structure, including the Fts3Phrase, + ** Fts3PhraseToken structures token buffers are all stored as a single + ** allocation so that the expression can be freed with a single call to + ** sqlite3_free(). Setting this up requires a two pass approach. + ** + ** The first pass, in the block below, uses a tokenizer cursor to iterate + ** through the tokens in the expression. This pass uses fts3ReallocOrFree() + ** to assemble data in two dynamic buffers: + ** + ** Buffer p: Points to the Fts3Expr structure, followed by the Fts3Phrase + ** structure, followed by the array of Fts3PhraseToken + ** structures. This pass only populates the Fts3PhraseToken array. + ** + ** Buffer zTemp: Contains copies of all tokens. + ** + ** The second pass, in the block that begins "if( rc==SQLITE_DONE )" below, + ** appends buffer zTemp to buffer p, and fills in the Fts3Expr and Fts3Phrase + ** structures. + */ rc = pModule->xOpen(pTokenizer, zInput, nInput, &pCursor); if( rc==SQLITE_OK ){ int ii; pCursor->pTokenizer = pTokenizer; for(ii=0; rc==SQLITE_OK; ii++){ - const char *zToken; - int nToken, iBegin, iEnd, iPos; - rc = pModule->xNext(pCursor, &zToken, &nToken, &iBegin, &iEnd, &iPos); + const char *zByte; + int nByte, iBegin, iEnd, iPos; + rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos); if( rc==SQLITE_OK ){ - int nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase); - p = fts3ReallocOrFree(p, nByte+ii*sizeof(struct PhraseToken)); - zTemp = fts3ReallocOrFree(zTemp, nTemp + nToken); - if( !p || !zTemp ){ - goto no_mem; - } - if( ii==0 ){ - memset(p, 0, nByte); - p->pPhrase = (Fts3Phrase *)&p[1]; - } - p->pPhrase = (Fts3Phrase *)&p[1]; - p->pPhrase->nToken = ii+1; - p->pPhrase->aToken[ii].n = nToken; - memcpy(&zTemp[nTemp], zToken, nToken); - nTemp += nToken; - if( iEnd<nInput && zInput[iEnd]=='*' ){ - p->pPhrase->aToken[ii].isPrefix = 1; - }else{ - p->pPhrase->aToken[ii].isPrefix = 0; - } + Fts3PhraseToken *pToken; + + p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken)); + if( !p ) goto no_mem; + + zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte); + if( !zTemp ) goto no_mem; + + assert( nToken==ii ); + pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii]; + memset(pToken, 0, sizeof(Fts3PhraseToken)); + + memcpy(&zTemp[nTemp], zByte, nByte); + nTemp += nByte; + + pToken->n = nByte; + pToken->isPrefix = (iEnd<nInput && zInput[iEnd]=='*'); + nToken = ii+1; } } @@ -102584,28 +119829,24 @@ static int getNextString( if( rc==SQLITE_DONE ){ int jj; - char *zNew = NULL; - int nNew = 0; - int nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase); - nByte += (p?(p->pPhrase->nToken-1):0) * sizeof(struct PhraseToken); - p = fts3ReallocOrFree(p, nByte + nTemp); - if( !p ){ - goto no_mem; - } - if( zTemp ){ - zNew = &(((char *)p)[nByte]); - memcpy(zNew, zTemp, nTemp); - }else{ - memset(p, 0, nByte+nTemp); - } + char *zBuf = 0; + + p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp); + if( !p ) goto no_mem; + memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p); + p->eType = FTSQUERY_PHRASE; p->pPhrase = (Fts3Phrase *)&p[1]; + p->pPhrase->iColumn = pParse->iDefaultCol; + p->pPhrase->nToken = nToken; + + zBuf = (char *)&p->pPhrase->aToken[nToken]; + memcpy(zBuf, zTemp, nTemp); + sqlite3_free(zTemp); + for(jj=0; jj<p->pPhrase->nToken; jj++){ - p->pPhrase->aToken[jj].z = &zNew[nNew]; - nNew += p->pPhrase->aToken[jj].n; + p->pPhrase->aToken[jj].z = zBuf; + zBuf += p->pPhrase->aToken[jj].n; } - sqlite3_free(zTemp); - p->eType = FTSQUERY_PHRASE; - p->pPhrase->iColumn = pParse->iDefaultCol; rc = SQLITE_OK; } @@ -102629,7 +119870,7 @@ no_mem: static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *); /* -** The output variable *ppExpr is populated with an allocated Fts3Expr +** The output variable *ppExpr is populated with an allocated Fts3Expr ** structure, or set to 0 if the end of the input buffer is reached. ** ** Returns an SQLite error code. SQLITE_OK if everything works, SQLITE_NOMEM @@ -102662,8 +119903,10 @@ static int getNextNode( const char *zInput = z; int nInput = n; + pParse->isNot = 0; + /* Skip over any whitespace before checking for a keyword, an open or - ** close bracket, or a quoted string. + ** close bracket, or a quoted string. */ while( nInput>0 && fts3isspace(*zInput) ){ nInput--; @@ -102699,17 +119942,16 @@ static int getNextNode( /* At this point this is probably a keyword. But for that to be true, ** the next byte must contain either whitespace, an open or close - ** parenthesis, a quote character, or EOF. + ** parenthesis, a quote character, or EOF. */ cNext = zInput[nKey]; - if( fts3isspace(cNext) + if( fts3isspace(cNext) || cNext=='"' || cNext=='(' || cNext==')' || cNext==0 ){ - pRet = (Fts3Expr *)sqlite3_malloc(sizeof(Fts3Expr)); + pRet = (Fts3Expr *)fts3MallocZero(sizeof(Fts3Expr)); if( !pRet ){ return SQLITE_NOMEM; } - memset(pRet, 0, sizeof(Fts3Expr)); pRet->eType = pKey->eType; pRet->nNear = nNear; *ppExpr = pRet; @@ -102727,7 +119969,6 @@ static int getNextNode( if( sqlite3_fts3_enable_parentheses ){ if( *zInput=='(' ){ int nConsumed; - int rc; pParse->nNest++; rc = fts3ExprParse(pParse, &zInput[1], nInput-1, ppExpr, &nConsumed); if( rc==SQLITE_OK && !*ppExpr ){ @@ -102736,7 +119977,7 @@ static int getNextNode( *pnConsumed = (int)((zInput - z) + 1 + nConsumed); return rc; } - + /* Check for a close bracket. */ if( *zInput==')' ){ pParse->nNest--; @@ -102760,15 +120001,15 @@ static int getNextNode( } - /* If control flows to this point, this must be a regular token, or + /* If control flows to this point, this must be a regular token, or ** the end of the input. Read a regular token using the sqlite3_tokenizer ** interface. Before doing so, figure out if there is an explicit - ** column specifier for the token. + ** column specifier for the token. ** ** TODO: Strangely, it is not possible to associate a column specifier ** with a quoted phrase, only with a single token. Not sure if this was ** an implementation artifact or an intentional decision when fts3 was - ** first implemented. Whichever it was, this module duplicates the + ** first implemented. Whichever it was, this module duplicates the ** limitation. */ iCol = pParse->iDefaultCol; @@ -102776,8 +120017,8 @@ static int getNextNode( for(ii=0; ii<pParse->nCol; ii++){ const char *zStr = pParse->azCol[ii]; int nStr = (int)strlen(zStr); - if( nInput>nStr && zInput[nStr]==':' - && sqlite3_strnicmp(zStr, zInput, nStr)==0 + if( nInput>nStr && zInput[nStr]==':' + && sqlite3_strnicmp(zStr, zInput, nStr)==0 ){ iCol = ii; iColLen = (int)((zInput - z) + nStr + 1); @@ -102822,7 +120063,7 @@ static int opPrecedence(Fts3Expr *p){ } /* -** Argument ppHead contains a pointer to the current head of a query +** Argument ppHead contains a pointer to the current head of a query ** expression tree being parsed. pPrev is the expression node most recently ** inserted into the tree. This function adds pNew, which is always a binary ** operator node, into the expression tree based on the relative precedence @@ -102852,7 +120093,7 @@ static void insertBinaryOperator( /* ** Parse the fts3 query expression found in buffer z, length n. This function -** returns either when the end of the buffer is reached or an unmatched +** returns either when the end of the buffer is reached or an unmatched ** closing bracket - ')' - is encountered. ** ** If successful, SQLITE_OK is returned, *ppExpr is set to point to the @@ -102881,17 +120122,16 @@ static int fts3ExprParse( if( rc==SQLITE_OK ){ int isPhrase; - if( !sqlite3_fts3_enable_parentheses - && p->eType==FTSQUERY_PHRASE && p->pPhrase->isNot + if( !sqlite3_fts3_enable_parentheses + && p->eType==FTSQUERY_PHRASE && pParse->isNot ){ /* Create an implicit NOT operator. */ - Fts3Expr *pNot = sqlite3_malloc(sizeof(Fts3Expr)); + Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr)); if( !pNot ){ sqlite3Fts3ExprFree(p); rc = SQLITE_NOMEM; goto exprparse_out; } - memset(pNot, 0, sizeof(Fts3Expr)); pNot->eType = FTSQUERY_NOT; pNot->pRight = p; if( pNotBranch ){ @@ -102901,7 +120141,6 @@ static int fts3ExprParse( p = pPrev; }else{ int eType = p->eType; - assert( eType!=FTSQUERY_PHRASE || !p->pPhrase->isNot ); isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); /* The isRequirePhrase variable is set to true if a phrase or @@ -102914,18 +120153,17 @@ static int fts3ExprParse( rc = SQLITE_ERROR; goto exprparse_out; } - + if( isPhrase && !isRequirePhrase ){ /* Insert an implicit AND operator. */ Fts3Expr *pAnd; assert( pRet && pPrev ); - pAnd = sqlite3_malloc(sizeof(Fts3Expr)); + pAnd = fts3MallocZero(sizeof(Fts3Expr)); if( !pAnd ){ sqlite3Fts3ExprFree(p); rc = SQLITE_NOMEM; goto exprparse_out; } - memset(pAnd, 0, sizeof(Fts3Expr)); pAnd->eType = FTSQUERY_AND; insertBinaryOperator(&pRet, pPrev, pAnd); pPrev = pAnd; @@ -102948,7 +120186,7 @@ static int fts3ExprParse( rc = SQLITE_ERROR; goto exprparse_out; } - + if( isPhrase ){ if( pRet ){ assert( pPrev && pPrev->pLeft && pPrev->pRight==0 ); @@ -103016,7 +120254,7 @@ exprparse_out: ** The first parameter, pTokenizer, is passed the fts3 tokenizer module to ** use to normalize query tokens while parsing the expression. The azCol[] ** array, which is assumed to contain nCol entries, should contain the names -** of each column in the target fts3 table, in order from left to right. +** of each column in the target fts3 table, in order from left to right. ** Column names must be nul-terminated strings. ** ** The iDefaultCol parameter should be passed the index of the table column @@ -103065,9 +120303,11 @@ SQLITE_PRIVATE int sqlite3Fts3ExprParse( */ SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *p){ if( p ){ + assert( p->eType==FTSQUERY_PHRASE || p->pPhrase==0 ); sqlite3Fts3ExprFree(p->pLeft); sqlite3Fts3ExprFree(p->pRight); - sqlite3_free(p->aDoclist); + sqlite3Fts3EvalPhraseCleanup(p->pPhrase); + sqlite3_free(p->aMI); sqlite3_free(p); } } @@ -103079,13 +120319,14 @@ SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *p){ #ifdef SQLITE_TEST +/* #include <stdio.h> */ /* ** Function to query the hash-table of tokenizers (see README.tokenizers). */ static int queryTestTokenizer( - sqlite3 *db, - const char *zName, + sqlite3 *db, + const char *zName, const sqlite3_tokenizer_module **pp ){ int rc; @@ -103109,51 +120350,57 @@ static int queryTestTokenizer( } /* -** This function is part of the test interface for the query parser. It -** writes a text representation of the query expression pExpr into the -** buffer pointed to by argument zBuf. It is assumed that zBuf is large -** enough to store the required text representation. +** Return a pointer to a buffer containing a text representation of the +** expression passed as the first argument. The buffer is obtained from +** sqlite3_malloc(). It is the responsibility of the caller to use +** sqlite3_free() to release the memory. If an OOM condition is encountered, +** NULL is returned. +** +** If the second argument is not NULL, then its contents are prepended to +** the returned expression text and then freed using sqlite3_free(). */ -static void exprToString(Fts3Expr *pExpr, char *zBuf){ +static char *exprToString(Fts3Expr *pExpr, char *zBuf){ switch( pExpr->eType ){ case FTSQUERY_PHRASE: { Fts3Phrase *pPhrase = pExpr->pPhrase; int i; - zBuf += sprintf(zBuf, "PHRASE %d %d", pPhrase->iColumn, pPhrase->isNot); - for(i=0; i<pPhrase->nToken; i++){ - zBuf += sprintf(zBuf," %.*s",pPhrase->aToken[i].n,pPhrase->aToken[i].z); - zBuf += sprintf(zBuf,"%s", (pPhrase->aToken[i].isPrefix?"+":"")); + zBuf = sqlite3_mprintf( + "%zPHRASE %d 0", zBuf, pPhrase->iColumn); + for(i=0; zBuf && i<pPhrase->nToken; i++){ + zBuf = sqlite3_mprintf("%z %.*s%s", zBuf, + pPhrase->aToken[i].n, pPhrase->aToken[i].z, + (pPhrase->aToken[i].isPrefix?"+":"") + ); } - return; + return zBuf; } case FTSQUERY_NEAR: - zBuf += sprintf(zBuf, "NEAR/%d ", pExpr->nNear); + zBuf = sqlite3_mprintf("%zNEAR/%d ", zBuf, pExpr->nNear); break; case FTSQUERY_NOT: - zBuf += sprintf(zBuf, "NOT "); + zBuf = sqlite3_mprintf("%zNOT ", zBuf); break; case FTSQUERY_AND: - zBuf += sprintf(zBuf, "AND "); + zBuf = sqlite3_mprintf("%zAND ", zBuf); break; case FTSQUERY_OR: - zBuf += sprintf(zBuf, "OR "); + zBuf = sqlite3_mprintf("%zOR ", zBuf); break; } - zBuf += sprintf(zBuf, "{"); - exprToString(pExpr->pLeft, zBuf); - zBuf += strlen(zBuf); - zBuf += sprintf(zBuf, "} "); + if( zBuf ) zBuf = sqlite3_mprintf("%z{", zBuf); + if( zBuf ) zBuf = exprToString(pExpr->pLeft, zBuf); + if( zBuf ) zBuf = sqlite3_mprintf("%z} {", zBuf); - zBuf += sprintf(zBuf, "{"); - exprToString(pExpr->pRight, zBuf); - zBuf += strlen(zBuf); - zBuf += sprintf(zBuf, "}"); + if( zBuf ) zBuf = exprToString(pExpr->pRight, zBuf); + if( zBuf ) zBuf = sqlite3_mprintf("%z}", zBuf); + + return zBuf; } /* -** This is the implementation of a scalar SQL function used to test the +** This is the implementation of a scalar SQL function used to test the ** expression parser. It should be called as follows: ** ** fts3_exprtest(<tokenizer>, <expr>, <column 1>, ...); @@ -103180,10 +120427,11 @@ static void fts3ExprTest( int nCol; int ii; Fts3Expr *pExpr; + char *zBuf = 0; sqlite3 *db = sqlite3_context_db_handle(context); if( argc<3 ){ - sqlite3_result_error(context, + sqlite3_result_error(context, "Usage: fts3_exprtest(tokenizer, expr, col1, ...", -1 ); return; @@ -103222,18 +120470,17 @@ static void fts3ExprTest( rc = sqlite3Fts3ExprParse( pTokenizer, azCol, nCol, nCol, zExpr, nExpr, &pExpr ); - if( rc==SQLITE_NOMEM ){ + if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){ + sqlite3_result_error(context, "Error parsing expression", -1); + }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){ sqlite3_result_error_nomem(context); - goto exprtest_out; - }else if( rc==SQLITE_OK ){ - char zBuf[4096]; - exprToString(pExpr, zBuf); - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); - sqlite3Fts3ExprFree(pExpr); }else{ - sqlite3_result_error(context, "Error parsing expression", -1); + sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + sqlite3_free(zBuf); } + sqlite3Fts3ExprFree(pExpr); + exprtest_out: if( pModule && pTokenizer ){ rc = pModule->xDestroy(pTokenizer); @@ -103242,8 +120489,8 @@ exprtest_out: } /* -** Register the query expression parser test function fts3_exprtest() -** with database connection db. +** Register the query expression parser test function fts3_exprtest() +** with database connection db. */ SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3* db){ return sqlite3_create_function( @@ -103283,6 +120530,9 @@ SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3* db){ */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) +/* #include <assert.h> */ +/* #include <stdlib.h> */ +/* #include <string.h> */ /* @@ -103303,8 +120553,8 @@ static void fts3HashFree(void *p){ ** fields of the Hash structure. ** ** "pNew" is a pointer to the hash table that is to be initialized. -** keyClass is one of the constants -** FTS3_HASH_BINARY or FTS3_HASH_STRING. The value of keyClass +** keyClass is one of the constants +** FTS3_HASH_BINARY or FTS3_HASH_STRING. The value of keyClass ** determines what kind of key the hash table will use. "copyKey" is ** true if the hash table should make its own private copy of keys and ** false if it should just use the supplied pointer. @@ -103381,7 +120631,7 @@ static int fts3BinCompare(const void *pKey1, int n1, const void *pKey2, int n2){ /* ** Return a pointer to the appropriate hash function given the key class. ** -** The C syntax in this function definition may be unfamilar to some +** The C syntax in this function definition may be unfamilar to some ** programmers, so we provide the following additional explanation: ** ** The name of the function is "ftsHashFunction". The function takes a @@ -103441,7 +120691,7 @@ static void fts3HashInsertElement( /* Resize the hash table so that it cantains "new_size" buckets. -** "new_size" must be a power of 2. The hash table might fail +** "new_size" must be a power of 2. The hash table might fail ** to resize if sqliteMalloc() fails. ** ** Return non-zero if a memory allocation error occurs. @@ -103486,7 +120736,7 @@ static Fts3HashElem *fts3FindElementByHash( count = pEntry->count; xCompare = ftsCompareFunction(pH->keyClass); while( count-- && elem ){ - if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){ + if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){ return elem; } elem = elem->next; @@ -103505,7 +120755,7 @@ static void fts3RemoveElementByHash( ){ struct _fts3ht *pEntry; if( elem->prev ){ - elem->prev->next = elem->next; + elem->prev->next = elem->next; }else{ pH->first = elem->next; } @@ -103533,8 +120783,8 @@ static void fts3RemoveElementByHash( } SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem( - const Fts3Hash *pH, - const void *pKey, + const Fts3Hash *pH, + const void *pKey, int nKey ){ int h; /* A hash on key */ @@ -103548,7 +120798,7 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem( return fts3FindElementByHash(pH,pKey,nKey, h & (pH->htsize-1)); } -/* +/* ** Attempt to locate an element of the hash table pH with a key ** that matches pKey,nKey. Return the data for this element if it is ** found, or NULL if there is no match. @@ -103663,7 +120913,10 @@ SQLITE_PRIVATE void *sqlite3Fts3HashInsert( */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - +/* #include <assert.h> */ +/* #include <stdlib.h> */ +/* #include <stdio.h> */ +/* #include <string.h> */ /* @@ -103717,7 +120970,7 @@ static int porterDestroy(sqlite3_tokenizer *pTokenizer){ /* ** Prepare to begin tokenizing a particular string. The input ** string to be tokenized is zInput[0..nInput-1]. A cursor -** used to incrementally tokenize this string is returned in +** used to incrementally tokenize this string is returned in ** *ppCursor. */ static int porterOpen( @@ -103770,7 +121023,7 @@ static const char cType[] = { /* ** isConsonant() and isVowel() determine if their first character in ** the string they point to is a consonant or a vowel, according -** to Porter ruls. +** to Porter ruls. ** ** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'. ** 'Y' is a consonant unless it follows another consonant, @@ -103890,11 +121143,11 @@ static int star_oh(const char *z){ /* ** If the word ends with zFrom and xCond() is true for the stem -** of the word that preceeds the zFrom ending, then change the +** of the word that preceeds the zFrom ending, then change the ** ending to zTo. ** ** The input word *pz and zFrom are both in reverse order. zTo -** is in normal order. +** is in normal order. ** ** Return TRUE if zFrom matches. Return FALSE if zFrom does not ** match. Not that TRUE is returned even if xCond() fails and @@ -103963,9 +121216,9 @@ static void copy_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){ ** word contains digits, 3 bytes are taken from the beginning and ** 3 bytes from the end. For long words without digits, 10 bytes ** are taken from each end. US-ASCII case folding still applies. -** -** If the input word contains not digits but does characters not -** in [a-zA-Z] then no stemming is attempted and this routine just +** +** If the input word contains not digits but does characters not +** in [a-zA-Z] then no stemming is attempted and this routine just ** copies the input into the input into the output with US-ASCII ** case folding. ** @@ -103976,7 +121229,7 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){ int i, j; char zReverse[28]; char *z, *z2; - if( nIn<3 || nIn>=sizeof(zReverse)-7 ){ + if( nIn<3 || nIn>=(int)sizeof(zReverse)-7 ){ /* The word is too big or too small for the porter stemmer. ** Fallback to the copy stemmer */ copy_stemmer(zIn, nIn, zOut, pnOut); @@ -104010,11 +121263,11 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){ } } - /* Step 1b */ + /* Step 1b */ z2 = z; if( stem(&z, "dee", "ee", m_gt_0) ){ /* Do nothing. The work was all in the test */ - }else if( + }else if( (stem(&z, "gni", "", hasVowel) || stem(&z, "de", "", hasVowel)) && z!=z2 ){ @@ -104307,13 +121560,11 @@ SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule( */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) -#ifndef SQLITE_CORE - SQLITE_EXTENSION_INIT1 -#endif - +/* #include <assert.h> */ +/* #include <string.h> */ /* -** Implementation of the SQL scalar function for accessing the underlying +** Implementation of the SQL scalar function for accessing the underlying ** hash table. This function may be called as follows: ** ** SELECT <function-name>(<key-name>); @@ -104375,7 +121626,7 @@ static void scalarFunc( sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT); } -static int fts3IsIdChar(char c){ +SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char c){ static const char isFtsIdChar[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ @@ -104413,9 +121664,9 @@ SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *zStr, int *pn){ break; default: - if( fts3IsIdChar(*z1) ){ + if( sqlite3Fts3IsIdChar(*z1) ){ z2 = &z1[1]; - while( fts3IsIdChar(*z2) ) z2++; + while( sqlite3Fts3IsIdChar(*z2) ) z2++; }else{ z1++; } @@ -104428,38 +121679,26 @@ SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *zStr, int *pn){ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( Fts3Hash *pHash, /* Tokenizer hash table */ - const char *zArg, /* Possible tokenizer specification */ + const char *zArg, /* Tokenizer name */ sqlite3_tokenizer **ppTok, /* OUT: Tokenizer (if applicable) */ - const char **pzTokenizer, /* OUT: Set to zArg if is tokenizer */ char **pzErr /* OUT: Set to malloced error message */ ){ int rc; char *z = (char *)zArg; - int n; + int n = 0; char *zCopy; char *zEnd; /* Pointer to nul-term of zCopy */ sqlite3_tokenizer_module *m; - if( !z ){ - zCopy = sqlite3_mprintf("simple"); - }else{ - if( sqlite3_strnicmp(z, "tokenize", 8) || fts3IsIdChar(z[8])){ - return SQLITE_OK; - } - zCopy = sqlite3_mprintf("%s", &z[8]); - *pzTokenizer = zArg; - } - if( !zCopy ){ - return SQLITE_NOMEM; - } - + zCopy = sqlite3_mprintf("%s", zArg); + if( !zCopy ) return SQLITE_NOMEM; zEnd = &zCopy[strlen(zCopy)]; z = (char *)sqlite3Fts3NextToken(zCopy, &n); z[n] = '\0'; sqlite3Fts3Dequote(z); - m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, z, (int)strlen(z)+1); + m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1); if( !m ){ *pzErr = sqlite3_mprintf("unknown tokenizer: %s", z); rc = SQLITE_ERROR; @@ -104486,7 +121725,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( if( rc!=SQLITE_OK ){ *pzErr = sqlite3_mprintf("unknown tokenizer"); }else{ - (*ppTok)->pModule = m; + (*ppTok)->pModule = m; } sqlite3_free((void *)aArg); } @@ -104498,9 +121737,11 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( #ifdef SQLITE_TEST +/* #include <tcl.h> */ +/* #include <string.h> */ /* -** Implementation of a special SQL scalar function for testing tokenizers +** Implementation of a special SQL scalar function for testing tokenizers ** designed to be used in concert with the Tcl testing framework. This ** function must be called with two arguments: ** @@ -104513,9 +121754,9 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( ** ** The return value is a string that may be interpreted as a Tcl ** list. For each token in the <input-string>, three elements are -** added to the returned list. The first is the token position, the +** added to the returned list. The first is the token position, the ** second is the token text (folded, stemmed, etc.) and the third is the -** substring of <input-string> associated with the token. For example, +** substring of <input-string> associated with the token. For example, ** using the built-in "simple" tokenizer: ** ** SELECT fts_tokenizer_test('simple', 'I don't see how'); @@ -104523,7 +121764,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( ** will return the string: ** ** "{0 i I 1 dont don't 2 see see 3 how how}" -** +** */ static void testFunc( sqlite3_context *context, @@ -104615,8 +121856,8 @@ finish: static int registerTokenizer( - sqlite3 *db, - char *zName, + sqlite3 *db, + char *zName, const sqlite3_tokenizer_module *p ){ int rc; @@ -104637,8 +121878,8 @@ int registerTokenizer( static int queryTokenizer( - sqlite3 *db, - char *zName, + sqlite3 *db, + char *zName, const sqlite3_tokenizer_module **pp ){ int rc; @@ -104719,23 +121960,23 @@ static void intTestFunc( /* ** Set up SQL objects in database db used to access the contents of ** the hash table pointed to by argument pHash. The hash table must -** been initialised to use string keys, and to take a private copy +** been initialised to use string keys, and to take a private copy ** of the key when a value is inserted. i.e. by a call similar to: ** ** sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1); ** ** This function adds a scalar function (see header comment above ** scalarFunc() in this file for details) and, if ENABLE_TABLE is -** defined at compilation time, a temporary virtual table (see header -** comment above struct HashTableVtab) to the database schema. Both +** defined at compilation time, a temporary virtual table (see header +** comment above struct HashTableVtab) to the database schema. Both ** provide read/write access to the contents of *pHash. ** ** The third argument to this function, zName, is used as the name ** of both the scalar and, if created, the virtual table. */ SQLITE_PRIVATE int sqlite3Fts3InitHashTable( - sqlite3 *db, - Fts3Hash *pHash, + sqlite3 *db, + Fts3Hash *pHash, const char *zName ){ int rc = SQLITE_OK; @@ -104753,15 +121994,23 @@ SQLITE_PRIVATE int sqlite3Fts3InitHashTable( } #endif - if( SQLITE_OK!=rc - || SQLITE_OK!=(rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0)) - || SQLITE_OK!=(rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0)) + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0); + } + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0); + } #ifdef SQLITE_TEST - || SQLITE_OK!=(rc = sqlite3_create_function(db, zTest, 2, any, p, testFunc, 0, 0)) - || SQLITE_OK!=(rc = sqlite3_create_function(db, zTest, 3, any, p, testFunc, 0, 0)) - || SQLITE_OK!=(rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0)) + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zTest, 2, any, p, testFunc, 0, 0); + } + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zTest, 3, any, p, testFunc, 0, 0); + } + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0); + } #endif - ); #ifdef SQLITE_TEST sqlite3_free(zTest); @@ -104801,7 +122050,10 @@ SQLITE_PRIVATE int sqlite3Fts3InitHashTable( */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - +/* #include <assert.h> */ +/* #include <stdlib.h> */ +/* #include <stdio.h> */ +/* #include <string.h> */ typedef struct simple_tokenizer { @@ -104823,6 +122075,9 @@ typedef struct simple_tokenizer_cursor { static int simpleDelim(simple_tokenizer *t, unsigned char c){ return c<0x80 && t->delim[c]; } +static int fts3_isalnum(int x){ + return (x>='0' && x<='9') || (x>='A' && x<='Z') || (x>='a' && x<='z'); +} /* ** Create a new tokenizer instance. @@ -104857,7 +122112,7 @@ static int simpleCreate( /* Mark non-alphanumeric ASCII characters as delimiters */ int i; for(i=1; i<0x80; i++){ - t->delim[i] = !isalnum(i) ? -1 : 0; + t->delim[i] = !fts3_isalnum(i) ? -1 : 0; } } @@ -104876,7 +122131,7 @@ static int simpleDestroy(sqlite3_tokenizer *pTokenizer){ /* ** Prepare to begin tokenizing a particular string. The input ** string to be tokenized is pInput[0..nBytes-1]. A cursor -** used to incrementally tokenize this string is returned in +** used to incrementally tokenize this string is returned in ** *ppCursor. */ static int simpleOpen( @@ -104963,7 +122218,7 @@ static int simpleNext( ** case-insensitivity. */ unsigned char ch = p[iStartOffset+i]; - c->pToken[i] = (char)(ch<0x80 ? tolower(ch) : ch); + c->pToken[i] = (char)((ch>='A' && ch<='Z') ? ch-'A'+'a' : ch); } *ppToken = c->pToken; *pnBytes = n; @@ -105018,21 +122273,62 @@ SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule( ** This file is part of the SQLite FTS3 extension module. Specifically, ** this file contains code to insert, update and delete rows from FTS3 ** tables. It also contains code to merge FTS3 b-tree segments. Some -** of the sub-routines used to merge segments are also used by the query +** of the sub-routines used to merge segments are also used by the query ** code in fts3.c. */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) +/* #include <string.h> */ +/* #include <assert.h> */ +/* #include <stdlib.h> */ + +/* +** When full-text index nodes are loaded from disk, the buffer that they +** are loaded into has the following number of bytes of padding at the end +** of it. i.e. if a full-text index node is 900 bytes in size, then a buffer +** of 920 bytes is allocated for it. +** +** This means that if we have a pointer into a buffer containing node data, +** it is always safe to read up to two varints from it without risking an +** overread, even if the node data is corrupted. +*/ +#define FTS3_NODE_PADDING (FTS3_VARINT_MAX*2) + +/* +** Under certain circumstances, b-tree nodes (doclists) can be loaded into +** memory incrementally instead of all at once. This can be a big performance +** win (reduced IO and CPU) if SQLite stops calling the virtual table xNext() +** method before retrieving all query results (as may happen, for example, +** if a query has a LIMIT clause). +** +** Incremental loading is used for b-tree nodes FTS3_NODE_CHUNK_THRESHOLD +** bytes and larger. Nodes are loaded in chunks of FTS3_NODE_CHUNKSIZE bytes. +** The code is written so that the hard lower-limit for each of these values +** is 1. Clearly such small values would be inefficient, but can be useful +** for testing purposes. +** +** If this module is built with SQLITE_TEST defined, these constants may +** be overridden at runtime for testing purposes. File fts3_test.c contains +** a Tcl interface to read and write the values. +*/ +#ifdef SQLITE_TEST +int test_fts3_node_chunksize = (4*1024); +int test_fts3_node_chunk_threshold = (4*1024)*4; +# define FTS3_NODE_CHUNKSIZE test_fts3_node_chunksize +# define FTS3_NODE_CHUNK_THRESHOLD test_fts3_node_chunk_threshold +#else +# define FTS3_NODE_CHUNKSIZE (4*1024) +# define FTS3_NODE_CHUNK_THRESHOLD (FTS3_NODE_CHUNKSIZE*4) +#endif typedef struct PendingList PendingList; typedef struct SegmentNode SegmentNode; typedef struct SegmentWriter SegmentWriter; /* -** Data structure used while accumulating terms in the pending-terms hash -** table. The hash table entry maps from term (a string) to a malloc'd -** instance of this structure. +** An instance of the following data structure is used to build doclists +** incrementally. See function fts3PendingListAppend() for details. */ struct PendingList { int nData; @@ -105043,6 +122339,17 @@ struct PendingList { sqlite3_int64 iLastPos; }; + +/* +** Each cursor has a (possibly empty) linked list of the following objects. +*/ +struct Fts3DeferredToken { + Fts3PhraseToken *pToken; /* Pointer to corresponding expr token */ + int iCol; /* Column token must occur in */ + Fts3DeferredToken *pNext; /* Next in list of deferred tokens */ + PendingList *pList; /* Doclist is assembled here */ +}; + /* ** An instance of this structure is used to iterate through the terms on ** a contiguous set of segment b-tree leaf nodes. Although the details of @@ -105062,12 +122369,17 @@ struct PendingList { */ struct Fts3SegReader { int iIdx; /* Index within level, or 0x7FFFFFFF for PT */ - sqlite3_int64 iStartBlock; - sqlite3_int64 iEndBlock; - sqlite3_stmt *pStmt; /* SQL Statement to access leaf nodes */ + + sqlite3_int64 iStartBlock; /* Rowid of first leaf block to traverse */ + sqlite3_int64 iLeafEndBlock; /* Rowid of final leaf block to traverse */ + sqlite3_int64 iEndBlock; /* Rowid of final block in segment (or 0) */ + sqlite3_int64 iCurrentBlock; /* Current leaf block (or 0) */ + char *aNode; /* Pointer to node data (or NULL) */ int nNode; /* Size of buffer at aNode (or 0) */ - int nTermAlloc; /* Allocated size of zTerm buffer */ + int nPopulate; /* If >0, bytes of buffer aNode[] loaded */ + sqlite3_blob *pBlob; /* If not NULL, blob handle to read node */ + Fts3HashElem **ppNextElem; /* Variables set by fts3SegReaderNext(). These may be read directly @@ -105077,15 +122389,20 @@ struct Fts3SegReader { */ int nTerm; /* Number of bytes in current term */ char *zTerm; /* Pointer to current term */ + int nTermAlloc; /* Allocated size of zTerm buffer */ char *aDoclist; /* Pointer to doclist of current entry */ int nDoclist; /* Size of doclist in current entry */ - /* The following variables are used to iterate through the current doclist */ + /* The following variables are used by fts3SegReaderNextDocid() to iterate + ** through the current doclist (aDoclist/nDoclist). + */ char *pOffsetList; + int nOffsetList; /* For descending pending seg-readers only */ sqlite3_int64 iDocid; }; #define fts3SegReaderIsPending(p) ((p)->ppNextElem!=0) +#define fts3SegReaderIsRootOnly(p) ((p)->aNode==(char *)&(p)[1]) /* ** An instance of this structure is used to create a segment b-tree in the @@ -105118,6 +122435,14 @@ struct SegmentWriter { ** fts3NodeAddTerm() ** fts3NodeWrite() ** fts3NodeFree() +** +** When a b+tree is written to the database (either as a result of a merge +** or the pending-terms table being flushed), leaves are written into the +** database file as soon as they are completely populated. The interior of +** the tree is assembled in memory and written out only once all leaves have +** been populated and stored. This is Ok, as the b+-tree fanout is usually +** very large, meaning that the interior of the tree consumes relatively +** little memory. */ struct SegmentNode { SegmentNode *pParent; /* Parent node (or NULL for root node) */ @@ -105137,7 +122462,7 @@ struct SegmentNode { */ #define SQL_DELETE_CONTENT 0 #define SQL_IS_EMPTY 1 -#define SQL_DELETE_ALL_CONTENT 2 +#define SQL_DELETE_ALL_CONTENT 2 #define SQL_DELETE_ALL_SEGMENTS 3 #define SQL_DELETE_ALL_SEGDIR 4 #define SQL_DELETE_ALL_DOCSIZE 5 @@ -105148,18 +122473,22 @@ struct SegmentNode { #define SQL_NEXT_SEGMENTS_ID 10 #define SQL_INSERT_SEGDIR 11 #define SQL_SELECT_LEVEL 12 -#define SQL_SELECT_ALL_LEVEL 13 +#define SQL_SELECT_LEVEL_RANGE 13 #define SQL_SELECT_LEVEL_COUNT 14 -#define SQL_SELECT_SEGDIR_COUNT_MAX 15 -#define SQL_DELETE_SEGDIR_BY_LEVEL 16 +#define SQL_SELECT_SEGDIR_MAX_LEVEL 15 +#define SQL_DELETE_SEGDIR_LEVEL 16 #define SQL_DELETE_SEGMENTS_RANGE 17 #define SQL_CONTENT_INSERT 18 -#define SQL_GET_BLOCK 19 -#define SQL_DELETE_DOCSIZE 20 -#define SQL_REPLACE_DOCSIZE 21 -#define SQL_SELECT_DOCSIZE 22 -#define SQL_SELECT_DOCTOTAL 23 -#define SQL_REPLACE_DOCTOTAL 24 +#define SQL_DELETE_DOCSIZE 19 +#define SQL_REPLACE_DOCSIZE 20 +#define SQL_SELECT_DOCSIZE 21 +#define SQL_SELECT_DOCTOTAL 22 +#define SQL_REPLACE_DOCTOTAL 23 + +#define SQL_SELECT_ALL_PREFIX_LEVEL 24 +#define SQL_DELETE_ALL_TERMS_SEGDIR 25 + +#define SQL_DELETE_SEGDIR_RANGE 26 /* ** This function is used to obtain an SQLite prepared statement handle @@ -105168,7 +122497,7 @@ struct SegmentNode { ** Otherwise, an SQLite error code is returned and *pp is set to 0. ** ** If argument apVal is not NULL, then it must point to an array with -** at least as many entries as the requested statement has bound +** at least as many entries as the requested statement has bound ** parameters. The values are bound to the statements parameters before ** returning. */ @@ -105186,55 +122515,49 @@ static int fts3SqlStmt( /* 4 */ "DELETE FROM %Q.'%q_segdir'", /* 5 */ "DELETE FROM %Q.'%q_docsize'", /* 6 */ "DELETE FROM %Q.'%q_stat'", -/* 7 */ "SELECT * FROM %Q.'%q_content' WHERE rowid=?", +/* 7 */ "SELECT %s FROM %Q.'%q_content' AS x WHERE rowid=?", /* 8 */ "SELECT (SELECT max(idx) FROM %Q.'%q_segdir' WHERE level = ?) + 1", /* 9 */ "INSERT INTO %Q.'%q_segments'(blockid, block) VALUES(?, ?)", /* 10 */ "SELECT coalesce((SELECT max(blockid) FROM %Q.'%q_segments') + 1, 1)", /* 11 */ "INSERT INTO %Q.'%q_segdir' VALUES(?,?,?,?,?,?)", - /* Return segments in order from oldest to newest.*/ + /* Return segments in order from oldest to newest.*/ /* 12 */ "SELECT idx, start_block, leaves_end_block, end_block, root " "FROM %Q.'%q_segdir' WHERE level = ? ORDER BY idx ASC", /* 13 */ "SELECT idx, start_block, leaves_end_block, end_block, root " - "FROM %Q.'%q_segdir' ORDER BY level DESC, idx ASC", + "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?" + "ORDER BY level DESC, idx ASC", /* 14 */ "SELECT count(*) FROM %Q.'%q_segdir' WHERE level = ?", -/* 15 */ "SELECT count(*), max(level) FROM %Q.'%q_segdir'", +/* 15 */ "SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", /* 16 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ?", /* 17 */ "DELETE FROM %Q.'%q_segments' WHERE blockid BETWEEN ? AND ?", -/* 18 */ "INSERT INTO %Q.'%q_content' VALUES(%z)", -/* 19 */ "SELECT block FROM %Q.'%q_segments' WHERE blockid = ?", -/* 20 */ "DELETE FROM %Q.'%q_docsize' WHERE docid = ?", -/* 21 */ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", -/* 22 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?", -/* 23 */ "SELECT value FROM %Q.'%q_stat' WHERE id=0", -/* 24 */ "REPLACE INTO %Q.'%q_stat' VALUES(0,?)", +/* 18 */ "INSERT INTO %Q.'%q_content' VALUES(%s)", +/* 19 */ "DELETE FROM %Q.'%q_docsize' WHERE docid = ?", +/* 20 */ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", +/* 21 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?", +/* 22 */ "SELECT value FROM %Q.'%q_stat' WHERE id=0", +/* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(0,?)", +/* 24 */ "", +/* 25 */ "", + +/* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", + }; int rc = SQLITE_OK; sqlite3_stmt *pStmt; assert( SizeofArray(azSql)==SizeofArray(p->aStmt) ); assert( eStmt<SizeofArray(azSql) && eStmt>=0 ); - + pStmt = p->aStmt[eStmt]; if( !pStmt ){ char *zSql; if( eStmt==SQL_CONTENT_INSERT ){ - int i; /* Iterator variable */ - char *zVarlist; /* The "?, ?, ..." string */ - zVarlist = (char *)sqlite3_malloc(2*p->nColumn+2); - if( !zVarlist ){ - *pp = 0; - return SQLITE_NOMEM; - } - zVarlist[0] = '?'; - zVarlist[p->nColumn*2+1] = '\0'; - for(i=1; i<=p->nColumn; i++){ - zVarlist[i*2-1] = ','; - zVarlist[i*2] = '?'; - } - zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, zVarlist); + zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist); + }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){ + zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist, p->zDb, p->zName); }else{ zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName); } @@ -105258,6 +122581,51 @@ static int fts3SqlStmt( return rc; } +static int fts3SelectDocsize( + Fts3Table *pTab, /* FTS3 table handle */ + int eStmt, /* Either SQL_SELECT_DOCSIZE or DOCTOTAL */ + sqlite3_int64 iDocid, /* Docid to bind for SQL_SELECT_DOCSIZE */ + sqlite3_stmt **ppStmt /* OUT: Statement handle */ +){ + sqlite3_stmt *pStmt = 0; /* Statement requested from fts3SqlStmt() */ + int rc; /* Return code */ + + assert( eStmt==SQL_SELECT_DOCSIZE || eStmt==SQL_SELECT_DOCTOTAL ); + + rc = fts3SqlStmt(pTab, eStmt, &pStmt, 0); + if( rc==SQLITE_OK ){ + if( eStmt==SQL_SELECT_DOCSIZE ){ + sqlite3_bind_int64(pStmt, 1, iDocid); + } + rc = sqlite3_step(pStmt); + if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){ + rc = sqlite3_reset(pStmt); + if( rc==SQLITE_OK ) rc = SQLITE_CORRUPT_VTAB; + pStmt = 0; + }else{ + rc = SQLITE_OK; + } + } + + *ppStmt = pStmt; + return rc; +} + +SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal( + Fts3Table *pTab, /* Fts3 table handle */ + sqlite3_stmt **ppStmt /* OUT: Statement handle */ +){ + return fts3SelectDocsize(pTab, SQL_SELECT_DOCTOTAL, 0, ppStmt); +} + +SQLITE_PRIVATE int sqlite3Fts3SelectDocsize( + Fts3Table *pTab, /* Fts3 table handle */ + sqlite3_int64 iDocid, /* Docid to read size data for */ + sqlite3_stmt **ppStmt /* OUT: Statement handle */ +){ + return fts3SelectDocsize(pTab, SQL_SELECT_DOCSIZE, iDocid, ppStmt); +} + /* ** Similar to fts3SqlStmt(). Except, after binding the parameters in ** array apVal[] to the SQL statement identified by eStmt, the statement @@ -105275,7 +122643,7 @@ static void fts3SqlExec( sqlite3_stmt *pStmt; int rc; if( *pRC ) return; - rc = fts3SqlStmt(p, eStmt, &pStmt, apVal); + rc = fts3SqlStmt(p, eStmt, &pStmt, apVal); if( rc==SQLITE_OK ){ sqlite3_step(pStmt); rc = sqlite3_reset(pStmt); @@ -105285,48 +122653,39 @@ static void fts3SqlExec( /* -** Read a single block from the %_segments table. If the specified block -** does not exist, return SQLITE_CORRUPT. If some other error (malloc, IO -** etc.) occurs, return the appropriate SQLite error code. -** -** Otherwise, if successful, set *pzBlock to point to a buffer containing -** the block read from the database, and *pnBlock to the size of the read -** block in bytes. +** This function ensures that the caller has obtained a shared-cache +** table-lock on the %_content table. This is required before reading +** data from the fts3 table. If this lock is not acquired first, then +** the caller may end up holding read-locks on the %_segments and %_segdir +** tables, but no read-lock on the %_content table. If this happens +** a second connection will be able to write to the fts3 table, but +** attempting to commit those writes might return SQLITE_LOCKED or +** SQLITE_LOCKED_SHAREDCACHE (because the commit attempts to obtain +** write-locks on the %_segments and %_segdir ** tables). ** -** WARNING: The returned buffer is only valid until the next call to -** sqlite3Fts3ReadBlock(). +** We try to avoid this because if FTS3 returns any error when committing +** a transaction, the whole transaction will be rolled back. And this is +** not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. It can +** still happen if the user reads data directly from the %_segments or +** %_segdir tables instead of going through FTS3 though. */ -SQLITE_PRIVATE int sqlite3Fts3ReadBlock( - Fts3Table *p, - sqlite3_int64 iBlock, - char const **pzBlock, - int *pnBlock -){ - sqlite3_stmt *pStmt; - int rc = fts3SqlStmt(p, SQL_GET_BLOCK, &pStmt, 0); - if( rc!=SQLITE_OK ) return rc; - sqlite3_reset(pStmt); - - if( pzBlock ){ - sqlite3_bind_int64(pStmt, 1, iBlock); - rc = sqlite3_step(pStmt); - if( rc!=SQLITE_ROW ){ - return (rc==SQLITE_DONE ? SQLITE_CORRUPT : rc); - } +SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *p){ + int rc; /* Return code */ + sqlite3_stmt *pStmt; /* Statement used to obtain lock */ - *pnBlock = sqlite3_column_bytes(pStmt, 0); - *pzBlock = (char *)sqlite3_column_blob(pStmt, 0); - if( sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){ - return SQLITE_CORRUPT; - } + rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_null(pStmt, 1); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); } - return SQLITE_OK; + return rc; } /* ** Set *ppStmt to a statement handle that may be used to iterate through ** all rows in the %_segdir table, from oldest to newest. If successful, -** return SQLITE_OK. If an error occurs while preparing the statement, +** return SQLITE_OK. If an error occurs while preparing the statement, ** return an SQLite error code. ** ** There is only ever one instance of this SQL statement compiled for @@ -105340,8 +122699,35 @@ SQLITE_PRIVATE int sqlite3Fts3ReadBlock( ** 3: end_block ** 4: root */ -SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table *p, sqlite3_stmt **ppStmt){ - return fts3SqlStmt(p, SQL_SELECT_ALL_LEVEL, ppStmt, 0); +SQLITE_PRIVATE int sqlite3Fts3AllSegdirs( + Fts3Table *p, /* FTS3 table */ + int iIndex, /* Index for p->aIndex[] */ + int iLevel, /* Level to select */ + sqlite3_stmt **ppStmt /* OUT: Compiled statement */ +){ + int rc; + sqlite3_stmt *pStmt = 0; + + assert( iLevel==FTS3_SEGCURSOR_ALL || iLevel>=0 ); + assert( iLevel<FTS3_SEGDIR_MAXLEVEL ); + assert( iIndex>=0 && iIndex<p->nIndex ); + + if( iLevel<0 ){ + /* "SELECT * FROM %_segdir WHERE level BETWEEN ? AND ? ORDER BY ..." */ + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int(pStmt, 1, iIndex*FTS3_SEGDIR_MAXLEVEL); + sqlite3_bind_int(pStmt, 2, (iIndex+1)*FTS3_SEGDIR_MAXLEVEL-1); + } + }else{ + /* "SELECT * FROM %_segdir WHERE level = ? ORDER BY ..." */ + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int(pStmt, 1, iLevel+iIndex*FTS3_SEGDIR_MAXLEVEL); + } + } + *ppStmt = pStmt; + return rc; } @@ -105454,6 +122840,47 @@ static int fts3PendingListAppend( } /* +** Free a PendingList object allocated by fts3PendingListAppend(). +*/ +static void fts3PendingListDelete(PendingList *pList){ + sqlite3_free(pList); +} + +/* +** Add an entry to one of the pending-terms hash tables. +*/ +static int fts3PendingTermsAddOne( + Fts3Table *p, + int iCol, + int iPos, + Fts3Hash *pHash, /* Pending terms hash table to add entry to */ + const char *zToken, + int nToken +){ + PendingList *pList; + int rc = SQLITE_OK; + + pList = (PendingList *)fts3HashFind(pHash, zToken, nToken); + if( pList ){ + p->nPendingData -= (pList->nData + nToken + sizeof(Fts3HashElem)); + } + if( fts3PendingListAppend(&pList, p->iPrevDocid, iCol, iPos, &rc) ){ + if( pList==fts3HashInsert(pHash, zToken, nToken, pList) ){ + /* Malloc failed while inserting the new entry. This can only + ** happen if there was no previous entry for this token. + */ + assert( 0==fts3HashFind(pHash, zToken, nToken) ); + sqlite3_free(pList); + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + p->nPendingData += (pList->nData + nToken + sizeof(Fts3HashElem)); + } + return rc; +} + +/* ** Tokenize the nul-terminated string zText and add all tokens to the ** pending-terms hash-table. The docid used is that currently stored in ** p->iPrevDocid, and the column is specified by argument iCol. @@ -105461,10 +122888,10 @@ static int fts3PendingListAppend( ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code. */ static int fts3PendingTermsAdd( - Fts3Table *p, /* FTS table into which text will be inserted */ - const char *zText, /* Text of document to be inseted */ - int iCol, /* Column number into which text is inserted */ - u32 *pnWord /* OUT: Number of tokens inserted */ + Fts3Table *p, /* Table into which text will be inserted */ + const char *zText, /* Text of document to be inserted */ + int iCol, /* Column into which text is being inserted */ + u32 *pnWord /* OUT: Number of tokens inserted */ ){ int rc; int iStart; @@ -105483,6 +122910,14 @@ static int fts3PendingTermsAdd( assert( pTokenizer && pModule ); + /* If the user has inserted a NULL value, this function may be called with + ** zText==0. In this case, add zero token entries to the hash table and + ** return early. */ + if( zText==0 ){ + *pnWord = 0; + return SQLITE_OK; + } + rc = pModule->xOpen(pTokenizer, zText, -1, &pCsr); if( rc!=SQLITE_OK ){ return rc; @@ -105493,8 +122928,7 @@ static int fts3PendingTermsAdd( while( SQLITE_OK==rc && SQLITE_OK==(rc = xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos)) ){ - PendingList *pList; - + int i; if( iPos>=nWord ) nWord = iPos+1; /* Positions cannot be negative; we use -1 as a terminator internally. @@ -105505,22 +122939,19 @@ static int fts3PendingTermsAdd( break; } - pList = (PendingList *)fts3HashFind(&p->pendingTerms, zToken, nToken); - if( pList ){ - p->nPendingData -= (pList->nData + nToken + sizeof(Fts3HashElem)); - } - if( fts3PendingListAppend(&pList, p->iPrevDocid, iCol, iPos, &rc) ){ - if( pList==fts3HashInsert(&p->pendingTerms, zToken, nToken, pList) ){ - /* Malloc failed while inserting the new entry. This can only - ** happen if there was no previous entry for this token. - */ - assert( 0==fts3HashFind(&p->pendingTerms, zToken, nToken) ); - sqlite3_free(pList); - rc = SQLITE_NOMEM; - } - } - if( rc==SQLITE_OK ){ - p->nPendingData += (pList->nData + nToken + sizeof(Fts3HashElem)); + /* Add the term to the terms index */ + rc = fts3PendingTermsAddOne( + p, iCol, iPos, &p->aIndex[0].hPending, zToken, nToken + ); + + /* Add the term to each of the prefix indexes that it is not too + ** short for. */ + for(i=1; rc==SQLITE_OK && i<p->nIndex; i++){ + struct Fts3Index *pIndex = &p->aIndex[i]; + if( nToken<pIndex->nPrefix ) continue; + rc = fts3PendingTermsAddOne( + p, iCol, iPos, &pIndex->hPending, zToken, pIndex->nPrefix + ); } } @@ -105529,8 +122960,8 @@ static int fts3PendingTermsAdd( return (rc==SQLITE_DONE ? SQLITE_OK : rc); } -/* -** Calling this function indicates that subsequent calls to +/* +** Calling this function indicates that subsequent calls to ** fts3PendingTermsAdd() are to add term/position-list pairs for the ** contents of the document with docid iDocid. */ @@ -105549,12 +122980,20 @@ static int fts3PendingTermsDocid(Fts3Table *p, sqlite_int64 iDocid){ return SQLITE_OK; } +/* +** Discard the contents of the pending-terms hash tables. +*/ SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *p){ - Fts3HashElem *pElem; - for(pElem=fts3HashFirst(&p->pendingTerms); pElem; pElem=fts3HashNext(pElem)){ - sqlite3_free(fts3HashData(pElem)); + int i; + for(i=0; i<p->nIndex; i++){ + Fts3HashElem *pElem; + Fts3Hash *pHash = &p->aIndex[i].hPending; + for(pElem=fts3HashFirst(pHash); pElem; pElem=fts3HashNext(pElem)){ + PendingList *pList = (PendingList *)fts3HashData(pElem); + fts3PendingListDelete(pList); + } + fts3HashClear(pHash); } - fts3HashClear(&p->pendingTerms); p->nPendingData = 0; } @@ -105570,12 +123009,11 @@ static int fts3InsertTerms(Fts3Table *p, sqlite3_value **apVal, u32 *aSz){ int i; /* Iterator variable */ for(i=2; i<p->nColumn+2; i++){ const char *zText = (const char *)sqlite3_value_text(apVal[i]); - if( zText ){ - int rc = fts3PendingTermsAdd(p, zText, i-2, &aSz[i-2]); - if( rc!=SQLITE_OK ){ - return rc; - } + int rc = fts3PendingTermsAdd(p, zText, i-2, &aSz[i-2]); + if( rc!=SQLITE_OK ){ + return rc; } + aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]); } return SQLITE_OK; } @@ -105635,8 +123073,8 @@ static int fts3InsertData( if( rc!=SQLITE_OK ) return rc; } - /* Execute the statement to insert the record. Set *piDocid to the - ** new docid value. + /* Execute the statement to insert the record. Set *piDocid to the + ** new docid value. */ sqlite3_step(pContentInsert); rc = sqlite3_reset(pContentInsert); @@ -105663,6 +123101,8 @@ static int fts3DeleteAll(Fts3Table *p){ fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGDIR, 0); if( p->bHasDocsize ){ fts3SqlExec(&rc, p, SQL_DELETE_ALL_DOCSIZE, 0); + } + if( p->bHasStat ){ fts3SqlExec(&rc, p, SQL_DELETE_ALL_STAT, 0); } return rc; @@ -105673,17 +123113,17 @@ static int fts3DeleteAll(Fts3Table *p){ ** (an integer) of a row about to be deleted. Remove all terms from the ** full-text index. */ -static void fts3DeleteTerms( +static void fts3DeleteTerms( int *pRC, /* Result code */ Fts3Table *p, /* The FTS table to delete from */ - sqlite3_value **apVal, /* apVal[] contains the docid to be deleted */ + sqlite3_value *pRowid, /* The docid to be deleted */ u32 *aSz /* Sizes of deleted document written here */ ){ int rc; sqlite3_stmt *pSelect; if( *pRC ) return; - rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, apVal); + rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid); if( rc==SQLITE_OK ){ if( SQLITE_ROW==sqlite3_step(pSelect) ){ int i; @@ -105695,6 +123135,7 @@ static void fts3DeleteTerms( *pRC = rc; return; } + aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i); } } rc = sqlite3_reset(pSelect); @@ -105708,9 +123149,9 @@ static void fts3DeleteTerms( ** Forward declaration to account for the circular dependency between ** functions fts3SegmentMerge() and fts3AllocateSegdirIdx(). */ -static int fts3SegmentMerge(Fts3Table *, int); +static int fts3SegmentMerge(Fts3Table *, int, int); -/* +/* ** This function allocates a new level iLevel index in the segdir table. ** Usually, indexes are allocated within a level sequentially starting ** with 0, so the allocated index is one greater than the value returned @@ -105719,13 +123160,18 @@ static int fts3SegmentMerge(Fts3Table *, int); ** SELECT max(idx) FROM %_segdir WHERE level = :iLevel ** ** However, if there are already FTS3_MERGE_COUNT indexes at the requested -** level, they are merged into a single level (iLevel+1) segment and the +** level, they are merged into a single level (iLevel+1) segment and the ** allocated index is 0. ** ** If successful, *piIdx is set to the allocated index slot and SQLITE_OK ** returned. Otherwise, an SQLite error code is returned. */ -static int fts3AllocateSegdirIdx(Fts3Table *p, int iLevel, int *piIdx){ +static int fts3AllocateSegdirIdx( + Fts3Table *p, + int iIndex, /* Index for p->aIndex */ + int iLevel, + int *piIdx +){ int rc; /* Return Code */ sqlite3_stmt *pNextIdx; /* Query for next idx at level iLevel */ int iNext = 0; /* Result of query pNextIdx */ @@ -105733,7 +123179,7 @@ static int fts3AllocateSegdirIdx(Fts3Table *p, int iLevel, int *piIdx){ /* Set variable iNext to the next available segdir index at level iLevel. */ rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pNextIdx, 0); if( rc==SQLITE_OK ){ - sqlite3_bind_int(pNextIdx, 1, iLevel); + sqlite3_bind_int(pNextIdx, 1, iIndex*FTS3_SEGDIR_MAXLEVEL + iLevel); if( SQLITE_ROW==sqlite3_step(pNextIdx) ){ iNext = sqlite3_column_int(pNextIdx, 0); } @@ -105747,7 +123193,7 @@ static int fts3AllocateSegdirIdx(Fts3Table *p, int iLevel, int *piIdx){ ** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext. */ if( iNext>=FTS3_MERGE_COUNT ){ - rc = fts3SegmentMerge(p, iLevel); + rc = fts3SegmentMerge(p, iIndex, iLevel); *piIdx = 0; }else{ *piIdx = iNext; @@ -105758,11 +123204,139 @@ static int fts3AllocateSegdirIdx(Fts3Table *p, int iLevel, int *piIdx){ } /* +** The %_segments table is declared as follows: +** +** CREATE TABLE %_segments(blockid INTEGER PRIMARY KEY, block BLOB) +** +** This function reads data from a single row of the %_segments table. The +** specific row is identified by the iBlockid parameter. If paBlob is not +** NULL, then a buffer is allocated using sqlite3_malloc() and populated +** with the contents of the blob stored in the "block" column of the +** identified table row is. Whether or not paBlob is NULL, *pnBlob is set +** to the size of the blob in bytes before returning. +** +** If an error occurs, or the table does not contain the specified row, +** an SQLite error code is returned. Otherwise, SQLITE_OK is returned. If +** paBlob is non-NULL, then it is the responsibility of the caller to +** eventually free the returned buffer. +** +** This function may leave an open sqlite3_blob* handle in the +** Fts3Table.pSegments variable. This handle is reused by subsequent calls +** to this function. The handle may be closed by calling the +** sqlite3Fts3SegmentsClose() function. Reusing a blob handle is a handy +** performance improvement, but the blob handle should always be closed +** before control is returned to the user (to prevent a lock being held +** on the database file for longer than necessary). Thus, any virtual table +** method (xFilter etc.) that may directly or indirectly call this function +** must call sqlite3Fts3SegmentsClose() before returning. +*/ +SQLITE_PRIVATE int sqlite3Fts3ReadBlock( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iBlockid, /* Access the row with blockid=$iBlockid */ + char **paBlob, /* OUT: Blob data in malloc'd buffer */ + int *pnBlob, /* OUT: Size of blob data */ + int *pnLoad /* OUT: Bytes actually loaded */ +){ + int rc; /* Return code */ + + /* pnBlob must be non-NULL. paBlob may be NULL or non-NULL. */ + assert( pnBlob); + + if( p->pSegments ){ + rc = sqlite3_blob_reopen(p->pSegments, iBlockid); + }else{ + if( 0==p->zSegmentsTbl ){ + p->zSegmentsTbl = sqlite3_mprintf("%s_segments", p->zName); + if( 0==p->zSegmentsTbl ) return SQLITE_NOMEM; + } + rc = sqlite3_blob_open( + p->db, p->zDb, p->zSegmentsTbl, "block", iBlockid, 0, &p->pSegments + ); + } + + if( rc==SQLITE_OK ){ + int nByte = sqlite3_blob_bytes(p->pSegments); + *pnBlob = nByte; + if( paBlob ){ + 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; + *pnLoad = nByte; + } + rc = sqlite3_blob_read(p->pSegments, aByte, nByte, 0); + memset(&aByte[nByte], 0, FTS3_NODE_PADDING); + if( rc!=SQLITE_OK ){ + sqlite3_free(aByte); + aByte = 0; + } + } + *paBlob = aByte; + } + } + + return rc; +} + +/* +** Close the blob handle at p->pSegments, if it is open. See comments above +** the sqlite3Fts3ReadBlock() function for details. +*/ +SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *p){ + sqlite3_blob_close(p->pSegments); + p->pSegments = 0; +} + +static int fts3SegReaderIncrRead(Fts3SegReader *pReader){ + int nRead; /* Number of bytes to read */ + int rc; /* Return code */ + + nRead = MIN(pReader->nNode - pReader->nPopulate, FTS3_NODE_CHUNKSIZE); + rc = sqlite3_blob_read( + pReader->pBlob, + &pReader->aNode[pReader->nPopulate], + nRead, + pReader->nPopulate + ); + + if( rc==SQLITE_OK ){ + pReader->nPopulate += nRead; + memset(&pReader->aNode[pReader->nPopulate], 0, FTS3_NODE_PADDING); + if( pReader->nPopulate==pReader->nNode ){ + sqlite3_blob_close(pReader->pBlob); + pReader->pBlob = 0; + pReader->nPopulate = 0; + } + } + return rc; +} + +static int fts3SegReaderRequire(Fts3SegReader *pReader, char *pFrom, int nByte){ + int rc = SQLITE_OK; + assert( !pReader->pBlob + || (pFrom>=pReader->aNode && pFrom<&pReader->aNode[pReader->nNode]) + ); + while( pReader->pBlob && rc==SQLITE_OK + && (pFrom - pReader->aNode + nByte)>pReader->nPopulate + ){ + rc = fts3SegReaderIncrRead(pReader); + } + return rc; +} + +/* ** Move the iterator passed as the first argument to the next term in the ** segment. If successful, SQLITE_OK is returned. If there is no next term, ** SQLITE_DONE. Otherwise, an SQLite error code. */ -static int fts3SegReaderNext(Fts3SegReader *pReader){ +static int fts3SegReaderNext( + Fts3Table *p, + Fts3SegReader *pReader, + int bIncr +){ + int rc; /* Return code of various sub-routines */ char *pNext; /* Cursor variable */ int nPrefix; /* Number of bytes in term prefix */ int nSuffix; /* Number of bytes in term suffix */ @@ -105774,7 +123348,7 @@ static int fts3SegReaderNext(Fts3SegReader *pReader){ } if( !pNext || pNext>=&pReader->aNode[pReader->nNode] ){ - int rc; + if( fts3SegReaderIsPending(pReader) ){ Fts3HashElem *pElem = *(pReader->ppNextElem); if( pElem==0 ){ @@ -105790,22 +123364,48 @@ static int fts3SegReaderNext(Fts3SegReader *pReader){ } return SQLITE_OK; } - if( !pReader->pStmt ){ - pReader->aNode = 0; + + if( !fts3SegReaderIsRootOnly(pReader) ){ + sqlite3_free(pReader->aNode); + sqlite3_blob_close(pReader->pBlob); + pReader->pBlob = 0; + } + pReader->aNode = 0; + + /* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf + ** blocks have already been traversed. */ + assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock ); + if( pReader->iCurrentBlock>=pReader->iLeafEndBlock ){ return SQLITE_OK; } - rc = sqlite3_step(pReader->pStmt); - if( rc!=SQLITE_ROW ){ - pReader->aNode = 0; - return (rc==SQLITE_DONE ? SQLITE_OK : rc); + + rc = sqlite3Fts3ReadBlock( + p, ++pReader->iCurrentBlock, &pReader->aNode, &pReader->nNode, + (bIncr ? &pReader->nPopulate : 0) + ); + if( rc!=SQLITE_OK ) return rc; + assert( pReader->pBlob==0 ); + if( bIncr && pReader->nPopulate<pReader->nNode ){ + pReader->pBlob = p->pSegments; + p->pSegments = 0; } - pReader->nNode = sqlite3_column_bytes(pReader->pStmt, 0); - pReader->aNode = (char *)sqlite3_column_blob(pReader->pStmt, 0); pNext = pReader->aNode; } + assert( !fts3SegReaderIsPending(pReader) ); + + rc = fts3SegReaderRequire(pReader, pNext, FTS3_VARINT_MAX*2); + if( rc!=SQLITE_OK ) return rc; + + /* Because of the FTS3_NODE_PADDING bytes of padding, the following is + ** safe (no risk of overread) even if the node data is corrupted. */ pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix); pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix); + if( nPrefix<0 || nSuffix<=0 + || &pNext[nSuffix]>&pReader->aNode[pReader->nNode] + ){ + return SQLITE_CORRUPT_VTAB; + } if( nPrefix+nSuffix>pReader->nTermAlloc ){ int nNew = (nPrefix+nSuffix)*2; @@ -105816,13 +123416,26 @@ static int fts3SegReaderNext(Fts3SegReader *pReader){ pReader->zTerm = zNew; pReader->nTermAlloc = nNew; } + + rc = fts3SegReaderRequire(pReader, pNext, nSuffix+FTS3_VARINT_MAX); + if( rc!=SQLITE_OK ) return rc; + memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix); pReader->nTerm = nPrefix+nSuffix; pNext += nSuffix; pNext += sqlite3Fts3GetVarint32(pNext, &pReader->nDoclist); - assert( pNext<&pReader->aNode[pReader->nNode] ); pReader->aDoclist = pNext; pReader->pOffsetList = 0; + + /* Check that the doclist does not appear to extend past the end of the + ** b-tree node. And that the final byte of the doclist is 0x00. If either + ** of these statements is untrue, then the data structure is corrupt. + */ + if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode] + || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1]) + ){ + return SQLITE_CORRUPT_VTAB; + } return SQLITE_OK; } @@ -105830,87 +123443,179 @@ static int fts3SegReaderNext(Fts3SegReader *pReader){ ** Set the SegReader to point to the first docid in the doclist associated ** with the current term. */ -static void fts3SegReaderFirstDocid(Fts3SegReader *pReader){ - int n; +static int fts3SegReaderFirstDocid(Fts3Table *pTab, Fts3SegReader *pReader){ + int rc = SQLITE_OK; assert( pReader->aDoclist ); assert( !pReader->pOffsetList ); - n = sqlite3Fts3GetVarint(pReader->aDoclist, &pReader->iDocid); - pReader->pOffsetList = &pReader->aDoclist[n]; + if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){ + u8 bEof = 0; + pReader->iDocid = 0; + pReader->nOffsetList = 0; + sqlite3Fts3DoclistPrev(0, + pReader->aDoclist, pReader->nDoclist, &pReader->pOffsetList, + &pReader->iDocid, &pReader->nOffsetList, &bEof + ); + }else{ + rc = fts3SegReaderRequire(pReader, pReader->aDoclist, FTS3_VARINT_MAX); + if( rc==SQLITE_OK ){ + int n = sqlite3Fts3GetVarint(pReader->aDoclist, &pReader->iDocid); + pReader->pOffsetList = &pReader->aDoclist[n]; + } + } + return rc; } /* ** Advance the SegReader to point to the next docid in the doclist ** associated with the current term. -** -** If arguments ppOffsetList and pnOffsetList are not NULL, then +** +** If arguments ppOffsetList and pnOffsetList are not NULL, then ** *ppOffsetList is set to point to the first column-offset list ** in the doclist entry (i.e. immediately past the docid varint). ** *pnOffsetList is set to the length of the set of column-offset ** lists, not including the nul-terminator byte. For example: */ -static void fts3SegReaderNextDocid( - Fts3SegReader *pReader, - char **ppOffsetList, - int *pnOffsetList +static int fts3SegReaderNextDocid( + Fts3Table *pTab, + Fts3SegReader *pReader, /* Reader to advance to next docid */ + char **ppOffsetList, /* OUT: Pointer to current position-list */ + int *pnOffsetList /* OUT: Length of *ppOffsetList in bytes */ ){ + int rc = SQLITE_OK; char *p = pReader->pOffsetList; char c = 0; - /* Pointer p currently points at the first byte of an offset list. The - ** following two lines advance it to point one byte past the end of - ** the same offset list. - */ - while( *p | c ) c = *p++ & 0x80; - p++; + assert( p ); - /* If required, populate the output variables with a pointer to and the - ** size of the previous offset-list. - */ - if( ppOffsetList ){ - *ppOffsetList = pReader->pOffsetList; - *pnOffsetList = (int)(p - pReader->pOffsetList - 1); + if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){ + /* A pending-terms seg-reader for an FTS4 table that uses order=desc. + ** Pending-terms doclists are always built up in ascending order, so + ** we have to iterate through them backwards here. */ + u8 bEof = 0; + if( ppOffsetList ){ + *ppOffsetList = pReader->pOffsetList; + *pnOffsetList = pReader->nOffsetList - 1; + } + sqlite3Fts3DoclistPrev(0, + pReader->aDoclist, pReader->nDoclist, &p, &pReader->iDocid, + &pReader->nOffsetList, &bEof + ); + if( bEof ){ + pReader->pOffsetList = 0; + }else{ + pReader->pOffsetList = p; + } + }else{ + char *pEnd = &pReader->aDoclist[pReader->nDoclist]; + + /* Pointer p currently points at the first byte of an offset list. The + ** following block advances it to point one byte past the end of + ** the same offset list. */ + while( 1 ){ + + /* The following line of code (and the "p++" below the while() loop) is + ** normally all that is required to move pointer p to the desired + ** position. The exception is if this node is being loaded from disk + ** incrementally and pointer "p" now points to the first byte passed + ** the populated part of pReader->aNode[]. + */ + while( *p | c ) c = *p++ & 0x80; + assert( *p==0 ); + + if( pReader->pBlob==0 || p<&pReader->aNode[pReader->nPopulate] ) break; + rc = fts3SegReaderIncrRead(pReader); + if( rc!=SQLITE_OK ) return rc; + } + p++; + + /* If required, populate the output variables with a pointer to and the + ** size of the previous offset-list. + */ + if( ppOffsetList ){ + *ppOffsetList = pReader->pOffsetList; + *pnOffsetList = (int)(p - pReader->pOffsetList - 1); + } + + while( p<pEnd && *p==0 ) p++; + + /* If there are no more entries in the doclist, set pOffsetList to + ** NULL. Otherwise, set Fts3SegReader.iDocid to the next docid and + ** Fts3SegReader.pOffsetList to point to the next offset list before + ** returning. + */ + if( p>=pEnd ){ + pReader->pOffsetList = 0; + }else{ + rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX); + if( rc==SQLITE_OK ){ + sqlite3_int64 iDelta; + pReader->pOffsetList = p + sqlite3Fts3GetVarint(p, &iDelta); + if( pTab->bDescIdx ){ + pReader->iDocid -= iDelta; + }else{ + pReader->iDocid += iDelta; + } + } + } } - /* If there are no more entries in the doclist, set pOffsetList to - ** NULL. Otherwise, set Fts3SegReader.iDocid to the next docid and - ** Fts3SegReader.pOffsetList to point to the next offset list before - ** returning. - */ - if( p>=&pReader->aDoclist[pReader->nDoclist] ){ - pReader->pOffsetList = 0; - }else{ - sqlite3_int64 iDelta; - pReader->pOffsetList = p + sqlite3Fts3GetVarint(p, &iDelta); - pReader->iDocid += iDelta; + return SQLITE_OK; +} + + +SQLITE_PRIVATE int sqlite3Fts3MsrOvfl( + Fts3Cursor *pCsr, + Fts3MultiSegReader *pMsr, + int *pnOvfl +){ + Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; + int nOvfl = 0; + int ii; + int rc = SQLITE_OK; + int pgsz = p->nPgsz; + + assert( p->bHasStat ); + assert( pgsz>0 ); + + for(ii=0; rc==SQLITE_OK && ii<pMsr->nSegment; ii++){ + Fts3SegReader *pReader = pMsr->apSegment[ii]; + if( !fts3SegReaderIsPending(pReader) + && !fts3SegReaderIsRootOnly(pReader) + ){ + sqlite3_int64 jj; + for(jj=pReader->iStartBlock; jj<=pReader->iLeafEndBlock; jj++){ + int nBlob; + rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0); + if( rc!=SQLITE_OK ) break; + if( (nBlob+35)>pgsz ){ + nOvfl += (nBlob + 34)/pgsz; + } + } + } } + *pnOvfl = nOvfl; + return rc; } /* -** Free all allocations associated with the iterator passed as the +** Free all allocations associated with the iterator passed as the ** second argument. */ -SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3Table *p, Fts3SegReader *pReader){ - if( pReader ){ - if( pReader->pStmt ){ - /* Move the leaf-range SELECT statement to the aLeavesStmt[] array, - ** so that it can be reused when required by another query. - */ - assert( p->nLeavesStmt<p->nLeavesTotal ); - sqlite3_reset(pReader->pStmt); - p->aLeavesStmt[p->nLeavesStmt++] = pReader->pStmt; - } - if( !fts3SegReaderIsPending(pReader) ){ - sqlite3_free(pReader->zTerm); +SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){ + if( pReader && !fts3SegReaderIsPending(pReader) ){ + sqlite3_free(pReader->zTerm); + if( !fts3SegReaderIsRootOnly(pReader) ){ + sqlite3_free(pReader->aNode); + sqlite3_blob_close(pReader->pBlob); } - sqlite3_free(pReader); } + sqlite3_free(pReader); } /* ** Allocate a new SegReader object. */ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( - Fts3Table *p, /* Virtual table handle */ int iAge, /* Segment "age". */ sqlite3_int64 iStartLeaf, /* First leaf to traverse */ sqlite3_int64 iEndLeaf, /* Final leaf to traverse */ @@ -105923,8 +123628,9 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( Fts3SegReader *pReader; /* Newly allocated SegReader object */ int nExtra = 0; /* Bytes to allocate segment root node */ + assert( iStartLeaf<=iEndLeaf ); if( iStartLeaf==0 ){ - nExtra = nRoot; + nExtra = nRoot + FTS3_NODE_PADDING; } pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra); @@ -105932,8 +123638,9 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( return SQLITE_NOMEM; } memset(pReader, 0, sizeof(Fts3SegReader)); - pReader->iStartBlock = iStartLeaf; pReader->iIdx = iAge; + pReader->iStartBlock = iStartLeaf; + pReader->iLeafEndBlock = iEndLeaf; pReader->iEndBlock = iEndBlock; if( nExtra ){ @@ -105941,59 +123648,15 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( pReader->aNode = (char *)&pReader[1]; pReader->nNode = nRoot; memcpy(pReader->aNode, zRoot, nRoot); + memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING); }else{ - /* If the text of the SQL statement to iterate through a contiguous - ** set of entries in the %_segments table has not yet been composed, - ** compose it now. - */ - if( !p->zSelectLeaves ){ - p->zSelectLeaves = sqlite3_mprintf( - "SELECT block FROM %Q.'%q_segments' WHERE blockid BETWEEN ? AND ? " - "ORDER BY blockid", p->zDb, p->zName - ); - if( !p->zSelectLeaves ){ - rc = SQLITE_NOMEM; - goto finished; - } - } - - /* If there are no free statements in the aLeavesStmt[] array, prepare - ** a new statement now. Otherwise, reuse a prepared statement from - ** aLeavesStmt[]. - */ - if( p->nLeavesStmt==0 ){ - if( p->nLeavesTotal==p->nLeavesAlloc ){ - int nNew = p->nLeavesAlloc + 16; - sqlite3_stmt **aNew = (sqlite3_stmt **)sqlite3_realloc( - p->aLeavesStmt, nNew*sizeof(sqlite3_stmt *) - ); - if( !aNew ){ - rc = SQLITE_NOMEM; - goto finished; - } - p->nLeavesAlloc = nNew; - p->aLeavesStmt = aNew; - } - rc = sqlite3_prepare_v2(p->db, p->zSelectLeaves, -1, &pReader->pStmt, 0); - if( rc!=SQLITE_OK ){ - goto finished; - } - p->nLeavesTotal++; - }else{ - pReader->pStmt = p->aLeavesStmt[--p->nLeavesStmt]; - } - - /* Bind the start and end leaf blockids to the prepared SQL statement. */ - sqlite3_bind_int64(pReader->pStmt, 1, iStartLeaf); - sqlite3_bind_int64(pReader->pStmt, 2, iEndLeaf); + pReader->iCurrentBlock = iStartLeaf-1; } - rc = fts3SegReaderNext(pReader); - finished: if( rc==SQLITE_OK ){ *ppReader = pReader; }else{ - sqlite3Fts3SegReaderFree(p, pReader); + sqlite3Fts3SegReaderFree(pReader); } return rc; } @@ -106020,24 +123683,42 @@ static int fts3CompareElemByTerm(const void *lhs, const void *rhs){ /* ** This function is used to allocate an Fts3SegReader that iterates through ** a subset of the terms stored in the Fts3Table.pendingTerms array. +** +** If the isPrefixIter parameter is zero, then the returned SegReader iterates +** through each term in the pending-terms table. Or, if isPrefixIter is +** non-zero, it iterates through each term and its prefixes. For example, if +** the pending terms hash table contains the terms "sqlite", "mysql" and +** "firebird", then the iterator visits the following 'terms' (in the order +** shown): +** +** f fi fir fire fireb firebi firebir firebird +** m my mys mysq mysql +** s sq sql sqli sqlit sqlite +** +** Whereas if isPrefixIter is zero, the terms visited are: +** +** firebird mysql sqlite */ SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( Fts3Table *p, /* Virtual table handle */ + int iIndex, /* Index for p->aIndex */ const char *zTerm, /* Term to search for */ int nTerm, /* Size of buffer zTerm */ - int isPrefix, /* True for a term-prefix query */ + int bPrefix, /* True for a prefix iterator */ Fts3SegReader **ppReader /* OUT: SegReader for pending-terms */ ){ Fts3SegReader *pReader = 0; /* Fts3SegReader object to return */ Fts3HashElem **aElem = 0; /* Array of term hash entries to scan */ int nElem = 0; /* Size of array at aElem */ int rc = SQLITE_OK; /* Return Code */ + Fts3Hash *pHash; - if( isPrefix ){ + pHash = &p->aIndex[iIndex].hPending; + if( bPrefix ){ int nAlloc = 0; /* Size of allocated array at aElem */ Fts3HashElem *pE = 0; /* Iterator variable */ - for(pE=fts3HashFirst(&p->pendingTerms); pE; pE=fts3HashNext(pE)){ + for(pE=fts3HashFirst(pHash); pE; pE=fts3HashNext(pE)){ char *zKey = (char *)fts3HashKey(pE); int nKey = fts3HashKeysize(pE); if( nTerm==0 || (nKey>=nTerm && 0==memcmp(zKey, zTerm, nTerm)) ){ @@ -106054,6 +123735,7 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( } aElem = aElem2; } + aElem[nElem++] = pE; } } @@ -106067,7 +123749,9 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( } }else{ - Fts3HashElem *pE = fts3HashFindElem(&p->pendingTerms, zTerm, nTerm); + /* The query is a simple term lookup that matches at most one term in + ** the index. All that is required is a straight hash-lookup. */ + Fts3HashElem *pE = fts3HashFindElem(pHash, zTerm, nTerm); if( pE ){ aElem = &pE; nElem = 1; @@ -106084,56 +123768,18 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( pReader->iIdx = 0x7FFFFFFF; pReader->ppNextElem = (Fts3HashElem **)&pReader[1]; memcpy(pReader->ppNextElem, aElem, nElem*sizeof(Fts3HashElem *)); - fts3SegReaderNext(pReader); } } - if( isPrefix ){ + if( bPrefix ){ sqlite3_free(aElem); } *ppReader = pReader; return rc; } - -/* -** The second argument to this function is expected to be a statement of -** the form: -** -** SELECT -** idx, -- col 0 -** start_block, -- col 1 -** leaves_end_block, -- col 2 -** end_block, -- col 3 -** root -- col 4 -** FROM %_segdir ... -** -** This function allocates and initializes a Fts3SegReader structure to -** iterate through the terms stored in the segment identified by the -** current row that pStmt is pointing to. -** -** If successful, the Fts3SegReader is left pointing to the first term -** in the segment and SQLITE_OK is returned. Otherwise, an SQLite error -** code is returned. -*/ -static int fts3SegReaderNew( - Fts3Table *p, /* Virtual table handle */ - sqlite3_stmt *pStmt, /* See above */ - int iAge, /* Segment "age". */ - Fts3SegReader **ppReader /* OUT: Allocated Fts3SegReader */ -){ - return sqlite3Fts3SegReaderNew(p, iAge, - sqlite3_column_int64(pStmt, 1), - sqlite3_column_int64(pStmt, 2), - sqlite3_column_int64(pStmt, 3), - sqlite3_column_blob(pStmt, 4), - sqlite3_column_bytes(pStmt, 4), - ppReader - ); -} - /* -** Compare the entries pointed to by two Fts3SegReader structures. +** Compare the entries pointed to by two Fts3SegReader structures. ** Comparison is as follows: ** ** 1) EOF is greater than not EOF. @@ -106189,10 +123835,22 @@ static int fts3SegReaderDoclistCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ assert( pLhs->aNode && pRhs->aNode ); return rc; } +static int fts3SegReaderDoclistCmpRev(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ + int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0); + if( rc==0 ){ + if( pLhs->iDocid==pRhs->iDocid ){ + rc = pRhs->iIdx - pLhs->iIdx; + }else{ + rc = (pLhs->iDocid < pRhs->iDocid) ? 1 : -1; + } + } + assert( pLhs->aNode && pRhs->aNode ); + return rc; +} /* ** Compare the term that the Fts3SegReader object passed as the first argument -** points to with the term specified by arguments zTerm and nTerm. +** points to with the term specified by arguments zTerm and nTerm. ** ** If the pSeg iterator is already at EOF, return 0. Otherwise, return ** -ve if the pSeg term is less than zTerm/nTerm, 0 if the two terms are @@ -106253,7 +123911,7 @@ static void fts3SegReaderSort( #endif } -/* +/* ** Insert a record into the %_segments table. */ static int fts3WriteSegment( @@ -106273,7 +123931,7 @@ static int fts3WriteSegment( return rc; } -/* +/* ** Insert a record into the %_segdir table. */ static int fts3WriteSegdir( @@ -106303,7 +123961,7 @@ static int fts3WriteSegdir( /* ** Return the size of the common prefix (if any) shared by zPrev and -** zNext, in bytes. For example, +** zNext, in bytes. For example, ** ** fts3PrefixCompress("abc", 3, "abcdef", 6) // returns 3 ** fts3PrefixCompress("abX", 3, "abcdef", 6) // returns 2 @@ -106326,8 +123984,8 @@ static int fts3PrefixCompress( ** (according to memcmp) than the previous term. */ static int fts3NodeAddTerm( - Fts3Table *p, /* Virtual table handle */ - SegmentNode **ppTree, /* IN/OUT: SegmentNode handle */ + Fts3Table *p, /* Virtual table handle */ + SegmentNode **ppTree, /* IN/OUT: SegmentNode handle */ int isCopyTerm, /* True if zTerm/nTerm is transient */ const char *zTerm, /* Pointer to buffer containing term */ int nTerm /* Size of term in bytes */ @@ -106336,7 +123994,7 @@ static int fts3NodeAddTerm( int rc; SegmentNode *pNew; - /* First try to append the term to the current node. Return early if + /* First try to append the term to the current node. Return early if ** this is possible. */ if( pTree ){ @@ -106356,8 +124014,8 @@ static int fts3NodeAddTerm( ** and the static node buffer (p->nNodeSize bytes) is not large ** enough. Use a separately malloced buffer instead This wastes ** 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. + ** 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_malloc(nReq); @@ -106401,7 +124059,7 @@ static int fts3NodeAddTerm( ** If this is the first node in the tree, the term is added to it. ** ** 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 + ** now. Instead, the term is inserted into the parent of pTree. If pTree ** has no parent, one is created here. */ pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize); @@ -106426,7 +124084,7 @@ static int fts3NodeAddTerm( pTree->zMalloc = 0; }else{ pNew->pLeftmost = pNew; - rc = fts3NodeAddTerm(p, &pNew, isCopyTerm, zTerm, nTerm); + rc = fts3NodeAddTerm(p, &pNew, isCopyTerm, zTerm, nTerm); } *ppTree = pNew; @@ -106437,8 +124095,8 @@ static int fts3NodeAddTerm( ** Helper function for fts3NodeWrite(). */ static int fts3TreeFinishNode( - SegmentNode *pTree, - int iHeight, + SegmentNode *pTree, + int iHeight, sqlite3_int64 iLeftChild ){ int nStart; @@ -106451,15 +124109,15 @@ static int fts3TreeFinishNode( /* ** Write the buffer for the segment node pTree and all of its peers to the -** database. Then call this function recursively to write the parent of -** pTree and its peers to the database. +** database. Then call this function recursively to write the parent of +** pTree and its peers to the database. ** ** Except, if pTree is a root node, do not write it to the database. Instead, ** set output variables *paRoot and *pnRoot to contain the root node. ** ** If successful, SQLITE_OK is returned and output variable *piLast is ** set to the largest blockid written to the database (or zero if no -** blocks were written to the db). Otherwise, an SQLite error code is +** blocks were written to the db). Otherwise, an SQLite error code is ** returned. */ static int fts3NodeWrite( @@ -106487,7 +124145,7 @@ static int fts3NodeWrite( for(pIter=pTree->pLeftmost; pIter && rc==SQLITE_OK; pIter=pIter->pRight){ int nStart = fts3TreeFinishNode(pIter, iHeight, iNextLeaf); int nWrite = pIter->nData - nStart; - + rc = fts3WriteSegment(p, iNextFree, &pIter->aData[nStart], nWrite); iNextFree++; iNextLeaf += (pIter->nEntry+1); @@ -106533,7 +124191,7 @@ static void fts3NodeFree(SegmentNode *pTree){ */ static int fts3SegWriterAdd( Fts3Table *p, /* Virtual table handle */ - SegmentWriter **ppWriter, /* IN/OUT: SegmentWriter handle */ + SegmentWriter **ppWriter, /* IN/OUT: SegmentWriter handle */ int isCopyTerm, /* True if buffer zTerm must be copied */ const char *zTerm, /* Pointer to buffer containing term */ int nTerm, /* Size of term in bytes */ @@ -106701,7 +124359,7 @@ static int fts3SegWriterFlush( } /* -** Release all memory held by the SegmentWriter object passed as the +** Release all memory held by the SegmentWriter object passed as the ** first argument. */ static void fts3SegWriterFree(SegmentWriter *pWriter){ @@ -106717,16 +124375,16 @@ static void fts3SegWriterFree(SegmentWriter *pWriter){ ** The first value in the apVal[] array is assumed to contain an integer. ** This function tests if there exist any documents with docid values that ** are different from that integer. i.e. if deleting the document with docid -** apVal[0] would mean the FTS3 table were empty. +** pRowid would mean the FTS3 table were empty. ** ** If successful, *pisEmpty is set to true if the table is empty except for -** document apVal[0], or false otherwise, and SQLITE_OK is returned. If an +** document pRowid, or false otherwise, and SQLITE_OK is returned. If an ** error occurs, an SQLite error code is returned. */ -static int fts3IsEmpty(Fts3Table *p, sqlite3_value **apVal, int *pisEmpty){ +static int fts3IsEmpty(Fts3Table *p, sqlite3_value *pRowid, int *pisEmpty){ sqlite3_stmt *pStmt; int rc; - rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, apVal); + rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid); if( rc==SQLITE_OK ){ if( SQLITE_ROW==sqlite3_step(pStmt) ){ *pisEmpty = sqlite3_column_int(pStmt, 0); @@ -106737,40 +124395,30 @@ static int fts3IsEmpty(Fts3Table *p, sqlite3_value **apVal, int *pisEmpty){ } /* -** Set *pnSegment to the number of segments of level iLevel in the database. +** Set *pnMax to the largest segment level in the database for the index +** iIndex. ** -** Return SQLITE_OK if successful, or an SQLite error code if not. -*/ -static int fts3SegmentCount(Fts3Table *p, int iLevel, int *pnSegment){ - sqlite3_stmt *pStmt; - int rc; - - assert( iLevel>=0 ); - rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_COUNT, &pStmt, 0); - if( rc!=SQLITE_OK ) return rc; - sqlite3_bind_int(pStmt, 1, iLevel); - if( SQLITE_ROW==sqlite3_step(pStmt) ){ - *pnSegment = sqlite3_column_int(pStmt, 0); - } - return sqlite3_reset(pStmt); -} - -/* -** Set *pnSegment to the total number of segments in the database. Set -** *pnMax to the largest segment level in the database (segment levels -** are stored in the 'level' column of the %_segdir table). +** Segment levels are stored in the 'level' column of the %_segdir table. ** ** Return SQLITE_OK if successful, or an SQLite error code if not. */ -static int fts3SegmentCountMax(Fts3Table *p, int *pnSegment, int *pnMax){ +static int fts3SegmentMaxLevel(Fts3Table *p, int iIndex, int *pnMax){ sqlite3_stmt *pStmt; int rc; + assert( iIndex>=0 && iIndex<p->nIndex ); - rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_COUNT_MAX, &pStmt, 0); + /* Set pStmt to the compiled version of: + ** + ** SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? + ** + ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR). + */ + rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); if( rc!=SQLITE_OK ) return rc; + sqlite3_bind_int(pStmt, 1, iIndex*FTS3_SEGDIR_MAXLEVEL); + sqlite3_bind_int(pStmt, 2, (iIndex+1)*FTS3_SEGDIR_MAXLEVEL - 1); if( SQLITE_ROW==sqlite3_step(pStmt) ){ - *pnSegment = sqlite3_column_int(pStmt, 0); - *pnMax = sqlite3_column_int(pStmt, 1); + *pnMax = sqlite3_column_int(pStmt, 0); } return sqlite3_reset(pStmt); } @@ -106779,9 +124427,9 @@ static int fts3SegmentCountMax(Fts3Table *p, int *pnSegment, int *pnMax){ ** This function is used after merging multiple segments into a single large ** segment to delete the old, now redundant, segment b-trees. Specifically, ** it: -** -** 1) Deletes all %_segments entries for the segments associated with -** each of the SegReader objects in the array passed as the third +** +** 1) Deletes all %_segments entries for the segments associated with +** each of the SegReader objects in the array passed as the third ** argument, and ** ** 2) deletes all %_segdir entries with level iLevel, or all %_segdir @@ -106791,6 +124439,7 @@ static int fts3SegmentCountMax(Fts3Table *p, int *pnSegment, int *pnMax){ */ static int fts3DeleteSegdir( Fts3Table *p, /* Virtual table handle */ + int iIndex, /* Index for p->aIndex */ int iLevel, /* Level of %_segdir entries to delete */ Fts3SegReader **apSegment, /* Array of SegReader objects */ int nReader /* Size of array apSegment */ @@ -106813,22 +124462,30 @@ static int fts3DeleteSegdir( return rc; } - if( iLevel>=0 ){ - rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_BY_LEVEL, &pDelete, 0); + assert( iLevel>=0 || iLevel==FTS3_SEGCURSOR_ALL ); + if( iLevel==FTS3_SEGCURSOR_ALL ){ + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_RANGE, &pDelete, 0); if( rc==SQLITE_OK ){ - sqlite3_bind_int(pDelete, 1, iLevel); - sqlite3_step(pDelete); - rc = sqlite3_reset(pDelete); + sqlite3_bind_int(pDelete, 1, iIndex*FTS3_SEGDIR_MAXLEVEL); + sqlite3_bind_int(pDelete, 2, (iIndex+1) * FTS3_SEGDIR_MAXLEVEL - 1); } }else{ - fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGDIR, 0); + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pDelete, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int(pDelete, 1, iIndex*FTS3_SEGDIR_MAXLEVEL + iLevel); + } + } + + if( rc==SQLITE_OK ){ + sqlite3_step(pDelete); + rc = sqlite3_reset(pDelete); } return rc; } /* -** When this function is called, buffer *ppList (size *pnList bytes) contains +** When this function is called, buffer *ppList (size *pnList bytes) contains ** a position list that may (or may not) feature multiple columns. This ** function adjusts the pointer *ppList and the length *pnList so that they ** identify the subset of the position list that corresponds to column iCol. @@ -106851,7 +124508,7 @@ static void fts3ColumnFilter( while( 1 ){ char c = 0; while( p<pEnd && (c | *p)&0xFE ) c = *p++ & 0x80; - + if( iCol==iCurrent ){ nList = (int)(p - pList); break; @@ -106871,162 +124528,313 @@ static void fts3ColumnFilter( } /* -** sqlite3Fts3SegReaderIterate() callback used when merging multiple -** segments to create a single, larger segment. +** Cache data in the Fts3MultiSegReader.aBuffer[] buffer (overwriting any +** existing data). Grow the buffer if required. +** +** If successful, return SQLITE_OK. Otherwise, if an OOM error is encountered +** trying to resize the buffer, return SQLITE_NOMEM. */ -static int fts3MergeCallback( - Fts3Table *p, /* FTS3 Virtual table handle */ - void *pContext, /* Pointer to SegmentWriter* to write with */ - char *zTerm, /* Term to write to the db */ - int nTerm, /* Number of bytes in zTerm */ - char *aDoclist, /* Doclist associated with zTerm */ - int nDoclist /* Number of bytes in doclist */ +static int fts3MsrBufferData( + Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ + char *pList, + int nList ){ - SegmentWriter **ppW = (SegmentWriter **)pContext; - return fts3SegWriterAdd(p, ppW, 1, zTerm, nTerm, aDoclist, nDoclist); -} + if( nList>pMsr->nBuffer ){ + char *pNew; + pMsr->nBuffer = nList*2; + pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer); + if( !pNew ) return SQLITE_NOMEM; + pMsr->aBuffer = pNew; + } -/* -** sqlite3Fts3SegReaderIterate() callback used when flushing the contents -** of the pending-terms hash table to the database. -*/ -static int fts3FlushCallback( - Fts3Table *p, /* FTS3 Virtual table handle */ - void *pContext, /* Pointer to SegmentWriter* to write with */ - char *zTerm, /* Term to write to the db */ - int nTerm, /* Number of bytes in zTerm */ - char *aDoclist, /* Doclist associated with zTerm */ - int nDoclist /* Number of bytes in doclist */ -){ - SegmentWriter **ppW = (SegmentWriter **)pContext; - return fts3SegWriterAdd(p, ppW, 0, zTerm, nTerm, aDoclist, nDoclist); + memcpy(pMsr->aBuffer, pList, nList); + return SQLITE_OK; } -/* -** This function is used to iterate through a contiguous set of terms -** stored in the full-text index. It merges data contained in one or -** more segments to support this. -** -** The second argument is passed an array of pointers to SegReader objects -** allocated with sqlite3Fts3SegReaderNew(). This function merges the range -** of terms selected by each SegReader. If a single term is present in -** more than one segment, the associated doclists are merged. For each -** term and (possibly merged) doclist in the merged range, the callback -** function xFunc is invoked with its arguments set as follows. -** -** arg 0: Copy of 'p' parameter passed to this function -** arg 1: Copy of 'pContext' parameter passed to this function -** arg 2: Pointer to buffer containing term -** arg 3: Size of arg 2 buffer in bytes -** arg 4: Pointer to buffer containing doclist -** arg 5: Size of arg 2 buffer in bytes -** -** The 4th argument to this function is a pointer to a structure of type -** Fts3SegFilter, defined in fts3Int.h. The contents of this structure -** further restrict the range of terms that callbacks are made for and -** modify the behaviour of this function. See comments above structure -** definition for details. -*/ -SQLITE_PRIVATE int sqlite3Fts3SegReaderIterate( +SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( Fts3Table *p, /* Virtual table handle */ - Fts3SegReader **apSegment, /* Array of Fts3SegReader objects */ - int nSegment, /* Size of apSegment array */ - Fts3SegFilter *pFilter, /* Restrictions on range of iteration */ - int (*xFunc)(Fts3Table *, void *, char *, int, char *, int), /* Callback */ - void *pContext /* Callback context (2nd argument) */ + Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ + sqlite3_int64 *piDocid, /* OUT: Docid value */ + char **paPoslist, /* OUT: Pointer to position list */ + int *pnPoslist /* OUT: Size of position list in bytes */ ){ - int i; /* Iterator variable */ - char *aBuffer = 0; /* Buffer to merge doclists in */ - int nAlloc = 0; /* Allocated size of aBuffer buffer */ - int rc = SQLITE_OK; /* Return code */ + int nMerge = pMsr->nAdvance; + Fts3SegReader **apSegment = pMsr->apSegment; + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( + p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp + ); - int isIgnoreEmpty = (pFilter->flags & FTS3_SEGMENT_IGNORE_EMPTY); - int isRequirePos = (pFilter->flags & FTS3_SEGMENT_REQUIRE_POS); - int isColFilter = (pFilter->flags & FTS3_SEGMENT_COLUMN_FILTER); - int isPrefix = (pFilter->flags & FTS3_SEGMENT_PREFIX); + if( nMerge==0 ){ + *paPoslist = 0; + return SQLITE_OK; + } - /* If there are zero segments, this function is a no-op. This scenario - ** comes about only when reading from an empty database. - */ - if( nSegment==0 ) goto finished; + while( 1 ){ + Fts3SegReader *pSeg; + pSeg = pMsr->apSegment[0]; + + if( pSeg->pOffsetList==0 ){ + *paPoslist = 0; + break; + }else{ + int rc; + char *pList; + int nList; + int j; + sqlite3_int64 iDocid = apSegment[0]->iDocid; + + rc = fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList); + j = 1; + while( rc==SQLITE_OK + && j<nMerge + && apSegment[j]->pOffsetList + && apSegment[j]->iDocid==iDocid + ){ + rc = fts3SegReaderNextDocid(p, apSegment[j], 0, 0); + j++; + } + if( rc!=SQLITE_OK ) return rc; + fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp); - /* If the Fts3SegFilter defines a specific term (or term prefix) to search + if( pMsr->iColFilter>=0 ){ + fts3ColumnFilter(pMsr->iColFilter, &pList, &nList); + } + + if( nList>0 ){ + if( fts3SegReaderIsPending(apSegment[0]) ){ + rc = fts3MsrBufferData(pMsr, pList, nList+1); + if( rc!=SQLITE_OK ) return rc; + *paPoslist = pMsr->aBuffer; + assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 ); + }else{ + *paPoslist = pList; + } + *piDocid = iDocid; + *pnPoslist = nList; + break; + } + } + } + + return SQLITE_OK; +} + +static int fts3SegReaderStart( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr, /* Cursor object */ + const char *zTerm, /* Term searched for (or NULL) */ + int nTerm /* Length of zTerm in bytes */ +){ + int i; + int nSeg = pCsr->nSegment; + + /* If the Fts3SegFilter defines a specific term (or term prefix) to search ** for, then advance each segment iterator until it points to a term of ** equal or greater value than the specified term. This prevents many ** unnecessary merge/sort operations for the case where single segment ** b-tree leaf nodes contain more than one term. */ - if( pFilter->zTerm ){ - int nTerm = pFilter->nTerm; - const char *zTerm = pFilter->zTerm; - for(i=0; i<nSegment; i++){ - Fts3SegReader *pSeg = apSegment[i]; - while( fts3SegReaderTermCmp(pSeg, zTerm, nTerm)<0 ){ - rc = fts3SegReaderNext(pSeg); - if( rc!=SQLITE_OK ) goto finished; } + for(i=0; pCsr->bRestart==0 && i<pCsr->nSegment; i++){ + Fts3SegReader *pSeg = pCsr->apSegment[i]; + do { + int rc = fts3SegReaderNext(p, pSeg, 0); + if( rc!=SQLITE_OK ) return rc; + }while( zTerm && fts3SegReaderTermCmp(pSeg, zTerm, nTerm)<0 ); + } + fts3SegReaderSort(pCsr->apSegment, nSeg, nSeg, fts3SegReaderCmp); + + return SQLITE_OK; +} + +SQLITE_PRIVATE int sqlite3Fts3SegReaderStart( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr, /* Cursor object */ + Fts3SegFilter *pFilter /* Restrictions on range of iteration */ +){ + pCsr->pFilter = pFilter; + return fts3SegReaderStart(p, pCsr, pFilter->zTerm, pFilter->nTerm); +} + +SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr, /* Cursor object */ + int iCol, /* Column to match on. */ + const char *zTerm, /* Term to iterate through a doclist for */ + int nTerm /* Number of bytes in zTerm */ +){ + int i; + int rc; + int nSegment = pCsr->nSegment; + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( + p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp + ); + + assert( pCsr->pFilter==0 ); + assert( zTerm && nTerm>0 ); + + /* Advance each segment iterator until it points to the term zTerm/nTerm. */ + rc = fts3SegReaderStart(p, pCsr, zTerm, nTerm); + if( rc!=SQLITE_OK ) return rc; + + /* Determine how many of the segments actually point to zTerm/nTerm. */ + for(i=0; i<nSegment; i++){ + Fts3SegReader *pSeg = pCsr->apSegment[i]; + if( !pSeg->aNode || fts3SegReaderTermCmp(pSeg, zTerm, nTerm) ){ + break; } } + pCsr->nAdvance = i; + + /* Advance each of the segments to point to the first docid. */ + for(i=0; i<pCsr->nAdvance; i++){ + rc = fts3SegReaderFirstDocid(p, pCsr->apSegment[i]); + if( rc!=SQLITE_OK ) return rc; + } + fts3SegReaderSort(pCsr->apSegment, i, i, xCmp); + + assert( iCol<0 || iCol<p->nColumn ); + pCsr->iColFilter = iCol; + + return SQLITE_OK; +} - fts3SegReaderSort(apSegment, nSegment, nSegment, fts3SegReaderCmp); - while( apSegment[0]->aNode ){ - int nTerm = apSegment[0]->nTerm; - char *zTerm = apSegment[0]->zTerm; - int nMerge = 1; +/* +** This function is called on a MultiSegReader that has been started using +** sqlite3Fts3MsrIncrStart(). One or more calls to MsrIncrNext() may also +** have been made. Calling this function puts the MultiSegReader in such +** a state that if the next two calls are: +** +** sqlite3Fts3SegReaderStart() +** sqlite3Fts3SegReaderStep() +** +** then the entire doclist for the term is available in +** MultiSegReader.aDoclist/nDoclist. +*/ +SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){ + int i; /* Used to iterate through segment-readers */ + + assert( pCsr->zTerm==0 ); + assert( pCsr->nTerm==0 ); + assert( pCsr->aDoclist==0 ); + assert( pCsr->nDoclist==0 ); + + pCsr->nAdvance = 0; + pCsr->bRestart = 1; + for(i=0; i<pCsr->nSegment; i++){ + pCsr->apSegment[i]->pOffsetList = 0; + pCsr->apSegment[i]->nOffsetList = 0; + pCsr->apSegment[i]->iDocid = 0; + } + + return SQLITE_OK; +} + + +SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr /* Cursor object */ +){ + int rc = SQLITE_OK; + + int isIgnoreEmpty = (pCsr->pFilter->flags & FTS3_SEGMENT_IGNORE_EMPTY); + int isRequirePos = (pCsr->pFilter->flags & FTS3_SEGMENT_REQUIRE_POS); + int isColFilter = (pCsr->pFilter->flags & FTS3_SEGMENT_COLUMN_FILTER); + int isPrefix = (pCsr->pFilter->flags & FTS3_SEGMENT_PREFIX); + int isScan = (pCsr->pFilter->flags & FTS3_SEGMENT_SCAN); + + Fts3SegReader **apSegment = pCsr->apSegment; + int nSegment = pCsr->nSegment; + Fts3SegFilter *pFilter = pCsr->pFilter; + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( + p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp + ); + + if( pCsr->nSegment==0 ) return SQLITE_OK; + + do { + int nMerge; + int i; + + /* Advance the first pCsr->nAdvance entries in the apSegment[] array + ** forward. Then sort the list in order of current term again. + */ + for(i=0; i<pCsr->nAdvance; i++){ + rc = fts3SegReaderNext(p, apSegment[i], 0); + if( rc!=SQLITE_OK ) return rc; + } + fts3SegReaderSort(apSegment, nSegment, pCsr->nAdvance, fts3SegReaderCmp); + pCsr->nAdvance = 0; + + /* If all the seg-readers are at EOF, we're finished. return SQLITE_OK. */ + assert( rc==SQLITE_OK ); + if( apSegment[0]->aNode==0 ) break; + + pCsr->nTerm = apSegment[0]->nTerm; + pCsr->zTerm = apSegment[0]->zTerm; /* If this is a prefix-search, and if the term that apSegment[0] points - ** to does not share a suffix with pFilter->zTerm/nTerm, then all + ** to does not share a suffix with pFilter->zTerm/nTerm, then all ** required callbacks have been made. In this case exit early. ** ** Similarly, if this is a search for an exact match, and the first term ** of segment apSegment[0] is not a match, exit early. */ - if( pFilter->zTerm ){ - if( nTerm<pFilter->nTerm - || (!isPrefix && nTerm>pFilter->nTerm) - || memcmp(zTerm, pFilter->zTerm, pFilter->nTerm) - ){ - goto finished; + if( pFilter->zTerm && !isScan ){ + if( pCsr->nTerm<pFilter->nTerm + || (!isPrefix && pCsr->nTerm>pFilter->nTerm) + || memcmp(pCsr->zTerm, pFilter->zTerm, pFilter->nTerm) + ){ + break; } } - while( nMerge<nSegment + nMerge = 1; + while( nMerge<nSegment && apSegment[nMerge]->aNode - && apSegment[nMerge]->nTerm==nTerm - && 0==memcmp(zTerm, apSegment[nMerge]->zTerm, nTerm) + && apSegment[nMerge]->nTerm==pCsr->nTerm + && 0==memcmp(pCsr->zTerm, apSegment[nMerge]->zTerm, pCsr->nTerm) ){ nMerge++; } assert( isIgnoreEmpty || (isRequirePos && !isColFilter) ); - if( nMerge==1 && !isIgnoreEmpty ){ - Fts3SegReader *p0 = apSegment[0]; - rc = xFunc(p, pContext, zTerm, nTerm, p0->aDoclist, p0->nDoclist); - if( rc!=SQLITE_OK ) goto finished; + if( nMerge==1 + && !isIgnoreEmpty + && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0) + ){ + pCsr->nDoclist = apSegment[0]->nDoclist; + if( fts3SegReaderIsPending(apSegment[0]) ){ + 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; }else{ int nDoclist = 0; /* Size of doclist */ sqlite3_int64 iPrev = 0; /* Previous docid stored in doclist */ /* The current term of the first nMerge entries in the array ** of Fts3SegReader objects is the same. The doclists must be merged - ** and a single term added to the new segment. + ** and a single term returned with the merged doclist. */ for(i=0; i<nMerge; i++){ - fts3SegReaderFirstDocid(apSegment[i]); + fts3SegReaderFirstDocid(p, apSegment[i]); } - fts3SegReaderSort(apSegment, nMerge, nMerge, fts3SegReaderDoclistCmp); + fts3SegReaderSort(apSegment, nMerge, nMerge, xCmp); while( apSegment[0]->pOffsetList ){ int j; /* Number of segments that share a docid */ char *pList; int nList; int nByte; sqlite3_int64 iDocid = apSegment[0]->iDocid; - fts3SegReaderNextDocid(apSegment[0], &pList, &nList); + fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList); j = 1; while( j<nMerge && apSegment[j]->pOffsetList && apSegment[j]->iDocid==iDocid ){ - fts3SegReaderNextDocid(apSegment[j], 0, 0); + fts3SegReaderNextDocid(p, apSegment[j], 0, 0); j++; } @@ -107035,217 +124843,165 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderIterate( } if( !isIgnoreEmpty || nList>0 ){ - nByte = sqlite3Fts3VarintLen(iDocid-iPrev) + (isRequirePos?nList+1:0); - if( nDoclist+nByte>nAlloc ){ + + /* Calculate the 'docid' delta value to write into the merged + ** doclist. */ + sqlite3_int64 iDelta; + if( p->bDescIdx && nDoclist>0 ){ + iDelta = iPrev - iDocid; + }else{ + iDelta = iDocid - iPrev; + } + assert( iDelta>0 || (nDoclist==0 && iDelta==iDocid) ); + assert( nDoclist>0 || iDelta==iDocid ); + + nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); + if( nDoclist+nByte>pCsr->nBuffer ){ char *aNew; - nAlloc = nDoclist+nByte*2; - aNew = sqlite3_realloc(aBuffer, nAlloc); + pCsr->nBuffer = (nDoclist+nByte)*2; + aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer); if( !aNew ){ - rc = SQLITE_NOMEM; - goto finished; + return SQLITE_NOMEM; } - aBuffer = aNew; + pCsr->aBuffer = aNew; } - nDoclist += sqlite3Fts3PutVarint(&aBuffer[nDoclist], iDocid-iPrev); + nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta); iPrev = iDocid; if( isRequirePos ){ - memcpy(&aBuffer[nDoclist], pList, nList); + memcpy(&pCsr->aBuffer[nDoclist], pList, nList); nDoclist += nList; - aBuffer[nDoclist++] = '\0'; + pCsr->aBuffer[nDoclist++] = '\0'; } } - fts3SegReaderSort(apSegment, nMerge, j, fts3SegReaderDoclistCmp); + fts3SegReaderSort(apSegment, nMerge, j, xCmp); } - if( nDoclist>0 ){ - rc = xFunc(p, pContext, zTerm, nTerm, aBuffer, nDoclist); - if( rc!=SQLITE_OK ) goto finished; + pCsr->aDoclist = pCsr->aBuffer; + pCsr->nDoclist = nDoclist; + rc = SQLITE_ROW; } } + pCsr->nAdvance = nMerge; + }while( rc==SQLITE_OK ); - /* If there is a term specified to filter on, and this is not a prefix - ** search, return now. The callback that corresponds to the required - ** term (if such a term exists in the index) has already been made. - */ - if( pFilter->zTerm && !isPrefix ){ - goto finished; - } + return rc; +} - for(i=0; i<nMerge; i++){ - rc = fts3SegReaderNext(apSegment[i]); - if( rc!=SQLITE_OK ) goto finished; + +SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish( + Fts3MultiSegReader *pCsr /* Cursor object */ +){ + if( pCsr ){ + int i; + for(i=0; i<pCsr->nSegment; i++){ + sqlite3Fts3SegReaderFree(pCsr->apSegment[i]); } - fts3SegReaderSort(apSegment, nSegment, nMerge, fts3SegReaderCmp); - } + sqlite3_free(pCsr->apSegment); + sqlite3_free(pCsr->aBuffer); - finished: - sqlite3_free(aBuffer); - return rc; + pCsr->nSegment = 0; + pCsr->apSegment = 0; + pCsr->aBuffer = 0; + } } /* -** Merge all level iLevel segments in the database into a single +** Merge all level iLevel segments in the database into a single ** iLevel+1 segment. Or, if iLevel<0, merge all segments into a -** single segment with a level equal to the numerically largest level +** single segment with a level equal to the numerically largest level ** currently present in the database. ** ** If this function is called with iLevel<0, but there is only one -** segment in the database, SQLITE_DONE is returned immediately. -** Otherwise, if successful, SQLITE_OK is returned. If an error occurs, +** segment in the database, SQLITE_DONE is returned immediately. +** Otherwise, if successful, SQLITE_OK is returned. If an error occurs, ** an SQLite error code is returned. */ -static int fts3SegmentMerge(Fts3Table *p, int iLevel){ - int i; /* Iterator variable */ +static int fts3SegmentMerge(Fts3Table *p, int iIndex, int iLevel){ int rc; /* Return code */ - int iIdx; /* Index of new segment */ - int iNewLevel; /* Level to create new segment at */ - sqlite3_stmt *pStmt = 0; - SegmentWriter *pWriter = 0; - int nSegment = 0; /* Number of segments being merged */ - Fts3SegReader **apSegment = 0; /* Array of Segment iterators */ - Fts3SegReader *pPending = 0; /* Iterator for pending-terms */ + int iIdx = 0; /* Index of new segment */ + int iNewLevel = 0; /* Level/index to create new segment at */ + SegmentWriter *pWriter = 0; /* Used to write the new, merged, segment */ Fts3SegFilter filter; /* Segment term filter condition */ + Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */ + int bIgnoreEmpty = 0; /* True to ignore empty segments */ - if( iLevel<0 ){ - /* This call is to merge all segments in the database to a single - ** segment. The level of the new segment is equal to the the numerically - ** greatest segment level currently present in the database. The index - ** of the new segment is always 0. - */ - iIdx = 0; - rc = sqlite3Fts3SegReaderPending(p, 0, 0, 1, &pPending); - if( rc!=SQLITE_OK ) goto finished; - rc = fts3SegmentCountMax(p, &nSegment, &iNewLevel); - if( rc!=SQLITE_OK ) goto finished; - nSegment += (pPending!=0); - if( nSegment<=1 ){ - return SQLITE_DONE; - } - }else{ - /* This call is to merge all segments at level iLevel. Find the next - ** available segment index at level iLevel+1. The call to - ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to - ** a single iLevel+2 segment if necessary. - */ - iNewLevel = iLevel+1; - rc = fts3AllocateSegdirIdx(p, iNewLevel, &iIdx); - if( rc!=SQLITE_OK ) goto finished; - rc = fts3SegmentCount(p, iLevel, &nSegment); - if( rc!=SQLITE_OK ) goto finished; - } - assert( nSegment>0 ); - assert( iNewLevel>=0 ); + assert( iLevel==FTS3_SEGCURSOR_ALL + || iLevel==FTS3_SEGCURSOR_PENDING + || iLevel>=0 + ); + assert( iLevel<FTS3_SEGDIR_MAXLEVEL ); + assert( iIndex>=0 && iIndex<p->nIndex ); - /* Allocate space for an array of pointers to segment iterators. */ - apSegment = (Fts3SegReader**)sqlite3_malloc(sizeof(Fts3SegReader *)*nSegment); - if( !apSegment ){ - rc = SQLITE_NOMEM; - goto finished; - } - memset(apSegment, 0, sizeof(Fts3SegReader *)*nSegment); + rc = sqlite3Fts3SegReaderCursor(p, iIndex, iLevel, 0, 0, 1, 0, &csr); + if( rc!=SQLITE_OK || csr.nSegment==0 ) goto finished; - /* Allocate a Fts3SegReader structure for each segment being merged. A - ** Fts3SegReader stores the state data required to iterate through all - ** entries on all leaves of a single segment. - */ - assert( SQL_SELECT_LEVEL+1==SQL_SELECT_ALL_LEVEL); - rc = fts3SqlStmt(p, SQL_SELECT_LEVEL+(iLevel<0), &pStmt, 0); - if( rc!=SQLITE_OK ) goto finished; - sqlite3_bind_int(pStmt, 1, iLevel); - for(i=0; SQLITE_ROW==(sqlite3_step(pStmt)); i++){ - rc = fts3SegReaderNew(p, pStmt, i, &apSegment[i]); - if( rc!=SQLITE_OK ){ + if( iLevel==FTS3_SEGCURSOR_ALL ){ + /* This call is to merge all segments in the database to a single + ** segment. The level of the new segment is equal to the the numerically + ** greatest segment level currently present in the database for this + ** index. The idx of the new segment is always 0. */ + if( csr.nSegment==1 ){ + rc = SQLITE_DONE; goto finished; } + rc = fts3SegmentMaxLevel(p, iIndex, &iNewLevel); + bIgnoreEmpty = 1; + + }else if( iLevel==FTS3_SEGCURSOR_PENDING ){ + iNewLevel = iIndex * FTS3_SEGDIR_MAXLEVEL; + rc = fts3AllocateSegdirIdx(p, iIndex, 0, &iIdx); + }else{ + /* This call is to merge all segments at level iLevel. find the next + ** available segment index at level iLevel+1. The call to + ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to + ** a single iLevel+2 segment if necessary. */ + rc = fts3AllocateSegdirIdx(p, iIndex, iLevel+1, &iIdx); + iNewLevel = iIndex * FTS3_SEGDIR_MAXLEVEL + iLevel+1; } - rc = sqlite3_reset(pStmt); - if( pPending ){ - apSegment[i] = pPending; - pPending = 0; - } - pStmt = 0; if( rc!=SQLITE_OK ) goto finished; + assert( csr.nSegment>0 ); + assert( iNewLevel>=(iIndex*FTS3_SEGDIR_MAXLEVEL) ); + assert( iNewLevel<((iIndex+1)*FTS3_SEGDIR_MAXLEVEL) ); memset(&filter, 0, sizeof(Fts3SegFilter)); filter.flags = FTS3_SEGMENT_REQUIRE_POS; - filter.flags |= (iLevel<0 ? FTS3_SEGMENT_IGNORE_EMPTY : 0); - rc = sqlite3Fts3SegReaderIterate(p, apSegment, nSegment, - &filter, fts3MergeCallback, (void *)&pWriter - ); + filter.flags |= (bIgnoreEmpty ? FTS3_SEGMENT_IGNORE_EMPTY : 0); + + rc = sqlite3Fts3SegReaderStart(p, &csr, &filter); + while( SQLITE_OK==rc ){ + rc = sqlite3Fts3SegReaderStep(p, &csr); + if( rc!=SQLITE_ROW ) break; + rc = fts3SegWriterAdd(p, &pWriter, 1, + csr.zTerm, csr.nTerm, csr.aDoclist, csr.nDoclist); + } if( rc!=SQLITE_OK ) goto finished; + assert( pWriter ); - rc = fts3DeleteSegdir(p, iLevel, apSegment, nSegment); - if( rc==SQLITE_OK ){ - rc = fts3SegWriterFlush(p, pWriter, iNewLevel, iIdx); + if( iLevel!=FTS3_SEGCURSOR_PENDING ){ + rc = fts3DeleteSegdir(p, iIndex, iLevel, csr.apSegment, csr.nSegment); + if( rc!=SQLITE_OK ) goto finished; } + rc = fts3SegWriterFlush(p, pWriter, iNewLevel, iIdx); finished: fts3SegWriterFree(pWriter); - if( apSegment ){ - for(i=0; i<nSegment; i++){ - sqlite3Fts3SegReaderFree(p, apSegment[i]); - } - sqlite3_free(apSegment); - } - sqlite3Fts3SegReaderFree(p, pPending); - sqlite3_reset(pStmt); + sqlite3Fts3SegReaderFinish(&csr); return rc; } -/* -** Flush the contents of pendingTerms to a level 0 segment. +/* +** Flush the contents of pendingTerms to level 0 segments. */ SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ - int rc; /* Return Code */ - int idx; /* Index of new segment created */ - SegmentWriter *pWriter = 0; /* Used to write the segment */ - Fts3SegReader *pReader = 0; /* Used to iterate through the hash table */ - - /* Allocate a SegReader object to iterate through the contents of the - ** pending-terms table. If an error occurs, or if there are no terms - ** in the pending-terms table, return immediately. - */ - rc = sqlite3Fts3SegReaderPending(p, 0, 0, 1, &pReader); - if( rc!=SQLITE_OK || pReader==0 ){ - return rc; - } - - /* Determine the next index at level 0. If level 0 is already full, this - ** call may merge all existing level 0 segments into a single level 1 - ** segment. - */ - rc = fts3AllocateSegdirIdx(p, 0, &idx); - - /* If no errors have occured, iterate through the contents of the - ** pending-terms hash table using the Fts3SegReader iterator. The callback - ** writes each term (along with its doclist) to the database via the - ** SegmentWriter handle pWriter. - */ - if( rc==SQLITE_OK ){ - void *c = (void *)&pWriter; /* SegReaderIterate() callback context */ - Fts3SegFilter f; /* SegReaderIterate() parameters */ - - memset(&f, 0, sizeof(Fts3SegFilter)); - f.flags = FTS3_SEGMENT_REQUIRE_POS; - rc = sqlite3Fts3SegReaderIterate(p, &pReader, 1, &f, fts3FlushCallback, c); - } - assert( pWriter || rc!=SQLITE_OK ); - - /* If no errors have occured, flush the SegmentWriter object to the - ** database. Then delete the SegmentWriter and Fts3SegReader objects - ** allocated by this function. - */ - if( rc==SQLITE_OK ){ - rc = fts3SegWriterFlush(p, pWriter, 0, idx); - } - fts3SegWriterFree(pWriter); - sqlite3Fts3SegReaderFree(p, pReader); - - if( rc==SQLITE_OK ){ - sqlite3Fts3PendingTermsClear(p); + int rc = SQLITE_OK; + int i; + for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){ + rc = fts3SegmentMerge(p, i, FTS3_SEGCURSOR_PENDING); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; } + sqlite3Fts3PendingTermsClear(p); return rc; } @@ -107285,75 +125041,6 @@ static void fts3DecodeIntArray( } /* -** Fill in the document size auxiliary information for the matchinfo -** structure. The auxiliary information is: -** -** N Total number of documents in the full-text index -** a0 Average length of column 0 over the whole index -** n0 Length of column 0 on the matching row -** ... -** aM Average length of column M over the whole index -** nM Length of column M on the matching row -** -** The fts3MatchinfoDocsizeLocal() routine fills in the nX values. -** The fts3MatchinfoDocsizeGlobal() routine fills in N and the aX values. -*/ -SQLITE_PRIVATE int sqlite3Fts3MatchinfoDocsizeLocal(Fts3Cursor *pCur, u32 *a){ - const char *pBlob; /* The BLOB holding %_docsize info */ - int nBlob; /* Size of the BLOB */ - sqlite3_stmt *pStmt; /* Statement for reading and writing */ - int i, j; /* Loop counters */ - sqlite3_int64 x; /* Varint value */ - int rc; /* Result code from subfunctions */ - Fts3Table *p; /* The FTS table */ - - p = (Fts3Table*)pCur->base.pVtab; - rc = fts3SqlStmt(p, SQL_SELECT_DOCSIZE, &pStmt, 0); - if( rc ){ - return rc; - } - sqlite3_bind_int64(pStmt, 1, pCur->iPrevId); - if( sqlite3_step(pStmt)==SQLITE_ROW ){ - nBlob = sqlite3_column_bytes(pStmt, 0); - pBlob = (const char*)sqlite3_column_blob(pStmt, 0); - for(i=j=0; i<p->nColumn && j<nBlob; i++){ - j = sqlite3Fts3GetVarint(&pBlob[j], &x); - a[2+i*2] = (u32)(x & 0xffffffff); - } - } - sqlite3_reset(pStmt); - return SQLITE_OK; -} -SQLITE_PRIVATE int sqlite3Fts3MatchinfoDocsizeGlobal(Fts3Cursor *pCur, u32 *a){ - const char *pBlob; /* The BLOB holding %_stat info */ - int nBlob; /* Size of the BLOB */ - sqlite3_stmt *pStmt; /* Statement for reading and writing */ - int i, j; /* Loop counters */ - sqlite3_int64 x; /* Varint value */ - int nDoc; /* Number of documents */ - int rc; /* Result code from subfunctions */ - Fts3Table *p; /* The FTS table */ - - p = (Fts3Table*)pCur->base.pVtab; - rc = fts3SqlStmt(p, SQL_SELECT_DOCTOTAL, &pStmt, 0); - if( rc ){ - return rc; - } - if( sqlite3_step(pStmt)==SQLITE_ROW ){ - nBlob = sqlite3_column_bytes(pStmt, 0); - pBlob = (const char*)sqlite3_column_blob(pStmt, 0); - j = sqlite3Fts3GetVarint(pBlob, &x); - a[0] = nDoc = (u32)(x & 0xffffffff); - for(i=0; i<p->nColumn && j<nBlob; i++){ - j = sqlite3Fts3GetVarint(&pBlob[j], &x); - a[1+i*2] = ((u32)(x & 0xffffffff) + nDoc/2)/nDoc; - } - } - sqlite3_reset(pStmt); - return SQLITE_OK; -} - -/* ** Insert the sizes (in tokens) for each column of the document ** with docid equal to p->iPrevDocid. The sizes are encoded as ** a blob of varints. @@ -107388,16 +125075,26 @@ static void fts3InsertDocsize( } /* -** Update the 0 record of the %_stat table so that it holds a blob -** which contains the document count followed by the cumulative -** document sizes for all columns. +** Record 0 of the %_stat table contains a blob consisting of N varints, +** where N is the number of user defined columns in the fts3 table plus +** two. If nCol is the number of user defined columns, then values of the +** varints are set as follows: +** +** Varint 0: Total number of rows in the table. +** +** Varint 1..nCol: For each column, the total number of tokens stored in +** the column for all rows of the table. +** +** Varint 1+nCol: The total size, in bytes, of all text values in all +** columns of all rows of the table. +** */ static void fts3UpdateDocTotals( - int *pRC, /* The result code */ - Fts3Table *p, /* Table being updated */ - u32 *aSzIns, /* Size increases */ - u32 *aSzDel, /* Size decreases */ - int nChng /* Change in the number of documents */ + int *pRC, /* The result code */ + Fts3Table *p, /* Table being updated */ + u32 *aSzIns, /* Size increases */ + u32 *aSzDel, /* Size decreases */ + int nChng /* Change in the number of documents */ ){ char *pBlob; /* Storage for BLOB written into %_stat */ int nBlob; /* Size of BLOB written into %_stat */ @@ -107406,13 +125103,15 @@ static void fts3UpdateDocTotals( int i; /* Loop counter */ int rc; /* Result code from subfunctions */ + const int nStat = p->nColumn+2; + if( *pRC ) return; - a = sqlite3_malloc( (sizeof(u32)+10)*(p->nColumn+1) ); + a = sqlite3_malloc( (sizeof(u32)+10)*nStat ); if( a==0 ){ *pRC = SQLITE_NOMEM; return; } - pBlob = (char*)&a[p->nColumn+1]; + pBlob = (char*)&a[nStat]; rc = fts3SqlStmt(p, SQL_SELECT_DOCTOTAL, &pStmt, 0); if( rc ){ sqlite3_free(a); @@ -107420,11 +125119,11 @@ static void fts3UpdateDocTotals( return; } if( sqlite3_step(pStmt)==SQLITE_ROW ){ - fts3DecodeIntArray(p->nColumn+1, a, + fts3DecodeIntArray(nStat, a, sqlite3_column_blob(pStmt, 0), sqlite3_column_bytes(pStmt, 0)); }else{ - memset(a, 0, sizeof(u32)*(p->nColumn+1) ); + memset(a, 0, sizeof(u32)*(nStat) ); } sqlite3_reset(pStmt); if( nChng<0 && a[0]<(u32)(-nChng) ){ @@ -107432,7 +125131,7 @@ static void fts3UpdateDocTotals( }else{ a[0] += nChng; } - for(i=0; i<p->nColumn; i++){ + for(i=0; i<p->nColumn+1; i++){ u32 x = a[i+1]; if( x+aSzIns[i] < aSzDel[i] ){ x = 0; @@ -107441,7 +125140,7 @@ static void fts3UpdateDocTotals( } a[i+1] = x; } - fts3EncodeIntArray(p->nColumn+1, a, pBlob, &nBlob); + fts3EncodeIntArray(nStat, a, pBlob, &nBlob); rc = fts3SqlStmt(p, SQL_REPLACE_DOCTOTAL, &pStmt, 0); if( rc ){ sqlite3_free(a); @@ -107454,12 +125153,29 @@ static void fts3UpdateDocTotals( sqlite3_free(a); } +static int fts3DoOptimize(Fts3Table *p, int bReturnDone){ + int i; + int bSeenDone = 0; + int rc = SQLITE_OK; + for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){ + rc = fts3SegmentMerge(p, i, FTS3_SEGCURSOR_ALL); + if( rc==SQLITE_DONE ){ + bSeenDone = 1; + rc = SQLITE_OK; + } + } + sqlite3Fts3SegmentsClose(p); + sqlite3Fts3PendingTermsClear(p); + + return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc; +} + /* ** Handle a 'special' INSERT of the form: ** ** "INSERT INTO tbl(tbl) VALUES(<expr>)" ** -** Argument pVal contains the result of <expr>. Currently the only +** Argument pVal contains the result of <expr>. Currently the only ** meaningful value to insert is the text 'optimize'. */ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ @@ -107470,12 +125186,7 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ if( !zVal ){ return SQLITE_NOMEM; }else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){ - rc = fts3SegmentMerge(p, -1); - if( rc==SQLITE_DONE ){ - rc = SQLITE_OK; - }else{ - sqlite3Fts3PendingTermsClear(p); - } + rc = fts3DoOptimize(p, 0); #ifdef SQLITE_TEST }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ p->nNodeSize = atoi(&zVal[9]); @@ -107492,6 +125203,179 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ } /* +** Delete all cached deferred doclists. Deferred doclists are cached +** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function. +*/ +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *pCsr){ + Fts3DeferredToken *pDef; + for(pDef=pCsr->pDeferred; pDef; pDef=pDef->pNext){ + fts3PendingListDelete(pDef->pList); + pDef->pList = 0; + } +} + +/* +** Free all entries in the pCsr->pDeffered list. Entries are added to +** this list using sqlite3Fts3DeferToken(). +*/ +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *pCsr){ + Fts3DeferredToken *pDef; + Fts3DeferredToken *pNext; + for(pDef=pCsr->pDeferred; pDef; pDef=pNext){ + pNext = pDef->pNext; + fts3PendingListDelete(pDef->pList); + sqlite3_free(pDef); + } + pCsr->pDeferred = 0; +} + +/* +** Generate deferred-doclists for all tokens in the pCsr->pDeferred list +** based on the row that pCsr currently points to. +** +** A deferred-doclist is like any other doclist with position information +** included, except that it only contains entries for a single row of the +** table, not for all rows. +*/ +SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){ + int rc = SQLITE_OK; /* Return code */ + if( pCsr->pDeferred ){ + int i; /* Used to iterate through table columns */ + sqlite3_int64 iDocid; /* Docid of the row pCsr points to */ + Fts3DeferredToken *pDef; /* Used to iterate through deferred tokens */ + + Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; + sqlite3_tokenizer *pT = p->pTokenizer; + sqlite3_tokenizer_module const *pModule = pT->pModule; + + assert( pCsr->isRequireSeek==0 ); + iDocid = sqlite3_column_int64(pCsr->pStmt, 0); + + for(i=0; i<p->nColumn && rc==SQLITE_OK; i++){ + const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1); + sqlite3_tokenizer_cursor *pTC = 0; + + rc = pModule->xOpen(pT, zText, -1, &pTC); + while( rc==SQLITE_OK ){ + char const *zToken; /* Buffer containing token */ + int nToken; /* Number of bytes in token */ + int iDum1, iDum2; /* Dummy variables */ + int iPos; /* Position of token in zText */ + + pTC->pTokenizer = pT; + rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos); + for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ + Fts3PhraseToken *pPT = pDef->pToken; + if( (pDef->iCol>=p->nColumn || pDef->iCol==i) + && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken)) + && (0==memcmp(zToken, pPT->z, pPT->n)) + ){ + fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc); + } + } + } + if( pTC ) pModule->xClose(pTC); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + + for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ + if( pDef->pList ){ + rc = fts3PendingListAppendVarint(&pDef->pList, 0); + } + } + } + + return rc; +} + +SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList( + Fts3DeferredToken *p, + char **ppData, + int *pnData +){ + char *pRet; + int nSkip; + sqlite3_int64 dummy; + + *ppData = 0; + *pnData = 0; + + if( p->pList==0 ){ + return SQLITE_OK; + } + + 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; + + memcpy(pRet, &p->pList->aData[nSkip], *pnData); + return SQLITE_OK; +} + +/* +** Add an entry for token pToken to the pCsr->pDeferred list. +*/ +SQLITE_PRIVATE int sqlite3Fts3DeferToken( + Fts3Cursor *pCsr, /* Fts3 table cursor */ + Fts3PhraseToken *pToken, /* Token to defer */ + int iCol /* Column that token must appear in (or -1) */ +){ + Fts3DeferredToken *pDeferred; + pDeferred = sqlite3_malloc(sizeof(*pDeferred)); + if( !pDeferred ){ + return SQLITE_NOMEM; + } + memset(pDeferred, 0, sizeof(*pDeferred)); + pDeferred->pToken = pToken; + pDeferred->pNext = pCsr->pDeferred; + pDeferred->iCol = iCol; + pCsr->pDeferred = pDeferred; + + assert( pToken->pDeferred==0 ); + pToken->pDeferred = pDeferred; + + return SQLITE_OK; +} + +/* +** SQLite value pRowid contains the rowid of a row that may or may not be +** present in the FTS3 table. If it is, delete it and adjust the contents +** of subsiduary data structures accordingly. +*/ +static int fts3DeleteByRowid( + Fts3Table *p, + sqlite3_value *pRowid, + int *pnDoc, + u32 *aSzDel +){ + int isEmpty = 0; + int rc = fts3IsEmpty(p, pRowid, &isEmpty); + if( rc==SQLITE_OK ){ + if( isEmpty ){ + /* Deleting this row means the whole table is empty. In this case + ** delete the contents of all three tables and throw away any + ** data in the pendingTerms hash table. */ + rc = fts3DeleteAll(p); + *pnDoc = *pnDoc - 1; + }else{ + sqlite3_int64 iRemove = sqlite3_value_int64(pRowid); + rc = fts3PendingTermsDocid(p, iRemove); + fts3DeleteTerms(&rc, p, pRowid, aSzDel); + fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid); + if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1; + if( p->bHasDocsize ){ + fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid); + } + } + } + + return rc; +} + +/* ** This function does the work for the xUpdate method of FTS3 virtual ** tables. */ @@ -107505,48 +125389,97 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod( int rc = SQLITE_OK; /* Return Code */ int isRemove = 0; /* True for an UPDATE or DELETE */ sqlite3_int64 iRemove = 0; /* Rowid removed by UPDATE or DELETE */ - u32 *aSzIns; /* Sizes of inserted documents */ + u32 *aSzIns = 0; /* Sizes of inserted documents */ u32 *aSzDel; /* Sizes of deleted documents */ int nChng = 0; /* Net change in number of documents */ + int bInsertDone = 0; + assert( p->pSegments==0 ); + + /* Check for a "special" INSERT operation. One of the form: + ** + ** INSERT INTO xyz(xyz) VALUES('command'); + */ + if( nArg>1 + && sqlite3_value_type(apVal[0])==SQLITE_NULL + && sqlite3_value_type(apVal[p->nColumn+2])!=SQLITE_NULL + ){ + rc = fts3SpecialInsert(p, apVal[p->nColumn+2]); + goto update_out; + } /* Allocate space to hold the change in document sizes */ - aSzIns = sqlite3_malloc( sizeof(aSzIns[0])*p->nColumn*2 ); - if( aSzIns==0 ) return SQLITE_NOMEM; - aSzDel = &aSzIns[p->nColumn]; - memset(aSzIns, 0, sizeof(aSzIns[0])*p->nColumn*2); + aSzIns = sqlite3_malloc( sizeof(aSzIns[0])*(p->nColumn+1)*2 ); + if( aSzIns==0 ){ + rc = SQLITE_NOMEM; + goto update_out; + } + aSzDel = &aSzIns[p->nColumn+1]; + memset(aSzIns, 0, sizeof(aSzIns[0])*(p->nColumn+1)*2); - /* If this is a DELETE or UPDATE operation, remove the old record. */ - if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ - int isEmpty; - rc = fts3IsEmpty(p, apVal, &isEmpty); - if( rc==SQLITE_OK ){ - if( isEmpty ){ - /* Deleting this row means the whole table is empty. In this case - ** delete the contents of all three tables and throw away any - ** data in the pendingTerms hash table. - */ - rc = fts3DeleteAll(p); + /* If this is an INSERT operation, or an UPDATE that modifies the rowid + ** value, then this operation requires constraint handling. + ** + ** If the on-conflict mode is REPLACE, this means that the existing row + ** should be deleted from the database before inserting the new row. Or, + ** if the on-conflict mode is other than REPLACE, then this method must + ** detect the conflict and return SQLITE_CONSTRAINT before beginning to + ** modify the database file. + */ + if( nArg>1 ){ + /* Find the value object that holds the new rowid value. */ + sqlite3_value *pNewRowid = apVal[3+p->nColumn]; + if( sqlite3_value_type(pNewRowid)==SQLITE_NULL ){ + pNewRowid = apVal[1]; + } + + if( sqlite3_value_type(pNewRowid)!=SQLITE_NULL && ( + sqlite3_value_type(apVal[0])==SQLITE_NULL + || sqlite3_value_int64(apVal[0])!=sqlite3_value_int64(pNewRowid) + )){ + /* The new rowid is not NULL (in this case the rowid will be + ** automatically assigned and there is no chance of a conflict), and + ** the statement is either an INSERT or an UPDATE that modifies the + ** rowid column. So if the conflict mode is REPLACE, then delete any + ** existing row with rowid=pNewRowid. + ** + ** Or, if the conflict mode is not REPLACE, insert the new record into + ** the %_content table. If we hit the duplicate rowid constraint (or any + ** other error) while doing so, return immediately. + ** + ** This branch may also run if pNewRowid contains a value that cannot + ** be losslessly converted to an integer. In this case, the eventual + ** call to fts3InsertData() (either just below or further on in this + ** function) will return SQLITE_MISMATCH. If fts3DeleteByRowid is + ** invoked, it will delete zero rows (since no row will have + ** docid=$pNewRowid if $pNewRowid is not an integer value). + */ + if( sqlite3_vtab_on_conflict(p->db)==SQLITE_REPLACE ){ + rc = fts3DeleteByRowid(p, pNewRowid, &nChng, aSzDel); }else{ - isRemove = 1; - iRemove = sqlite3_value_int64(apVal[0]); - rc = fts3PendingTermsDocid(p, iRemove); - fts3DeleteTerms(&rc, p, apVal, aSzDel); - fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, apVal); - if( p->bHasDocsize ){ - fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, apVal); - nChng--; - } + rc = fts3InsertData(p, apVal, pRowid); + bInsertDone = 1; } } - }else if( sqlite3_value_type(apVal[p->nColumn+2])!=SQLITE_NULL ){ - sqlite3_free(aSzIns); - return fts3SpecialInsert(p, apVal[p->nColumn+2]); + } + if( rc!=SQLITE_OK ){ + goto update_out; } + /* If this is a DELETE or UPDATE operation, remove the old record. */ + if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ + assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER ); + rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel); + isRemove = 1; + iRemove = sqlite3_value_int64(apVal[0]); + } + /* If this is an INSERT or UPDATE operation, insert the new record. */ if( nArg>1 && rc==SQLITE_OK ){ - rc = fts3InsertData(p, apVal, pRowid); + if( bInsertDone==0 ){ + rc = fts3InsertData(p, apVal, pRowid); + if( rc==SQLITE_CONSTRAINT ) rc = SQLITE_CORRUPT_VTAB; + } if( rc==SQLITE_OK && (!isRemove || *pRowid!=iRemove) ){ rc = fts3PendingTermsDocid(p, *pRowid); } @@ -107554,39 +125487,40 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod( rc = fts3InsertTerms(p, apVal, aSzIns); } if( p->bHasDocsize ){ - nChng++; fts3InsertDocsize(&rc, p, aSzIns); } + nChng++; } - if( p->bHasDocsize ){ + if( p->bHasStat ){ fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nChng); } + update_out: sqlite3_free(aSzIns); + sqlite3Fts3SegmentsClose(p); return rc; } -/* +/* ** Flush any data in the pending-terms hash table to disk. If successful, -** merge all segments in the database (including the new segment, if -** there was any data to flush) into a single segment. +** merge all segments in the database (including the new segment, if +** there was any data to flush) into a single segment. */ SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){ int rc; rc = sqlite3_exec(p->db, "SAVEPOINT fts3", 0, 0, 0); if( rc==SQLITE_OK ){ - rc = fts3SegmentMerge(p, -1); - if( rc==SQLITE_OK ){ - rc = sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); - if( rc==SQLITE_OK ){ - sqlite3Fts3PendingTermsClear(p); - } + rc = fts3DoOptimize(p, 1); + if( rc==SQLITE_OK || rc==SQLITE_DONE ){ + int rc2 = sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); + if( rc2!=SQLITE_OK ) rc = rc2; }else{ sqlite3_exec(p->db, "ROLLBACK TO fts3", 0, 0, 0); sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); } } + sqlite3Fts3SegmentsClose(p); return rc; } @@ -107609,6 +125543,24 @@ SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) +/* #include <string.h> */ +/* #include <assert.h> */ + +/* +** Characters that may appear in the second argument to matchinfo(). +*/ +#define FTS3_MATCHINFO_NPHRASE 'p' /* 1 value */ +#define FTS3_MATCHINFO_NCOL 'c' /* 1 value */ +#define FTS3_MATCHINFO_NDOC 'n' /* 1 value */ +#define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */ +#define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */ +#define FTS3_MATCHINFO_LCS 's' /* nCol values */ +#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */ + +/* +** The default value for the second argument to matchinfo(). +*/ +#define FTS3_MATCHINFO_DEFAULT "pcx" /* @@ -107617,13 +125569,13 @@ SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){ */ typedef struct LoadDoclistCtx LoadDoclistCtx; struct LoadDoclistCtx { - Fts3Table *pTab; /* FTS3 Table */ + Fts3Cursor *pCsr; /* FTS3 Cursor */ int nPhrase; /* Number of phrases seen so far */ int nToken; /* Number of tokens seen so far */ }; /* -** The following types are used as part of the implementation of the +** The following types are used as part of the implementation of the ** fts3BestSnippet() routine. */ typedef struct SnippetIter SnippetIter; @@ -107656,13 +125608,15 @@ struct SnippetFragment { }; /* -** This type is used as an fts3ExprIterate() 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 */ int nCol; /* Number of columns in table */ + int nPhrase; /* Number of matchable phrases in query */ + sqlite3_int64 nDoc; /* Number of docs in database */ u32 *aMatchinfo; /* Pre-allocated buffer */ }; @@ -107737,7 +125691,7 @@ static int fts3ExprIterate2( ** are part of a sub-tree that is the right-hand-side of a NOT operator. ** For each phrase node found, the supplied callback function is invoked. ** -** If the callback function returns anything other than SQLITE_OK, +** 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. @@ -107752,98 +125706,30 @@ static int fts3ExprIterate( } /* -** The argument to this function is always a phrase node. Its doclist -** (Fts3Expr.aDoclist[]) and the doclists associated with all phrase nodes -** to the left of this one in the query tree have already been loaded. -** -** If this phrase node is part of a series of phrase nodes joined by -** NEAR operators (and is not the left-most of said series), then elements are -** removed from the phrases doclist consistent with the NEAR restriction. If -** required, elements may be removed from the doclists of phrases to the -** left of this one that are part of the same series of NEAR operator -** connected phrases. -** -** If an OOM error occurs, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK. -*/ -static int fts3ExprNearTrim(Fts3Expr *pExpr){ - int rc = SQLITE_OK; - Fts3Expr *pParent = pExpr->pParent; - - assert( pExpr->eType==FTSQUERY_PHRASE ); - while( rc==SQLITE_OK - && pParent - && pParent->eType==FTSQUERY_NEAR - && pParent->pRight==pExpr - ){ - /* This expression (pExpr) is the right-hand-side of a NEAR operator. - ** Find the expression to the left of the same operator. - */ - int nNear = pParent->nNear; - Fts3Expr *pLeft = pParent->pLeft; - - if( pLeft->eType!=FTSQUERY_PHRASE ){ - assert( pLeft->eType==FTSQUERY_NEAR ); - assert( pLeft->pRight->eType==FTSQUERY_PHRASE ); - pLeft = pLeft->pRight; - } - - rc = sqlite3Fts3ExprNearTrim(pLeft, pExpr, nNear); - - pExpr = pLeft; - pParent = pExpr->pParent; - } - - return rc; -} - -/* ** This is an fts3ExprIterate() callback used while loading the doclists ** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also ** fts3ExprLoadDoclists(). */ -static int fts3ExprLoadDoclistsCb1(Fts3Expr *pExpr, int iPhrase, void *ctx){ +static int fts3ExprLoadDoclistsCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ int rc = SQLITE_OK; + Fts3Phrase *pPhrase = pExpr->pPhrase; LoadDoclistCtx *p = (LoadDoclistCtx *)ctx; UNUSED_PARAMETER(iPhrase); p->nPhrase++; - p->nToken += pExpr->pPhrase->nToken; - - if( pExpr->isLoaded==0 ){ - rc = sqlite3Fts3ExprLoadDoclist(p->pTab, pExpr); - pExpr->isLoaded = 1; - if( rc==SQLITE_OK ){ - rc = fts3ExprNearTrim(pExpr); - } - } + p->nToken += pPhrase->nToken; return rc; } /* -** This is an fts3ExprIterate() callback used while loading the doclists -** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also -** fts3ExprLoadDoclists(). -*/ -static int fts3ExprLoadDoclistsCb2(Fts3Expr *pExpr, int iPhrase, void *ctx){ - UNUSED_PARAMETER(iPhrase); - UNUSED_PARAMETER(ctx); - if( pExpr->aDoclist ){ - pExpr->pCurrent = pExpr->aDoclist; - pExpr->iCurrent = 0; - pExpr->pCurrent += sqlite3Fts3GetVarint(pExpr->pCurrent, &pExpr->iCurrent); - } - return SQLITE_OK; -} - -/* ** Load the doclists for each phrase in the query associated with FTS3 cursor -** pCsr. +** pCsr. ** -** If pnPhrase is not NULL, then *pnPhrase is set to the number of matchable -** phrases in the expression (all phrases except those directly or -** indirectly descended from the right-hand-side of a NOT operator). If +** If pnPhrase is not NULL, then *pnPhrase is set to the number of matchable +** phrases in the expression (all phrases except those directly or +** indirectly descended from the right-hand-side of a NOT operator). If ** pnToken is not NULL, then it is set to the number of tokens in all ** matchable phrases of the expression. */ @@ -107854,18 +125740,27 @@ static int fts3ExprLoadDoclists( ){ int rc; /* Return Code */ LoadDoclistCtx sCtx = {0,0,0}; /* Context for fts3ExprIterate() */ - sCtx.pTab = (Fts3Table *)pCsr->base.pVtab; - rc = fts3ExprIterate(pCsr->pExpr, fts3ExprLoadDoclistsCb1, (void *)&sCtx); - if( rc==SQLITE_OK ){ - (void)fts3ExprIterate(pCsr->pExpr, fts3ExprLoadDoclistsCb2, 0); - } + sCtx.pCsr = pCsr; + rc = fts3ExprIterate(pCsr->pExpr, fts3ExprLoadDoclistsCb, (void *)&sCtx); if( pnPhrase ) *pnPhrase = sCtx.nPhrase; if( pnToken ) *pnToken = sCtx.nToken; return rc; } +static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ + (*(int *)ctx)++; + UNUSED_PARAMETER(pExpr); + UNUSED_PARAMETER(iPhrase); + return SQLITE_OK; +} +static int fts3ExprPhraseCount(Fts3Expr *pExpr){ + int nPhrase = 0; + (void)fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase); + return nPhrase; +} + /* -** Advance the position list iterator specified by the first two +** Advance the position list iterator specified by the first two ** arguments so that it points to the first element with a value greater ** than or equal to parameter iNext. */ @@ -107934,7 +125829,7 @@ static int fts3SnippetNextCandidate(SnippetIter *pIter){ } /* -** Retrieve information about the current candidate snippet of snippet +** Retrieve information about the current candidate snippet of snippet ** iterator pIter. */ static void fts3SnippetDetails( @@ -107997,7 +125892,7 @@ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){ pPhrase->nToken = pExpr->pPhrase->nToken; - pCsr = sqlite3Fts3FindPositions(pExpr, p->pCsr->iPrevId, p->iCol); + pCsr = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol); if( pCsr ){ int iFirst = 0; pPhrase->pList = pCsr; @@ -108014,14 +125909,14 @@ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){ } /* -** Select the fragment of text consisting of nFragment contiguous tokens +** Select the fragment of text consisting of nFragment contiguous tokens ** from column iCol that represent the "best" snippet. The best snippet ** is the snippet with the highest score, where scores are calculated ** by adding: ** ** (a) +1 point for each occurence of a matchable phrase in the snippet. ** -** (b) +1000 points for the first occurence of each matchable phrase in +** (b) +1000 points for the first occurence of each matchable phrase in ** the snippet for which the corresponding mCovered bit is not set. ** ** The selected snippet parameters are stored in structure *pFragment before @@ -108081,7 +125976,7 @@ static int fts3BestSnippet( } } - /* Loop through all candidate snippets. Store the best snippet in + /* Loop through all candidate snippets. Store the best snippet in ** *pFragment. Store its associated 'score' in iBestScore. */ pFragment->iCol = iCol; @@ -108151,8 +126046,8 @@ static int fts3StringAppend( ** ** ........X.....X ** -** This function "shifts" the beginning of the snippet forward in the -** document so that there are approximately the same number of +** This function "shifts" the beginning of the snippet forward in the +** document so that there are approximately the same number of ** non-highlighted terms to the right of the final highlighted term as there ** are to the left of the first highlighted term. For example, to this: ** @@ -108160,10 +126055,10 @@ static int fts3StringAppend( ** ** This is done as part of extracting the snippet text, not when selecting ** the snippet. Snippet selection is done based on doclists only, so there -** is no way for fts3BestSnippet() to know whether or not the document -** actually contains terms that follow the final highlighted term. +** is no way for fts3BestSnippet() to know whether or not the document +** actually contains terms that follow the final highlighted term. */ -int fts3SnippetShift( +static int fts3SnippetShift( Fts3Table *pTab, /* FTS3 table snippet comes from */ int nSnippet, /* Number of tokens desired for snippet */ const char *zDoc, /* Document text to extract snippet from */ @@ -108252,7 +126147,7 @@ static int fts3SnippetText( sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor open on zDoc/nDoc */ const char *ZDUMMY; /* Dummy argument used with tokenizer */ int DUMMY1; /* Dummy argument used with tokenizer */ - + zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol); if( zDoc==0 ){ if( sqlite3_column_type(pCsr->pStmt, iCol)!=SQLITE_NULL ){ @@ -108280,7 +126175,7 @@ static int fts3SnippetText( if( rc==SQLITE_DONE ){ /* Special case - the last token of the snippet is also the last token ** of the column. Append any punctuation that occurred between the end - ** of the previous token and the end of the document to the output. + ** of the previous token and the end of the document to the output. ** Then break out of the loop. */ rc = fts3StringAppend(pOut, &zDoc[iEnd], -1); } @@ -108295,7 +126190,7 @@ static int fts3SnippetText( /* Now that the shift has been done, check if the initial "..." are ** required. They are required if (a) this is not the first fragment, - ** or (b) this fragment does not begin at position 0 of its column. + ** or (b) this fragment does not begin at position 0 of its column. */ if( rc==SQLITE_OK && (iPos>0 || iFragment>0) ){ rc = fts3StringAppend(pOut, zEllipsis, -1); @@ -108327,8 +126222,8 @@ static int fts3SnippetText( /* -** This function is used to count the entries in a column-list (a -** delta-encoded list of term offsets within a single column of a single +** This function is used to count the entries in a column-list (a +** delta-encoded list of term offsets within a single column of a single ** row). When this function is called, *ppCollist should point to the ** beginning of the first varint in the column-list (the varint that ** contains the position of the first matching term in the column data). @@ -108354,143 +126249,452 @@ static int fts3ColumnlistCount(char **ppCollist){ return nEntry; } -static void fts3LoadColumnlistCounts(char **pp, u32 *aOut, int isGlobal){ - char *pCsr = *pp; - while( *pCsr ){ - int nHit; - sqlite3_int64 iCol = 0; - if( *pCsr==0x01 ){ - pCsr++; - pCsr += sqlite3Fts3GetVarint(pCsr, &iCol); - } - nHit = fts3ColumnlistCount(&pCsr); - assert( nHit>0 ); - if( isGlobal ){ - aOut[iCol*3+1]++; - } - aOut[iCol*3] += nHit; - } - pCsr++; - *pp = pCsr; -} - /* ** fts3ExprIterate() callback used to collect the "global" matchinfo stats -** for a single query. The "global" stats are those elements of the matchinfo -** array that are constant for all rows returned by the current query. +** for a single query. +** +** fts3ExprIterate() callback to load the 'global' elements of a +** FTS3_MATCHINFO_HITS matchinfo array. The global stats are those elements +** of the matchinfo array that are constant for all rows returned by the +** current query. +** +** Argument pCtx is actually a pointer to a struct of type MatchInfo. This +** function populates Matchinfo.aMatchinfo[] as follows: +** +** for(iCol=0; iCol<nCol; iCol++){ +** aMatchinfo[3*iPhrase*nCol + 3*iCol + 1] = X; +** aMatchinfo[3*iPhrase*nCol + 3*iCol + 2] = Y; +** } +** +** where X is the number of matches for phrase iPhrase is column iCol of all +** rows of the table. Y is the number of rows for which column iCol contains +** at least one instance of phrase iPhrase. +** +** If the phrase pExpr consists entirely of deferred tokens, then all X and +** Y values are set to nDoc, where nDoc is the number of documents in the +** file system. This is done because the full-text index doclist is required +** to calculate these values properly, and the full-text index doclist is +** not available for deferred tokens. */ -static int fts3ExprGlobalMatchinfoCb( +static int fts3ExprGlobalHitsCb( Fts3Expr *pExpr, /* Phrase expression node */ int iPhrase, /* Phrase number (numbered from zero) */ void *pCtx /* Pointer to MatchInfo structure */ ){ MatchInfo *p = (MatchInfo *)pCtx; - char *pCsr; - char *pEnd; - const int iStart = 2 + (iPhrase * p->nCol * 3) + 1; + return sqlite3Fts3EvalPhraseStats( + p->pCursor, pExpr, &p->aMatchinfo[3*iPhrase*p->nCol] + ); +} + +/* +** 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 */ + int iPhrase, /* Phrase number */ + void *pCtx /* Pointer to MatchInfo structure */ +){ + MatchInfo *p = (MatchInfo *)pCtx; + int iStart = iPhrase * p->nCol * 3; + int i; - assert( pExpr->isLoaded ); + for(i=0; i<p->nCol; i++){ + char *pCsr; + pCsr = sqlite3Fts3EvalPhrasePoslist(p->pCursor, pExpr, i); + if( pCsr ){ + p->aMatchinfo[iStart+i*3] = fts3ColumnlistCount(&pCsr); + }else{ + p->aMatchinfo[iStart+i*3] = 0; + } + } + + return SQLITE_OK; +} + +static int fts3MatchinfoCheck( + Fts3Table *pTab, + char cArg, + char **pzErr +){ + if( (cArg==FTS3_MATCHINFO_NPHRASE) + || (cArg==FTS3_MATCHINFO_NCOL) + || (cArg==FTS3_MATCHINFO_NDOC && pTab->bHasStat) + || (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bHasStat) + || (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize) + || (cArg==FTS3_MATCHINFO_LCS) + || (cArg==FTS3_MATCHINFO_HITS) + ){ + return SQLITE_OK; + } + *pzErr = sqlite3_mprintf("unrecognized matchinfo request: %c", cArg); + return SQLITE_ERROR; +} + +static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ + int nVal; /* Number of integers output by cArg */ + + switch( cArg ){ + case FTS3_MATCHINFO_NDOC: + case FTS3_MATCHINFO_NPHRASE: + case FTS3_MATCHINFO_NCOL: + nVal = 1; + break; + + case FTS3_MATCHINFO_AVGLENGTH: + case FTS3_MATCHINFO_LENGTH: + case FTS3_MATCHINFO_LCS: + nVal = pInfo->nCol; + break; + + default: + assert( cArg==FTS3_MATCHINFO_HITS ); + nVal = pInfo->nCol * pInfo->nPhrase * 3; + break; + } + + return nVal; +} - /* Fill in the global hit count matrix row for this phrase. */ - pCsr = pExpr->aDoclist; - pEnd = &pExpr->aDoclist[pExpr->nDoclist]; - while( pCsr<pEnd ){ - while( *pCsr++ & 0x80 ); /* Skip past docid. */ - fts3LoadColumnlistCounts(&pCsr, &p->aMatchinfo[iStart], 1); +static int fts3MatchinfoSelectDoctotal( + Fts3Table *pTab, + sqlite3_stmt **ppStmt, + sqlite3_int64 *pnDoc, + const char **paLen +){ + sqlite3_stmt *pStmt; + const char *a; + sqlite3_int64 nDoc; + + if( !*ppStmt ){ + int rc = sqlite3Fts3SelectDoctotal(pTab, ppStmt); + if( rc!=SQLITE_OK ) return rc; } + pStmt = *ppStmt; + assert( sqlite3_data_count(pStmt)==1 ); + a = sqlite3_column_blob(pStmt, 0); + a += sqlite3Fts3GetVarint(a, &nDoc); + if( nDoc==0 ) return SQLITE_CORRUPT_VTAB; + *pnDoc = (u32)nDoc; + + if( paLen ) *paLen = a; return SQLITE_OK; } /* -** fts3ExprIterate() callback used to collect the "local" matchinfo stats -** for a single query. The "local" stats are those elements of the matchinfo -** array that are different for each row returned by the query. +** An instance of the following structure is used to store state while +** iterating through a multi-column position-list corresponding to the +** hits for a single phrase on a single row in order to calculate the +** values for a matchinfo() FTS3_MATCHINFO_LCS request. +*/ +typedef struct LcsIterator LcsIterator; +struct LcsIterator { + Fts3Expr *pExpr; /* Pointer to phrase expression */ + int iPosOffset; /* Tokens count up to end of this phrase */ + char *pRead; /* Cursor used to iterate through aDoclist */ + int iPos; /* Current position */ +}; + +/* +** If LcsIterator.iCol is set to the following value, the iterator has +** finished iterating through all offsets for all columns. */ -static int fts3ExprLocalMatchinfoCb( +#define LCS_ITERATOR_FINISHED 0x7FFFFFFF; + +static int fts3MatchinfoLcsCb( Fts3Expr *pExpr, /* Phrase expression node */ - int iPhrase, /* Phrase number */ + int iPhrase, /* Phrase number (numbered from zero) */ void *pCtx /* Pointer to MatchInfo structure */ ){ - MatchInfo *p = (MatchInfo *)pCtx; + LcsIterator *aIter = (LcsIterator *)pCtx; + aIter[iPhrase].pExpr = pExpr; + return SQLITE_OK; +} - if( pExpr->aDoclist ){ - char *pCsr; - int iStart = 2 + (iPhrase * p->nCol * 3); - int i; +/* +** Advance the iterator passed as an argument to the next position. Return +** 1 if the iterator is at EOF or if it now points to the start of the +** position list for the next column. +*/ +static int fts3LcsIteratorAdvance(LcsIterator *pIter){ + char *pRead = pIter->pRead; + sqlite3_int64 iRead; + int rc = 0; - for(i=0; i<p->nCol; i++) p->aMatchinfo[iStart+i*3] = 0; + pRead += sqlite3Fts3GetVarint(pRead, &iRead); + if( iRead==0 || iRead==1 ){ + pRead = 0; + rc = 1; + }else{ + pIter->iPos += (int)(iRead-2); + } - pCsr = sqlite3Fts3FindPositions(pExpr, p->pCursor->iPrevId, -1); - if( pCsr ){ - fts3LoadColumnlistCounts(&pCsr, &p->aMatchinfo[iStart], 0); + pIter->pRead = pRead; + return rc; +} + +/* +** This function implements the FTS3_MATCHINFO_LCS matchinfo() flag. +** +** If the call is successful, the longest-common-substring lengths for each +** column are written into the first nCol elements of the pInfo->aMatchinfo[] +** array before returning. SQLITE_OK is returned in this case. +** +** Otherwise, if an error occurs, an SQLite error code is returned and the +** data written to the first nCol elements of pInfo->aMatchinfo[] is +** undefined. +*/ +static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){ + LcsIterator *aIter; + int i; + int iCol; + int nToken = 0; + + /* Allocate and populate the array of LcsIterator objects. The array + ** contains one element for each matchable phrase in the query. + **/ + aIter = sqlite3_malloc(sizeof(LcsIterator) * pCsr->nPhrase); + if( !aIter ) return SQLITE_NOMEM; + memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase); + (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); + + for(i=0; i<pInfo->nPhrase; i++){ + LcsIterator *pIter = &aIter[i]; + nToken -= pIter->pExpr->pPhrase->nToken; + pIter->iPosOffset = nToken; + } + + for(iCol=0; iCol<pInfo->nCol; iCol++){ + int nLcs = 0; /* LCS value for this column */ + int nLive = 0; /* Number of iterators in aIter not at EOF */ + + for(i=0; i<pInfo->nPhrase; i++){ + LcsIterator *pIt = &aIter[i]; + pIt->pRead = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol); + if( pIt->pRead ){ + pIt->iPos = pIt->iPosOffset; + fts3LcsIteratorAdvance(&aIter[i]); + nLive++; + } } + + while( nLive>0 ){ + LcsIterator *pAdv = 0; /* The iterator to advance by one position */ + int nThisLcs = 0; /* LCS for the current iterator positions */ + + for(i=0; i<pInfo->nPhrase; i++){ + LcsIterator *pIter = &aIter[i]; + if( pIter->pRead==0 ){ + /* This iterator is already at EOF for this column. */ + nThisLcs = 0; + }else{ + if( pAdv==0 || pIter->iPos<pAdv->iPos ){ + pAdv = pIter; + } + if( nThisLcs==0 || pIter->iPos==pIter[-1].iPos ){ + nThisLcs++; + }else{ + nThisLcs = 1; + } + if( nThisLcs>nLcs ) nLcs = nThisLcs; + } + } + if( fts3LcsIteratorAdvance(pAdv) ) nLive--; + } + + pInfo->aMatchinfo[iCol] = nLcs; } + sqlite3_free(aIter); return SQLITE_OK; } /* -** Populate pCsr->aMatchinfo[] with data for the current row. The +** Populate the buffer pInfo->aMatchinfo[] with an array of integers to +** be returned by the matchinfo() function. Argument zArg contains the +** format string passed as the second argument to matchinfo (or the +** default value "pcx" if no second argument was specified). The format +** string has already been validated and the pInfo->aMatchinfo[] array +** is guaranteed to be large enough for the output. +** +** If bGlobal is true, then populate all fields of the matchinfo() output. +** If it is false, then assume that those fields that do not change between +** rows (i.e. FTS3_MATCHINFO_NPHRASE, NCOL, NDOC, AVGLENGTH and part of HITS) +** have already been populated. +** +** Return SQLITE_OK if successful, or an SQLite error code if an error +** occurs. If a value other than SQLITE_OK is returned, the state the +** pInfo->aMatchinfo[] buffer is left in is undefined. +*/ +static int fts3MatchinfoValues( + Fts3Cursor *pCsr, /* FTS3 cursor object */ + int bGlobal, /* True to grab the global stats */ + MatchInfo *pInfo, /* Matchinfo context object */ + const char *zArg /* Matchinfo format string */ +){ + int rc = SQLITE_OK; + int i; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + sqlite3_stmt *pSelect = 0; + + for(i=0; rc==SQLITE_OK && zArg[i]; i++){ + + switch( zArg[i] ){ + case FTS3_MATCHINFO_NPHRASE: + if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase; + break; + + case FTS3_MATCHINFO_NCOL: + if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nCol; + break; + + case FTS3_MATCHINFO_NDOC: + if( bGlobal ){ + sqlite3_int64 nDoc = 0; + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0); + pInfo->aMatchinfo[0] = (u32)nDoc; + } + break; + + case FTS3_MATCHINFO_AVGLENGTH: + if( bGlobal ){ + sqlite3_int64 nDoc; /* Number of rows in table */ + const char *a; /* Aggregate column length array */ + + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, &a); + if( rc==SQLITE_OK ){ + int iCol; + for(iCol=0; iCol<pInfo->nCol; iCol++){ + u32 iVal; + sqlite3_int64 nToken; + a += sqlite3Fts3GetVarint(a, &nToken); + iVal = (u32)(((u32)(nToken&0xffffffff)+nDoc/2)/nDoc); + pInfo->aMatchinfo[iCol] = iVal; + } + } + } + break; + + case FTS3_MATCHINFO_LENGTH: { + sqlite3_stmt *pSelectDocsize = 0; + rc = sqlite3Fts3SelectDocsize(pTab, pCsr->iPrevId, &pSelectDocsize); + if( rc==SQLITE_OK ){ + int iCol; + const char *a = sqlite3_column_blob(pSelectDocsize, 0); + for(iCol=0; iCol<pInfo->nCol; iCol++){ + sqlite3_int64 nToken; + a += sqlite3Fts3GetVarint(a, &nToken); + pInfo->aMatchinfo[iCol] = (u32)nToken; + } + } + sqlite3_reset(pSelectDocsize); + break; + } + + case FTS3_MATCHINFO_LCS: + rc = fts3ExprLoadDoclists(pCsr, 0, 0); + if( rc==SQLITE_OK ){ + rc = fts3MatchinfoLcs(pCsr, pInfo); + } + break; + + default: { + Fts3Expr *pExpr; + assert( zArg[i]==FTS3_MATCHINFO_HITS ); + pExpr = pCsr->pExpr; + rc = fts3ExprLoadDoclists(pCsr, 0, 0); + if( rc!=SQLITE_OK ) break; + if( bGlobal ){ + if( pCsr->pDeferred ){ + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc, 0); + if( rc!=SQLITE_OK ) break; + } + rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); + if( rc!=SQLITE_OK ) break; + } + (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo); + break; + } + } + + pInfo->aMatchinfo += fts3MatchinfoSize(pInfo, zArg[i]); + } + + sqlite3_reset(pSelect); + return rc; +} + + +/* +** Populate pCsr->aMatchinfo[] with data for the current row. The ** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32). */ -static int fts3GetMatchinfo(Fts3Cursor *pCsr){ +static int fts3GetMatchinfo( + Fts3Cursor *pCsr, /* FTS3 Cursor object */ + const char *zArg /* Second argument to matchinfo() function */ +){ MatchInfo sInfo; Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; int rc = SQLITE_OK; + int bGlobal = 0; /* Collect 'global' stats as well as local */ + memset(&sInfo, 0, sizeof(MatchInfo)); sInfo.pCursor = pCsr; sInfo.nCol = pTab->nColumn; + /* If there is cached matchinfo() data, but the format string for the + ** cache does not match the format string for this request, discard + ** the cached data. */ + if( pCsr->zMatchinfo && strcmp(pCsr->zMatchinfo, zArg) ){ + assert( pCsr->aMatchinfo ); + sqlite3_free(pCsr->aMatchinfo); + pCsr->zMatchinfo = 0; + pCsr->aMatchinfo = 0; + } + + /* If Fts3Cursor.aMatchinfo[] is NULL, then this is the first time the + ** matchinfo function has been called for this query. In this case + ** allocate the array used to accumulate the matchinfo data and + ** initialize those elements that are constant for every row. + */ if( pCsr->aMatchinfo==0 ){ - /* If Fts3Cursor.aMatchinfo[] is NULL, then this is the first time the - ** matchinfo function has been called for this query. In this case - ** allocate the array used to accumulate the matchinfo data and - ** initialize those elements that are constant for every row. - */ - int nPhrase; /* Number of phrases */ - int nMatchinfo; /* Number of u32 elements in match-info */ + int nMatchinfo = 0; /* Number of u32 elements in match-info */ + int nArg; /* Bytes in zArg */ + int i; /* Used to iterate through zArg */ - /* Load doclists for each phrase in the query. */ - rc = fts3ExprLoadDoclists(pCsr, &nPhrase, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - nMatchinfo = 2 + 3*sInfo.nCol*nPhrase; - if( pTab->bHasDocsize ){ - nMatchinfo += 1 + 2*pTab->nColumn; - } + /* Determine the number of phrases in the query */ + pCsr->nPhrase = fts3ExprPhraseCount(pCsr->pExpr); + sInfo.nPhrase = pCsr->nPhrase; - sInfo.aMatchinfo = (u32 *)sqlite3_malloc(sizeof(u32)*nMatchinfo); - if( !sInfo.aMatchinfo ){ - return SQLITE_NOMEM; + /* Determine the number of integers in the buffer returned by this call. */ + for(i=0; zArg[i]; i++){ + nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]); } - memset(sInfo.aMatchinfo, 0, sizeof(u32)*nMatchinfo); + /* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */ + nArg = (int)strlen(zArg); + pCsr->aMatchinfo = (u32 *)sqlite3_malloc(sizeof(u32)*nMatchinfo + nArg + 1); + if( !pCsr->aMatchinfo ) return SQLITE_NOMEM; - /* First element of match-info is the number of phrases in the query */ - sInfo.aMatchinfo[0] = nPhrase; - sInfo.aMatchinfo[1] = sInfo.nCol; - (void)fts3ExprIterate(pCsr->pExpr, fts3ExprGlobalMatchinfoCb,(void*)&sInfo); - if( pTab->bHasDocsize ){ - int ofst = 2 + 3*sInfo.aMatchinfo[0]*sInfo.aMatchinfo[1]; - rc = sqlite3Fts3MatchinfoDocsizeGlobal(pCsr, &sInfo.aMatchinfo[ofst]); - } - pCsr->aMatchinfo = sInfo.aMatchinfo; + pCsr->zMatchinfo = (char *)&pCsr->aMatchinfo[nMatchinfo]; + pCsr->nMatchinfo = nMatchinfo; + memcpy(pCsr->zMatchinfo, zArg, nArg+1); + memset(pCsr->aMatchinfo, 0, sizeof(u32)*nMatchinfo); pCsr->isMatchinfoNeeded = 1; + bGlobal = 1; } sInfo.aMatchinfo = pCsr->aMatchinfo; - if( rc==SQLITE_OK && pCsr->isMatchinfoNeeded ){ - (void)fts3ExprIterate(pCsr->pExpr, fts3ExprLocalMatchinfoCb, (void*)&sInfo); - if( pTab->bHasDocsize ){ - int ofst = 2 + 3*sInfo.aMatchinfo[0]*sInfo.aMatchinfo[1]; - rc = sqlite3Fts3MatchinfoDocsizeLocal(pCsr, &sInfo.aMatchinfo[ofst]); - } + sInfo.nPhrase = pCsr->nPhrase; + if( pCsr->isMatchinfoNeeded ){ + rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg); pCsr->isMatchinfoNeeded = 0; } - return SQLITE_OK; + return rc; } /* @@ -108512,7 +126716,7 @@ SQLITE_PRIVATE void sqlite3Fts3Snippet( /* The returned text includes up to four fragments of text extracted from ** the data in the current row. The first iteration of the for(...) loop - ** below attempts to locate a single fragment of text nToken tokens in + ** below attempts to locate a single fragment of text nToken tokens in ** size that contains at least one instance of all phrases in the query ** expression that appear in the current row. If such a fragment of text ** cannot be found, the second iteration of the loop attempts to locate @@ -108551,7 +126755,7 @@ SQLITE_PRIVATE void sqlite3Fts3Snippet( ** columns of the FTS3 table. Otherwise, only column iCol is considered. */ for(iRead=0; iRead<pTab->nColumn; iRead++){ - SnippetFragment sF; + SnippetFragment sF = {0, 0, 0, 0}; int iS; if( iCol>=0 && iRead!=iCol ) continue; @@ -108579,12 +126783,13 @@ SQLITE_PRIVATE void sqlite3Fts3Snippet( assert( nFToken>0 ); for(i=0; i<nSnippet && rc==SQLITE_OK; i++){ - rc = fts3SnippetText(pCsr, &aSnippet[i], + rc = fts3SnippetText(pCsr, &aSnippet[i], i, (i==nSnippet-1), nFToken, zStart, zEnd, zEllipsis, &res ); } snippet_out: + sqlite3Fts3SegmentsClose(pTab); if( rc!=SQLITE_OK ){ sqlite3_result_error_code(pCtx, rc); sqlite3_free(res.z); @@ -108604,6 +126809,7 @@ struct TermOffset { }; struct TermOffsetCtx { + Fts3Cursor *pCsr; int iCol; /* Column of table to populate aTerm for */ int iTerm; sqlite3_int64 iDocid; @@ -108621,7 +126827,7 @@ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){ int iPos = 0; /* First position in position-list */ UNUSED_PARAMETER(iPhrase); - pList = sqlite3Fts3FindPositions(pExpr, p->iDocid, p->iCol); + pList = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol); nTerm = pExpr->pPhrase->nToken; if( pList ){ fts3GetDeltaPosition(&pList, &iPos); @@ -108674,8 +126880,9 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets( goto offsets_out; } sCtx.iDocid = pCsr->iPrevId; + sCtx.pCsr = pCsr; - /* Loop through the table columns, appending offset information to + /* Loop through the table columns, appending offset information to ** string-buffer res for each column. */ for(iCol=0; iCol<pTab->nColumn; iCol++){ @@ -108686,7 +126893,7 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets( const char *zDoc; int nDoc; - /* Initialize the contents of sCtx.aTerm[] for column iCol. There is + /* Initialize the contents of sCtx.aTerm[] for column iCol. There is ** no way that this operation can fail, so the return code from ** fts3ExprIterate() can be discarded. */ @@ -108694,11 +126901,11 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets( sCtx.iTerm = 0; (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void *)&sCtx); - /* Retreive the text stored in column iCol. If an SQL NULL is stored + /* 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 - ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM - ** to the caller. + ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM + ** to the caller. */ zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol+1); nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol+1); @@ -108744,12 +126951,12 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets( } if( rc==SQLITE_OK ){ char aBuffer[64]; - sqlite3_snprintf(sizeof(aBuffer), aBuffer, + sqlite3_snprintf(sizeof(aBuffer), aBuffer, "%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart ); rc = fts3StringAppend(&res, aBuffer, -1); }else if( rc==SQLITE_DONE ){ - rc = SQLITE_CORRUPT; + rc = SQLITE_CORRUPT_VTAB; } } } @@ -108764,6 +126971,7 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets( offsets_out: sqlite3_free(sCtx.aTerm); assert( rc!=SQLITE_DONE ); + sqlite3Fts3SegmentsClose(pTab); if( rc!=SQLITE_OK ){ sqlite3_result_error_code(pCtx, rc); sqlite3_free(res.z); @@ -108776,21 +126984,43 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets( /* ** Implementation of matchinfo() function. */ -SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *pContext, Fts3Cursor *pCsr){ +SQLITE_PRIVATE void sqlite3Fts3Matchinfo( + sqlite3_context *pContext, /* Function call context */ + Fts3Cursor *pCsr, /* FTS3 table cursor */ + const char *zArg /* Second arg to matchinfo() function */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; int rc; + int i; + const char *zFormat; + + if( zArg ){ + for(i=0; zArg[i]; i++){ + char *zErr = 0; + if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){ + sqlite3_result_error(pContext, zErr, -1); + sqlite3_free(zErr); + return; + } + } + zFormat = zArg; + }else{ + zFormat = FTS3_MATCHINFO_DEFAULT; + } + if( !pCsr->pExpr ){ sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC); return; } - rc = fts3GetMatchinfo(pCsr); + + /* Retrieve matchinfo() data. */ + rc = fts3GetMatchinfo(pCsr, zFormat); + sqlite3Fts3SegmentsClose(pTab); + if( rc!=SQLITE_OK ){ sqlite3_result_error_code(pContext, rc); }else{ - Fts3Table *pTab = (Fts3Table*)pCsr->base.pVtab; - int n = sizeof(u32)*(2+pCsr->aMatchinfo[0]*pCsr->aMatchinfo[1]*3); - if( pTab->bHasDocsize ){ - n += sizeof(u32)*(1 + 2*pTab->nColumn); - } + int n = pCsr->nMatchinfo * sizeof(u32); sqlite3_result_blob(pContext, pCsr->aMatchinfo, n, SQLITE_TRANSIENT); } } @@ -108814,23 +127044,62 @@ SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *pContext, Fts3Cursor * ** algorithms packaged as an SQLite virtual table module. */ +/* +** Database Format of R-Tree Tables +** -------------------------------- +** +** The data structure for a single virtual r-tree table is stored in three +** native SQLite tables declared as follows. In each case, the '%' character +** in the table name is replaced with the user-supplied name of the r-tree +** table. +** +** CREATE TABLE %_node(nodeno INTEGER PRIMARY KEY, data BLOB) +** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER) +** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER) +** +** The data for each node of the r-tree structure is stored in the %_node +** table. For each node that is not the root node of the r-tree, there is +** an entry in the %_parent table associating the node with its parent. +** And for each row of data in the table, there is an entry in the %_rowid +** table that maps from the entries rowid to the id of the node that it +** is stored on. +** +** The root node of an r-tree always exists, even if the r-tree table is +** empty. The nodeno of the root node is always 1. All other nodes in the +** table must be the same size as the root node. The content of each node +** is formatted as follows: +** +** 1. If the node is the root node (node 1), then the first 2 bytes +** of the node contain the tree depth as a big-endian integer. +** For non-root nodes, the first 2 bytes are left unused. +** +** 2. The next 2 bytes contain the number of entries currently +** stored in the node. +** +** 3. The remainder of the node contains the node entries. Each entry +** consists of a single 8-byte integer followed by an even number +** of 4-byte coordinates. For leaf nodes the integer is the rowid +** of a record. For internal nodes it is the node number of a +** child page. +*/ + #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) /* ** This file contains an implementation of a couple of different variants -** of the r-tree algorithm. See the README file for further details. The +** of the r-tree algorithm. See the README file for further details. The ** same data-structure is used for all, but the algorithms for insert and -** delete operations vary. The variants used are selected at compile time +** delete operations vary. The variants used are selected at compile time ** by defining the following symbols: */ -/* Either, both or none of the following may be set to activate +/* Either, both or none of the following may be set to activate ** r*tree variant algorithms. */ #define VARIANT_RSTARTREE_CHOOSESUBTREE 0 #define VARIANT_RSTARTREE_REINSERT 1 -/* +/* ** Exactly one of the following must be set to 1. */ #define VARIANT_GUTTMAN_QUADRATIC_SPLIT 0 @@ -108854,36 +127123,50 @@ SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *pContext, Fts3Cursor * #define AssignCells splitNodeStartree #endif +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +#endif #ifndef SQLITE_CORE SQLITE_EXTENSION_INIT1 #else #endif +/* #include <string.h> */ +/* #include <assert.h> */ #ifndef SQLITE_AMALGAMATION +#include "sqlite3rtree.h" typedef sqlite3_int64 i64; typedef unsigned char u8; typedef unsigned int u32; #endif +/* The following macro is used to suppress compiler warnings. +*/ +#ifndef UNUSED_PARAMETER +# define UNUSED_PARAMETER(x) (void)(x) +#endif + typedef struct Rtree Rtree; typedef struct RtreeCursor RtreeCursor; typedef struct RtreeNode RtreeNode; typedef struct RtreeCell RtreeCell; typedef struct RtreeConstraint RtreeConstraint; +typedef struct RtreeMatchArg RtreeMatchArg; +typedef struct RtreeGeomCallback RtreeGeomCallback; typedef union RtreeCoord RtreeCoord; /* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */ #define RTREE_MAX_DIMENSIONS 5 /* Size of hash table Rtree.aHash. This hash table is not expected to -** ever contain very many entries, so a fixed number of buckets is +** ever contain very many entries, so a fixed number of buckets is ** used. */ #define HASHSIZE 128 -/* +/* ** An rtree virtual-table object. */ struct Rtree { @@ -108894,13 +127177,13 @@ struct Rtree { int nBytesPerCell; /* Bytes consumed per cell */ int iDepth; /* Current depth of the r-tree structure */ char *zDb; /* Name of database containing r-tree table */ - char *zName; /* Name of r-tree table */ - RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ + char *zName; /* Name of r-tree table */ + RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ int nBusy; /* Current number of users of this structure */ /* List of nodes removed during a CondenseTree operation. List is ** linked together via the pointer normally used for hash chains - - ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree + ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree ** headed by the node (leaf nodes have RtreeNode.iNode==0). */ RtreeNode *pDeleted; @@ -108929,7 +127212,7 @@ struct Rtree { #define RTREE_COORD_INT32 1 /* -** The minimum number of cells allowed for a node is a third of the +** The minimum number of cells allowed for a node is a third of the ** maximum. In Gutman's notation: ** ** m = M/3 @@ -108942,6 +127225,15 @@ struct Rtree { #define RTREE_MAXCELLS 51 /* +** The smallest possible node-size is (512-64)==448 bytes. And the largest +** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates). +** Therefore all non-root nodes must contain at least 3 entries. Since +** 2^40 is greater than 2^64, an r-tree structure always has a depth of +** 40 or less. +*/ +#define RTREE_MAX_DEPTH 40 + +/* ** An rtree cursor object. */ struct RtreeCursor { @@ -108973,35 +127265,23 @@ union RtreeCoord { ** A search constraint. */ struct RtreeConstraint { - int iCoord; /* Index of constrained coordinate */ - int op; /* Constraining operation */ - double rValue; /* Constraint value. */ + int iCoord; /* Index of constrained coordinate */ + int op; /* Constraining operation */ + double rValue; /* Constraint value. */ + int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *); + sqlite3_rtree_geometry *pGeom; /* Constraint callback argument for a MATCH */ }; /* Possible values for RtreeConstraint.op */ -#define RTREE_EQ 0x41 -#define RTREE_LE 0x42 -#define RTREE_LT 0x43 -#define RTREE_GE 0x44 -#define RTREE_GT 0x45 - -/* +#define RTREE_EQ 0x41 +#define RTREE_LE 0x42 +#define RTREE_LT 0x43 +#define RTREE_GE 0x44 +#define RTREE_GT 0x45 +#define RTREE_MATCH 0x46 + +/* ** An rtree structure node. -** -** Data format (RtreeNode.zData): -** -** 1. If the node is the root node (node 1), then the first 2 bytes -** of the node contain the tree depth as a big-endian integer. -** For non-root nodes, the first 2 bytes are left unused. -** -** 2. The next 2 bytes contain the number of entries currently -** stored in the node. -** -** 3. The remainder of the node contains the node entries. Each entry -** consists of a single 8-byte integer followed by an even number -** of 4-byte coordinates. For leaf nodes the integer is the rowid -** of a record. For internal nodes it is the node number of a -** child page. */ struct RtreeNode { RtreeNode *pParent; /* Parent node */ @@ -109013,7 +127293,7 @@ struct RtreeNode { }; #define NCELL(pNode) readInt16(&(pNode)->zData[2]) -/* +/* ** Structure to store a deserialized rtree record. */ struct RtreeCell { @@ -109021,6 +127301,40 @@ struct RtreeCell { RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; }; + +/* +** Value for the first field of every RtreeMatchArg object. The MATCH +** operator tests that the first field of a blob operand matches this +** value to avoid operating on invalid blobs (which could cause a segfault). +*/ +#define RTREE_GEOMETRY_MAGIC 0x891245AB + +/* +** An instance of this structure must be supplied as a blob argument to +** the right-hand-side of an SQL MATCH operator used to constrain an +** r-tree query. +*/ +struct RtreeMatchArg { + u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ + int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *); + void *pContext; + int nParam; + double aParam[1]; +}; + +/* +** When a geometry callback is created (see sqlite3_rtree_geometry_callback), +** a single instance of the following structure is allocated. It is used +** as the context for the user-function created by by s_r_g_c(). The object +** is eventually deleted by the destructor mechanism provided by +** sqlite3_create_function_v2() (which is called by s_r_g_c() to create +** the geometry callback function). +*/ +struct RtreeGeomCallback { + int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *); + void *pContext; +}; + #ifndef MAX # define MAX(x,y) ((x) < (y) ? (y) : (x)) #endif @@ -109037,22 +127351,22 @@ static int readInt16(u8 *p){ } static void readCoord(u8 *p, RtreeCoord *pCoord){ u32 i = ( - (((u32)p[0]) << 24) + - (((u32)p[1]) << 16) + - (((u32)p[2]) << 8) + + (((u32)p[0]) << 24) + + (((u32)p[1]) << 16) + + (((u32)p[2]) << 8) + (((u32)p[3]) << 0) ); *(u32 *)pCoord = i; } static i64 readInt64(u8 *p){ return ( - (((i64)p[0]) << 56) + - (((i64)p[1]) << 48) + - (((i64)p[2]) << 40) + - (((i64)p[3]) << 32) + - (((i64)p[4]) << 24) + - (((i64)p[5]) << 16) + - (((i64)p[6]) << 8) + + (((i64)p[0]) << 56) + + (((i64)p[1]) << 48) + + (((i64)p[2]) << 40) + + (((i64)p[3]) << 32) + + (((i64)p[4]) << 24) + + (((i64)p[5]) << 16) + + (((i64)p[6]) << 8) + (((i64)p[7]) << 0) ); } @@ -109103,10 +127417,8 @@ static void nodeReference(RtreeNode *p){ ** Clear the content of node p (set all bytes to 0x00). */ static void nodeZero(Rtree *pRtree, RtreeNode *p){ - if( p ){ - memset(&p->zData[2], 0, pRtree->iNodeSize-2); - p->isDirty = 1; - } + memset(&p->zData[2], 0, pRtree->iNodeSize-2); + p->isDirty = 1; } /* @@ -109115,7 +127427,7 @@ static void nodeZero(Rtree *pRtree, RtreeNode *p){ */ static int nodeHash(i64 iNode){ return ( - (iNode>>56) ^ (iNode>>48) ^ (iNode>>40) ^ (iNode>>32) ^ + (iNode>>56) ^ (iNode>>48) ^ (iNode>>40) ^ (iNode>>32) ^ (iNode>>24) ^ (iNode>>16) ^ (iNode>> 8) ^ (iNode>> 0) ) % HASHSIZE; } @@ -109126,7 +127438,6 @@ static int nodeHash(i64 iNode){ */ static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){ RtreeNode *p; - assert( iNode!=0 ); for(p=pRtree->aHash[nodeHash(iNode)]; p && p->iNode!=iNode; p=p->pNext); return p; } @@ -109135,13 +127446,11 @@ static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){ ** Add node pNode to the node hash table. */ static void nodeHashInsert(Rtree *pRtree, RtreeNode *pNode){ - if( pNode ){ - int iHash; - assert( pNode->pNext==0 ); - iHash = nodeHash(pNode->iNode); - pNode->pNext = pRtree->aHash[iHash]; - pRtree->aHash[iHash] = pNode; - } + int iHash; + assert( pNode->pNext==0 ); + iHash = nodeHash(pNode->iNode); + pNode->pNext = pRtree->aHash[iHash]; + pRtree->aHash[iHash] = pNode; } /* @@ -109163,11 +127472,11 @@ static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){ ** assigned a node number when nodeWrite() is called to write the ** node contents out to the database. */ -static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent, int zero){ +static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ RtreeNode *pNode; pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize); if( pNode ){ - memset(pNode, 0, sizeof(RtreeNode) + (zero?pRtree->iNodeSize:0)); + memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize); pNode->zData = (u8 *)&pNode[1]; pNode->nRef = 1; pNode->pParent = pParent; @@ -109188,6 +127497,7 @@ nodeAcquire( RtreeNode **ppNode /* OUT: Acquired node */ ){ int rc; + int rc2 = SQLITE_OK; RtreeNode *pNode; /* Check if the requested node is already in the hash table. If so, @@ -109204,39 +127514,63 @@ nodeAcquire( return SQLITE_OK; } - pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize); - if( !pNode ){ - *ppNode = 0; - return SQLITE_NOMEM; - } - pNode->pParent = pParent; - pNode->zData = (u8 *)&pNode[1]; - pNode->nRef = 1; - pNode->iNode = iNode; - pNode->isDirty = 0; - pNode->pNext = 0; - sqlite3_bind_int64(pRtree->pReadNode, 1, iNode); rc = sqlite3_step(pRtree->pReadNode); if( rc==SQLITE_ROW ){ const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0); - assert( sqlite3_column_bytes(pRtree->pReadNode, 0)==pRtree->iNodeSize ); - memcpy(pNode->zData, zBlob, pRtree->iNodeSize); - nodeReference(pParent); - }else{ - sqlite3_free(pNode); - pNode = 0; + if( pRtree->iNodeSize==sqlite3_column_bytes(pRtree->pReadNode, 0) ){ + pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize); + if( !pNode ){ + rc2 = SQLITE_NOMEM; + }else{ + pNode->pParent = pParent; + pNode->zData = (u8 *)&pNode[1]; + pNode->nRef = 1; + pNode->iNode = iNode; + pNode->isDirty = 0; + pNode->pNext = 0; + memcpy(pNode->zData, zBlob, pRtree->iNodeSize); + nodeReference(pParent); + } + } } - - *ppNode = pNode; rc = sqlite3_reset(pRtree->pReadNode); + if( rc==SQLITE_OK ) rc = rc2; - if( rc==SQLITE_OK && iNode==1 ){ + /* If the root node was just loaded, set pRtree->iDepth to the height + ** of the r-tree structure. A height of zero means all data is stored on + ** the root node. A height of one means the children of the root node + ** are the leaves, and so on. If the depth as specified on the root node + ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt. + */ + if( pNode && iNode==1 ){ pRtree->iDepth = readInt16(pNode->zData); + if( pRtree->iDepth>RTREE_MAX_DEPTH ){ + rc = SQLITE_CORRUPT_VTAB; + } } - assert( (rc==SQLITE_OK && pNode) || (pNode==0 && rc!=SQLITE_OK) ); - nodeHashInsert(pRtree, pNode); + /* If no error has occurred so far, check if the "number of entries" + ** field on the node is too large. If so, set the return code to + ** SQLITE_CORRUPT_VTAB. + */ + if( pNode && rc==SQLITE_OK ){ + if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){ + rc = SQLITE_CORRUPT_VTAB; + } + } + + if( rc==SQLITE_OK ){ + if( pNode!=0 ){ + nodeHashInsert(pRtree, pNode); + }else{ + rc = SQLITE_CORRUPT_VTAB; + } + *ppNode = pNode; + }else{ + sqlite3_free(pNode); + *ppNode = 0; + } return rc; } @@ -109245,9 +127579,9 @@ nodeAcquire( ** Overwrite cell iCell of node pNode with the contents of pCell. */ static void nodeOverwriteCell( - Rtree *pRtree, - RtreeNode *pNode, - RtreeCell *pCell, + Rtree *pRtree, + RtreeNode *pNode, + RtreeCell *pCell, int iCell ){ int ii; @@ -109279,9 +127613,9 @@ static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){ */ static int nodeInsertCell( - Rtree *pRtree, - RtreeNode *pNode, - RtreeCell *pCell + Rtree *pRtree, + RtreeNode *pNode, + RtreeCell *pCell ){ int nCell; /* Current number of cells in pNode */ int nMaxCell; /* Maximum number of cells for pNode */ @@ -109289,8 +127623,7 @@ nodeInsertCell( nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell; nCell = NCELL(pNode); - assert(nCell<=nMaxCell); - + assert( nCell<=nMaxCell ); if( nCell<nMaxCell ){ nodeOverwriteCell(pRtree, pNode, pCell, nCell); writeInt16(&pNode->zData[2], nCell+1); @@ -109358,8 +127691,8 @@ nodeRelease(Rtree *pRtree, RtreeNode *pNode){ ** an internal node, then the 64-bit integer is a child page number. */ static i64 nodeGetRowid( - Rtree *pRtree, - RtreeNode *pNode, + Rtree *pRtree, + RtreeNode *pNode, int iCell ){ assert( iCell<NCELL(pNode) ); @@ -109370,8 +127703,8 @@ static i64 nodeGetRowid( ** Return coordinate iCoord from cell iCell in node pNode. */ static void nodeGetCoord( - Rtree *pRtree, - RtreeNode *pNode, + Rtree *pRtree, + RtreeNode *pNode, int iCell, int iCoord, RtreeCoord *pCoord /* Space to write result to */ @@ -109384,8 +127717,8 @@ static void nodeGetCoord( ** to by pCell with the results. */ static void nodeGetCell( - Rtree *pRtree, - RtreeNode *pNode, + Rtree *pRtree, + RtreeNode *pNode, int iCell, RtreeCell *pCell ){ @@ -109404,7 +127737,7 @@ static int rtreeInit( sqlite3 *, void *, int, const char *const*, sqlite3_vtab **, char **, int ); -/* +/* ** Rtree virtual table module xCreate method. */ static int rtreeCreate( @@ -109417,7 +127750,7 @@ static int rtreeCreate( return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 1); } -/* +/* ** Rtree virtual table module xConnect method. */ static int rtreeConnect( @@ -109457,7 +127790,7 @@ static void rtreeRelease(Rtree *pRtree){ } } -/* +/* ** Rtree virtual table module xDisconnect method. */ static int rtreeDisconnect(sqlite3_vtab *pVtab){ @@ -109465,7 +127798,7 @@ static int rtreeDisconnect(sqlite3_vtab *pVtab){ return SQLITE_OK; } -/* +/* ** Rtree virtual table module xDestroy method. */ static int rtreeDestroy(sqlite3_vtab *pVtab){ @@ -109475,7 +127808,7 @@ static int rtreeDestroy(sqlite3_vtab *pVtab){ "DROP TABLE '%q'.'%q_node';" "DROP TABLE '%q'.'%q_rowid';" "DROP TABLE '%q'.'%q_parent';", - pRtree->zDb, pRtree->zName, + pRtree->zDb, pRtree->zName, pRtree->zDb, pRtree->zName, pRtree->zDb, pRtree->zName ); @@ -109492,7 +127825,7 @@ static int rtreeDestroy(sqlite3_vtab *pVtab){ return rc; } -/* +/* ** Rtree virtual table module xOpen method. */ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ @@ -109510,14 +127843,33 @@ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ return rc; } + /* +** Free the RtreeCursor.aConstraint[] array and its contents. +*/ +static void freeCursorConstraints(RtreeCursor *pCsr){ + if( pCsr->aConstraint ){ + int i; /* Used to iterate through constraint array */ + for(i=0; i<pCsr->nConstraint; i++){ + sqlite3_rtree_geometry *pGeom = pCsr->aConstraint[i].pGeom; + if( pGeom ){ + if( pGeom->xDelUser ) pGeom->xDelUser(pGeom->pUser); + sqlite3_free(pGeom); + } + } + sqlite3_free(pCsr->aConstraint); + pCsr->aConstraint = 0; + } +} + +/* ** Rtree virtual table module xClose method. */ static int rtreeClose(sqlite3_vtab_cursor *cur){ Rtree *pRtree = (Rtree *)(cur->pVtab); int rc; RtreeCursor *pCsr = (RtreeCursor *)cur; - sqlite3_free(pCsr->aConstraint); + freeCursorConstraints(pCsr); rc = nodeRelease(pRtree, pCsr->pNode); sqlite3_free(pCsr); return rc; @@ -109526,7 +127878,7 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){ /* ** Rtree virtual table module xEof method. ** -** Return non-zero if the cursor does not currently point to a valid +** Return non-zero if the cursor does not currently point to a valid ** record (i.e if the scan has finished), or zero otherwise. */ static int rtreeEof(sqlite3_vtab_cursor *cur){ @@ -109535,15 +127887,42 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){ } /* +** The r-tree constraint passed as the second argument to this function is +** guaranteed to be a MATCH constraint. +*/ +static int testRtreeGeom( + Rtree *pRtree, /* R-Tree object */ + RtreeConstraint *pConstraint, /* MATCH constraint to test */ + RtreeCell *pCell, /* Cell to test */ + int *pbRes /* OUT: Test result */ +){ + int i; + double aCoord[RTREE_MAX_DIMENSIONS*2]; + int nCoord = pRtree->nDim*2; + + assert( pConstraint->op==RTREE_MATCH ); + assert( pConstraint->pGeom ); + + for(i=0; i<nCoord; i++){ + aCoord[i] = DCOORD(pCell->aCoord[i]); + } + return pConstraint->xGeom(pConstraint->pGeom, nCoord, aCoord, pbRes); +} + +/* ** Cursor pCursor currently points to a cell in a non-leaf page. -** Return true if the sub-tree headed by the cell is filtered -** (excluded) by the constraints in the pCursor->aConstraint[] +** Set *pbEof to true if the sub-tree headed by the cell is filtered +** (excluded) by the constraints in the pCursor->aConstraint[] ** array, or false otherwise. +** +** Return SQLITE_OK if successful or an SQLite error code if an error +** occurs within a geometry callback. */ -static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor){ +static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){ RtreeCell cell; int ii; int bRes = 0; + int rc = SQLITE_OK; nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){ @@ -109551,40 +127930,60 @@ static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor){ double cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]); double cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]); - assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE - || p->op==RTREE_GT || p->op==RTREE_EQ + assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE + || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH ); switch( p->op ){ - case RTREE_LE: case RTREE_LT: bRes = p->rValue<cell_min; break; - case RTREE_GE: case RTREE_GT: bRes = p->rValue>cell_max; break; + case RTREE_LE: case RTREE_LT: + bRes = p->rValue<cell_min; + break; + + case RTREE_GE: case RTREE_GT: + bRes = p->rValue>cell_max; + break; + case RTREE_EQ: bRes = (p->rValue>cell_max || p->rValue<cell_min); break; + + default: { + assert( p->op==RTREE_MATCH ); + rc = testRtreeGeom(pRtree, p, &cell, &bRes); + bRes = !bRes; + break; + } } } - return bRes; + *pbEof = bRes; + return rc; } -/* -** Return true if the cell that cursor pCursor currently points to -** would be filtered (excluded) by the constraints in the -** pCursor->aConstraint[] array, or false otherwise. +/* +** Test if the cell that cursor pCursor currently points to +** would be filtered (excluded) by the constraints in the +** pCursor->aConstraint[] array. If so, set *pbEof to true before +** returning. If the cell is not filtered (excluded) by the constraints, +** set pbEof to zero. +** +** Return SQLITE_OK if successful or an SQLite error code if an error +** occurs within a geometry callback. ** ** This function assumes that the cell is part of a leaf node. */ -static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor){ +static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){ RtreeCell cell; int ii; + *pbEof = 0; nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); for(ii=0; ii<pCursor->nConstraint; ii++){ RtreeConstraint *p = &pCursor->aConstraint[ii]; double coord = DCOORD(cell.aCoord[p->iCoord]); int res; - assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE - || p->op==RTREE_GT || p->op==RTREE_EQ + assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE + || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH ); switch( p->op ){ case RTREE_LE: res = (coord<=p->rValue); break; @@ -109592,23 +127991,35 @@ static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor){ case RTREE_GE: res = (coord>=p->rValue); break; case RTREE_GT: res = (coord>p->rValue); break; case RTREE_EQ: res = (coord==p->rValue); break; + default: { + int rc; + assert( p->op==RTREE_MATCH ); + rc = testRtreeGeom(pRtree, p, &cell, &res); + if( rc!=SQLITE_OK ){ + return rc; + } + break; + } } - if( !res ) return 1; + if( !res ){ + *pbEof = 1; + return SQLITE_OK; + } } - return 0; + return SQLITE_OK; } /* ** Cursor pCursor currently points at a node that heads a sub-tree of ** height iHeight (if iHeight==0, then the node is a leaf). Descend -** to point to the left-most cell of the sub-tree that matches the +** to point to the left-most cell of the sub-tree that matches the ** configured constraints. */ static int descendToCell( - Rtree *pRtree, - RtreeCursor *pCursor, + Rtree *pRtree, + RtreeCursor *pCursor, int iHeight, int *pEof /* OUT: Set to true if cannot descend */ ){ @@ -109624,19 +128035,18 @@ static int descendToCell( assert( iHeight>=0 ); if( iHeight==0 ){ - isEof = testRtreeEntry(pRtree, pCursor); + rc = testRtreeEntry(pRtree, pCursor, &isEof); }else{ - isEof = testRtreeCell(pRtree, pCursor); + rc = testRtreeCell(pRtree, pCursor, &isEof); } - if( isEof || iHeight==0 ){ - *pEof = isEof; - return SQLITE_OK; + if( rc!=SQLITE_OK || isEof || iHeight==0 ){ + goto descend_to_cell_out; } iRowid = nodeGetRowid(pRtree, pCursor->pNode, pCursor->iCell); rc = nodeAcquire(pRtree, iRowid, pCursor->pNode, &pChild); if( rc!=SQLITE_OK ){ - return rc; + goto descend_to_cell_out; } nodeRelease(pRtree, pCursor->pNode); @@ -109646,7 +128056,7 @@ static int descendToCell( pCursor->iCell = ii; rc = descendToCell(pRtree, pCursor, iHeight-1, &isEof); if( rc!=SQLITE_OK ){ - return rc; + goto descend_to_cell_out; } } @@ -109658,35 +128068,46 @@ static int descendToCell( pCursor->iCell = iSavedCell; } +descend_to_cell_out: *pEof = isEof; - return SQLITE_OK; + return rc; } /* -** One of the cells in node pNode is guaranteed to have a 64-bit +** One of the cells in node pNode is guaranteed to have a 64-bit ** integer value equal to iRowid. Return the index of this cell. */ -static int nodeRowidIndex(Rtree *pRtree, RtreeNode *pNode, i64 iRowid){ +static int nodeRowidIndex( + Rtree *pRtree, + RtreeNode *pNode, + i64 iRowid, + int *piIndex +){ int ii; - for(ii=0; nodeGetRowid(pRtree, pNode, ii)!=iRowid; ii++){ - assert( ii<(NCELL(pNode)-1) ); + int nCell = NCELL(pNode); + for(ii=0; ii<nCell; ii++){ + if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){ + *piIndex = ii; + return SQLITE_OK; + } } - return ii; + return SQLITE_CORRUPT_VTAB; } /* ** Return the index of the cell containing a pointer to node pNode ** in its parent. If pNode is the root node, return -1. */ -static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode){ +static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode, int *piIndex){ RtreeNode *pParent = pNode->pParent; if( pParent ){ - return nodeRowidIndex(pRtree, pParent, pNode->iNode); + return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex); } - return -1; + *piIndex = -1; + return SQLITE_OK; } -/* +/* ** Rtree virtual table module xNext method. */ static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ @@ -109694,13 +128115,17 @@ static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; int rc = SQLITE_OK; + /* RtreeCursor.pNode must not be NULL. If is is NULL, then this cursor is + ** already at EOF. It is against the rules to call the xNext() method of + ** a cursor that has already reached EOF. + */ + assert( pCsr->pNode ); + if( pCsr->iStrategy==1 ){ /* This "scan" is a direct lookup by rowid. There is no next entry. */ nodeRelease(pRtree, pCsr->pNode); pCsr->pNode = 0; - } - - else if( pCsr->pNode ){ + }else{ /* Move to the next entry that matches the configured constraints. */ int iHeight = 0; while( pCsr->pNode ){ @@ -109714,7 +128139,10 @@ static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ } } pCsr->pNode = pNode->pParent; - pCsr->iCell = nodeParentIndex(pRtree, pNode); + rc = nodeParentIndex(pRtree, pNode, &pCsr->iCell); + if( rc!=SQLITE_OK ){ + return rc; + } nodeReference(pCsr->pNode); nodeRelease(pRtree, pNode); iHeight++; @@ -109724,7 +128152,7 @@ static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ return rc; } -/* +/* ** Rtree virtual table module xRowid method. */ static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ @@ -109737,7 +128165,7 @@ static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ return SQLITE_OK; } -/* +/* ** Rtree virtual table module xColumn method. */ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ @@ -109761,8 +128189,8 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ return SQLITE_OK; } -/* -** Use nodeAcquire() to obtain the leaf node containing the record with +/* +** Use nodeAcquire() to obtain the leaf node containing the record with ** rowid iRowid. If successful, set *ppLeaf to point to the node and ** return SQLITE_OK. If there is no such record in the table, set ** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf @@ -109782,12 +128210,57 @@ static int findLeafNode(Rtree *pRtree, i64 iRowid, RtreeNode **ppLeaf){ return rc; } - /* +** This function is called to configure the RtreeConstraint object passed +** as the second argument for a MATCH constraint. The value passed as the +** first argument to this function is the right-hand operand to the MATCH +** operator. +*/ +static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ + RtreeMatchArg *p; + sqlite3_rtree_geometry *pGeom; + int nBlob; + + /* Check that value is actually a blob. */ + if( !sqlite3_value_type(pValue)==SQLITE_BLOB ) return SQLITE_ERROR; + + /* Check that the blob is roughly the right size. */ + nBlob = sqlite3_value_bytes(pValue); + if( nBlob<(int)sizeof(RtreeMatchArg) + || ((nBlob-sizeof(RtreeMatchArg))%sizeof(double))!=0 + ){ + return SQLITE_ERROR; + } + + pGeom = (sqlite3_rtree_geometry *)sqlite3_malloc( + sizeof(sqlite3_rtree_geometry) + nBlob + ); + if( !pGeom ) return SQLITE_NOMEM; + memset(pGeom, 0, sizeof(sqlite3_rtree_geometry)); + p = (RtreeMatchArg *)&pGeom[1]; + + memcpy(p, sqlite3_value_blob(pValue), nBlob); + if( p->magic!=RTREE_GEOMETRY_MAGIC + || nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(double)) + ){ + sqlite3_free(pGeom); + return SQLITE_ERROR; + } + + pGeom->pContext = p->pContext; + pGeom->nParam = p->nParam; + pGeom->aParam = p->aParam; + + pCons->xGeom = p->xGeom; + pCons->pGeom = pGeom; + return SQLITE_OK; +} + +/* ** Rtree virtual table module xFilter method. */ static int rtreeFilter( - sqlite3_vtab_cursor *pVtabCursor, + sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ @@ -109800,8 +128273,7 @@ static int rtreeFilter( rtreeReference(pRtree); - sqlite3_free(pCsr->aConstraint); - pCsr->aConstraint = 0; + freeCursorConstraints(pCsr); pCsr->iStrategy = idxNum; if( idxNum==1 ){ @@ -109809,13 +128281,14 @@ static int rtreeFilter( RtreeNode *pLeaf; /* Leaf on which the required cell resides */ i64 iRowid = sqlite3_value_int64(argv[0]); rc = findLeafNode(pRtree, iRowid, &pLeaf); - pCsr->pNode = pLeaf; - if( pLeaf && rc==SQLITE_OK ){ - pCsr->iCell = nodeRowidIndex(pRtree, pLeaf, iRowid); + pCsr->pNode = pLeaf; + if( pLeaf ){ + assert( rc==SQLITE_OK ); + rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &pCsr->iCell); } }else{ - /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array - ** with the configured constraints. + /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array + ** with the configured constraints. */ if( argc>0 ){ pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc); @@ -109823,16 +128296,28 @@ static int rtreeFilter( if( !pCsr->aConstraint ){ rc = SQLITE_NOMEM; }else{ - assert( (idxStr==0 && argc==0) || strlen(idxStr)==argc*2 ); + memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc); + assert( (idxStr==0 && argc==0) || (int)strlen(idxStr)==argc*2 ); for(ii=0; ii<argc; ii++){ RtreeConstraint *p = &pCsr->aConstraint[ii]; p->op = idxStr[ii*2]; p->iCoord = idxStr[ii*2+1]-'a'; - p->rValue = sqlite3_value_double(argv[ii]); + if( p->op==RTREE_MATCH ){ + /* A MATCH operator. The right-hand-side must be a blob that + ** can be cast into an RtreeMatchArg object. One created using + ** an sqlite3_rtree_geometry_callback() SQL user function. + */ + rc = deserializeGeometry(argv[ii], p); + if( rc!=SQLITE_OK ){ + break; + } + }else{ + p->rValue = sqlite3_value_double(argv[ii]); + } } } } - + if( rc==SQLITE_OK ){ pCsr->pNode = 0; rc = nodeAcquire(pRtree, 1, 0, &pRoot); @@ -109863,19 +128348,18 @@ static int rtreeFilter( /* ** Rtree virtual table module xBestIndex method. There are three -** table scan strategies to choose from (in order from most to +** table scan strategies to choose from (in order from most to ** least desirable): ** ** idxNum idxStr Strategy ** ------------------------------------------------ ** 1 Unused Direct lookup by rowid. -** 2 See below R-tree query. -** 3 Unused Full table scan. +** 2 See below R-tree query or full-table scan. ** ------------------------------------------------ ** -** If strategy 1 or 3 is used, then idxStr is not meaningful. If strategy -** 2 is used, idxStr is formatted to contain 2 bytes for each -** constraint used. The first two bytes of idxStr correspond to +** If strategy 1 is used, then idxStr is not meaningful. If strategy +** 2 is used, idxStr is formatted to contain 2 bytes for each +** constraint used. The first two bytes of idxStr correspond to ** the constraint in sqlite3_index_info.aConstraintUsage[] with ** (argvIndex==1) etc. ** @@ -109889,6 +128373,7 @@ static int rtreeFilter( ** < 0x43 ('C') ** >= 0x44 ('D') ** > 0x45 ('E') +** MATCH 0x46 ('F') ** ---------------------- ** ** The second of each pair of bytes identifies the coordinate column @@ -109897,14 +128382,15 @@ static int rtreeFilter( */ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int rc = SQLITE_OK; - int ii, cCol; + int ii; int iIdx = 0; char zIdxStr[RTREE_MAX_DIMENSIONS*8+1]; memset(zIdxStr, 0, sizeof(zIdxStr)); + UNUSED_PARAMETER(tab); assert( pIdxInfo->idxStr==0 ); - for(ii=0; ii<pIdxInfo->nConstraint; ii++){ + for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ @@ -109919,56 +128405,31 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ pIdxInfo->aConstraintUsage[jj].omit = 1; /* This strategy involves a two rowid lookups on an B-Tree structures - ** and then a linear search of an R-Tree node. This should be - ** considered almost as quick as a direct rowid lookup (for which + ** and then a linear search of an R-Tree node. This should be + ** considered almost as quick as a direct rowid lookup (for which ** sqlite uses an internal cost of 0.0). - */ + */ pIdxInfo->estimatedCost = 10.0; return SQLITE_OK; } - if( p->usable && p->iColumn>0 ){ - u8 op = 0; + if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){ + u8 op; switch( p->op ){ case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break; case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break; case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; + default: + assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH ); + op = RTREE_MATCH; + break; } - if( op ){ - /* Make sure this particular constraint has not been used before. - ** If it has been used before, ignore it. - ** - ** A <= or < can be used if there is a prior >= or >. - ** A >= or > can be used if there is a prior < or <=. - ** A <= or < is disqualified if there is a prior <=, <, or ==. - ** A >= or > is disqualified if there is a prior >=, >, or ==. - ** A == is disqualifed if there is any prior constraint. - */ - int j, opmsk; - static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 }; - assert( compatible[RTREE_EQ & 7]==0 ); - assert( compatible[RTREE_LT & 7]==1 ); - assert( compatible[RTREE_LE & 7]==1 ); - assert( compatible[RTREE_GT & 7]==2 ); - assert( compatible[RTREE_GE & 7]==2 ); - cCol = p->iColumn - 1 + 'a'; - opmsk = compatible[op & 7]; - for(j=0; j<iIdx; j+=2){ - if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){ - op = 0; - break; - } - } - } - if( op ){ - assert( iIdx<sizeof(zIdxStr)-1 ); - zIdxStr[iIdx++] = op; - zIdxStr[iIdx++] = cCol; - pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); - pIdxInfo->aConstraintUsage[ii].omit = 1; - } + zIdxStr[iIdx++] = op; + zIdxStr[iIdx++] = p->iColumn - 1 + 'a'; + pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); + pIdxInfo->aConstraintUsage[ii].omit = 1; } } @@ -109989,7 +128450,7 @@ static float cellArea(Rtree *pRtree, RtreeCell *p){ float area = 1.0; int ii; for(ii=0; ii<(pRtree->nDim*2); ii+=2){ - area = area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); + area = (float)(area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]))); } return area; } @@ -110002,7 +128463,7 @@ static float cellMargin(Rtree *pRtree, RtreeCell *p){ float margin = 0.0; int ii; for(ii=0; ii<(pRtree->nDim*2); ii+=2){ - margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); + margin += (float)(DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); } return margin; } @@ -110035,8 +128496,8 @@ static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ for(ii=0; ii<(pRtree->nDim*2); ii+=2){ RtreeCoord *a1 = &p1->aCoord[ii]; RtreeCoord *a2 = &p2->aCoord[ii]; - if( (!isInt && (a2[0].f<a1[0].f || a2[1].f>a1[1].f)) - || ( isInt && (a2[0].i<a1[0].i || a2[1].i>a1[1].i)) + if( (!isInt && (a2[0].f<a1[0].f || a2[1].f>a1[1].f)) + || ( isInt && (a2[0].i<a1[0].i || a2[1].i>a1[1].i)) ){ return 0; } @@ -110058,16 +128519,22 @@ static float cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){ #if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT static float cellOverlap( - Rtree *pRtree, - RtreeCell *p, - RtreeCell *aCell, - int nCell, + Rtree *pRtree, + RtreeCell *p, + RtreeCell *aCell, + int nCell, int iExclude ){ int ii; float overlap = 0.0; for(ii=0; ii<nCell; ii++){ - if( ii!=iExclude ){ +#if VARIANT_RSTARTREE_CHOOSESUBTREE + if( ii!=iExclude ) +#else + assert( iExclude==-1 ); + UNUSED_PARAMETER(iExclude); +#endif + { int jj; float o = 1.0; for(jj=0; jj<(pRtree->nDim*2); jj+=2){ @@ -110081,7 +128548,7 @@ static float cellOverlap( o = 0.0; break; }else{ - o = o * (x2-x1); + o = o * (float)(x2-x1); } } overlap += o; @@ -110093,19 +128560,19 @@ static float cellOverlap( #if VARIANT_RSTARTREE_CHOOSESUBTREE static float cellOverlapEnlargement( - Rtree *pRtree, - RtreeCell *p, - RtreeCell *pInsert, - RtreeCell *aCell, - int nCell, + Rtree *pRtree, + RtreeCell *p, + RtreeCell *pInsert, + RtreeCell *aCell, + int nCell, int iExclude ){ - float before; - float after; + double before; + double after; before = cellOverlap(pRtree, p, aCell, nCell, iExclude); cellUnion(pRtree, p, pInsert); after = cellOverlap(pRtree, p, aCell, nCell, iExclude); - return after-before; + return (float)(after-before); } #endif @@ -110127,11 +128594,11 @@ static int ChooseLeaf( for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ int iCell; - sqlite3_int64 iBest; + sqlite3_int64 iBest = 0; - float fMinGrowth; - float fMinArea; - float fMinOverlap; + float fMinGrowth = 0.0; + float fMinArea = 0.0; + float fMinOverlap = 0.0; int nCell = NCELL(pNode); RtreeCell cell; @@ -110160,22 +128627,31 @@ static int ChooseLeaf( ** the smallest area. */ for(iCell=0; iCell<nCell; iCell++){ + int bBest = 0; float growth; float area; float overlap = 0.0; nodeGetCell(pRtree, pNode, iCell, &cell); growth = cellGrowth(pRtree, &cell, pCell); area = cellArea(pRtree, &cell); + #if VARIANT_RSTARTREE_CHOOSESUBTREE if( ii==(pRtree->iDepth-1) ){ overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell); } -#endif - if( (iCell==0) - || (overlap<fMinOverlap) + if( (iCell==0) + || (overlap<fMinOverlap) || (overlap==fMinOverlap && growth<fMinGrowth) || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea) ){ + bBest = 1; + } +#else + if( iCell==0||growth<fMinGrowth||(growth==fMinGrowth && area<fMinArea) ){ + bBest = 1; + } +#endif + if( bBest ){ fMinOverlap = overlap; fMinGrowth = growth; fMinArea = area; @@ -110198,25 +128674,30 @@ static int ChooseLeaf( ** the node pNode. This function updates the bounding box cells in ** all ancestor elements. */ -static void AdjustTree( +static int AdjustTree( Rtree *pRtree, /* Rtree table */ RtreeNode *pNode, /* Adjust ancestry of this node. */ RtreeCell *pCell /* This cell was just inserted */ ){ RtreeNode *p = pNode; while( p->pParent ){ - RtreeCell cell; RtreeNode *pParent = p->pParent; - int iCell = nodeParentIndex(pRtree, p); + RtreeCell cell; + int iCell; + + if( nodeParentIndex(pRtree, p, &iCell) ){ + return SQLITE_CORRUPT_VTAB; + } nodeGetCell(pRtree, pParent, iCell, &cell); if( !cellContains(pRtree, &cell, pCell) ){ cellUnion(pRtree, &cell, pCell); nodeOverwriteCell(pRtree, pParent, &cell, iCell); } - + p = pParent; } + return SQLITE_OK; } /* @@ -110248,9 +128729,9 @@ static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int); */ static RtreeCell *LinearPickNext( Rtree *pRtree, - RtreeCell *aCell, - int nCell, - RtreeCell *pLeftBox, + RtreeCell *aCell, + int nCell, + RtreeCell *pLeftBox, RtreeCell *pRightBox, int *aiUsed ){ @@ -110266,9 +128747,9 @@ static RtreeCell *LinearPickNext( */ static void LinearPickSeeds( Rtree *pRtree, - RtreeCell *aCell, - int nCell, - int *piLeftSeed, + RtreeCell *aCell, + int nCell, + int *piLeftSeed, int *piRightSeed ){ int i; @@ -110277,7 +128758,7 @@ static void LinearPickSeeds( float maxNormalInnerWidth = 0.0; /* Pick two "seed" cells from the array of cells. The algorithm used - ** here is the LinearPickSeeds algorithm from Gutman[1984]. The + ** here is the LinearPickSeeds algorithm from Gutman[1984]. The ** indices of the two seed cells in the array are stored in local ** variables iLeftSeek and iRightSeed. */ @@ -110328,9 +128809,9 @@ static void LinearPickSeeds( */ static RtreeCell *QuadraticPickNext( Rtree *pRtree, - RtreeCell *aCell, - int nCell, - RtreeCell *pLeftBox, + RtreeCell *aCell, + int nCell, + RtreeCell *pLeftBox, RtreeCell *pRightBox, int *aiUsed ){ @@ -110360,9 +128841,9 @@ static RtreeCell *QuadraticPickNext( */ static void QuadraticPickSeeds( Rtree *pRtree, - RtreeCell *aCell, - int nCell, - int *piLeftSeed, + RtreeCell *aCell, + int nCell, + int *piLeftSeed, int *piRightSeed ){ int ii; @@ -110393,7 +128874,7 @@ static void QuadraticPickSeeds( /* ** Arguments aIdx, aDistance and aSpare all point to arrays of size -** nIdx. The aIdx array contains the set of integers from 0 to +** nIdx. The aIdx array contains the set of integers from 0 to ** (nIdx-1) in no particular order. This function sorts the values ** in aIdx according to the indexed values in aDistance. For ** example, assuming the inputs: @@ -110409,9 +128890,9 @@ static void QuadraticPickSeeds( ** sorting algorithm. */ static void SortByDistance( - int *aIdx, - int nIdx, - float *aDistance, + int *aIdx, + int nIdx, + float *aDistance, int *aSpare ){ if( nIdx>1 ){ @@ -110465,7 +128946,7 @@ static void SortByDistance( /* ** Arguments aIdx, aCell and aSpare all point to arrays of size -** nIdx. The aIdx array contains the set of integers from 0 to +** nIdx. The aIdx array contains the set of integers from 0 to ** (nIdx-1) in no particular order. This function sorts the values ** in aIdx according to dimension iDim of the cells in aCell. The ** minimum value of dimension iDim is considered first, the @@ -110476,10 +128957,10 @@ static void SortByDistance( */ static void SortByDimension( Rtree *pRtree, - int *aIdx, - int nIdx, - int iDim, - RtreeCell *aCell, + int *aIdx, + int nIdx, + int iDim, + RtreeCell *aCell, int *aSpare ){ if( nIdx>1 ){ @@ -110547,9 +129028,9 @@ static int splitNodeStartree( int *aSpare; int ii; - int iBestDim; - int iBestSplit; - float fBestMargin; + int iBestDim = 0; + int iBestSplit = 0; + float fBestMargin = 0.0; int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); @@ -110571,14 +129052,14 @@ static int splitNodeStartree( for(ii=0; ii<pRtree->nDim; ii++){ float margin = 0.0; - float fBestOverlap; - float fBestArea; - int iBestLeft; + float fBestOverlap = 0.0; + float fBestArea = 0.0; + int iBestLeft = 0; int nLeft; for( - nLeft=RTREE_MINCELLS(pRtree); - nLeft<=(nCell-RTREE_MINCELLS(pRtree)); + nLeft=RTREE_MINCELLS(pRtree); + nLeft<=(nCell-RTREE_MINCELLS(pRtree)); nLeft++ ){ RtreeCell left; @@ -110668,8 +129149,8 @@ static int splitNodeGuttman( for(i=nCell-2; i>0; i--){ RtreeCell *pNext; pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed); - float diff = - cellGrowth(pRtree, pBboxLeft, pNext) - + float diff = + cellGrowth(pRtree, pBboxLeft, pNext) - cellGrowth(pRtree, pBboxRight, pNext) ; if( (RTREE_MINCELLS(pRtree)-NCELL(pRight)==i) @@ -110689,9 +129170,9 @@ static int splitNodeGuttman( #endif static int updateMapping( - Rtree *pRtree, - i64 iRowid, - RtreeNode *pNode, + Rtree *pRtree, + i64 iRowid, + RtreeNode *pNode, int iHeight ){ int (*xSetMapping)(Rtree *, sqlite3_int64, sqlite3_int64); @@ -110727,7 +129208,7 @@ static int SplitNode( RtreeCell leftbbox; RtreeCell rightbbox; - /* Allocate an array and populate it with a copy of pCell and + /* Allocate an array and populate it with a copy of pCell and ** all cells from node pLeft. Then zero the original node. */ aCell = sqlite3_malloc((sizeof(RtreeCell)+sizeof(int))*(nCell+1)); @@ -110745,14 +129226,14 @@ static int SplitNode( nCell++; if( pNode->iNode==1 ){ - pRight = nodeNew(pRtree, pNode, 1); - pLeft = nodeNew(pRtree, pNode, 1); + pRight = nodeNew(pRtree, pNode); + pLeft = nodeNew(pRtree, pNode); pRtree->iDepth++; pNode->isDirty = 1; writeInt16(pNode->zData, pRtree->iDepth); }else{ pLeft = pNode; - pRight = nodeNew(pRtree, pLeft->pParent, 1); + pRight = nodeNew(pRtree, pLeft->pParent); nodeReference(pLeft); } @@ -110769,8 +129250,12 @@ static int SplitNode( goto splitnode_out; } - /* Ensure both child nodes have node numbers assigned to them. */ - if( (0==pRight->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pRight))) + /* Ensure both child nodes have node numbers assigned to them by calling + ** nodeWrite(). Node pRight always needs a node number, as it was created + ** by nodeNew() above. But node pLeft sometimes already has a node number. + ** In this case avoid the all to nodeWrite(). + */ + if( SQLITE_OK!=(rc = nodeWrite(pRtree, pRight)) || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft))) ){ goto splitnode_out; @@ -110786,9 +129271,15 @@ static int SplitNode( } }else{ RtreeNode *pParent = pLeft->pParent; - int iCell = nodeParentIndex(pRtree, pLeft); - nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell); - AdjustTree(pRtree, pParent, &leftbbox); + int iCell; + rc = nodeParentIndex(pRtree, pLeft, &iCell); + if( rc==SQLITE_OK ){ + nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell); + rc = AdjustTree(pRtree, pParent, &leftbbox); + } + if( rc!=SQLITE_OK ){ + goto splitnode_out; + } } if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){ goto splitnode_out; @@ -110832,20 +129323,43 @@ splitnode_out: return rc; } +/* +** If node pLeaf is not the root of the r-tree and its pParent pointer is +** still NULL, load all ancestor nodes of pLeaf into memory and populate +** the pLeaf->pParent chain all the way up to the root node. +** +** This operation is required when a row is deleted (or updated - an update +** is implemented as a delete followed by an insert). SQLite provides the +** rowid of the row to delete, which can be used to find the leaf on which +** the entry resides (argument pLeaf). Once the leaf is located, this +** function is called to determine its ancestry. +*/ static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){ int rc = SQLITE_OK; - if( pLeaf->iNode!=1 && pLeaf->pParent==0 ){ - sqlite3_bind_int64(pRtree->pReadParent, 1, pLeaf->iNode); - if( sqlite3_step(pRtree->pReadParent)==SQLITE_ROW ){ - i64 iNode = sqlite3_column_int64(pRtree->pReadParent, 0); - rc = nodeAcquire(pRtree, iNode, 0, &pLeaf->pParent); - }else{ - rc = SQLITE_ERROR; - } - sqlite3_reset(pRtree->pReadParent); - if( rc==SQLITE_OK ){ - rc = fixLeafParent(pRtree, pLeaf->pParent); + RtreeNode *pChild = pLeaf; + while( rc==SQLITE_OK && pChild->iNode!=1 && pChild->pParent==0 ){ + int rc2 = SQLITE_OK; /* sqlite3_reset() return code */ + sqlite3_bind_int64(pRtree->pReadParent, 1, pChild->iNode); + rc = sqlite3_step(pRtree->pReadParent); + if( rc==SQLITE_ROW ){ + RtreeNode *pTest; /* Used to test for reference loops */ + i64 iNode; /* Node number of parent node */ + + /* Before setting pChild->pParent, test that we are not creating a + ** loop of references (as we would if, say, pChild==pParent). We don't + ** want to do this as it leads to a memory leak when trying to delete + ** the referenced counted node structures. + */ + iNode = sqlite3_column_int64(pRtree->pReadParent, 0); + for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent); + if( !pTest ){ + rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent); + } } + rc = sqlite3_reset(pRtree->pReadParent); + if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT_VTAB; + pChild = pChild->pParent; } return rc; } @@ -110854,18 +129368,24 @@ static int deleteCell(Rtree *, RtreeNode *, int, int); static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ int rc; - RtreeNode *pParent; + int rc2; + RtreeNode *pParent = 0; int iCell; assert( pNode->nRef==1 ); /* Remove the entry in the parent cell. */ - iCell = nodeParentIndex(pRtree, pNode); - pParent = pNode->pParent; - pNode->pParent = 0; - if( SQLITE_OK!=(rc = deleteCell(pRtree, pParent, iCell, iHeight+1)) - || SQLITE_OK!=(rc = nodeRelease(pRtree, pParent)) - ){ + rc = nodeParentIndex(pRtree, pNode, &iCell); + if( rc==SQLITE_OK ){ + pParent = pNode->pParent; + pNode->pParent = 0; + rc = deleteCell(pRtree, pParent, iCell, iHeight+1); + } + rc2 = nodeRelease(pRtree, pParent); + if( rc==SQLITE_OK ){ + rc = rc2; + } + if( rc!=SQLITE_OK ){ return rc; } @@ -110882,7 +129402,7 @@ static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteParent)) ){ return rc; } - + /* Remove the node from the in-memory hash table and link it into ** the Rtree.pDeleted list. Its contents will be re-inserted later on. */ @@ -110895,10 +129415,11 @@ static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ return SQLITE_OK; } -static void fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){ +static int fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){ RtreeNode *pParent = pNode->pParent; + int rc = SQLITE_OK; if( pParent ){ - int ii; + int ii; int nCell = NCELL(pNode); RtreeCell box; /* Bounding box for pNode */ nodeGetCell(pRtree, pNode, 0, &box); @@ -110908,10 +129429,13 @@ static void fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){ cellUnion(pRtree, &box, &cell); } box.iRowid = pNode->iNode; - ii = nodeParentIndex(pRtree, pNode); - nodeOverwriteCell(pRtree, pParent, &box, ii); - fixBoundingBox(pRtree, pParent); + rc = nodeParentIndex(pRtree, pNode, &ii); + if( rc==SQLITE_OK ){ + nodeOverwriteCell(pRtree, pParent, &box, ii); + rc = fixBoundingBox(pRtree, pParent); + } } + return rc; } /* @@ -110919,6 +129443,7 @@ static void fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){ ** cell, adjust the r-tree data structure if required. */ static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){ + RtreeNode *pParent; int rc; if( SQLITE_OK!=(rc = fixLeafParent(pRtree, pNode)) ){ @@ -110935,14 +129460,13 @@ static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){ ** cell in the parent node so that it tightly contains the updated ** node. */ - if( pNode->iNode!=1 ){ - RtreeNode *pParent = pNode->pParent; - if( (pParent->iNode!=1 || NCELL(pParent)!=1) - && (NCELL(pNode)<RTREE_MINCELLS(pRtree)) - ){ + pParent = pNode->pParent; + assert( pParent || pNode->iNode==1 ); + if( pParent ){ + if( NCELL(pNode)<RTREE_MINCELLS(pRtree) ){ rc = removeNode(pRtree, pNode, iHeight); }else{ - fixBoundingBox(pRtree, pNode); + rc = fixBoundingBox(pRtree, pNode); } } @@ -110950,9 +129474,9 @@ static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){ } static int Reinsert( - Rtree *pRtree, - RtreeNode *pNode, - RtreeCell *pCell, + Rtree *pRtree, + RtreeNode *pNode, + RtreeCell *pCell, int iHeight ){ int *aOrder; @@ -110993,19 +129517,19 @@ static int Reinsert( } aOrder[ii] = ii; for(iDim=0; iDim<pRtree->nDim; iDim++){ - aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]); - aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]); + aCenterCoord[iDim] += (float)DCOORD(aCell[ii].aCoord[iDim*2]); + aCenterCoord[iDim] += (float)DCOORD(aCell[ii].aCoord[iDim*2+1]); } } for(iDim=0; iDim<pRtree->nDim; iDim++){ - aCenterCoord[iDim] = aCenterCoord[iDim]/((float)nCell*2.0); + aCenterCoord[iDim] = (float)(aCenterCoord[iDim]/((float)nCell*2.0)); } for(ii=0; ii<nCell; ii++){ aDistance[ii] = 0.0; for(iDim=0; iDim<pRtree->nDim; iDim++){ - float coord = DCOORD(aCell[ii].aCoord[iDim*2+1]) - - DCOORD(aCell[ii].aCoord[iDim*2]); + float coord = (float)(DCOORD(aCell[ii].aCoord[iDim*2+1]) - + DCOORD(aCell[ii].aCoord[iDim*2])); aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); } } @@ -111025,7 +129549,7 @@ static int Reinsert( } } if( rc==SQLITE_OK ){ - fixBoundingBox(pRtree, pNode); + rc = fixBoundingBox(pRtree, pNode); } for(; rc==SQLITE_OK && ii<nCell; ii++){ /* Find a node to store this cell in. pNode->iNode currently contains @@ -111049,7 +129573,7 @@ static int Reinsert( } /* -** Insert cell pCell into node pNode. Node pNode is the head of a +** Insert cell pCell into node pNode. Node pNode is the head of a ** subtree iHeight high (leaf nodes have iHeight==0). */ static int rtreeInsertCell( @@ -111079,11 +129603,13 @@ static int rtreeInsertCell( rc = SplitNode(pRtree, pNode, pCell, iHeight); #endif }else{ - AdjustTree(pRtree, pNode, pCell); - if( iHeight==0 ){ - rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); - }else{ - rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode); + rc = AdjustTree(pRtree, pNode, pCell); + if( rc==SQLITE_OK ){ + if( iHeight==0 ){ + rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); + }else{ + rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode); + } } } return rc; @@ -111102,10 +129628,10 @@ static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){ /* Find a node to store this cell in. pNode->iNode currently contains ** the height of the sub-tree headed by the cell. */ - rc = ChooseLeaf(pRtree, &cell, pNode->iNode, &pInsert); + rc = ChooseLeaf(pRtree, &cell, (int)pNode->iNode, &pInsert); if( rc==SQLITE_OK ){ int rc2; - rc = rtreeInsertCell(pRtree, pInsert, &cell, pNode->iNode); + rc = rtreeInsertCell(pRtree, pInsert, &cell, (int)pNode->iNode); rc2 = nodeRelease(pRtree, pInsert); if( rc==SQLITE_OK ){ rc = rc2; @@ -111128,122 +129654,120 @@ static int newRowid(Rtree *pRtree, i64 *piRowid){ return rc; } -#ifndef NDEBUG -static int hashIsEmpty(Rtree *pRtree){ - int ii; - for(ii=0; ii<HASHSIZE; ii++){ - assert( !pRtree->aHash[ii] ); - } - return 1; -} -#endif - /* -** The xUpdate method for rtree module virtual tables. +** Remove the entry with rowid=iDelete from the r-tree structure. */ -static int rtreeUpdate( - sqlite3_vtab *pVtab, - int nData, - sqlite3_value **azData, - sqlite_int64 *pRowid -){ - Rtree *pRtree = (Rtree *)pVtab; - int rc = SQLITE_OK; +static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ + int rc; /* Return code */ + RtreeNode *pLeaf; /* Leaf node containing record iDelete */ + int iCell; /* Index of iDelete cell in pLeaf */ + RtreeNode *pRoot; /* Root node of rtree structure */ - rtreeReference(pRtree); - assert(nData>=1); - assert(hashIsEmpty(pRtree)); + /* Obtain a reference to the root node to initialise Rtree.iDepth */ + rc = nodeAcquire(pRtree, 1, 0, &pRoot); - /* If azData[0] is not an SQL NULL value, it is the rowid of a - ** record to delete from the r-tree table. The following block does - ** just that. + /* Obtain a reference to the leaf node that contains the entry + ** about to be deleted. */ - if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){ - i64 iDelete; /* The rowid to delete */ - RtreeNode *pLeaf; /* Leaf node containing record iDelete */ - int iCell; /* Index of iDelete cell in pLeaf */ - RtreeNode *pRoot; - - /* Obtain a reference to the root node to initialise Rtree.iDepth */ - rc = nodeAcquire(pRtree, 1, 0, &pRoot); - - /* Obtain a reference to the leaf node that contains the entry - ** about to be deleted. - */ - if( rc==SQLITE_OK ){ - iDelete = sqlite3_value_int64(azData[0]); - rc = findLeafNode(pRtree, iDelete, &pLeaf); - } + if( rc==SQLITE_OK ){ + rc = findLeafNode(pRtree, iDelete, &pLeaf); + } - /* Delete the cell in question from the leaf node. */ + /* Delete the cell in question from the leaf node. */ + if( rc==SQLITE_OK ){ + int rc2; + rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell); if( rc==SQLITE_OK ){ - int rc2; - iCell = nodeRowidIndex(pRtree, pLeaf, iDelete); rc = deleteCell(pRtree, pLeaf, iCell, 0); - rc2 = nodeRelease(pRtree, pLeaf); - if( rc==SQLITE_OK ){ - rc = rc2; - } } - - /* Delete the corresponding entry in the <rtree>_rowid table. */ + rc2 = nodeRelease(pRtree, pLeaf); if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete); - sqlite3_step(pRtree->pDeleteRowid); - rc = sqlite3_reset(pRtree->pDeleteRowid); + rc = rc2; } + } - /* Check if the root node now has exactly one child. If so, remove - ** it, schedule the contents of the child for reinsertion and - ** reduce the tree height by one. - ** - ** This is equivalent to copying the contents of the child into - ** the root node (the operation that Gutman's paper says to perform - ** in this scenario). - */ - if( rc==SQLITE_OK && pRtree->iDepth>0 ){ - if( rc==SQLITE_OK && NCELL(pRoot)==1 ){ - RtreeNode *pChild; - i64 iChild = nodeGetRowid(pRtree, pRoot, 0); - rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); - if( rc==SQLITE_OK ){ - rc = removeNode(pRtree, pChild, pRtree->iDepth-1); - } - if( rc==SQLITE_OK ){ - pRtree->iDepth--; - writeInt16(pRoot->zData, pRtree->iDepth); - pRoot->isDirty = 1; - } - } - } + /* Delete the corresponding entry in the <rtree>_rowid table. */ + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete); + sqlite3_step(pRtree->pDeleteRowid); + rc = sqlite3_reset(pRtree->pDeleteRowid); + } - /* Re-insert the contents of any underfull nodes removed from the tree. */ - for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){ - if( rc==SQLITE_OK ){ - rc = reinsertNodeContent(pRtree, pLeaf); - } - pRtree->pDeleted = pLeaf->pNext; - sqlite3_free(pLeaf); + /* Check if the root node now has exactly one child. If so, remove + ** it, schedule the contents of the child for reinsertion and + ** reduce the tree height by one. + ** + ** This is equivalent to copying the contents of the child into + ** the root node (the operation that Gutman's paper says to perform + ** in this scenario). + */ + if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){ + int rc2; + RtreeNode *pChild; + i64 iChild = nodeGetRowid(pRtree, pRoot, 0); + rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); + if( rc==SQLITE_OK ){ + rc = removeNode(pRtree, pChild, pRtree->iDepth-1); + } + rc2 = nodeRelease(pRtree, pChild); + if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK ){ + pRtree->iDepth--; + writeInt16(pRoot->zData, pRtree->iDepth); + pRoot->isDirty = 1; } + } - /* Release the reference to the root node. */ + /* Re-insert the contents of any underfull nodes removed from the tree. */ + for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){ if( rc==SQLITE_OK ){ - rc = nodeRelease(pRtree, pRoot); - }else{ - nodeRelease(pRtree, pRoot); + rc = reinsertNodeContent(pRtree, pLeaf); } + pRtree->pDeleted = pLeaf->pNext; + sqlite3_free(pLeaf); } - /* If the azData[] array contains more than one element, elements - ** (azData[2]..azData[argc-1]) contain a new record to insert into - ** the r-tree structure. + /* Release the reference to the root node. */ + if( rc==SQLITE_OK ){ + rc = nodeRelease(pRtree, pRoot); + }else{ + nodeRelease(pRtree, pRoot); + } + + return rc; +} + +/* +** The xUpdate method for rtree module virtual tables. +*/ +static int rtreeUpdate( + sqlite3_vtab *pVtab, + int nData, + sqlite3_value **azData, + sqlite_int64 *pRowid +){ + Rtree *pRtree = (Rtree *)pVtab; + int rc = SQLITE_OK; + RtreeCell cell; /* New cell to insert if nData>1 */ + int bHaveRowid = 0; /* Set to 1 after new rowid is determined */ + + rtreeReference(pRtree); + assert(nData>=1); + + /* Constraint handling. A write operation on an r-tree table may return + ** SQLITE_CONSTRAINT for two reasons: + ** + ** 1. A duplicate rowid value, or + ** 2. The supplied data violates the "x2>=x1" constraint. + ** + ** In the first case, if the conflict-handling mode is REPLACE, then + ** the conflicting row can be removed before proceeding. In the second + ** case, SQLITE_CONSTRAINT must be returned regardless of the + ** conflict-handling mode specified by the user. */ - if( rc==SQLITE_OK && nData>1 ){ - /* Insert a new record into the r-tree */ - RtreeCell cell; + if( nData>1 ){ int ii; - RtreeNode *pLeaf; /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */ assert( nData==(pRtree->nDim*2 + 3) ); @@ -111267,19 +129791,51 @@ static int rtreeUpdate( } } - /* Figure out the rowid of the new row. */ - if( sqlite3_value_type(azData[2])==SQLITE_NULL ){ - rc = newRowid(pRtree, &cell.iRowid); - }else{ + /* If a rowid value was supplied, check if it is already present in + ** the table. If so, the constraint has failed. */ + if( sqlite3_value_type(azData[2])!=SQLITE_NULL ){ cell.iRowid = sqlite3_value_int64(azData[2]); - sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); - if( SQLITE_ROW==sqlite3_step(pRtree->pReadRowid) ){ - sqlite3_reset(pRtree->pReadRowid); - rc = SQLITE_CONSTRAINT; - goto constraint; + if( sqlite3_value_type(azData[0])==SQLITE_NULL + || sqlite3_value_int64(azData[0])!=cell.iRowid + ){ + int steprc; + sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); + steprc = sqlite3_step(pRtree->pReadRowid); + rc = sqlite3_reset(pRtree->pReadRowid); + if( SQLITE_ROW==steprc ){ + if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ + rc = rtreeDeleteRowid(pRtree, cell.iRowid); + }else{ + rc = SQLITE_CONSTRAINT; + goto constraint; + } + } } - rc = sqlite3_reset(pRtree->pReadRowid); + bHaveRowid = 1; + } + } + + /* If azData[0] is not an SQL NULL value, it is the rowid of a + ** record to delete from the r-tree table. The following block does + ** just that. + */ + if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){ + rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(azData[0])); + } + + /* If the azData[] array contains more than one element, elements + ** (azData[2]..azData[argc-1]) contain a new record to insert into + ** the r-tree structure. + */ + if( rc==SQLITE_OK && nData>1 ){ + /* Insert the new record into the r-tree */ + RtreeNode *pLeaf; + + /* Figure out the rowid of the new row. */ + if( bHaveRowid==0 ){ + rc = newRowid(pRtree, &cell.iRowid); } + *pRowid = cell.iRowid; if( rc==SQLITE_OK ){ rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); @@ -111310,8 +129866,8 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ "ALTER TABLE %Q.'%q_node' RENAME TO \"%w_node\";" "ALTER TABLE %Q.'%q_parent' RENAME TO \"%w_parent\";" "ALTER TABLE %Q.'%q_rowid' RENAME TO \"%w_rowid\";" - , pRtree->zDb, pRtree->zName, zNewName - , pRtree->zDb, pRtree->zName, zNewName + , pRtree->zDb, pRtree->zName, zNewName + , pRtree->zDb, pRtree->zName, zNewName , pRtree->zDb, pRtree->zName, zNewName ); if( zSql ){ @@ -111322,7 +129878,7 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ } static sqlite3_module rtreeModule = { - 0, /* iVersion */ + 0, /* iVersion */ rtreeCreate, /* xCreate - create a table */ rtreeConnect, /* xConnect - connect to an existing table */ rtreeBestIndex, /* xBestIndex - Determine search strategy */ @@ -111341,14 +129897,17 @@ static sqlite3_module rtreeModule = { 0, /* xCommit - commit transaction */ 0, /* xRollback - rollback transaction */ 0, /* xFindFunction - function overloading */ - rtreeRename /* xRename - rename the table */ + rtreeRename, /* xRename - rename the table */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ }; static int rtreeSqlInit( - Rtree *pRtree, - sqlite3 *db, - const char *zDb, - const char *zPrefix, + Rtree *pRtree, + sqlite3 *db, + const char *zDb, + const char *zPrefix, int isCreate ){ int rc = SQLITE_OK; @@ -111406,7 +129965,7 @@ static int rtreeSqlInit( for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){ char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix); if( zSql ){ - rc = sqlite3_prepare_v2(db, zSql, -1, appStmt[i], 0); + rc = sqlite3_prepare_v2(db, zSql, -1, appStmt[i], 0); }else{ rc = SQLITE_NOMEM; } @@ -111448,9 +130007,9 @@ static int getIntFromStmt(sqlite3 *db, const char *zSql, int *piVal){ ** table already exists. In this case the node-size is determined by inspecting ** the root node of the tree. ** -** Otherwise, for an xCreate(), use 64 bytes less than the database page-size. -** This ensures that each node is stored on a single database page. If the -** database page-size is so large that more than RTREE_MAXCELLS entries +** Otherwise, for an xCreate(), use 64 bytes less than the database page-size. +** This ensures that each node is stored on a single database page. If the +** database page-size is so large that more than RTREE_MAXCELLS entries ** would fit in a single node, use a smaller node-size. */ static int getNodeSize( @@ -111461,7 +130020,7 @@ static int getNodeSize( int rc; char *zSql; if( isCreate ){ - int iPageSize; + int iPageSize = 0; zSql = sqlite3_mprintf("PRAGMA %Q.page_size", pRtree->zDb); rc = getIntFromStmt(db, zSql, &iPageSize); if( rc==SQLITE_OK ){ @@ -111482,7 +130041,7 @@ static int getNodeSize( return rc; } -/* +/* ** This function is the implementation of both the xConnect and xCreate ** methods of the r-tree virtual table. ** @@ -111503,7 +130062,7 @@ static int rtreeInit( Rtree *pRtree; int nDb; /* Length of string argv[1] */ int nName; /* Length of string argv[2] */ - int eCoordType = (int)pAux; + int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32); const char *aErrMsg[] = { 0, /* 0 */ @@ -111518,6 +130077,8 @@ static int rtreeInit( return SQLITE_ERROR; } + sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + /* Allocate the sqlite3_vtab structure */ nDb = strlen(argv[1]); nName = strlen(argv[2]); @@ -111591,7 +130152,7 @@ static int rtreeInit( ** ** The human readable string takes the form of a Tcl list with one ** entry for each cell in the r-tree node. Each entry is itself a -** list, containing the 8-byte rowid/pageno followed by the +** list, containing the 8-byte rowid/pageno followed by the ** <num-dimension>*2 coordinates. */ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ @@ -111600,6 +130161,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ Rtree tree; int ii; + UNUSED_PARAMETER(nArg); memset(&node, 0, sizeof(RtreeNode)); memset(&tree, 0, sizeof(Rtree)); tree.nDim = sqlite3_value_int(apArg[0]); @@ -111613,7 +130175,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ int jj; nodeGetCell(&tree, &node, ii, &cell); - sqlite3_snprintf(512-nCell,&zCell[nCell],"%d", cell.iRowid); + sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid); nCell = strlen(zCell); for(jj=0; jj<tree.nDim*2; jj++){ sqlite3_snprintf(512-nCell,&zCell[nCell]," %f",(double)cell.aCoord[jj].f); @@ -111628,15 +130190,16 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ zText = sqlite3_mprintf("{%s}", zCell); } } - + sqlite3_result_text(ctx, zText, -1, sqlite3_free); } static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ - if( sqlite3_value_type(apArg[0])!=SQLITE_BLOB + UNUSED_PARAMETER(nArg); + if( sqlite3_value_type(apArg[0])!=SQLITE_BLOB || sqlite3_value_bytes(apArg[0])<2 ){ - sqlite3_result_error(ctx, "Invalid argument to rtreedepth()", -1); + sqlite3_result_error(ctx, "Invalid argument to rtreedepth()", -1); }else{ u8 *zBlob = (u8 *)sqlite3_value_blob(apArg[0]); sqlite3_result_int(ctx, readInt16(zBlob)); @@ -111645,18 +130208,15 @@ static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ /* ** Register the r-tree module with database handle db. This creates the -** virtual table module "rtree" and the debugging/analysis scalar +** virtual table module "rtree" and the debugging/analysis scalar ** function "rtreenode". */ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db){ - int rc = SQLITE_OK; + const int utf8 = SQLITE_UTF8; + int rc; + rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0); if( rc==SQLITE_OK ){ - int utf8 = SQLITE_UTF8; - rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0); - } - if( rc==SQLITE_OK ){ - int utf8 = SQLITE_UTF8; rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0); } if( rc==SQLITE_OK ){ @@ -111671,6 +130231,70 @@ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db){ return rc; } +/* +** A version of sqlite3_free() that can be used as a callback. This is used +** in two places - as the destructor for the blob value returned by the +** invocation of a geometry function, and as the destructor for the geometry +** functions themselves. +*/ +static void doSqlite3Free(void *p){ + sqlite3_free(p); +} + +/* +** Each call to sqlite3_rtree_geometry_callback() creates an ordinary SQLite +** scalar user function. This C function is the callback used for all such +** registered SQL functions. +** +** The scalar user functions return a blob that is interpreted by r-tree +** table MATCH operators. +*/ +static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ + RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); + RtreeMatchArg *pBlob; + int nBlob; + + nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(double); + pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob); + if( !pBlob ){ + sqlite3_result_error_nomem(ctx); + }else{ + int i; + pBlob->magic = RTREE_GEOMETRY_MAGIC; + pBlob->xGeom = pGeomCtx->xGeom; + pBlob->pContext = pGeomCtx->pContext; + pBlob->nParam = nArg; + for(i=0; i<nArg; i++){ + pBlob->aParam[i] = sqlite3_value_double(aArg[i]); + } + sqlite3_result_blob(ctx, pBlob, nBlob, doSqlite3Free); + } +} + +/* +** Register a new geometry function for use with the r-tree MATCH operator. +*/ +SQLITE_API int sqlite3_rtree_geometry_callback( + sqlite3 *db, + const char *zGeom, + int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *), + void *pContext +){ + RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ + + /* Allocate and populate the context object. */ + pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); + if( !pGeomCtx ) return SQLITE_NOMEM; + pGeomCtx->xGeom = xGeom; + pGeomCtx->pContext = pContext; + + /* Create the new user-function. Register a destructor function to delete + ** the context object when it is no longer required. */ + return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, + (void *)pGeomCtx, geomCallback, 0, 0, doSqlite3Free + ); +} + #if !SQLITE_CORE SQLITE_API int sqlite3_extension_init( sqlite3 *db, @@ -111699,9 +130323,9 @@ SQLITE_API int sqlite3_extension_init( ************************************************************************* ** $Id: icu.c,v 1.7 2007/12/13 21:54:11 drh Exp $ ** -** This file implements an integration between the ICU library -** ("International Components for Unicode", an open-source library -** for handling unicode data) and SQLite. The integration uses +** This file implements an integration between the ICU library +** ("International Components for Unicode", an open-source library +** for handling unicode data) and SQLite. The integration uses ** ICU to provide the following to SQLite: ** ** * An implementation of the SQL regexp() function (and hence REGEXP @@ -111712,7 +130336,7 @@ SQLITE_API int sqlite3_extension_init( ** ** * Integration of ICU and SQLite collation seqences. ** -** * An implementation of the LIKE operator that uses ICU to +** * An implementation of the LIKE operator that uses ICU to ** provide case-independent matching. */ @@ -111724,6 +130348,7 @@ SQLITE_API int sqlite3_extension_init( #include <unicode/ustring.h> #include <unicode/ucol.h> +/* #include <assert.h> */ #ifndef SQLITE_CORE SQLITE_EXTENSION_INIT1 @@ -111747,7 +130372,7 @@ static void xFree(void *p){ /* ** Compare two UTF-8 strings for equality where the first string is -** a "LIKE" expression. Return true (1) if they are the same and +** a "LIKE" expression. Return true (1) if they are the same and ** false (0) if they are different. */ static int icuLikeCompare( @@ -111782,7 +130407,7 @@ static int icuLikeCompare( uint8_t c; /* Skip any MATCH_ALL or MATCH_ONE characters that follow a - ** MATCH_ALL. For each MATCH_ONE, skip one character in the + ** MATCH_ALL. For each MATCH_ONE, skip one character in the ** test string. */ while( (c=zPattern[iPattern]) == MATCH_ALL || c == MATCH_ONE ){ @@ -111835,15 +130460,15 @@ static int icuLikeCompare( ** ** A LIKE B ** -** is implemented as like(B, A). If there is an escape character E, +** is implemented as like(B, A). If there is an escape character E, ** ** A LIKE B ESCAPE E ** ** is mapped to like(B, A, E). */ static void icuLikeFunc( - sqlite3_context *context, - int argc, + sqlite3_context *context, + int argc, sqlite3_value **argv ){ const unsigned char *zA = sqlite3_value_text(argv[0]); @@ -111869,7 +130494,7 @@ static void icuLikeFunc( if( zE==0 ) return; U8_NEXT(zE, i, nE, uEsc); if( i!=nE){ - sqlite3_result_error(context, + sqlite3_result_error(context, "ESCAPE expression must be a single character", -1); return; } @@ -111884,7 +130509,7 @@ static void icuLikeFunc( ** This function is called when an ICU function called from within ** the implementation of an SQL scalar function returns an error. ** -** The scalar function context passed as the first argument is +** The scalar function context passed as the first argument is ** loaded with an error message based on the following two args. */ static void icuFunctionError( @@ -111910,7 +130535,7 @@ static void icuRegexpDelete(void *p){ /* ** Implementation of SQLite REGEXP operator. This scalar function takes ** two arguments. The first is a regular expression pattern to compile -** the second is a string to match against that pattern. If either +** the second is a string to match against that pattern. If either ** argument is an SQL NULL, then NULL Is returned. Otherwise, the result ** is 1 if the string matches the pattern, or 0 otherwise. ** @@ -111932,8 +130557,10 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ UBool res; const UChar *zString = sqlite3_value_text16(apArg[1]); - /* If the left hand side of the regexp operator is NULL, - ** then the result is also NULL. + (void)nArg; /* Unused parameter */ + + /* If the left hand side of the regexp operator is NULL, + ** then the result is also NULL. */ if( !zString ){ return; @@ -111971,7 +130598,7 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ } /* Set the text that the regular expression operates on to a NULL - ** pointer. This is not really necessary, but it is tidier than + ** pointer. This is not really necessary, but it is tidier than ** leaving the regular expression object configured with an invalid ** pointer after this function returns. */ @@ -111982,7 +130609,7 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ } /* -** Implementations of scalar functions for case mapping - upper() and +** Implementations of scalar functions for case mapping - upper() and ** lower(). Function upper() converts its input to upper-case (ABC). ** Function lower() converts to lower-case (abc). ** @@ -111990,7 +130617,7 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ ** "language specific". Refer to ICU documentation for the differences ** between the two. ** -** To utilise "general" case mapping, the upper() or lower() scalar +** To utilise "general" case mapping, the upper() or lower() scalar ** functions are invoked with one argument: ** ** upper('ABC') -> 'abc' @@ -112082,7 +130709,7 @@ static int icuCollationColl( /* ** Implementation of the scalar function icu_load_collation(). ** -** This scalar function is used to add ICU collation based collation +** This scalar function is used to add ICU collation based collation ** types to an SQLite database connection. It is intended to be called ** as follows: ** @@ -112093,8 +130720,8 @@ static int icuCollationColl( ** collation sequence to create. */ static void icuLoadCollation( - sqlite3_context *p, - int nArg, + sqlite3_context *p, + int nArg, sqlite3_value **apArg ){ sqlite3 *db = (sqlite3 *)sqlite3_user_data(p); @@ -112119,7 +130746,7 @@ static void icuLoadCollation( } assert(p); - rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, + rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, icuCollationColl, icuCollationDel ); if( rc!=SQLITE_OK ){ @@ -112160,7 +130787,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){ int rc = SQLITE_OK; int i; - for(i=0; rc==SQLITE_OK && i<(sizeof(scalars)/sizeof(struct IcuScalar)); i++){ + for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){ struct IcuScalar *p = &scalars[i]; rc = sqlite3_create_function( db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0 @@ -112172,7 +130799,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){ #if !SQLITE_CORE SQLITE_API int sqlite3_extension_init( - sqlite3 *db, + sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ @@ -112197,15 +130824,16 @@ SQLITE_API int sqlite3_extension_init( ** ************************************************************************* ** This file implements a tokenizer for fts3 based on the ICU library. -** -** $Id: fts3_icu.c,v 1.3 2008/09/01 18:34:20 danielk1977 Exp $ */ - #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) #ifdef SQLITE_ENABLE_ICU +/* #include <assert.h> */ +/* #include <string.h> */ #include <unicode/ubrk.h> +/* #include <unicode/ucol.h> */ +/* #include <unicode/ustring.h> */ #include <unicode/utf16.h> typedef struct IcuTokenizer IcuTokenizer; @@ -112272,7 +130900,7 @@ static int icuDestroy(sqlite3_tokenizer *pTokenizer){ /* ** Prepare to begin tokenizing a particular string. The input ** string to be tokenized is pInput[0..nBytes-1]. A cursor -** used to incrementally tokenize this string is returned in +** used to incrementally tokenize this string is returned in ** *ppCursor. */ static int icuOpen( @@ -112311,7 +130939,7 @@ static int icuOpen( pCsr->aOffset = (int *)&pCsr->aChar[nChar]; pCsr->aOffset[iOut] = iInput; - U8_NEXT(zInput, iInput, nInput, c); + U8_NEXT(zInput, iInput, nInput, c); while( c>0 ){ int isError = 0; c = u_foldCase(c, opt); |