diff --git a/sqlite3.c b/sqlite3.c
--- a/sqlite3.c
+++ b/sqlite3.c
@@ -1,8 +1,8 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.32.1. By combining all the individual C code files into this
+** version 3.31.1. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
** of 5% or more are commonly seen when SQLite is compiled as a single
** translation unit.
@@ -216,13 +216,10 @@
"ENABLE_ATOMIC_WRITE",
#endif
#if SQLITE_ENABLE_BATCH_ATOMIC_WRITE
"ENABLE_BATCH_ATOMIC_WRITE",
#endif
-#if SQLITE_ENABLE_BYTECODE_VTAB
- "ENABLE_BYTECODE_VTAB",
-#endif
#if SQLITE_ENABLE_CEROD
"ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
#endif
#if SQLITE_ENABLE_COLUMN_METADATA
"ENABLE_COLUMN_METADATA",
@@ -381,10 +378,13 @@
"FTS5_ENABLE_TEST_MI",
#endif
#if SQLITE_FTS5_NO_WITHOUT_ROWID
"FTS5_NO_WITHOUT_ROWID",
#endif
+#if SQLITE_HAS_CODEC
+ "HAS_CODEC",
+#endif
#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
"HAVE_ISNAN",
#endif
#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX
"HOMEGROWN_RECURSIVE_MUTEX",
@@ -537,10 +537,13 @@
"OMIT_BETWEEN_OPTIMIZATION",
#endif
#if SQLITE_OMIT_BLOB_LITERAL
"OMIT_BLOB_LITERAL",
#endif
+#if SQLITE_OMIT_BTREECOUNT
+ "OMIT_BTREECOUNT",
+#endif
#if SQLITE_OMIT_CAST
"OMIT_CAST",
#endif
#if SQLITE_OMIT_CHECK
"OMIT_CHECK",
@@ -1160,13 +1163,13 @@
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.32.1"
-#define SQLITE_VERSION_NUMBER 3032001
-#define SQLITE_SOURCE_ID "2020-05-25 16:19:56 0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba83350"
+#define SQLITE_VERSION "3.31.1"
+#define SQLITE_VERSION_NUMBER 3031001
+#define SQLITE_SOURCE_ID "2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837bb4d6"
/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
@@ -1336,26 +1339,30 @@
** for the [sqlite3] object.
** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
** the [sqlite3] object is successfully destroyed and all associated
** resources are deallocated.
**
-** Ideally, applications should [sqlite3_finalize | finalize] all
-** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and
-** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
-** with the [sqlite3] object prior to attempting to close the object.
** ^If the database connection is associated with unfinalized prepared
-** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
-** sqlite3_close() will leave the database connection open and return
-** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
-** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
-** it returns [SQLITE_OK] regardless, but instead of deallocating the database
-** connection immediately, it marks the database connection as an unusable
-** "zombie" and makes arrangements to automatically deallocate the database
-** connection after all prepared statements are finalized, all BLOB handles
-** are closed, and all backups have finished. The sqlite3_close_v2() interface
-** is intended for use with host languages that are garbage collected, and
-** where the order in which destructors are called is arbitrary.
+** statements or unfinished sqlite3_backup objects then sqlite3_close()
+** will leave the database connection open and return [SQLITE_BUSY].
+** ^If sqlite3_close_v2() is called with unfinalized prepared statements
+** and/or unfinished sqlite3_backups, then the database connection becomes
+** an unusable "zombie" which will automatically be deallocated when the
+** last prepared statement is finalized or the last sqlite3_backup is
+** finished. The sqlite3_close_v2() interface is intended for use with
+** host languages that are garbage collected, and where the order in which
+** destructors are called is arbitrary.
+**
+** Applications should [sqlite3_finalize | finalize] all [prepared statements],
+** [sqlite3_blob_close | close] all [BLOB handles], and
+** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
+** with the [sqlite3] object prior to attempting to close the object. ^If
+** sqlite3_close_v2() is called on a [database connection] that still has
+** outstanding [prepared statements], [BLOB handles], and/or
+** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation
+** of resources is deferred until all [prepared statements], [BLOB handles],
+** and [sqlite3_backup] objects are also destroyed.
**
** ^If an [sqlite3] object is destroyed while a transaction is open,
** the transaction is automatically rolled back.
**
** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
@@ -1540,25 +1547,22 @@
#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
-#define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
-#define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
#define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
-#define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
@@ -2123,16 +2127,14 @@
** so that all subsequent write operations are independent.
** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
**
**
[[SQLITE_FCNTL_LOCK_TIMEOUT]]
-** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS
-** to block for up to M milliseconds before failing when attempting to
-** obtain a file lock using the xLock or xShmLock methods of the VFS.
-** The parameter is a pointer to a 32-bit signed integer that contains
-** the value that M is to be set to. Before returning, the 32-bit signed
-** integer is overwritten with the previous value of M.
+** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
+** a file lock using the xLock or xShmLock methods of the VFS to wait
+** for up to M milliseconds before failing, where M is the single
+** unsigned integer parameter.
**
** [[SQLITE_FCNTL_DATA_VERSION]]
** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
** a database file. The argument is a pointer to a 32-bit unsigned integer.
** The "data version" for the pager is written into the pointer. The
@@ -2150,15 +2152,10 @@
** but omits changes implemented by the database connection on which it is
** called. This file control is the only mechanism to detect changes that
** happen either internally or externally and that are associated with
** a particular attached database.
**
-** [[SQLITE_FCNTL_CKPT_START]]
-** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint
-** in wal mode before the client starts to copy pages from the wal
-** file to the database file.
-**
** [[SQLITE_FCNTL_CKPT_DONE]]
** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
** in wal mode after the client has finished copying pages from the wal
** file to the database file, but before the *-shm file is updated to
** record the fact that the pages have been checkpointed.
@@ -2198,12 +2195,10 @@
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
#define SQLITE_FCNTL_DATA_VERSION 35
#define SQLITE_FCNTL_SIZE_LIMIT 36
#define SQLITE_FCNTL_CKPT_DONE 37
-#define SQLITE_FCNTL_RESERVE_BYTES 38
-#define SQLITE_FCNTL_CKPT_START 39
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -4578,23 +4573,12 @@
**
** These are utility routines, useful to [VFS|custom VFS implementations],
** that check if a database file was a URI that contained a specific query
** parameter, and if so obtains the value of that query parameter.
**
-** The first parameter to these interfaces (hereafter referred to
-** as F) must be one of:
-**
-** - A database filename pointer created by the SQLite core and
-** passed into the xOpen() method of a VFS implemention, or
-**
- A filename obtained from [sqlite3_db_filename()], or
-**
- A new filename constructed using [sqlite3_create_filename()].
-**
-** If the F parameter is not one of the above, then the behavior is
-** undefined and probably undesirable. Older versions of SQLite were
-** more tolerant of invalid F parameters than newer versions.
-**
-** If F is a suitable filename (as described in the previous paragraph)
+** If F is the database filename pointer passed into the xOpen() method of
+** a VFS implementation or it is the return value of [sqlite3_db_filename()]
** and if P is the name of the query parameter, then
** sqlite3_uri_parameter(F,P) returns the value of the P
** parameter if it exists or a NULL pointer if P does not appear as a
** query parameter on F. If P is a query parameter of F and it
** has no explicit value, then sqlite3_uri_parameter(F,P) returns
@@ -4673,82 +4657,10 @@
*/
SQLITE_API const char *sqlite3_filename_database(const char*);
SQLITE_API const char *sqlite3_filename_journal(const char*);
SQLITE_API const char *sqlite3_filename_wal(const char*);
-/*
-** CAPI3REF: Database File Corresponding To A Journal
-**
-** ^If X is the name of a rollback or WAL-mode journal file that is
-** passed into the xOpen method of [sqlite3_vfs], then
-** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file]
-** object that represents the main database file.
-**
-** This routine is intended for use in custom [VFS] implementations
-** only. It is not a general-purpose interface.
-** The argument sqlite3_file_object(X) must be a filename pointer that
-** has been passed into [sqlite3_vfs].xOpen method where the
-** flags parameter to xOpen contains one of the bits
-** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use
-** of this routine results in undefined and probably undesirable
-** behavior.
-*/
-SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
-
-/*
-** CAPI3REF: Create and Destroy VFS Filenames
-**
-** These interfces are provided for use by [VFS shim] implementations and
-** are not useful outside of that context.
-**
-** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of
-** database filename D with corresponding journal file J and WAL file W and
-** with N URI parameters key/values pairs in the array P. The result from
-** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that
-** is safe to pass to routines like:
-**
-** - [sqlite3_uri_parameter()],
-**
- [sqlite3_uri_boolean()],
-**
- [sqlite3_uri_int64()],
-**
- [sqlite3_uri_key()],
-**
- [sqlite3_filename_database()],
-**
- [sqlite3_filename_journal()], or
-**
- [sqlite3_filename_wal()].
-**
-** If a memory allocation error occurs, sqlite3_create_filename() might
-** return a NULL pointer. The memory obtained from sqlite3_create_filename(X)
-** must be released by a corresponding call to sqlite3_free_filename(Y).
-**
-** The P parameter in sqlite3_create_filename(D,J,W,N,P) should be an array
-** of 2*N pointers to strings. Each pair of pointers in this array corresponds
-** to a key and value for a query parameter. The P parameter may be a NULL
-** pointer if N is zero. None of the 2*N pointers in the P array may be
-** NULL pointers and key pointers should not be empty strings.
-** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
-** be NULL pointers, though they can be empty strings.
-**
-** The sqlite3_free_filename(Y) routine releases a memory allocation
-** previously obtained from sqlite3_create_filename(). Invoking
-** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op.
-**
-** If the Y parameter to sqlite3_free_filename(Y) is anything other
-** than a NULL pointer or a pointer previously acquired from
-** sqlite3_create_filename(), then bad things such as heap
-** corruption or segfaults may occur. The value Y should be
-** used again after sqlite3_free_filename(Y) has been called. This means
-** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y,
-** then the corresponding [sqlite3_module.xClose() method should also be
-** invoked prior to calling sqlite3_free_filename(Y).
-*/
-SQLITE_API char *sqlite3_create_filename(
- const char *zDatabase,
- const char *zJournal,
- const char *zWal,
- int nParam,
- const char **azParam
-);
-SQLITE_API void sqlite3_free_filename(char*);
/*
** CAPI3REF: Error Codes And Messages
** METHOD: sqlite3
**
@@ -5327,34 +5239,16 @@
** occurrences have the same index as the first occurrence.
** ^The index for named parameters can be looked up using the
** [sqlite3_bind_parameter_index()] API if desired. ^The index
** for "?NNN" parameters is the value of NNN.
** ^The NNN value must be between 1 and the [sqlite3_limit()]
-** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 32766).
+** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
**
** ^The third argument is the value to bind to the parameter.
** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16()
** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter
** is ignored and the end result is the same as sqlite3_bind_null().
-** ^If the third parameter to sqlite3_bind_text() is not NULL, then
-** it should be a pointer to well-formed UTF8 text.
-** ^If the third parameter to sqlite3_bind_text16() is not NULL, then
-** it should be a pointer to well-formed UTF16 text.
-** ^If the third parameter to sqlite3_bind_text64() is not NULL, then
-** it should be a pointer to a well-formed unicode string that is
-** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16
-** otherwise.
-**
-** [[byte-order determination rules]] ^The byte-order of
-** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
-** found in first character, which is removed, or in the absence of a BOM
-** the byte order is the native byte order of the host
-** machine for sqlite3_bind_text16() or the byte order specified in
-** the 6th parameter for sqlite3_bind_text64().)^
-** ^If UTF16 input text contains invalid unicode
-** characters, then SQLite might change those invalid characters
-** into the unicode replacement character: U+FFFD.
**
** ^(In those routines that have a fourth argument, its value is the
** number of bytes in the parameter. To be clear: the value is the
** number of bytes in the value, not the number of characters.)^
** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16()
@@ -5364,11 +5258,11 @@
** the behavior is undefined.
** If a non-negative fourth parameter is provided to sqlite3_bind_text()
** or sqlite3_bind_text16() or sqlite3_bind_text64() then
** that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL
-** terminated. If any NUL characters occurs at byte offsets less than
+** terminated. If any NUL characters occur at byte offsets less than
** the value of the fourth parameter then the resulting string value will
** contain embedded NULs. The result of expressions involving strings
** with embedded NULs is undefined.
**
** ^The fifth argument to the BLOB and string binding interfaces
@@ -6532,11 +6426,11 @@
** when first called if N is less than or equal to zero or if a memory
** allocate error occurs.
**
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
** determined by the N parameter on first successful call. Changing the
-** value of N in any subsequent call to sqlite3_aggregate_context() within
+** value of N in any subsequents call to sqlite3_aggregate_context() within
** the same aggregate function instance will not resize the memory
** allocation.)^ Within the xFinal callback, it is customary to set
** N=0 in calls to sqlite3_aggregate_context(C,N) so that no
** pointless memory allocations occur.
**
@@ -6689,13 +6583,12 @@
** cause the implemented SQL function to throw an exception.
** ^SQLite uses the string pointed to by the
** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
** as the text of an error message. ^SQLite interprets the error
** message string from sqlite3_result_error() as UTF-8. ^SQLite
-** interprets the string from sqlite3_result_error16() as UTF-16 using
-** the same [byte-order determination rules] as [sqlite3_bind_text16()].
-** ^If the third parameter to sqlite3_result_error()
+** interprets the string from sqlite3_result_error16() as UTF-16 in native
+** byte order. ^If the third parameter to sqlite3_result_error()
** or sqlite3_result_error16() is negative then SQLite takes as the error
** message all text up through the first zero character.
** ^If the third parameter to sqlite3_result_error() or
** sqlite3_result_error16() is non-negative then SQLite takes that many
** bytes (not characters) from the 2nd parameter as the error message.
@@ -6759,29 +6652,10 @@
** ^If the 4th parameter to the sqlite3_result_text* interfaces
** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
** then SQLite makes a copy of the result into space obtained
** from [sqlite3_malloc()] before it returns.
**
-** ^For the sqlite3_result_text16(), sqlite3_result_text16le(), and
-** sqlite3_result_text16be() routines, and for sqlite3_result_text64()
-** when the encoding is not UTF8, if the input UTF16 begins with a
-** byte-order mark (BOM, U+FEFF) then the BOM is removed from the
-** string and the rest of the string is interpreted according to the
-** byte-order specified by the BOM. ^The byte-order specified by
-** the BOM at the beginning of the text overrides the byte-order
-** specified by the interface procedure. ^So, for example, if
-** sqlite3_result_text16le() is invoked with text that begins
-** with bytes 0xfe, 0xff (a big-endian byte-order mark) then the
-** first two bytes of input are skipped and the remaining input
-** is interpreted as UTF16BE text.
-**
-** ^For UTF16 input text to the sqlite3_result_text16(),
-** sqlite3_result_text16be(), sqlite3_result_text16le(), and
-** sqlite3_result_text64() routines, if the text contains invalid
-** UTF16 characters, the invalid characters might be converted
-** into the unicode replacement character, U+FFFD.
-**
** ^The sqlite3_result_value() interface sets the result of
** the application-defined function to be a copy of the
** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
** so that the [sqlite3_value] specified in the parameter may change or
@@ -6983,10 +6857,55 @@
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const void*)
);
+#ifdef SQLITE_HAS_CODEC
+/*
+** Specify the key for an encrypted database. This routine should be
+** called right after sqlite3_open().
+**
+** The code to implement this API is not available in the public release
+** of SQLite.
+*/
+SQLITE_API int sqlite3_key(
+ sqlite3 *db, /* Database to be rekeyed */
+ const void *pKey, int nKey /* The key */
+);
+SQLITE_API int sqlite3_key_v2(
+ sqlite3 *db, /* Database to be rekeyed */
+ const char *zDbName, /* Name of the database */
+ const void *pKey, int nKey /* The key */
+);
+
+/*
+** Change the key on an open database. If the current database is not
+** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
+** database is decrypted.
+**
+** The code to implement this API is not available in the public release
+** of SQLite.
+*/
+SQLITE_API int sqlite3_rekey(
+ sqlite3 *db, /* Database to be rekeyed */
+ const void *pKey, int nKey /* The new key */
+);
+SQLITE_API int sqlite3_rekey_v2(
+ sqlite3 *db, /* Database to be rekeyed */
+ const char *zDbName, /* Name of the database */
+ const void *pKey, int nKey /* The new key */
+);
+
+/*
+** Specify the activation key for a SEE database. Unless
+** activated, none of the SEE routines will work.
+*/
+SQLITE_API void sqlite3_activate_see(
+ const char *zPassPhrase /* Activation phrase */
+);
+#endif
+
#ifdef SQLITE_ENABLE_CEROD
/*
** Specify the activation key for a CEROD database. Unless
** activated, none of the CEROD routines will work.
*/
@@ -8725,11 +8644,11 @@
#define SQLITE_TESTCTRL_FAULT_INSTALL 9
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
#define SQLITE_TESTCTRL_PENDING_BYTE 11
#define SQLITE_TESTCTRL_ASSERT 12
#define SQLITE_TESTCTRL_ALWAYS 13
-#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
+#define SQLITE_TESTCTRL_RESERVE 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
@@ -13351,16 +13270,13 @@
#endif
/*
** The maximum value of a ?nnn wildcard that the parser will accept.
-** If the value exceeds 32767 then extra space is required for the Expr
-** structure. But otherwise, we believe that the number can be as large
-** as a signed 32-bit integer can hold.
*/
#ifndef SQLITE_MAX_VARIABLE_NUMBER
-# define SQLITE_MAX_VARIABLE_NUMBER 32766
+# define SQLITE_MAX_VARIABLE_NUMBER 999
#endif
/* 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.
**
@@ -13445,25 +13361,10 @@
#pragma warn -aus /* Assigned value is never used */
#pragma warn -csu /* Comparing signed and unsigned */
#pragma warn -spa /* Suspicious pointer arithmetic */
#endif
-/*
-** WAL mode depends on atomic aligned 32-bit loads and stores in a few
-** places. The following macros try to make this explicit.
-*/
-#ifndef __has_feature
-# define __has_feature(x) 0 /* compatibility with non-clang compilers */
-#endif
-#if GCC_VERSION>=4007000 || __has_feature(c_atomic)
-# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED)
-# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
-#else
-# define AtomicLoad(PTR) (*(PTR))
-# define AtomicStore(PTR,VAL) (*(PTR) = (VAL))
-#endif
-
/*
** Include standard header files as necessary
*/
#ifdef HAVE_STDINT_H
#include
@@ -14537,10 +14438,11 @@
typedef struct BusyHandler BusyHandler;
struct BusyHandler {
int (*xBusyHandler)(void *,int); /* The busy callback */
void *pBusyArg; /* First arg to busy callback */
int nBusy; /* Incremented with each busy call */
+ u8 bExtraFileArg; /* Include sqlite3_file as callback arg */
};
/*
** Name of the master database table. The master database table
** is a special table that holds the names and attributes of all
@@ -14794,11 +14696,11 @@
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 sqlite3BtreeGetRequestedReserve(Btree*);
+SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree*);
SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p);
SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int,int*);
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
@@ -15056,11 +14958,13 @@
#ifndef NDEBUG
SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
#endif
SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor*);
+#ifndef SQLITE_OMIT_BTREECOUNT
SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
+#endif
#ifdef SQLITE_TEST
SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*);
#endif
@@ -15349,12 +15253,12 @@
#define OP_ElseNotEq 58 /* jump, same as TK_ESCAPE */
#define OP_DecrJumpZero 59 /* jump, synopsis: if (--r[P1])==0 goto P2 */
#define OP_IncrVacuum 60 /* jump */
#define OP_VNext 61 /* jump */
#define OP_Init 62 /* jump, synopsis: Start at P2 */
-#define OP_PureFunc 63 /* synopsis: r[P3]=func(r[P2@NP]) */
-#define OP_Function 64 /* synopsis: r[P3]=func(r[P2@NP]) */
+#define OP_PureFunc 63 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_Function 64 /* synopsis: r[P3]=func(r[P2@P5]) */
#define OP_Return 65
#define OP_EndCoroutine 66
#define OP_HaltIfNull 67 /* synopsis: if r[P3]=null halt */
#define OP_Halt 68
#define OP_Integer 69 /* synopsis: r[P2]=P1 */
@@ -15416,12 +15320,12 @@
#define OP_SorterData 125 /* synopsis: r[P2]=data */
#define OP_RowData 126 /* synopsis: r[P2]=data */
#define OP_Rowid 127 /* synopsis: r[P2]=rowid */
#define OP_NullRow 128
#define OP_SeekEnd 129
-#define OP_IdxInsert 130 /* synopsis: key=r[P2] */
-#define OP_SorterInsert 131 /* synopsis: key=r[P2] */
+#define OP_SorterInsert 130 /* synopsis: key=r[P2] */
+#define OP_IdxInsert 131 /* synopsis: key=r[P2] */
#define OP_IdxDelete 132 /* synopsis: key=r[P2@P3] */
#define OP_DeferredSeek 133 /* synopsis: Move P3 to P1.rowid if needed */
#define OP_IdxRowid 134 /* synopsis: r[P2]=rowid */
#define OP_FinishSeek 135
#define OP_Destroy 136
@@ -15571,11 +15475,10 @@
SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr);
-SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr);
SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters(Parse*,int addr, int n, u32 mask, int);
#else
@@ -15631,13 +15534,10 @@
SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*);
SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*);
-#ifdef SQLITE_ENABLE_BYTECODE_VTAB
-SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*);
-#endif
/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
** each VDBE opcode.
**
** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op
@@ -15870,10 +15770,13 @@
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*, u32*, int);
+#ifdef SQLITE_HAS_CODEC
+SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager*,Pager*);
+#endif
SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager*, int);
SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
SQLITE_PRIVATE void sqlite3PagerShrink(Pager*);
@@ -15919,26 +15822,18 @@
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, sqlite3*);
# ifdef SQLITE_ENABLE_SNAPSHOT
-SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager*, sqlite3_snapshot **ppSnapshot);
-SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager*, sqlite3_snapshot *pSnapshot);
+SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
+SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager);
# endif
#endif
-#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_ENABLE_SETLK_TIMEOUT)
-SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager*, int);
-SQLITE_PRIVATE void sqlite3PagerWalDb(Pager*, sqlite3*);
-#else
-# define sqlite3PagerWalWriteLock(y,z) SQLITE_OK
-# define sqlite3PagerWalDb(x,y)
-#endif
-
#ifdef SQLITE_DIRECT_OVERFLOW_READ
SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
#endif
#ifdef SQLITE_ENABLE_ZIPVFS
@@ -15960,16 +15855,25 @@
SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*);
SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager);
+#else
+# define sqlite3PagerResetLockTimeout(X)
+#endif
/* Functions used to truncate the database file. */
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16);
+#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*);
SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage*);
#endif
@@ -16633,10 +16537,11 @@
** have been filled out. If the schema changes, these column names might
** changes and so the view will need to be reset.
*/
#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */
#define DB_UnresetViews 0x0002 /* Some views have defined column names */
+#define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */
#define DB_ResetWanted 0x0008 /* Reset the schema when nSchemaLock==0 */
/*
** The number of different kinds of things that can be limited
** using the sqlite3_limit() interface.
@@ -16790,11 +16695,11 @@
** Each database connection is an instance of the following structure.
*/
struct sqlite3 {
sqlite3_vfs *pVfs; /* OS Interface */
struct Vdbe *pVdbe; /* List of active virtual machines */
- CollSeq *pDfltColl; /* BINARY collseq for the database encoding */
+ CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
sqlite3_mutex *mutex; /* Connection mutex */
Db *aDb; /* All backends */
int nDb; /* Number of backends currently in use */
u32 mDbFlags; /* flags recording internal state */
u64 flags; /* flags settable by pragmas. See below */
@@ -16893,11 +16798,10 @@
Hash aFunc; /* Hash table of connection functions */
Hash aCollSeq; /* All collating sequences */
BusyHandler busyHandler; /* Busy callback */
Db aDbStatic[2]; /* Static space for the 2 default backends */
Savepoint *pSavepoint; /* List of active savepoints */
- int nAnalysisLimit; /* Number of index rows to ANALYZE */
int busyTimeout; /* Busy handler timeout, in msec */
int nSavepoint; /* Number of non-transaction savepoints */
int nStatement; /* Number of nested statement-transactions */
i64 nDeferredCons; /* Net deferred constraints this transaction. */
i64 nDeferredImmCons; /* Net deferred immediate constraints */
@@ -17000,11 +16904,10 @@
#define DBFLAG_PreferBuiltin 0x0002 /* Preference to built-in funcs */
#define DBFLAG_Vacuum 0x0004 /* Currently in a VACUUM */
#define DBFLAG_VacuumInto 0x0008 /* Currently running VACUUM INTO */
#define DBFLAG_SchemaKnownOk 0x0010 /* Schema is known to be valid */
#define DBFLAG_InternalFunc 0x0020 /* Allow use of internal functions */
-#define DBFLAG_EncodingFixed 0x0040 /* No longer possible to change enc. */
/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
@@ -17119,11 +17022,11 @@
#define SQLITE_FUNC_EPHEM 0x0010 /* Ephemeral. Delete with VDBE */
#define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/
#define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */
#define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */
#define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */
-/* 0x0200 -- available for reuse */
+#define SQLITE_FUNC_COALESCE 0x0200 /* Built-in coalesce() or ifnull() */
#define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */
#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
** single query - might change over time */
@@ -17140,11 +17043,10 @@
#define INLINEFUNC_coalesce 0
#define INLINEFUNC_implies_nonnull_row 1
#define INLINEFUNC_expr_implies_expr 2
#define INLINEFUNC_expr_compare 3
#define INLINEFUNC_affinity 4
-#define INLINEFUNC_iif 5
#define INLINEFUNC_unlikely 99 /* Default case */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
** used to create the initializers for the FuncDef structures.
@@ -17305,11 +17207,10 @@
Expr *pDflt; /* Default value or GENERATED ALWAYS AS value */
char *zColl; /* Collating sequence. If NULL, use the default */
u8 notNull; /* An OE_ code for handling a NOT NULL constraint */
char affinity; /* One of the SQLITE_AFF_... values */
u8 szEst; /* Estimated size of value in this column. sizeof(INT)==1 */
- u8 hName; /* Column name hash for faster lookup */
u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */
};
/* Allowed values for Column.colFlags:
*/
@@ -17525,15 +17426,12 @@
** done as a macro so that it will be optimized out when virtual
** table support is omitted from the build.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
# define IsVirtual(X) ((X)->nModuleArg)
-# define ExprIsVtab(X) \
- ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->nModuleArg)
#else
# define IsVirtual(X) 0
-# define ExprIsVtab(X) 0
#endif
/*
** Macros to determine if a column is hidden. IsOrdinaryHiddenColumn()
** only works for non-virtual tables (ordinary tables and views) and is
@@ -17841,11 +17739,11 @@
/*
** An instance of this structure contains information needed to generate
** code for a SELECT that contains aggregate functions.
**
** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a
-** pointer to this structure. The Expr.iAgg field is the index in
+** pointer to this structure. The Expr.iColumn field is the index in
** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate
** code for that node.
**
** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the
** original Select structure that describes the SELECT statement. These
@@ -17887,14 +17785,14 @@
** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater
** than 32767 we have to make it 32-bit. 16-bit is preferred because
** it uses less memory in the Expr object, which is a big memory user
** in systems with lots of prepared statements. And few applications
** need more than about 10 or 20 variables. But some extreme users want
-** to have prepared statements with over 32766 variables, and for them
+** to have prepared statements with over 32767 variables, and for them
** the option is available (at compile-time).
*/
-#if SQLITE_MAX_VARIABLE_NUMBER<32767
+#if SQLITE_MAX_VARIABLE_NUMBER<=32767
typedef i16 ynVar;
#else
typedef int ynVar;
#endif
@@ -17966,13 +17864,10 @@
char affExpr; /* affinity, or RAISE type */
u8 op2; /* TK_REGISTER/TK_TRUTH: original value of Expr.op
** TK_COLUMN: the value of p5 for OP_Column
** TK_AGG_FUNCTION: nesting depth
** TK_FUNCTION: NC_SelfRef flag if needs OP_PureFunc */
-#ifdef SQLITE_DEBUG
- u8 vvaFlags; /* Verification flags. */
-#endif
u32 flags; /* Various flags. EP_* See below */
union {
char *zToken; /* Token value. Zero terminated and dequoted */
int iValue; /* Non-negative integer value if EP_IntValue */
} u;
@@ -18043,11 +17938,11 @@
#define EP_Skip 0x001000 /* Operator does not contribute to affinity */
#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
#define EP_Win 0x008000 /* Contains window functions */
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
- /* 0x020000 // available for reuse */
+#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
#define EP_Alias 0x400000 /* Is an alias for a result set column */
@@ -18057,11 +17952,10 @@
#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
#define EP_FromDDL 0x40000000 /* Originates from sqlite_master */
- /* 0x80000000 // Available */
/*
** The EP_Propagate mask is a set of properties that automatically propagate
** upwards into parent nodes.
*/
@@ -18076,28 +17970,18 @@
#define ExprSetProperty(E,P) (E)->flags|=(P)
#define ExprClearProperty(E,P) (E)->flags&=~(P)
#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
-
-/* Flags for use with Expr.vvaFlags
-*/
-#define EP_NoReduce 0x01 /* Cannot EXPRDUP_REDUCE this Expr */
-#define EP_Immutable 0x02 /* Do not change this Expr node */
-
/* The ExprSetVVAProperty() macro is used for Verification, Validation,
** and Accreditation only. It works like ExprSetProperty() during VVA
** processes but is a no-op for delivery.
*/
#ifdef SQLITE_DEBUG
-# define ExprSetVVAProperty(E,P) (E)->vvaFlags|=(P)
-# define ExprHasVVAProperty(E,P) (((E)->vvaFlags&(P))!=0)
-# define ExprClearVVAProperties(E) (E)->vvaFlags = 0
+# define ExprSetVVAProperty(E,P) (E)->flags|=(P)
#else
# define ExprSetVVAProperty(E,P)
-# define ExprHasVVAProperty(E,P) 0
-# define ExprClearVVAProperties(E)
#endif
/*
** 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
@@ -19067,11 +18951,10 @@
Select *pSelect; /* HAVING to WHERE clause ctx */
struct WindowRewrite *pRewrite; /* Window rewrite context */
struct WhereConst *pConst; /* WHERE clause constants */
struct RenameCtx *pRename; /* RENAME COLUMN context */
struct Table *pTab; /* Table of generated column */
- struct SrcList_item *pSrcItem; /* A single FROM clause item */
} u;
};
/* Forward declarations */
SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*);
@@ -19080,13 +18963,10 @@
SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*);
SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*);
SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*);
SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*);
-SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker*,Select*);
-SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker*,Select*);
-
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*);
#endif
/*
@@ -19227,20 +19107,17 @@
#define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__)
#define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__)
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3NomemError(int);
SQLITE_PRIVATE int sqlite3IoerrnomemError(int);
+SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno);
# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__)
# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__)
+# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptPgnoError(__LINE__,(P))
#else
# define SQLITE_NOMEM_BKPT SQLITE_NOMEM
# define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM
-#endif
-#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_CORRUPT_PGNO)
-SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno);
-# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptPgnoError(__LINE__,(P))
-#else
# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptError(__LINE__)
#endif
/*
** FTS3 and FTS4 both require virtual table support
@@ -19506,11 +19383,15 @@
SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
SQLITE_PRIVATE void sqlite3AddGenerated(Parse*,Expr*,Token*);
SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
sqlite3_vfs**,char**,char **);
-#define sqlite3CodecQueryParameters(A,B,C) 0
+#ifdef SQLITE_HAS_CODEC
+SQLITE_PRIVATE int sqlite3CodecQueryParameters(sqlite3*,const char*,const char*);
+#else
+# define sqlite3CodecQueryParameters(A,B,C) 0
+#endif
SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
#ifdef SQLITE_UNTESTABLE
# define sqlite3FaultSim(X) SQLITE_OK
#else
@@ -19615,11 +19496,11 @@
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Column*, int);
#endif
SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
-SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int);
+SQLITE_PRIVATE int sqlite3ExprCodeAtInit(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8);
#define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */
#define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */
@@ -19770,11 +19651,10 @@
# define sqlite3AuthRead(a,b,c,d)
# define sqlite3AuthCheck(a,b,c,d,e) SQLITE_OK
# define sqlite3AuthContextPush(a,b,c)
# define sqlite3AuthContextPop(a) ((void)(a))
#endif
-SQLITE_PRIVATE int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName);
SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*);
SQLITE_PRIVATE void sqlite3Detach(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*);
SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*);
@@ -19819,25 +19699,23 @@
** macros handle the common case without a procedure call, but then call
** the procedure for larger varints.
*/
#define getVarint32(A,B) \
(u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite3GetVarint32((A),(u32 *)&(B)))
-#define getVarint32NR(A,B) \
- B=(u32)*(A);if(B>=0x80)sqlite3GetVarint32((A),(u32*)&(B))
#define putVarint32(A,B) \
(u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\
sqlite3PutVarint((A),(B)))
#define getVarint sqlite3GetVarint
#define putVarint sqlite3PutVarint
SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*);
SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int);
-SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2);
-SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity);
+SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2);
+SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table*,int);
-SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr);
+SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr);
SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8);
SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*);
SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
SQLITE_PRIVATE void sqlite3Error(sqlite3*,int);
SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int);
@@ -19856,14 +19734,13 @@
SQLITE_PRIVATE const char *sqlite3ErrStr(int);
SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq*);
SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
-SQLITE_PRIVATE void sqlite3SetTextEncoding(sqlite3 *db, u8);
-SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr);
-SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr);
-SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,const Expr*,const Expr*);
+SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
+SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr);
+SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr*);
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
@@ -19926,12 +19803,10 @@
const struct ExprList_item*,
const char*,
const char*,
const char*
);
-SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr*);
-SQLITE_PRIVATE u8 sqlite3StrIHash(const char*);
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*);
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
SQLITE_PRIVATE int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
@@ -19943,11 +19818,11 @@
SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*);
SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*);
SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
-SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
+SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*);
SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*);
SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*);
@@ -20068,14 +19943,12 @@
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db);
#ifndef SQLITE_OMIT_VIRTUALTABLE
SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
-SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
#else
# define sqlite3ShadowTableName(A,B) 0
-# define sqlite3IsShadowTableOf(A,B,C) 0
#endif
SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
@@ -20094,12 +19967,12 @@
#ifdef SQLITE_ENABLE_NORMALIZE
SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*);
#endif
SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
-SQLITE_PRIVATE CollSeq *sqlite3ExprCompareCollSeq(Parse*,const Expr*);
-SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, const Expr*, const Expr*);
+SQLITE_PRIVATE CollSeq *sqlite3ExprCompareCollSeq(Parse*,Expr*);
+SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
SQLITE_PRIVATE const char *sqlite3JournalModename(int);
#ifndef SQLITE_OMIT_WAL
SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
@@ -20449,13 +20322,20 @@
** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
**
** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** SQLITE_USE_URI symbol defined.
+**
+** URI filenames are enabled by default if SQLITE_HAS_CODEC is
+** enabled.
*/
#ifndef SQLITE_USE_URI
-# define SQLITE_USE_URI 0
+# ifdef SQLITE_HAS_CODEC
+# define SQLITE_USE_URI 1
+# else
+# define SQLITE_USE_URI 0
+# endif
#endif
/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
** that compile-time option is omitted.
@@ -20681,12 +20561,11 @@
/*
** VDBE_DISPLAY_P4 is true or false depending on whether or not the
** "explain" P4 display logic is enabled.
*/
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
- || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) \
- || defined(SQLITE_ENABLE_BYTECODE_VTAB)
+ || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
# define VDBE_DISPLAY_P4 1
#else
# define VDBE_DISPLAY_P4 0
#endif
@@ -21069,13 +20948,13 @@
#endif
u16 nResColumn; /* Number of columns in one row of the result set */
u8 errorAction; /* Recovery action to do in case of an error */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
u8 prepFlags; /* SQLITE_PREPARE_* flags */
- u8 doingRerun; /* True if rerunning after an auto-reprepare */
bft expired:2; /* 1: recompile VM immediately 2: when convenient */
bft explain:2; /* True if EXPLAIN present on SQL command */
+ bft doingRerun:1; /* True if rerunning after an auto-reprepare */
bft changeCntOn:1; /* True to update the change-counter */
bft runOnlyOnce:1; /* Automatically expire on reset */
bft usesStmtJournal:1; /* True if uses a statement journal */
bft readOnly:1; /* True for statements that do not write */
bft bIsReader:1; /* True for statements that read */
@@ -21147,18 +21026,11 @@
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
-#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
-SQLITE_PRIVATE int sqlite3VdbeNextOpcode(Vdbe*,Mem*,int,int*,int*,Op**);
-SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3*,Op*);
-#endif
-#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS)
-SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(sqlite3*,const Op*,const char*);
-#endif
-#if !defined(SQLITE_OMIT_EXPLAIN)
+#ifndef SQLITE_OMIT_EXPLAIN
SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
#endif
SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
@@ -21190,17 +21062,16 @@
SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8);
SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*);
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
#ifndef SQLITE_OMIT_WINDOWFUNC
SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
#endif
-#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
+#ifndef SQLITE_OMIT_EXPLAIN
SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
#endif
SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
@@ -22276,16 +22147,16 @@
u8 nName; /* Length of th name */
char *zName; /* Name of the transformation */
double rLimit; /* Maximum NNN value for this transform */
double rXform; /* Constant used for this transform */
} aXformType[] = {
- { 0, 6, "second", 464269060800.0, 1000.0 },
- { 0, 6, "minute", 7737817680.0, 60000.0 },
- { 0, 4, "hour", 128963628.0, 3600000.0 },
- { 0, 3, "day", 5373485.0, 86400000.0 },
- { 1, 5, "month", 176546.0, 2592000000.0 },
- { 2, 4, "year", 14713.0, 31536000000.0 },
+ { 0, 6, "second", 464269060800.0, 86400000.0/(24.0*60.0*60.0) },
+ { 0, 6, "minute", 7737817680.0, 86400000.0/(24.0*60.0) },
+ { 0, 4, "hour", 128963628.0, 86400000.0/24.0 },
+ { 0, 3, "day", 5373485.0, 86400000.0 },
+ { 1, 5, "month", 176546.0, 30.0*86400000.0 },
+ { 2, 4, "year", 14713.0, 365.0*86400000.0 },
};
/*
** Process a modifier to a date-time stamp. The modifiers are
** as follows:
@@ -25841,11 +25712,10 @@
#ifdef SQLITE_DEBUG
GLOBAL(int, mutexIsInit) = 1;
#endif
- sqlite3MemoryBarrier();
return rc;
}
/*
** Shutdown the mutex system. This call frees resources allocated by
@@ -27369,11 +27239,11 @@
if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){
n = mem0.hardLimit;
}
mem0.alarmThreshold = n;
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- AtomicStore(&mem0.nearlyFull, n>0 && n<=nUsed);
+ mem0.nearlyFull = (n>0 && n<=nUsed);
sqlite3_mutex_leave(mem0.mutex);
excess = sqlite3_memory_used() - n;
if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
return priorLimit;
}
@@ -27437,11 +27307,11 @@
** 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 AtomicLoad(&mem0.nearlyFull);
+ return mem0.nearlyFull;
}
/*
** Deinitialize the memory allocation subsystem.
*/
@@ -27501,21 +27371,21 @@
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
if( mem0.alarmThreshold>0 ){
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.alarmThreshold - nFull ){
- AtomicStore(&mem0.nearlyFull, 1);
+ mem0.nearlyFull = 1;
sqlite3MallocAlarm(nFull);
if( mem0.hardLimit ){
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.hardLimit - nFull ){
*pp = 0;
return;
}
}
}else{
- AtomicStore(&mem0.nearlyFull, 0);
+ mem0.nearlyFull = 0;
}
}
p = sqlite3GlobalConfig.m.xMalloc(nFull);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
if( p==0 && mem0.alarmThreshold>0 ){
@@ -27740,16 +27610,14 @@
if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
mem0.alarmThreshold-nDiff ){
sqlite3MallocAlarm(nDiff);
}
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
if( pNew==0 && mem0.alarmThreshold>0 ){
sqlite3MallocAlarm((int)nBytes);
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
}
-#endif
if( pNew ){
nNew = sqlite3MallocSize(pNew);
sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
}
sqlite3_mutex_leave(mem0.mutex);
@@ -27930,11 +27798,11 @@
}
}else{
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
- pNew = sqlite3Realloc(p, n);
+ pNew = sqlite3_realloc64(p, n);
if( !pNew ){
sqlite3OomFault(db);
}
sqlite3MemdebugSetType(pNew,
(db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
@@ -28020,11 +27888,11 @@
*/
SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){
if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
db->mallocFailed = 1;
if( db->nVdbeExec>0 ){
- AtomicStore(&db->u1.isInterrupted, 1);
+ db->u1.isInterrupted = 1;
}
DisableLookaside;
if( db->pParse ){
db->pParse->rc = SQLITE_NOMEM_BKPT;
}
@@ -28039,11 +27907,11 @@
** VDBEs.
*/
SQLITE_PRIVATE void sqlite3OomClear(sqlite3 *db){
if( db->mallocFailed && db->nVdbeExec==0 ){
db->mallocFailed = 0;
- AtomicStore(&db->u1.isInterrupted, 0);
+ db->u1.isInterrupted = 0;
assert( db->lookaside.bDisable>0 );
EnableLookaside;
}
}
@@ -28277,17 +28145,10 @@
#ifndef SQLITE_PRINT_BUF_SIZE
# define SQLITE_PRINT_BUF_SIZE 70
#endif
#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
-/*
-** Hard limit on the precision of floating-point conversions.
-*/
-#ifndef SQLITE_PRINTF_PRECISION_LIMIT
-# define SQLITE_FP_PRECISION_LIMIT 100000000
-#endif
-
/*
** Render a string given by "fmt" into the StrAccum object.
*/
SQLITE_API void sqlite3_str_vappendf(
sqlite3_str *pAccum, /* Accumulate results here */
@@ -28484,12 +28345,10 @@
** precision The specified precision. The default
** is -1.
** xtype The class of the conversion.
** infop Pointer to the appropriate info struct.
*/
- assert( width>=0 );
- assert( precision>=(-1) );
switch( xtype ){
case etPOINTER:
flag_long = sizeof(char*)==sizeof(i64) ? 2 :
sizeof(char*)==sizeof(long int) ? 1 : 0;
/* Fall through into the next case */
@@ -28607,15 +28466,10 @@
}
#ifdef SQLITE_OMIT_FLOATING_POINT
length = 0;
#else
if( precision<0 ) precision = 6; /* Set default precision */
-#ifdef SQLITE_FP_PRECISION_LIMIT
- if( precision>SQLITE_FP_PRECISION_LIMIT ){
- precision = SQLITE_FP_PRECISION_LIMIT;
- }
-#endif
if( realvalue<0.0 ){
realvalue = -realvalue;
prefix = '-';
}else{
prefix = flag_prefix;
@@ -28894,11 +28748,11 @@
}else{
escarg = va_arg(ap,char*);
}
isnull = escarg==0;
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
- /* For %q, %Q, and %w, the precision is the number of bytes (or
+ /* For %q, %Q, and %w, the precision is the number of byte (or
** characters if the ! flags is present) to use from the input.
** Because of the extra quoting characters inserted, the number
** of output characters may be larger than the precision.
*/
k = precision;
@@ -29021,11 +28875,11 @@
p->nAlloc = (int)szNew;
}
if( p->db ){
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
}else{
- zNew = sqlite3Realloc(zOld, p->nAlloc);
+ zNew = sqlite3_realloc64(zOld, p->nAlloc);
}
if( zNew ){
assert( p->zText!=0 || p->nChar==0 );
if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
@@ -29363,11 +29217,11 @@
** and segfaults if you give it a long long int.
*/
SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
va_list ap;
StrAccum acc;
- char zBuf[SQLITE_PRINT_BUF_SIZE*10];
+ char zBuf[500];
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
va_start(ap,zFormat);
sqlite3_str_vappendf(&acc, zFormat, ap);
va_end(ap);
sqlite3StrAccumFinish(&acc);
@@ -29535,12 +29389,12 @@
sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
}else if( pItem->zName ){
sqlite3_str_appendf(&x, " %s", pItem->zName);
}
if( pItem->pTab ){
- sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx",
- pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed);
+ sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p",
+ pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab);
}
if( pItem->zAlias ){
sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
}
if( pItem->fg.jointype & JT_LEFT ){
@@ -29795,31 +29649,28 @@
** Generate a human-readable explanation of an expression tree.
*/
SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
const char *zBinOp = 0; /* Binary operator */
const char *zUniOp = 0; /* Unary operator */
- char zFlgs[200];
+ char zFlgs[60];
pView = sqlite3TreeViewPush(pView, moreToFollow);
if( pExpr==0 ){
sqlite3TreeViewLine(pView, "nil");
sqlite3TreeViewPop(pView);
return;
}
- if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){
+ if( pExpr->flags || pExpr->affExpr ){
StrAccum x;
sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
sqlite3_str_appendf(&x, " fg.af=%x.%c",
pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
if( ExprHasProperty(pExpr, EP_FromJoin) ){
sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable);
}
if( ExprHasProperty(pExpr, EP_FromDDL) ){
sqlite3_str_appendf(&x, " DDL");
}
- if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
- sqlite3_str_appendf(&x, " IMMUTABLE");
- }
sqlite3StrAccumFinish(&x);
}else{
zFlgs[0] = 0;
}
switch( pExpr->op ){
@@ -29922,11 +29773,10 @@
case TK_SLASH: zBinOp = "DIV"; break;
case TK_LSHIFT: zBinOp = "LSHIFT"; break;
case TK_RSHIFT: zBinOp = "RSHIFT"; break;
case TK_CONCAT: zBinOp = "CONCAT"; break;
case TK_DOT: zBinOp = "DOT"; break;
- case TK_LIMIT: zBinOp = "LIMIT"; break;
case TK_UMINUS: zUniOp = "UMINUS"; break;
case TK_UPLUS: zUniOp = "UPLUS"; break;
case TK_BITNOT: zUniOp = "BITNOT"; break;
case TK_NOT: zUniOp = "NOT"; break;
@@ -29979,13 +29829,12 @@
#else
pWin = 0;
#endif
}
if( pExpr->op==TK_AGG_FUNCTION ){
- sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s iAgg=%d agg=%p",
- pExpr->op2, pExpr->u.zToken, zFlgs,
- pExpr->iAgg, pExpr->pAggInfo);
+ sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s",
+ pExpr->op2, pExpr->u.zToken, zFlgs);
}else if( pExpr->op2!=0 ){
const char *zOp2;
char zBuf[8];
sqlite3_snprintf(sizeof(zBuf),zBuf,"0x%02x",pExpr->op2);
zOp2 = zBuf;
@@ -30695,10 +30544,30 @@
*zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \
*zOut++ = (u8)(c&0x00FF); \
} \
}
+#define READ_UTF16LE(zIn, TERM, c){ \
+ c = (*zIn++); \
+ c += ((*zIn++)<<8); \
+ if( c>=0xD800 && c<0xE000 && TERM ){ \
+ int c2 = (*zIn++); \
+ c2 += ((*zIn++)<<8); \
+ c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
+ } \
+}
+
+#define READ_UTF16BE(zIn, TERM, c){ \
+ c = ((*zIn++)<<8); \
+ c += (*zIn++); \
+ if( c>=0xD800 && c<0xE000 && TERM ){ \
+ int c2 = ((*zIn++)<<8); \
+ c2 += (*zIn++); \
+ c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
+ } \
+}
+
/*
** Translate a single UTF-8 character. Return the unicode value.
**
** During translation, assume that the byte that zTerm points
** is a 0x00.
@@ -30871,63 +30740,17 @@
}else{
assert( desiredEnc==SQLITE_UTF8 );
if( pMem->enc==SQLITE_UTF16LE ){
/* UTF-16 Little-endian -> UTF-8 */
while( zIn=0xd800 && c<0xe000 ){
-#ifdef SQLITE_REPLACE_INVALID_UTF
- if( c>=0xdc00 || zIn>=zTerm ){
- c = 0xfffd;
- }else{
- int c2 = *(zIn++);
- c2 += (*(zIn++))<<8;
- if( c2<0xdc00 || c2>=0xe000 ){
- zIn -= 2;
- c = 0xfffd;
- }else{
- c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
- }
- }
-#else
- if( zIn UTF-8 */
while( zIn=0xd800 && c<0xe000 ){
-#ifdef SQLITE_REPLACE_INVALID_UTF
- if( c>=0xdc00 || zIn>=zTerm ){
- c = 0xfffd;
- }else{
- int c2 = (*(zIn++))<<8;
- c2 += *(zIn++);
- if( c2<0xdc00 || c2>=0xe000 ){
- zIn -= 2;
- c = 0xfffd;
- }else{
- c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
- }
- }
-#else
- if( zInn = (int)(z - zOut);
}
@@ -31082,19 +30905,22 @@
SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){
int c;
unsigned char const *z = zIn;
int n = 0;
- if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++;
- while( n=0xd8 && c<0xdc && z[0]>=0xdc && z[0]<0xe0 ) z += 2;
- n++;
+ if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
+ while( n=0xD800 && i<=0xDFFF ) t = 0xFFFD;
if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
assert( c==t );
assert( (z-zBuf)==n );
}
+ for(i=0; i<0x00110000; i++){
+ if( i>=0xD800 && i<0xE000 ) continue;
+ z = zBuf;
+ WRITE_UTF16LE(z, i);
+ n = (int)(z-zBuf);
+ assert( n>0 && n<=4 );
+ z[0] = 0;
+ z = zBuf;
+ READ_UTF16LE(z, 1, c);
+ assert( c==i );
+ assert( (z-zBuf)==n );
+ }
+ for(i=0; i<0x00110000; i++){
+ if( i>=0xD800 && i<0xE000 ) continue;
+ z = zBuf;
+ WRITE_UTF16BE(z, i);
+ n = (int)(z-zBuf);
+ assert( n>0 && n<=4 );
+ z[0] = 0;
+ z = zBuf;
+ READ_UTF16BE(z, 1, c);
+ assert( c==i );
+ assert( (z-zBuf)==n );
+ }
}
#endif /* SQLITE_TEST */
#endif /* SQLITE_OMIT_UTF16 */
/************** End of utf.c *************************************************/
@@ -31445,23 +31295,10 @@
b = (unsigned char *)zRight;
while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
}
-/*
-** Compute an 8-bit hash on a string that is insensitive to case differences
-*/
-SQLITE_PRIVATE u8 sqlite3StrIHash(const char *z){
- u8 h = 0;
- if( z==0 ) return 0;
- while( z[0] ){
- h += UpperToLower[(unsigned char)z[0]];
- z++;
- }
- return h;
-}
-
/*
** Compute 10 to the E-th power. Examples: E==1 results in 10.
** E==2 results in 100. E==50 results in 1.0e50.
**
** This routine only works for values of E between 1 and 341.
@@ -32397,11 +32234,11 @@
h += 9*(1&~(h>>4));
#endif
return (u8)(h & 0xf);
}
-#if !defined(SQLITE_OMIT_BLOB_LITERAL)
+#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
/*
** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
** value. Return a pointer to its binary value. Space to hold the
** binary value has been obtained from malloc and must be freed by
** the calling routine.
@@ -32418,11 +32255,11 @@
}
zBlob[i/2] = 0;
}
return zBlob;
}
-#endif /* !SQLITE_OMIT_BLOB_LITERAL */
+#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
/*
** Log an error that is an API call on a connection pointer that should
** not have been used. The "type" of connection pointer is given as the
** argument. The zType is a word like "NULL" or "closed" or "invalid".
@@ -33129,12 +32966,12 @@
/* 58 */ "ElseNotEq" OpHelp(""),
/* 59 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
/* 60 */ "IncrVacuum" OpHelp(""),
/* 61 */ "VNext" OpHelp(""),
/* 62 */ "Init" OpHelp("Start at P2"),
- /* 63 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"),
- /* 64 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
+ /* 63 */ "PureFunc" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 64 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
/* 65 */ "Return" OpHelp(""),
/* 66 */ "EndCoroutine" OpHelp(""),
/* 67 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
/* 68 */ "Halt" OpHelp(""),
/* 69 */ "Integer" OpHelp("r[P2]=P1"),
@@ -33196,12 +33033,12 @@
/* 125 */ "SorterData" OpHelp("r[P2]=data"),
/* 126 */ "RowData" OpHelp("r[P2]=data"),
/* 127 */ "Rowid" OpHelp("r[P2]=rowid"),
/* 128 */ "NullRow" OpHelp(""),
/* 129 */ "SeekEnd" OpHelp(""),
- /* 130 */ "IdxInsert" OpHelp("key=r[P2]"),
- /* 131 */ "SorterInsert" OpHelp("key=r[P2]"),
+ /* 130 */ "SorterInsert" OpHelp("key=r[P2]"),
+ /* 131 */ "IdxInsert" OpHelp("key=r[P2]"),
/* 132 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
/* 133 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
/* 134 */ "IdxRowid" OpHelp("r[P2]=rowid"),
/* 135 */ "FinishSeek" OpHelp(""),
/* 136 */ "Destroy" OpHelp(""),
@@ -34138,11 +33975,11 @@
if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break;
osClose(fd);
sqlite3_log(SQLITE_WARNING,
"attempt to open \"%s\" as file descriptor %d", z, fd);
fd = -1;
- if( osOpen("/dev/null", O_RDONLY, m)<0 ) break;
+ if( osOpen("/dev/null", f, m)<0 ) break;
}
if( fd>=0 ){
if( m!=0 ){
struct stat statbuf;
if( osFstat(fd, &statbuf)==0
@@ -35014,21 +34851,20 @@
static int osSetPosixAdvisoryLock(
int h, /* The file descriptor on which to take the lock */
struct flock *pLock, /* The description of the lock */
unixFile *pFile /* Structure holding timeout value */
){
- int tm = pFile->iBusyTimeout;
int rc = osFcntl(h,F_SETLK,pLock);
- while( rc<0 && tm>0 ){
+ while( rc<0 && pFile->iBusyTimeout>0 ){
/* On systems that support some kind of blocking file lock with a timeout,
** make appropriate changes here to invoke that blocking file lock. On
** generic posix, however, there is no such API. So we simply try the
** lock once every millisecond until either the timeout expires, or until
** the lock is obtained. */
usleep(1000);
rc = osFcntl(h,F_SETLK,pLock);
- tm--;
+ pFile->iBusyTimeout--;
}
return rc;
}
#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
@@ -37135,11 +36971,11 @@
zDirname[ii] = '\0';
}else{
if( zDirname[0]!='/' ) zDirname[0] = '.';
zDirname[1] = 0;
}
- fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
+ fd = robust_open(zDirname, O_RDONLY|O_BINARY|O_NOFOLLOW, 0);
if( fd>=0 ){
OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
}
*pFd = fd;
if( fd>=0 ) return SQLITE_OK;
@@ -37445,13 +37281,11 @@
*(int*)pArg = fileHasMoved(pFile);
return SQLITE_OK;
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
case SQLITE_FCNTL_LOCK_TIMEOUT: {
- int iOld = pFile->iBusyTimeout;
pFile->iBusyTimeout = *(int*)pArg;
- *(int*)pArg = iOld;
return SQLITE_OK;
}
#endif
#if SQLITE_MAX_MMAP_SIZE>0
case SQLITE_FCNTL_MMAP_SIZE: {
@@ -37766,24 +37600,17 @@
/* Locks are within range */
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
if( pShmNode->hShm>=0 ){
- int res;
/* Initialize the locking parameters */
f.l_type = lockType;
f.l_whence = SEEK_SET;
f.l_start = ofst;
f.l_len = n;
- res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
- if( res==-1 ){
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
- rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY);
-#else
- rc = SQLITE_BUSY;
-#endif
- }
+ rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
+ rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
}
/* Update the global lock state and do debug tracing */
#ifdef SQLITE_DEBUG
{ u16 mask;
@@ -38276,29 +38103,10 @@
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
- /* Check that, if this to be a blocking lock, no locks that occur later
- ** in the following list than the lock being obtained are already held:
- **
- ** 1. Checkpointer lock (ofst==1).
- ** 2. Write lock (ofst==0).
- ** 3. Read locks (ofst>=3 && ofstiBusyTimeout==0 || (
- (ofst!=2) /* not RECOVER */
- && (ofst!=1 || (p->exclMask|p->sharedMask)==0)
- && (ofst!=0 || (p->exclMask|p->sharedMask)<3)
- && (ofst<3 || (p->exclMask|p->sharedMask)<(1<1 || mask==(1<pShmMutex);
if( flags & SQLITE_SHM_UNLOCK ){
u16 allMask = 0; /* Mask of locks held by siblings */
@@ -45085,11 +44893,10 @@
}
/* Forward references to VFS helper methods used for temporary files */
static int winGetTempname(sqlite3_vfs *, char **);
static int winIsDir(const void *);
-static BOOL winIsLongPathPrefix(const char *);
static BOOL winIsDriveLetterAndColon(const char *);
/*
** Control and query of the open file handle.
*/
@@ -46855,13 +46662,11 @@
pFile->pVfs = pVfs;
pFile->h = h;
if( isReadonly ){
pFile->ctrlFlags |= WINFILE_RDONLY;
}
- if( (flags & SQLITE_OPEN_MAIN_DB)
- && sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE)
- ){
+ if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
pFile->ctrlFlags |= WINFILE_PSOW;
}
pFile->lastErrno = NO_ERROR;
pFile->zPath = zName;
#if SQLITE_MAX_MMAP_SIZE>0
@@ -47067,21 +46872,10 @@
OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
zFilename, pResOut, *pResOut));
return SQLITE_OK;
}
-/*
-** Returns non-zero if the specified path name starts with the "long path"
-** prefix.
-*/
-static BOOL winIsLongPathPrefix(
- const char *zPathname
-){
- return ( zPathname[0]=='\\' && zPathname[1]=='\\'
- && zPathname[2]=='?' && zPathname[3]=='\\' );
-}
-
/*
** Returns non-zero if the specified path name starts with a drive letter
** followed by a colon character.
*/
static BOOL winIsDriveLetterAndColon(
@@ -47142,15 +46936,14 @@
DWORD nByte;
void *zConverted;
char *zOut;
#endif
- /* If this path name begins with "/X:" or "\\?\", where "X" is any
- ** alphabetic character, discard the initial "/" from the pathname.
+ /* If this path name begins with "/X:", where "X" is any alphabetic
+ ** character, discard the initial "/" from the pathname.
*/
- if( zRelative[0]=='/' && (winIsDriveLetterAndColon(zRelative+1)
- || winIsLongPathPrefix(zRelative+1)) ){
+ if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
zRelative++;
}
#if defined(__CYGWIN__)
SimulateIOError( return SQLITE_ERROR );
@@ -47902,11 +47695,11 @@
if( newSz>p->szMax ){
return SQLITE_FULL;
}
newSz *= 2;
if( newSz>p->szMax ) newSz = p->szMax;
- pNew = sqlite3Realloc(p->aData, newSz);
+ pNew = sqlite3_realloc64(p->aData, newSz);
if( pNew==0 ) return SQLITE_NOMEM;
p->aData = pNew;
p->szAlloc = newSz;
return SQLITE_OK;
}
@@ -48349,15 +48142,14 @@
*/
SQLITE_PRIVATE int sqlite3MemdbInit(void){
sqlite3_vfs *pLower = sqlite3_vfs_find(0);
int sz = pLower->szOsFile;
memdb_vfs.pAppData = pLower;
- /* The following conditional can only be true when compiled for
- ** Windows x86 and SQLITE_MAX_MMAP_SIZE=0. We always leave
- ** it in, to be safe, but it is marked as NO_TEST since there
- ** is no way to reach it under most builds. */
- if( szmallocFailed flag is set and this
** routine returns NULL.
*/
static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
@@ -51395,11 +51187,11 @@
if( iBatch!=pRowSet->iBatch ){ /*OPTIMIZATION-IF-FALSE*/
p = pRowSet->pEntry;
if( p ){
struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
- /* Only sort the current set of entries if they need it */
+ /* Only sort the current set of entiries if they need it */
p = rowSetEntrySort(p);
}
for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
ppPrevTree = &pTree->pRight;
if( pTree->pLeft==0 ){
@@ -51617,15 +51409,10 @@
#endif
/* Return the sqlite3_file object for the WAL file */
SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal);
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
-SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock);
-SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db);
-#endif
-
#endif /* ifndef SQLITE_OMIT_WAL */
#endif /* SQLITE_WAL_H */
/************** End of wal.h *************************************************/
/************** Continuing where we left off in pager.c **********************/
@@ -52012,10 +51799,24 @@
** 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
+*/
+#ifdef SQLITE_HAS_CODEC
+# define CODEC1(P,D,N,X,E) \
+ if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; }
+# define CODEC2(P,D,N,X,E,O) \
+ if( P->xCodec==0 ){ O=(char*)D; }else \
+ if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; }
+#else
+# define CODEC1(P,D,N,X,E) /* NO-OP */
+# define CODEC2(P,D,N,X,E,O) O=(char*)D
+#endif
+
/*
** 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.
@@ -52297,10 +52098,16 @@
#ifdef SQLITE_TEST
int nRead; /* Database pages read */
#endif
void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */
+#ifdef SQLITE_HAS_CODEC
+ void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
+ void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
+ void (*xCodecFree)(void*); /* Destructor for the codec */
+ void *pCodec; /* First argument to xCodec... methods */
+#endif
char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */
PCache *pPCache; /* Pointer to page cache object */
#ifndef SQLITE_OMIT_WAL
Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */
char *zWal; /* File name for write-ahead log */
@@ -52423,10 +52230,13 @@
** * the desired page is not currently in the wal file.
*/
SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
if( pPager->fd->pMethods==0 ) return 0;
if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
+#ifdef SQLITE_HAS_CODEC
+ if( pPager->xCodec!=0 ) return 0;
+#endif
#ifndef SQLITE_OMIT_WAL
if( pPager->pWal ){
u32 iRead = 0;
int rc;
rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
@@ -52656,11 +52466,15 @@
*/
static void setGetterMethod(Pager *pPager){
if( pPager->errCode ){
pPager->xGet = getPageError;
#if SQLITE_MAX_MMAP_SIZE>0
- }else if( USEFETCH(pPager) ){
+ }else if( USEFETCH(pPager)
+#ifdef SQLITE_HAS_CODEC
+ && pPager->xCodec==0
+#endif
+ ){
pPager->xGet = getPageMMap;
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
}else{
pPager->xGet = getPageNormal;
}
@@ -53804,10 +53618,39 @@
i -= 200;
}
return cksum;
}
+/*
+** 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
+
+#ifdef SQLITE_HAS_CODEC
+/*
+** Make sure the number of reserved bits is the same in the destination
+** pager as it is in the source. This comes up when a VACUUM changes the
+** number of reserved bits to the "optimal" amount.
+*/
+SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){
+ if( pDest->nReserve!=pSrc->nReserve ){
+ pDest->nReserve = pSrc->nReserve;
+ pagerReportSize(pDest);
+ }
+}
+#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.
@@ -53855,10 +53698,15 @@
Pgno pgno; /* The page number of a page in journal */
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 */
+#ifdef SQLITE_HAS_CODEC
+ /* The jrnlEnc flag is true if Journal pages should be passed through
+ ** the codec. It is false for pure in-memory journals. */
+ const int jrnlEnc = (isMainJrnl || pPager->subjInMemory==0);
+#endif
assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */
assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */
assert( isMainJrnl || pDone ); /* pDone always used on sub-journals */
assert( isSavepnt || pDone==0 ); /* pDone never used on non-savepoint */
@@ -53917,10 +53765,11 @@
/* 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 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.
@@ -53984,16 +53833,30 @@
** This is usually safe even for an encrypted database - as the data
** was encrypted before it was written to the journal file. The exception
** is if the data was just read from an in-memory sub-journal. In that
** case it must be encrypted here before it is copied into the database
** file. */
+#ifdef SQLITE_HAS_CODEC
+ if( !jrnlEnc ){
+ CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
+ rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
+ CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
+ }else
+#endif
rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
if( pgno>pPager->dbFileSize ){
pPager->dbFileSize = pgno;
}
if( pPager->pBackup ){
+#ifdef SQLITE_HAS_CODEC
+ if( jrnlEnc ){
+ CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
+ sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
+ CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT,aData);
+ }else
+#endif
sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
}
}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
@@ -54040,10 +53903,15 @@
/* If this was page 1, then restore the value of Pager.dbFileVers.
** Do this before any decoding. */
if( pgno==1 ){
memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
}
+
+ /* Decode the page just read from disk */
+#if SQLITE_HAS_CODEC
+ if( jrnlEnc ){ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); }
+#endif
sqlite3PcacheRelease(pPg);
}
return rc;
}
@@ -54142,16 +54010,13 @@
}
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.
- ** NB: zJournal is really a MAIN_JOURNAL. But call it a
- ** MASTER_JOURNAL here so that the VFS will not send the zJournal
- ** name into sqlite3_database_file_object().
*/
int c;
- int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
+ int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
if( rc!=SQLITE_OK ){
goto delmaster_out;
}
@@ -54602,10 +54467,12 @@
}else{
u8 *dbFileVers = &((u8*)pPg->pData)[24];
memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
}
}
+ CODEC1(pPager, pPg->pData, pPg->pgno, 3, rc = SQLITE_NOMEM_BKPT);
+
PAGER_INCR(sqlite3_pager_readdb_count);
PAGER_INCR(pPager->nRead);
IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno));
PAGERTRACE(("FETCH %d page %d hash(%08x)\n",
PAGERID(pPager), pPg->pgno, pager_pagehash(pPg)));
@@ -55345,10 +55212,11 @@
*pPageSize = pPager->pageSize;
if( rc==SQLITE_OK ){
if( nReserve<0 ) nReserve = pPager->nReserve;
assert( nReserve>=0 && nReserve<1000 );
pPager->nReserve = (i16)nReserve;
+ pagerReportSize(pPager);
pagerFixMaplimit(pPager);
}
return rc;
}
@@ -55740,10 +55608,15 @@
IOTRACE(("CLOSE %p\n", pPager))
sqlite3OsClose(pPager->jfd);
sqlite3OsClose(pPager->fd);
sqlite3PageFree(pTmp);
sqlite3PcacheClose(pPager->pPCache);
+
+#ifdef SQLITE_HAS_CODEC
+ if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
+#endif
+
assert( !pPager->aSavepoint && !pPager->pInJournal );
assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );
sqlite3_free(pPager);
return SQLITE_OK;
@@ -55990,11 +55863,12 @@
char *pData; /* Data to write */
assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
if( pList->pgno==1 ) pager_write_changecounter(pList);
- pData = pList->pData;
+ /* Encode the database */
+ CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM_BKPT, pData);
/* Write out the page data. */
rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
/* If page 1 was just written, update Pager.dbFileVers to match
@@ -56079,10 +55953,16 @@
** write the journal record into the file. */
if( rc==SQLITE_OK ){
void *pData = pPg->pData;
i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
char *pData2;
+
+#if SQLITE_HAS_CODEC
+ if( !pPager->subjInMemory ){
+ CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
+ }else
+#endif
pData2 = pData;
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);
@@ -56351,11 +56231,10 @@
** Pager object (sizeof(Pager) bytes)
** PCache object (sqlite3PcacheSize() bytes)
** Database file handle (pVfs->szOsFile bytes)
** Sub-journal file handle (journalFileSize bytes)
** Main journal file handle (journalFileSize bytes)
- ** Ptr back to the Pager (sizeof(Pager*) bytes)
** \0\0\0\0 database prefix (4 bytes)
** Database file name (nPathname+1 bytes)
** URI query parameters (nUriByte bytes)
** Journal filename (nPathname+8+1 bytes)
** WAL filename (nPathname+4+1 bytes)
@@ -56380,22 +56259,16 @@
** - \0
** - Journal Path
** - \0
** - WAL Path (zWALName)
** - \0
- **
- ** The sqlite3_create_filename() interface and the databaseFilename() utility
- ** that is used by sqlite3_filename_database() and kin also depend on the
- ** specific formatting and order of the various filenames, so if the format
- ** changes here, be sure to change it there as well.
*/
pPtr = (u8 *)sqlite3MallocZero(
ROUND8(sizeof(*pPager)) + /* Pager structure */
ROUND8(pcacheSize) + /* PCache object */
ROUND8(pVfs->szOsFile) + /* The main db file */
journalFileSize * 2 + /* The two journal files */
- sizeof(pPager) + /* Space to hold a pointer */
4 + /* Database prefix */
nPathname + 1 + /* database filename */
nUriByte + /* query parameters */
nPathname + 8 + 1 + /* Journal filename */
#ifndef SQLITE_OMIT_WAL
@@ -56412,11 +56285,10 @@
pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize);
pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile);
pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
- memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager);
/* Fill in the Pager.zFilename and pPager.zQueryParam fields */
pPtr += 4; /* Skip zero prefix */
pPager->zFilename = (char*)pPtr;
if( nPathname>0 ){
@@ -56613,23 +56485,10 @@
*ppPager = pPager;
return SQLITE_OK;
}
-/*
-** Return the sqlite3_file for the main database given the name
-** of the corresonding WAL or Journal name as passed into
-** xOpen.
-*/
-SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){
- Pager *pPager;
- while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){
- zName--;
- }
- pPager = *(Pager**)(zName - 4 - sizeof(Pager*));
- return pPager->fd;
-}
/*
** This function is called after transitioning from PAGER_UNLOCK to
** PAGER_SHARED state. It tests if there is a hot journal present in
@@ -57181,10 +57040,13 @@
const int bMmapOk = (pgno>1
&& (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
);
assert( USEFETCH(pPager) );
+#ifdef SQLITE_HAS_CODEC
+ assert( pPager->xCodec==0 );
+#endif
/* Optimization note: Adding the "pgno<=1" term before "pgno==0" here
** allows the compiler optimizer to reuse the results of the "pgno>1"
** test in the previous statement, and avoid testing pgno==0 in the
** common case where pgno is large. */
@@ -57311,10 +57173,11 @@
Pager *pPager;
assert( pPg!=0 );
assert( pPg->pgno==1 );
assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
pPager = pPg->pPager;
+ sqlite3PagerResetLockTimeout(pPager);
sqlite3PcacheRelease(pPg);
pagerUnlockIfUnused(pPager);
}
/*
@@ -57508,11 +57371,11 @@
** contains the database locks. The following assert verifies
** that we do not. */
assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
assert( pPager->journalHdr<=pPager->journalOff );
- pData2 = pPg->pData;
+ CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
cksum = pager_cksum(pPager, (u8*)pData2);
/* 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
@@ -57873,11 +57736,11 @@
/* If running in direct mode, write the contents of page 1 to the file. */
if( DIRECT_MODE ){
const void *zBuf;
assert( pPager->dbFileSize>0 );
- zBuf = pPgHdr->pData;
+ CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM_BKPT, zBuf);
if( rc==SQLITE_OK ){
rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
pPager->aStat[PAGER_STAT_WRITE]++;
}
if( rc==SQLITE_OK ){
@@ -58583,11 +58446,11 @@
**
** The return value to this routine is always safe to use with
** sqlite3_uri_parameter() and sqlite3_filename_database() and friends.
*/
SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){
- static const char zFake[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ static const char zFake[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
return (nullIfMemDb && pPager->memDb) ? &zFake[4] : pPager->zFilename;
}
/*
** Return the VFS structure for the pager.
@@ -58603,10 +58466,20 @@
*/
SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
return pPager->fd;
}
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+/*
+** Reset the lock timeout for pager.
+*/
+SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager){
+ int x = 0;
+ sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x);
+}
+#endif
+
/*
** Return the file handle for the journal file (if it exists).
** This will be either the rollback journal or the WAL file.
*/
SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
@@ -58622,10 +58495,58 @@
*/
SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
return pPager->zJournal;
}
+#ifdef SQLITE_HAS_CODEC
+/*
+** Set or retrieve the codec for this pager
+*/
+SQLITE_PRIVATE void sqlite3PagerSetCodec(
+ Pager *pPager,
+ void *(*xCodec)(void*,void*,Pgno,int),
+ void (*xCodecSizeChng)(void*,int,int),
+ void (*xCodecFree)(void*),
+ void *pCodec
+){
+ if( pPager->xCodecFree ){
+ pPager->xCodecFree(pPager->pCodec);
+ }else{
+ pager_reset(pPager);
+ }
+ pPager->xCodec = pPager->memDb ? 0 : xCodec;
+ pPager->xCodecSizeChng = xCodecSizeChng;
+ pPager->xCodecFree = xCodecFree;
+ pPager->pCodec = pCodec;
+ setGetterMethod(pPager);
+ pagerReportSize(pPager);
+}
+SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
+ return pPager->pCodec;
+}
+
+/*
+** 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;
+}
+
+/*
+** Return the current pager state
+*/
+SQLITE_PRIVATE int sqlite3PagerState(Pager *pPager){
+ return pPager->eState;
+}
+#endif /* SQLITE_HAS_CODEC */
+
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** Move the page pPg to location pgno in the file.
**
** There must be no references to the page previously located at
@@ -59016,10 +58937,11 @@
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
pPager->pBusyHandlerArg,
pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
pnLog, pnCkpt
);
+ sqlite3PagerResetLockTimeout(pPager);
}
return rc;
}
SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
@@ -59180,35 +59102,11 @@
}
}
return rc;
}
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
-/*
-** If pager pPager is a wal-mode database not in exclusive locking mode,
-** invoke the sqlite3WalWriteLock() function on the associated Wal object
-** with the same db and bLock parameters as were passed to this function.
-** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
-*/
-SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){
- int rc = SQLITE_OK;
- if( pagerUseWal(pPager) && pPager->exclusiveMode==0 ){
- rc = sqlite3WalWriteLock(pPager->pWal, bLock);
- }
- return rc;
-}
-/*
-** Set the database handle used by the wal layer to determine if
-** blocking locks are required.
-*/
-SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){
- if( pagerUseWal(pPager) ){
- sqlite3WalDb(pPager->pWal, db);
- }
-}
-#endif
#ifdef SQLITE_ENABLE_SNAPSHOT
/*
** If this is a WAL database, obtain a snapshot handle for the snapshot
** currently open. Otherwise, return an error.
@@ -59224,14 +59122,11 @@
/*
** If this is a WAL database, store a pointer to pSnapshot. Next time a
** read transaction is opened, attempt to read from the snapshot it
** identifies. If this is not a WAL database, return an error.
*/
-SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(
- Pager *pPager,
- sqlite3_snapshot *pSnapshot
-){
+SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){
int rc = SQLITE_OK;
if( pPager->pWal ){
sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot);
}else{
rc = SQLITE_ERROR;
@@ -59563,10 +59458,22 @@
# define WALTRACE(X) if(sqlite3WalTrace) sqlite3DebugPrintf X
#else
# define WALTRACE(X)
#endif
+/*
+** WAL mode depends on atomic aligned 32-bit loads and stores in a few
+** places. The following macros try to make this explicit.
+*/
+#if GCC_VESRION>=5004000
+# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED)
+# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
+#else
+# define AtomicLoad(PTR) (*(PTR))
+# define AtomicStore(PTR,VAL) (*(PTR) = (VAL))
+#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
@@ -59772,13 +59679,10 @@
u8 lockError; /* True if a locking error has occurred */
#endif
#ifdef SQLITE_ENABLE_SNAPSHOT
WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */
#endif
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
- sqlite3 *db;
-#endif
};
/*
** Candidate values for Wal.exclusiveMode.
*/
@@ -59873,11 +59777,11 @@
/* Enlarge the pWal->apWiData[] array if required */
if( pWal->nWiData<=iPage ){
sqlite3_int64 nByte = sizeof(u32*)*(iPage+1);
volatile u32 **apNew;
- apNew = (volatile u32 **)sqlite3Realloc((void *)pWal->apWiData, nByte);
+ apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
if( !apNew ){
*ppPage = 0;
return SQLITE_NOMEM_BKPT;
}
memset((void*)&apNew[pWal->nWiData], 0,
@@ -59994,47 +59898,29 @@
aOut[0] = s1;
aOut[1] = s2;
}
-/*
-** If there is the possibility of concurrent access to the SHM file
-** from multiple threads and/or processes, then do a memory barrier.
-*/
static void walShmBarrier(Wal *pWal){
if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
sqlite3OsShmBarrier(pWal->pDbFd);
}
}
-/*
-** Add the SQLITE_NO_TSAN as part of the return-type of a function
-** definition as a hint that the function contains constructs that
-** might give false-positive TSAN warnings.
-**
-** See tag-20200519-1.
-*/
-#if defined(__clang__) && !defined(SQLITE_NO_TSAN)
-# define SQLITE_NO_TSAN __attribute__((no_sanitize_thread))
-#else
-# define SQLITE_NO_TSAN
-#endif
-
/*
** Write the header information in pWal->hdr into the wal-index.
**
** The checksum on pWal->hdr is updated before it is written.
*/
-static SQLITE_NO_TSAN void walIndexWriteHdr(Wal *pWal){
+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);
- /* Possible TSAN false-positive. See tag-20200519-1 */
memcpy((void*)&aHdr[1], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
walShmBarrier(pWal);
memcpy((void*)&aHdr[0], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
}
@@ -60166,11 +60052,11 @@
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&0xFF)!=SQLITE_BUSY); )
+ 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,
@@ -60182,11 +60068,11 @@
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&0xFF)!=SQLITE_BUSY); )
+ 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,
@@ -61002,93 +60888,10 @@
}
*pp = p;
return rc;
}
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
-/*
-** Attempt to enable blocking locks. Blocking locks are enabled only if (a)
-** they are supported by the VFS, and (b) the database handle is configured
-** with a busy-timeout. Return 1 if blocking locks are successfully enabled,
-** or 0 otherwise.
-*/
-static int walEnableBlocking(Wal *pWal){
- int res = 0;
- if( pWal->db ){
- int tmout = pWal->db->busyTimeout;
- if( tmout ){
- int rc;
- rc = sqlite3OsFileControl(
- pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout
- );
- res = (rc==SQLITE_OK);
- }
- }
- return res;
-}
-
-/*
-** Disable blocking locks.
-*/
-static void walDisableBlocking(Wal *pWal){
- int tmout = 0;
- sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
-}
-
-/*
-** If parameter bLock is true, attempt to enable blocking locks, take
-** the WRITER lock, and then disable blocking locks. If blocking locks
-** cannot be enabled, no attempt to obtain the WRITER lock is made. Return
-** an SQLite error code if an error occurs, or SQLITE_OK otherwise. It is not
-** an error if blocking locks can not be enabled.
-**
-** If the bLock parameter is false and the WRITER lock is held, release it.
-*/
-SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock){
- int rc = SQLITE_OK;
- assert( pWal->readLock<0 || bLock==0 );
- if( bLock ){
- assert( pWal->db );
- if( walEnableBlocking(pWal) ){
- rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
- if( rc==SQLITE_OK ){
- pWal->writeLock = 1;
- }
- walDisableBlocking(pWal);
- }
- }else if( pWal->writeLock ){
- walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
- pWal->writeLock = 0;
- }
- return rc;
-}
-
-/*
-** Set the database handle used to determine if blocking locks are required.
-*/
-SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){
- pWal->db = db;
-}
-
-/*
-** Take an exclusive WRITE lock. Blocking if so configured.
-*/
-static int walLockWriter(Wal *pWal){
- int rc;
- walEnableBlocking(pWal);
- rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
- walDisableBlocking(pWal);
- return rc;
-}
-#else
-# define walEnableBlocking(x) 0
-# define walDisableBlocking(x)
-# define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1)
-# define sqlite3WalDb(pWal, db)
-#endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */
-
-
/*
** 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.
@@ -61102,16 +60905,10 @@
){
int rc;
do {
rc = walLockExclusive(pWal, lockIdx, n);
}while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
- if( rc==SQLITE_BUSY_TIMEOUT ){
- walDisableBlocking(pWal);
- rc = SQLITE_BUSY;
- }
-#endif
return rc;
}
/*
** The cache of the wal-index header must be valid to call this function.
@@ -61145,11 +60942,11 @@
pWal->nCkpt++;
pWal->hdr.mxFrame = 0;
sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
walIndexWriteHdr(pWal);
- AtomicStore(&pInfo->nBackfill, 0);
+ pInfo->nBackfill = 0;
pInfo->nBackfillAttempted = 0;
pInfo->aReadMark[1] = 0;
for(i=2; iaReadMark[i] = READMARK_NOT_USED;
assert( pInfo->aReadMark[0]==0 );
}
@@ -61220,17 +61017,36 @@
** cannot be backfilled from the WAL.
*/
mxSafeFrame = pWal->hdr.mxFrame;
mxPage = pWal->hdr.nPage;
for(i=1; iaReadMark+i);
+ /* Thread-sanitizer reports that the following is an unsafe read,
+ ** as some other thread may be in the process of updating the value
+ ** of the aReadMark[] slot. The assumption here is that if that is
+ ** happening, the other client may only be increasing the value,
+ ** not decreasing it. So assuming either that either the "old" or
+ ** "new" version of the value is read, and not some arbitrary value
+ ** that would never be written by a real client, things are still
+ ** safe.
+ **
+ ** Astute readers have pointed out that the assumption stated in the
+ ** last sentence of the previous paragraph is not guaranteed to be
+ ** true for all conforming systems. However, the assumption is true
+ ** for all compilers and architectures in common use today (circa
+ ** 2019-11-27) and the alternatives are both slow and complex, and
+ ** so we will continue to go with the current design for now. If this
+ ** bothers you, or if you really are running on a system where aligned
+ ** 32-bit reads and writes are not atomic, then you can simply avoid
+ ** the use of WAL mode, or only use WAL mode together with
+ ** PRAGMA locking_mode=EXCLUSIVE and all will be well.
+ */
+ 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 ){
- u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
- AtomicStore(pInfo->aReadMark+i, iMark);
+ pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
}else if( rc==SQLITE_BUSY ){
mxSafeFrame = y;
xBusy = 0;
}else{
@@ -61244,11 +61060,11 @@
rc = walIteratorInit(pWal, pInfo->nBackfill, &pIter);
assert( rc==SQLITE_OK || pIter==0 );
}
if( pIter
- && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK
+ && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
){
u32 nBackfill = pInfo->nBackfill;
pInfo->nBackfillAttempted = mxSafeFrame;
@@ -61259,11 +61075,10 @@
** about the eventual size of the db file to the VFS layer.
*/
if( rc==SQLITE_OK ){
i64 nReq = ((i64)mxPage * szPage);
i64 nSize; /* Current size of database file */
- sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0);
rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
if( rc==SQLITE_OK && nSizepDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
}
}
@@ -61271,11 +61086,11 @@
/* 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( AtomicLoad(&db->u1.isInterrupted) ){
+ if( db->u1.isInterrupted ){
rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
break;
}
if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
continue;
@@ -61287,11 +61102,10 @@
iOffset = (iDbpage-1)*(i64)szPage;
testcase( IS_BIG_INT(iOffset) );
rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
if( rc!=SQLITE_OK ) break;
}
- sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);
/* If work was actually accomplished... */
if( rc==SQLITE_OK ){
if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
i64 szDb = pWal->hdr.nPage*(i64)szPage;
@@ -61300,11 +61114,15 @@
if( rc==SQLITE_OK ){
rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
}
}
if( rc==SQLITE_OK ){
- AtomicStore(&pInfo->nBackfill, mxSafeFrame);
+ rc = sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);
+ if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
+ }
+ if( rc==SQLITE_OK ){
+ pInfo->nBackfill = mxSafeFrame;
}
}
/* Release the reader lock held while backfilling */
walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
@@ -61459,11 +61277,11 @@
** 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 SQLITE_NO_TSAN int walIndexTryHdr(Wal *pWal, int *pChanged){
+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. */
@@ -61472,23 +61290,17 @@
/* 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.
**
- ** tag-20200519-1:
** 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. TSAN and similar tools can sometimes
- ** give false-positive warnings about these accesses because the tools do not
- ** account for the double-read and the memory barrier. The use of mutexes
- ** here would be problematic as the memory being accessed is potentially
- ** shared among multiple processes and not all mutex implementions work
- ** reliably in that environment.
+ ** reordering the reads and writes.
*/
aHdr = walIndexHdr(pWal);
- memcpy(&h1, (void *)&aHdr[0], sizeof(h1)); /* Possible TSAN false-positive */
+ 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 */
@@ -61574,36 +61386,32 @@
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->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){
if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
walUnlockShared(pWal, WAL_WRITE_LOCK);
rc = SQLITE_READONLY_RECOVERY;
}
- }else{
- int bWriteLock = pWal->writeLock;
- if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){
- 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;
- }
- }
- if( bWriteLock==0 ){
- pWal->writeLock = 0;
- walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
+ }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
@@ -61929,11 +61737,11 @@
}
assert( pWal->nWiData>0 );
assert( pWal->apWiData[0]!=0 );
pInfo = walCkptInfo(pWal);
- if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame
+ if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame
#ifdef SQLITE_ENABLE_SNAPSHOT
&& (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0)
#endif
){
/* The WAL has been completely backfilled (or it is empty).
@@ -61991,12 +61799,11 @@
&& (mxReadMarkaReadMark+i,mxFrame);
- mxReadMark = mxFrame;
+ mxReadMark = AtomicStore(pInfo->aReadMark+i,mxFrame);
mxI = i;
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
break;
}else if( rc!=SQLITE_BUSY ){
return rc;
@@ -62096,11 +61903,11 @@
void *pBuf2 = sqlite3_malloc(szPage);
if( pBuf1==0 || pBuf2==0 ){
rc = SQLITE_NOMEM;
}else{
u32 i = pInfo->nBackfillAttempted;
- for(i=pInfo->nBackfillAttempted; i>AtomicLoad(&pInfo->nBackfill); i--){
+ for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){
WalHashLoc sLoc; /* Hash table location */
u32 pgno; /* Page number in db file */
i64 iDbOff; /* Offset of db file entry */
i64 iWalOff; /* Offset of wal file entry */
@@ -62151,39 +61958,16 @@
** needs to be flushed.
*/
SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
int rc; /* Return code */
int cnt = 0; /* Number of TryBeginRead attempts */
+
#ifdef SQLITE_ENABLE_SNAPSHOT
int bChanged = 0;
WalIndexHdr *pSnapshot = pWal->pSnapshot;
-#endif
-
- assert( pWal->ckptLock==0 );
-
-#ifdef SQLITE_ENABLE_SNAPSHOT
- if( pSnapshot ){
- if( memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
- bChanged = 1;
- }
-
- /* It is possible that there is a checkpointer thread running
- ** concurrent with this code. If this is the case, it may be that the
- ** checkpointer has already determined that it will checkpoint
- ** snapshot X, where X is later in the wal file than pSnapshot, but
- ** has not yet set the pInfo->nBackfillAttempted variable to indicate
- ** its intent. To avoid the race condition this leads to, ensure that
- ** there is no checkpointer process by taking a shared CKPT lock
- ** before checking pInfo->nBackfillAttempted. */
- (void)walEnableBlocking(pWal);
- rc = walLockShared(pWal, WAL_CKPT_LOCK);
- walDisableBlocking(pWal);
-
- if( rc!=SQLITE_OK ){
- return rc;
- }
- pWal->ckptLock = 1;
+ if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
+ bChanged = 1;
}
#endif
do{
rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
@@ -62212,46 +61996,52 @@
volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );
- /* Check that the wal file has not been wrapped. Assuming that it has
- ** not, also check that no checkpointer has attempted to checkpoint any
- ** frames beyond pSnapshot->mxFrame. If either of these conditions are
- ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
- ** with *pSnapshot and set *pChanged as appropriate for opening the
- ** snapshot. */
- if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
- && pSnapshot->mxFrame>=pInfo->nBackfillAttempted
- ){
- assert( pWal->readLock>0 );
- memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
- *pChanged = bChanged;
- }else{
- rc = SQLITE_ERROR_SNAPSHOT;
+ /* It is possible that there is a checkpointer thread running
+ ** concurrent with this code. If this is the case, it may be that the
+ ** checkpointer has already determined that it will checkpoint
+ ** snapshot X, where X is later in the wal file than pSnapshot, but
+ ** has not yet set the pInfo->nBackfillAttempted variable to indicate
+ ** its intent. To avoid the race condition this leads to, ensure that
+ ** there is no checkpointer process by taking a shared CKPT lock
+ ** before checking pInfo->nBackfillAttempted.
+ **
+ ** TODO: Does the aReadMark[] lock prevent a checkpointer from doing
+ ** this already?
+ */
+ rc = walLockShared(pWal, WAL_CKPT_LOCK);
+
+ if( rc==SQLITE_OK ){
+ /* Check that the wal file has not been wrapped. Assuming that it has
+ ** not, also check that no checkpointer has attempted to checkpoint any
+ ** frames beyond pSnapshot->mxFrame. If either of these conditions are
+ ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
+ ** with *pSnapshot and set *pChanged as appropriate for opening the
+ ** snapshot. */
+ if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
+ && pSnapshot->mxFrame>=pInfo->nBackfillAttempted
+ ){
+ assert( pWal->readLock>0 );
+ memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
+ *pChanged = bChanged;
+ }else{
+ rc = SQLITE_ERROR_SNAPSHOT;
+ }
+
+ /* Release the shared CKPT lock obtained above. */
+ walUnlockShared(pWal, WAL_CKPT_LOCK);
+ pWal->minFrame = 1;
}
- /* A client using a non-current snapshot may not ignore any frames
- ** from the start of the wal file. This is because, for a system
- ** where (minFrame < iSnapshot < maxFrame), a checkpointer may
- ** have omitted to checkpoint a frame earlier than minFrame in
- ** the file because there exists a frame after iSnapshot that
- ** is the same database page. */
- pWal->minFrame = 1;
if( rc!=SQLITE_OK ){
sqlite3WalEndReadTransaction(pWal);
}
}
}
-
- /* Release the shared CKPT lock obtained above. */
- if( pWal->ckptLock ){
- assert( pSnapshot );
- walUnlockShared(pWal, WAL_CKPT_LOCK);
- pWal->ckptLock = 0;
- }
#endif
return rc;
}
/*
@@ -62327,28 +62117,26 @@
for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){
WalHashLoc sLoc; /* Hash table location */
int iKey; /* Hash slot index */
int nCollide; /* Number of hash collisions remaining */
int rc; /* Error code */
- u32 iH;
rc = walHashGet(pWal, iHash, &sLoc);
if( rc!=SQLITE_OK ){
return rc;
}
nCollide = HASHTABLE_NSLOT;
- iKey = walHash(pgno);
- while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
+ for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
+ u32 iH = sLoc.aHash[iKey];
u32 iFrame = iH + sLoc.iZero;
if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
assert( iFrame>iRead || CORRUPT_DB );
iRead = iFrame;
}
if( (nCollide--)==0 ){
return SQLITE_CORRUPT_BKPT;
}
- iKey = walNextHash(iKey);
}
if( iRead ) break;
}
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
@@ -62420,20 +62208,10 @@
** There can only be a single writer active at a time.
*/
SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
int rc;
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
- /* If the write-lock is already held, then it was obtained before the
- ** read-transaction was even opened, making this call a no-op.
- ** Return early. */
- if( pWal->writeLock ){
- assert( !memcmp(&pWal->hdr,(void *)walIndexHdr(pWal),sizeof(WalIndexHdr)) );
- return SQLITE_OK;
- }
-#endif
-
/* Cannot start a write transaction without first holding a read
** transaction. */
assert( pWal->readLock>=0 );
assert( pWal->writeLock==0 && pWal->iReCksum==0 );
@@ -62675,11 +62453,15 @@
sqlite3_int64 iOffset /* Byte offset at which to write */
){
int rc; /* Result code from subfunctions */
void *pData; /* Data actually written */
u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */
+#if defined(SQLITE_HAS_CODEC)
+ if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT;
+#else
pData = pPage->pData;
+#endif
walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame);
rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset);
if( rc ) return rc;
/* Write the page data */
rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame));
@@ -62858,11 +62640,15 @@
i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE;
void *pData;
if( pWal->iReCksum==0 || iWriteiReCksum ){
pWal->iReCksum = iWrite;
}
+#if defined(SQLITE_HAS_CODEC)
+ if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM;
+#else
pData = p->pData;
+#endif
rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOff);
if( rc ) return rc;
p->flags &= ~PGHDR_WAL_APPEND;
continue;
}
@@ -63006,56 +62792,49 @@
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
if( pWal->readOnly ) return SQLITE_READONLY;
WALTRACE(("WAL%p: checkpoint begins\n", pWal));
- /* Enable blocking locks, if possible. If blocking locks are successfully
- ** enabled, set xBusy2=0 so that the busy-handler is never invoked. */
- sqlite3WalDb(pWal, db);
- (void)walEnableBlocking(pWal);
-
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
- ** "checkpoint" lock on the database file.
- ** EVIDENCE-OF: R-10421-19736 If any other process is running a
- ** checkpoint operation at the same time, the lock cannot be obtained and
- ** SQLITE_BUSY is returned.
- ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
- ** it will not be invoked in this case.
- */
+ ** "checkpoint" lock on the database file. */
rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
- testcase( rc==SQLITE_BUSY );
- testcase( rc!=SQLITE_OK && xBusy2!=0 );
- if( rc==SQLITE_OK ){
- pWal->ckptLock = 1;
-
- /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
- ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
- ** file.
- **
- ** EVIDENCE-OF: R-60642-04082 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.
+ if( rc ){
+ /* EVIDENCE-OF: R-10421-19736 If any other process is running a
+ ** checkpoint operation at the same time, the lock cannot be obtained and
+ ** SQLITE_BUSY is returned.
+ ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
+ ** it will not be invoked in this case.
*/
- if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
- rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1);
- if( rc==SQLITE_OK ){
- pWal->writeLock = 1;
- }else if( rc==SQLITE_BUSY ){
- eMode2 = SQLITE_CHECKPOINT_PASSIVE;
- xBusy2 = 0;
- rc = SQLITE_OK;
- }
- }
+ testcase( rc==SQLITE_BUSY );
+ testcase( xBusy!=0 );
+ return rc;
}
+ pWal->ckptLock = 1;
+ /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
+ ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
+ ** file.
+ **
+ ** EVIDENCE-OF: R-60642-04082 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.
+ */
+ 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;
+ xBusy2 = 0;
+ rc = SQLITE_OK;
+ }
+ }
/* Read the wal-index header. */
if( rc==SQLITE_OK ){
- walDisableBlocking(pWal);
rc = walIndexReadHdr(pWal, &isChanged);
- (void)walEnableBlocking(pWal);
if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
}
}
@@ -63083,23 +62862,15 @@
** the cache needs to be reset.
*/
memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
}
- walDisableBlocking(pWal);
- sqlite3WalDb(pWal, 0);
-
/* Release the locks. */
sqlite3WalEndWriteTransaction(pWal);
- if( pWal->ckptLock ){
- walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
- pWal->ckptLock = 0;
- }
+ walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
+ pWal->ckptLock = 0;
WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
- if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
-#endif
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
@@ -63212,14 +62983,11 @@
return rc;
}
/* Try to open on pSnapshot when the next read-transaction starts
*/
-SQLITE_PRIVATE void sqlite3WalSnapshotOpen(
- Wal *pWal,
- sqlite3_snapshot *pSnapshot
-){
+SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){
pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
}
/*
** Return a +ve value if snapshot p1 is newer than p2. A -ve value if
@@ -63734,11 +63502,13 @@
u8 incrVacuum; /* True if incr-vacuum is enabled */
u8 bDoTruncate; /* True to truncate db on commit */
#endif
u8 inTransaction; /* Transaction state */
u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
- u8 nReserveWanted; /* Desired number of extra bytes per page */
+#ifdef SQLITE_HAS_CODEC
+ u8 optimalReserve; /* Desired amount of reserved space per page */
+#endif
u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
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 */
@@ -64935,11 +64705,11 @@
** free-list for reuse. It returns false if it is safe to retrieve the
** page from the pager layer with the 'no-content' flag set. True otherwise.
*/
static int btreeGetHasContent(BtShared *pBt, Pgno pgno){
Bitvec *p = pBt->pHasContent;
- return p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTestNotNull(p, pgno));
+ return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno)));
}
/*
** Clear (destroy) the BtShared.pHasContent bitvec. This should be
** invoked at the conclusion of each write-transaction.
@@ -65773,11 +65543,11 @@
u8 *pEnd = &data[cellOffset + nCell*2];
u8 *pAddr;
int sz2 = 0;
int sz = get2byte(&data[iFree+2]);
int top = get2byte(&data[hdr+5]);
- if( top>=iFree ){
+ if( NEVER(top>=iFree) ){
return SQLITE_CORRUPT_PAGE(pPage);
}
if( iFree2 ){
if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
sz2 = get2byte(&data[iFree2+2]);
@@ -66104,11 +65874,11 @@
if( iStart<=x ){
/* The new freeblock is at the beginning of the cell content area,
** so just extend the cell content area rather than create another
** freelist entry */
if( iStartdb );
assert( sqlite3_mutex_held(pBt->db->mutex) );
- return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
+ return sqlite3InvokeBusyHandler(&pBt->db->busyHandler,
+ sqlite3PagerFile(pBt->pPager));
}
/*
** Open a database file.
**
@@ -67179,21 +66950,23 @@
** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size
** and autovacuum mode can no longer be changed.
*/
SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
int rc = SQLITE_OK;
- int x;
BtShared *pBt = p->pBt;
- assert( nReserve>=0 && nReserve<=255 );
+ assert( nReserve>=-1 && nReserve<=255 );
sqlite3BtreeEnter(p);
- pBt->nReserveWanted = nReserve;
- x = pBt->pageSize - pBt->usableSize;
- if( nReservepBt->optimalReserve ) pBt->optimalReserve = (u8)nReserve;
+#endif
if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
sqlite3BtreeLeave(p);
return SQLITE_READONLY;
}
+ if( nReserve<0 ){
+ nReserve = pBt->pageSize - pBt->usableSize;
+ }
assert( nReserve>=0 && nReserve<=255 );
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
((pageSize-1)&pageSize)==0 ){
assert( (pageSize & 7)==0 );
assert( !pBt->pCursor );
@@ -67235,21 +67008,23 @@
/*
** 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
** sometimes used by extensions.
**
-** The value returned is the larger of the current reserve size and
-** the latest reserve size requested by SQLITE_FILECTRL_RESERVE_BYTES.
-** The amount of reserve can only grow - never shrink.
+** If SQLITE_HAS_MUTEX is defined then the number returned is the
+** greater of the current reserved space and the maximum requested
+** reserve space.
*/
-SQLITE_PRIVATE int sqlite3BtreeGetRequestedReserve(Btree *p){
- int n1, n2;
+SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree *p){
+ int n;
sqlite3BtreeEnter(p);
- n1 = (int)p->pBt->nReserveWanted;
- n2 = sqlite3BtreeGetReserveNoMutex(p);
+ n = sqlite3BtreeGetReserveNoMutex(p);
+#ifdef SQLITE_HAS_CODEC
+ if( npBt->optimalReserve ) n = p->pBt->optimalReserve;
+#endif
sqlite3BtreeLeave(p);
- return n1>n2 ? n1 : n2;
+ return n;
}
/*
** Set the maximum page count for a database if mxPage is positive.
@@ -67695,11 +67470,10 @@
** when A already has a read lock, we encourage A to give up and let B
** proceed.
*/
SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
BtShared *pBt = p->pBt;
- Pager *pPager = pBt->pPager;
int rc = SQLITE_OK;
sqlite3BtreeEnter(p);
btreeIntegrity(p);
@@ -67711,11 +67485,11 @@
goto trans_begun;
}
assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
if( (p->db->flags & SQLITE_ResetDatabase)
- && sqlite3PagerIsreadonly(pPager)==0
+ && sqlite3PagerIsreadonly(pBt->pPager)==0
){
pBt->btsFlags &= ~BTS_READ_ONLY;
}
/* Write transactions are not possible on a read-only database */
@@ -67759,22 +67533,10 @@
if( SQLITE_OK!=rc ) goto trans_begun;
pBt->btsFlags &= ~BTS_INITIALLY_EMPTY;
if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY;
do {
- sqlite3PagerWalDb(pPager, p->db);
-
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
- /* If transitioning from no transaction directly to a write transaction,
- ** block for the WRITER lock first if possible. */
- if( pBt->pPage1==0 && wrflag ){
- assert( pBt->inTransaction==TRANS_NONE );
- rc = sqlite3PagerWalWriteLock(pPager, 1);
- if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break;
- }
-#endif
-
/* Call lockBtree() until either pBt->pPage1 is populated or
** lockBtree() returns something other than SQLITE_OK. lockBtree()
** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
** reading page 1 it discovers that the page-size of the database
** file is not pBt->pageSize. In this case lockBtree() will update
@@ -67784,11 +67546,11 @@
if( rc==SQLITE_OK && wrflag ){
if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){
rc = SQLITE_READONLY;
}else{
- rc = sqlite3PagerBegin(pPager, wrflag>1, sqlite3TempInMemory(p->db));
+ rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db));
if( rc==SQLITE_OK ){
rc = newDatabase(pBt);
}else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
/* if there was no transaction opened when this function was
** called and SQLITE_BUSY_SNAPSHOT is returned, change the error
@@ -67797,19 +67559,15 @@
}
}
}
if( rc!=SQLITE_OK ){
- (void)sqlite3PagerWalWriteLock(pPager, 0);
unlockBtreeIfUnused(pBt);
}
}while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
btreeInvokeBusyHandler(pBt) );
- sqlite3PagerWalDb(pPager, 0);
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
- if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
-#endif
+ sqlite3PagerResetLockTimeout(pBt->pPager);
if( rc==SQLITE_OK ){
if( p->inTrans==TRANS_NONE ){
pBt->nTransaction++;
#ifndef SQLITE_OMIT_SHARED_CACHE
@@ -67857,11 +67615,11 @@
if( wrflag ){
/* This call makes sure that the pager has the correct number of
** open savepoints. If the second parameter is greater than 0 and
** the sub-journal is not already open, then it will be opened here.
*/
- rc = sqlite3PagerOpenSavepoint(pPager, p->db->nSavepoint);
+ rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
}
}
btreeIntegrity(p);
sqlite3BtreeLeave(p);
@@ -71493,11 +71251,11 @@
/* Remove cells from the start and end of the page */
assert( nCell>=0 );
if( iOldnCell) ) return SQLITE_CORRUPT_BKPT;
+ if( nShift>nCell ) return SQLITE_CORRUPT_BKPT;
memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
nCell -= nShift;
}
if( iNewEnd < iOldEnd ){
int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
@@ -73850,10 +73608,11 @@
}
sqlite3BtreeLeave(p);
return rc;
}
+#ifndef SQLITE_OMIT_BTREECOUNT
/*
** 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.
@@ -73871,11 +73630,11 @@
}
/* Unless an error occurs, the following loop runs one iteration for each
** page in the B-Tree structure (not including overflow pages).
*/
- while( rc==SQLITE_OK && !AtomicLoad(&db->u1.isInterrupted) ){
+ while( rc==SQLITE_OK && !db->u1.isInterrupted ){
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
** this page contains countable entries. Increment the entry counter
@@ -73922,10 +73681,11 @@
}
/* An error has occurred. Return an error code. */
return rc;
}
+#endif
/*
** Return the pager associated with a BTree. This routine is used for
** testing and debugging only.
*/
@@ -73996,11 +73756,11 @@
}
if( getPageReferenced(pCheck, iPage) ){
checkAppendMsg(pCheck, "2nd reference to page %d", iPage);
return 1;
}
- if( AtomicLoad(&pCheck->db->u1.isInterrupted) ) return 1;
+ if( pCheck->db->u1.isInterrupted ) return 1;
setPageReferenced(pCheck, iPage);
return 0;
}
#ifndef SQLITE_OMIT_AUTOVACUUM
@@ -74972,11 +74732,11 @@
** Attempt to set the page size of the destination to match the page size
** of the source.
*/
static int setDestPgsz(sqlite3_backup *p){
int rc;
- rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),0,0);
+ rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0);
return rc;
}
/*
** Check that there is no open read-transaction on the b-tree passed as the
@@ -75095,10 +74855,17 @@
Pager * const pDestPager = sqlite3BtreePager(p->pDest);
const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
const int nCopy = MIN(nSrcPgsz, nDestPgsz);
const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
+#ifdef SQLITE_HAS_CODEC
+ /* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is
+ ** guaranteed that the shared-mutex is held by this thread, handle
+ ** p->pSrc may not actually be the owner. */
+ int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc);
+ int nDestReserve = sqlite3BtreeGetOptimalReserve(p->pDest);
+#endif
int rc = SQLITE_OK;
i64 iOff;
assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 );
assert( p->bDestLocked );
@@ -75111,10 +74878,30 @@
*/
if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){
rc = SQLITE_READONLY;
}
+#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!=(u32)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.
*/
for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOffdb;
b.pSrc = pFrom;
b.pDest = pTo;
b.iNext = 1;
+#ifdef SQLITE_HAS_CODEC
+ sqlite3PagerAlignReserve(sqlite3BtreePager(pTo), sqlite3BtreePager(pFrom));
+#endif
+
/* 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
** within a single call (unless an error occurs). The assert() statement
** checks this assumption - (p->rc) should be set to either SQLITE_DONE
@@ -76595,18 +76386,23 @@
u16 mFlags;
if( pVdbe->db->flags & SQLITE_VdbeTrace ){
sqlite3DebugPrintf("Invalidate R[%d] due to change in R[%d]\n",
(int)(pX - pVdbe->aMem), (int)(pMem - pVdbe->aMem));
}
- /* If pX is marked as a shallow copy of pMem, then try to verify that
+ /* If pX is marked as a shallow copy of pMem, then verify that
** no significant changes have been made to pX since the OP_SCopy.
** A significant change would indicated a missed call to this
** function for pX. Minor changes, such as adding or removing a
** dual type, are allowed, as long as the underlying value is the
** same. */
mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i );
+ /* assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r ); */
+ /* ^^ */
+ /* Cannot reliably compare doubles for equality */
+ assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) );
+ assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 );
/* pMem is the register that is changing. But also mark pX as
** undefined so that we can quickly detect the shallow-copy error */
pX->flags = MEM_Undefined;
pX->pScopyFrom = 0;
@@ -76798,11 +76594,11 @@
** destroyed.
**
** If this routine fails for any reason (malloc returns NULL or unable
** to read from the disk) then the pMem is left in an inconsistent state.
*/
-SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
+static SQLITE_NOINLINE int vdbeMemFromBtreeResize(
BtCursor *pCur, /* Cursor pointing at record to retrieve. */
u32 offset, /* Offset from the start of data to return bytes from. */
u32 amt, /* Number of bytes to return. */
Mem *pMem /* OUT: Return data in this Mem structure. */
){
@@ -76821,32 +76617,35 @@
sqlite3VdbeMemRelease(pMem);
}
}
return rc;
}
-SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(
+SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
BtCursor *pCur, /* Cursor pointing at record to retrieve. */
+ u32 offset, /* Offset from the start of data to return bytes from. */
u32 amt, /* Number of bytes to return. */
Mem *pMem /* OUT: Return data in this Mem structure. */
){
+ char *zData; /* Data from the btree layer */
u32 available = 0; /* Number of bytes available on the local btree page */
int rc = SQLITE_OK; /* Return code */
assert( sqlite3BtreeCursorIsValid(pCur) );
assert( !VdbeMemDynamic(pMem) );
/* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
** that both the BtShared and database handle mutexes are held. */
assert( !sqlite3VdbeMemIsRowSet(pMem) );
- pMem->z = (char *)sqlite3BtreePayloadFetch(pCur, &available);
- assert( pMem->z!=0 );
+ zData = (char *)sqlite3BtreePayloadFetch(pCur, &available);
+ assert( zData!=0 );
- if( amt<=available ){
+ if( offset+amt<=available ){
+ pMem->z = &zData[offset];
pMem->flags = MEM_Blob|MEM_Ephem;
pMem->n = (int)amt;
}else{
- rc = sqlite3VdbeMemFromBtree(pCur, 0, amt, pMem);
+ rc = vdbeMemFromBtreeResize(pCur, offset, amt, pMem);
}
return rc;
}
@@ -77957,11 +77756,11 @@
(void)z2;
}
#endif
/*
-** Add a new OP_Explain opcode.
+** Add a new OP_ opcode.
**
** If the bPush flag is true, then make this opcode the parent for
** subsequent Explains until sqlite3VdbeExplainPop() is called.
*/
SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
@@ -78598,38 +78397,10 @@
*/
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
sqlite3VdbeChangeP2(p, addr, p->nOp);
}
-/*
-** Change the P2 operand of the jump instruction at addr so that
-** the jump lands on the next opcode. Or if the jump instruction was
-** the previous opcode (and is thus a no-op) then simply back up
-** the next instruction counter by one slot so that the jump is
-** overwritten by the next inserted opcode.
-**
-** This routine is an optimization of sqlite3VdbeJumpHere() that
-** strives to omit useless byte-code like this:
-**
-** 7 Once 0 8 0
-** 8 ...
-*/
-SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe *p, int addr){
- if( addr==p->nOp-1 ){
- assert( p->aOp[addr].opcode==OP_Once
- || p->aOp[addr].opcode==OP_If
- || p->aOp[addr].opcode==OP_FkIfZero );
- assert( p->aOp[addr].p4type==0 );
-#ifdef SQLITE_VDBE_COVERAGE
- sqlite3VdbeGetOp(p,-1)->iSrcLine = 0; /* Erase VdbeCoverage() macros */
-#endif
- p->nOp--;
- }else{
- sqlite3VdbeChangeP2(p, addr, p->nOp);
- }
-}
-
/*
** If the input FuncDef structure is ephemeral, then free it. If
** the FuncDef is not ephermal, then do nothing.
*/
@@ -78997,23 +78768,21 @@
** "PX" -> "r[X]"
** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1
** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0
** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x
*/
-SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(
- sqlite3 *db, /* Optional - Oom error reporting only */
+static int displayComment(
const Op *pOp, /* The opcode to be commented */
- const char *zP4 /* Previously obtained value for P4 */
+ const char *zP4, /* Previously obtained value for P4 */
+ char *zTemp, /* Write result here */
+ int nTemp /* Space available in zTemp[] */
){
const char *zOpName;
const char *zSynopsis;
int nOpName;
- int ii;
+ int ii, jj;
char zAlt[50];
- StrAccum x;
-
- sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
zOpName = sqlite3OpcodeName(pOp->opcode);
nOpName = sqlite3Strlen30(zOpName);
if( zOpName[nOpName+1] ){
int seenCom = 0;
char c;
@@ -79024,68 +78793,57 @@
}else{
sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3);
}
zSynopsis = zAlt;
}
- for(ii=0; (c = zSynopsis[ii])!=0; ii++){
+ for(ii=jj=0; jjzComment);
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", pOp->zComment);
seenCom = 1;
}else{
int v1 = translateP(c, pOp);
int v2;
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "%d", v1);
if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){
ii += 3;
+ jj += sqlite3Strlen30(zTemp+jj);
v2 = translateP(zSynopsis[ii], pOp);
if( strncmp(zSynopsis+ii+1,"+1",2)==0 ){
ii += 2;
v2++;
}
- if( v2<2 ){
- sqlite3_str_appendf(&x, "%d", v1);
- }else{
- sqlite3_str_appendf(&x, "%d..%d", v1, v1+v2-1);
- }
- }else if( strncmp(zSynopsis+ii+1, "@NP", 3)==0 ){
- sqlite3_context *pCtx = pOp->p4.pCtx;
- if( pOp->p4type!=P4_FUNCCTX || pCtx->argc==1 ){
- sqlite3_str_appendf(&x, "%d", v1);
- }else if( pCtx->argc>1 ){
- sqlite3_str_appendf(&x, "%d..%d", v1, v1+pCtx->argc-1);
- }else{
- assert( x.nChar>2 );
- x.nChar -= 2;
- ii++;
- }
- ii += 3;
- }else{
- sqlite3_str_appendf(&x, "%d", v1);
- if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){
- ii += 4;
+ if( v2>1 ){
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1);
}
+ }else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){
+ ii += 4;
}
}
+ jj += sqlite3Strlen30(zTemp+jj);
}else{
- sqlite3_str_appendchar(&x, 1, c);
+ zTemp[jj++] = c;
}
}
- if( !seenCom && pOp->zComment ){
- sqlite3_str_appendf(&x, "; %s", pOp->zComment);
+ if( !seenCom && jjzComment ){
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "; %s", pOp->zComment);
+ jj += sqlite3Strlen30(zTemp+jj);
}
+ if( jjzComment ){
- sqlite3_str_appendall(&x, pOp->zComment);
- }
- if( (x.accError & SQLITE_NOMEM)!=0 && db!=0 ){
- sqlite3OomFault(db);
+ sqlite3_snprintf(nTemp, zTemp, "%s", pOp->zComment);
+ jj = sqlite3Strlen30(zTemp);
+ }else{
+ zTemp[0] = 0;
+ jj = 0;
}
- return sqlite3StrAccumFinish(&x);
+ return jj;
}
-#endif /* SQLITE_ENABLE_EXPLAIN_COMMENTS */
+#endif /* SQLITE_DEBUG */
#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
/*
** Translate the P4.pExpr value for an OP_CursorHint opcode into text
** that can be displayed in the P4 column of EXPLAIN output.
@@ -79162,15 +78920,15 @@
#if VDBE_DISPLAY_P4
/*
** Compute a string that describes the P4 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
-SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
- char *zP4 = 0;
+static char *displayP4(Op *pOp, char *zTemp, int nTemp){
+ char *zP4 = zTemp;
StrAccum x;
-
- sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
+ assert( nTemp>=20 );
+ sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
switch( pOp->p4type ){
case P4_KEYINFO: {
int j;
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
assert( pKeyInfo->aSortFlags!=0 );
@@ -79192,15 +78950,12 @@
displayP4Expr(&x, pOp->p4.pExpr);
break;
}
#endif
case P4_COLLSEQ: {
- static const char *const encnames[] = {"?", "8", "16LE", "16BE"};
CollSeq *pColl = pOp->p4.pColl;
- assert( pColl->enc>=0 && pColl->enc<4 );
- sqlite3_str_appendf(&x, "%.18s-%s", pColl->zName,
- encnames[pColl->enc]);
+ sqlite3_str_appendf(&x, "(%.20s)", pColl->zName);
break;
}
case P4_FUNCDEF: {
FuncDef *pDef = pOp->p4.pFunc;
sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
@@ -79250,36 +79005,40 @@
int i;
int *ai = pOp->p4.ai;
int n = ai[0]; /* The first element of an INTARRAY is always the
** count of the number of elements to follow */
for(i=1; i<=n; i++){
- sqlite3_str_appendf(&x, "%c%d", (i==1 ? '[' : ','), ai[i]);
+ sqlite3_str_appendf(&x, ",%d", ai[i]);
}
+ zTemp[0] = '[';
sqlite3_str_append(&x, "]", 1);
break;
}
case P4_SUBPROGRAM: {
- zP4 = "program";
+ sqlite3_str_appendf(&x, "program");
break;
}
case P4_DYNBLOB:
case P4_ADVANCE: {
+ zTemp[0] = 0;
break;
}
case P4_TABLE: {
- zP4 = pOp->p4.pTab->zName;
+ sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
break;
}
default: {
zP4 = pOp->p4.z;
+ if( zP4==0 ){
+ zP4 = zTemp;
+ zTemp[0] = 0;
+ }
}
}
- if( zP4 ) sqlite3_str_appendall(&x, zP4);
- if( (x.accError & SQLITE_NOMEM)!=0 ){
- sqlite3OomFault(db);
- }
- return sqlite3StrAccumFinish(&x);
+ sqlite3StrAccumFinish(&x);
+ assert( zP4!=0 );
+ return zP4;
}
#endif /* VDBE_DISPLAY_P4 */
/*
** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
@@ -79365,34 +79124,28 @@
/*
** Print a single opcode. This routine is used for debugging only.
*/
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
char *zP4;
- char *zCom;
- sqlite3 dummyDb;
+ char zPtr[50];
+ char zCom[100];
static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n";
if( pOut==0 ) pOut = stdout;
- sqlite3BeginBenignMalloc();
- dummyDb.mallocFailed = 1;
- zP4 = sqlite3VdbeDisplayP4(&dummyDb, pOp);
+ zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
- zCom = sqlite3VdbeDisplayComment(0, pOp, zP4);
+ displayComment(pOp, zP4, zCom, sizeof(zCom));
#else
- zCom = 0;
+ zCom[0] = 0;
#endif
/* NB: The sqlite3OpcodeName() function is implemented by code created
** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the
** information from the vdbe.c source text */
fprintf(pOut, zFormat1, pc,
- sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3,
- zP4 ? zP4 : "", pOp->p5,
- zCom ? zCom : ""
+ sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
+ zCom
);
fflush(pOut);
- sqlite3_free(zP4);
- sqlite3_free(zCom);
- sqlite3EndBenignMalloc();
}
#endif
/*
** Initialize an array of N Mem element.
@@ -79479,65 +79232,116 @@
assert( sqlite3VdbeFrameIsValid(pFrame) );
pFrame->pParent = pFrame->v->pDelFrame;
pFrame->v->pDelFrame = pFrame;
}
-#if defined(SQLITE_ENABLE_BYTECODE_VTAB) || !defined(SQLITE_OMIT_EXPLAIN)
+
+/*
+** Delete a VdbeFrame object and its contents. VdbeFrame objects are
+** allocated by the OP_Program opcode in sqlite3VdbeExec().
+*/
+SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){
+ int i;
+ Mem *aMem = VdbeFrameMem(p);
+ VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
+ assert( sqlite3VdbeFrameIsValid(p) );
+ for(i=0; inChildCsr; i++){
+ sqlite3VdbeFreeCursor(p->v, apCsr[i]);
+ }
+ releaseMemArray(aMem, p->nChildMem);
+ sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
+ sqlite3DbFree(p->v->db, p);
+}
+
+#ifndef SQLITE_OMIT_EXPLAIN
/*
-** Locate the next opcode to be displayed in EXPLAIN or EXPLAIN
-** QUERY PLAN output.
+** Give a listing of the program in the virtual machine.
+**
+** The interface is the same as sqlite3VdbeExec(). But instead of
+** running the code, it invokes the callback once for each instruction.
+** This feature is used to implement "EXPLAIN".
+**
+** When p->explain==1, each instruction is listed. When
+** p->explain==2, only OP_Explain instructions are listed and these
+** are shown in a different format. p->explain==2 is used to implement
+** EXPLAIN QUERY PLAN.
+** 2018-04-24: In p->explain==2 mode, the OP_Init opcodes of triggers
+** are also shown, so that the boundaries between the main program and
+** each trigger are clear.
**
-** Return SQLITE_ROW on success. Return SQLITE_DONE if there are no
-** more opcodes to be displayed.
+** When p->explain==1, first the main program is listed, then each of
+** the trigger subprograms are listed one by one.
*/
-SQLITE_PRIVATE int sqlite3VdbeNextOpcode(
- Vdbe *p, /* The statement being explained */
- Mem *pSub, /* Storage for keeping track of subprogram nesting */
- int eMode, /* 0: normal. 1: EQP. 2: TablesUsed */
- int *piPc, /* IN/OUT: Current rowid. Overwritten with next rowid */
- int *piAddr, /* OUT: Write index into (*paOp)[] here */
- Op **paOp /* OUT: Write the opcode array here */
+SQLITE_PRIVATE int sqlite3VdbeList(
+ Vdbe *p /* The VDBE */
){
int nRow; /* Stop when row count reaches this */
int nSub = 0; /* Number of sub-vdbes seen so far */
SubProgram **apSub = 0; /* Array of sub-vdbes */
- int i; /* Next instruction address */
- int rc = SQLITE_OK; /* Result code */
- Op *aOp = 0; /* Opcode array */
- int iPc; /* Rowid. Copy of value in *piPc */
+ Mem *pSub = 0; /* Memory cell hold array of subprogs */
+ sqlite3 *db = p->db; /* The database connection */
+ int i; /* Loop counter */
+ int rc = SQLITE_OK; /* Return code */
+ Mem *pMem = &p->aMem[1]; /* First Mem of result set */
+ int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
+ Op *pOp = 0;
+
+ assert( p->explain );
+ assert( p->magic==VDBE_MAGIC_RUN );
+ assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
+
+ /* Even though this opcode does not use dynamic strings for
+ ** the result, result columns may become dynamic if the user calls
+ ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
+ */
+ releaseMemArray(pMem, 8);
+ p->pResultSet = 0;
+
+ if( p->rc==SQLITE_NOMEM ){
+ /* This happens if a malloc() inside a call to sqlite3_column_text() or
+ ** sqlite3_column_text16() failed. */
+ sqlite3OomFault(db);
+ return SQLITE_ERROR;
+ }
/* When the number of output rows reaches nRow, that means the
** listing has finished and sqlite3_step() should return SQLITE_DONE.
** nRow is the sum of the number of rows in the main program, plus
** the sum of the number of rows in all trigger subprograms encountered
** so far. The nRow value will increase as new trigger subprograms are
** encountered, but p->pc will eventually catch up to nRow.
*/
nRow = p->nOp;
- if( pSub!=0 ){
+ if( bListSubprogs ){
+ /* The first 8 memory cells are used for the result set. So we will
+ ** commandeer the 9th cell to use as storage for an array of pointers
+ ** to trigger subprograms. The VDBE is guaranteed to have at least 9
+ ** cells. */
+ assert( p->nMem>9 );
+ pSub = &p->aMem[9];
if( pSub->flags&MEM_Blob ){
- /* pSub is initiallly NULL. It is initialized to a BLOB by
- ** the P4_SUBPROGRAM processing logic below */
+ /* On the first call to sqlite3_step(), pSub will hold a NULL. It is
+ ** initialized to a BLOB by the P4_SUBPROGRAM processing logic below */
nSub = pSub->n/sizeof(Vdbe*);
apSub = (SubProgram **)pSub->z;
}
for(i=0; inOp;
}
}
- iPc = *piPc;
+
while(1){ /* Loop exits via break */
- i = iPc++;
+ i = p->pc++;
if( i>=nRow ){
p->rc = SQLITE_OK;
rc = SQLITE_DONE;
break;
}
if( inOp ){
- /* The rowid is small enough that we are still in the
+ /* The output line number is small enough that we are still in the
** main program. */
- aOp = p->aOp;
+ pOp = &p->aOp[i];
}else{
/* We are currently listing subprograms. Figure out which one and
** pick up the appropriate opcode. */
int j;
i -= p->nOp;
@@ -79545,182 +79349,118 @@
assert( nSub>0 );
for(j=0; i>=apSub[j]->nOp; j++){
i -= apSub[j]->nOp;
assert( inOp || j+1aOp;
+ pOp = &apSub[j]->aOp[i];
}
/* When an OP_Program opcode is encounter (the only opcode that has
** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
** kept in p->aMem[9].z to hold the new program - assuming this subprogram
** has not already been seen.
*/
- if( pSub!=0 && aOp[i].p4type==P4_SUBPROGRAM ){
+ if( bListSubprogs && pOp->p4type==P4_SUBPROGRAM ){
int nByte = (nSub+1)*sizeof(SubProgram*);
int j;
for(j=0; jp4.pProgram ) break;
}
if( j==nSub ){
p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
if( p->rc!=SQLITE_OK ){
rc = SQLITE_ERROR;
break;
}
apSub = (SubProgram **)pSub->z;
- apSub[nSub++] = aOp[i].p4.pProgram;
- MemSetTypeFlag(pSub, MEM_Blob);
+ apSub[nSub++] = pOp->p4.pProgram;
+ pSub->flags |= MEM_Blob;
pSub->n = nSub*sizeof(SubProgram*);
- nRow += aOp[i].p4.pProgram->nOp;
+ nRow += pOp->p4.pProgram->nOp;
}
}
- if( eMode==0 ) break;
-#ifdef SQLITE_ENABLE_BYTECODE_VTAB
- if( eMode==2 ){
- Op *pOp = aOp + i;
- if( pOp->opcode==OP_OpenRead ) break;
- if( pOp->opcode==OP_OpenWrite && (pOp->p5 & OPFLAG_P2ISREG)==0 ) break;
- if( pOp->opcode==OP_ReopenIdx ) break;
- }else
-#endif
- {
- assert( eMode==1 );
- if( aOp[i].opcode==OP_Explain ) break;
- if( aOp[i].opcode==OP_Init && iPc>1 ) break;
- }
- }
- *piPc = iPc;
- *piAddr = i;
- *paOp = aOp;
- return rc;
-}
-#endif /* SQLITE_ENABLE_BYTECODE_VTAB || !SQLITE_OMIT_EXPLAIN */
-
-
-/*
-** Delete a VdbeFrame object and its contents. VdbeFrame objects are
-** allocated by the OP_Program opcode in sqlite3VdbeExec().
-*/
-SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){
- int i;
- Mem *aMem = VdbeFrameMem(p);
- VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
- assert( sqlite3VdbeFrameIsValid(p) );
- for(i=0; inChildCsr; i++){
- sqlite3VdbeFreeCursor(p->v, apCsr[i]);
- }
- releaseMemArray(aMem, p->nChildMem);
- sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
- sqlite3DbFree(p->v->db, p);
-}
-
-#ifndef SQLITE_OMIT_EXPLAIN
-/*
-** Give a listing of the program in the virtual machine.
-**
-** The interface is the same as sqlite3VdbeExec(). But instead of
-** running the code, it invokes the callback once for each instruction.
-** This feature is used to implement "EXPLAIN".
-**
-** When p->explain==1, each instruction is listed. When
-** p->explain==2, only OP_Explain instructions are listed and these
-** are shown in a different format. p->explain==2 is used to implement
-** EXPLAIN QUERY PLAN.
-** 2018-04-24: In p->explain==2 mode, the OP_Init opcodes of triggers
-** are also shown, so that the boundaries between the main program and
-** each trigger are clear.
-**
-** When p->explain==1, first the main program is listed, then each of
-** the trigger subprograms are listed one by one.
-*/
-SQLITE_PRIVATE int sqlite3VdbeList(
- Vdbe *p /* The VDBE */
-){
- Mem *pSub = 0; /* Memory cell hold array of subprogs */
- sqlite3 *db = p->db; /* The database connection */
- int i; /* Loop counter */
- int rc = SQLITE_OK; /* Return code */
- Mem *pMem = &p->aMem[1]; /* First Mem of result set */
- int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
- Op *aOp; /* Array of opcodes */
- Op *pOp; /* Current opcode */
-
- assert( p->explain );
- assert( p->magic==VDBE_MAGIC_RUN );
- assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
-
- /* Even though this opcode does not use dynamic strings for
- ** the result, result columns may become dynamic if the user calls
- ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
- */
- releaseMemArray(pMem, 8);
- p->pResultSet = 0;
-
- if( p->rc==SQLITE_NOMEM ){
- /* This happens if a malloc() inside a call to sqlite3_column_text() or
- ** sqlite3_column_text16() failed. */
- sqlite3OomFault(db);
- return SQLITE_ERROR;
+ if( p->explain<2 ) break;
+ if( pOp->opcode==OP_Explain ) break;
+ if( pOp->opcode==OP_Init && p->pc>1 ) break;
}
- if( bListSubprogs ){
- /* The first 8 memory cells are used for the result set. So we will
- ** commandeer the 9th cell to use as storage for an array of pointers
- ** to trigger subprograms. The VDBE is guaranteed to have at least 9
- ** cells. */
- assert( p->nMem>9 );
- pSub = &p->aMem[9];
- }else{
- pSub = 0;
- }
-
- /* Figure out which opcode is next to display */
- rc = sqlite3VdbeNextOpcode(p, pSub, p->explain==2, &p->pc, &i, &aOp);
-
if( rc==SQLITE_OK ){
- pOp = aOp + i;
- if( AtomicLoad(&db->u1.isInterrupted) ){
+ if( db->u1.isInterrupted ){
p->rc = SQLITE_INTERRUPT;
rc = SQLITE_ERROR;
sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
}else{
- char *zP4 = sqlite3VdbeDisplayP4(db, pOp);
- if( p->explain==2 ){
- sqlite3VdbeMemSetInt64(pMem, pOp->p1);
- sqlite3VdbeMemSetInt64(pMem+1, pOp->p2);
- sqlite3VdbeMemSetInt64(pMem+2, pOp->p3);
- sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free);
- p->nResColumn = 4;
+ char *zP4;
+ if( p->explain==1 ){
+ pMem->flags = MEM_Int;
+ 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 );
+ pMem->n = sqlite3Strlen30(pMem->z);
+ pMem->enc = SQLITE_UTF8;
+ pMem++;
+ }
+
+ pMem->flags = MEM_Int;
+ pMem->u.i = pOp->p1; /* P1 */
+ pMem++;
+
+ pMem->flags = MEM_Int;
+ pMem->u.i = pOp->p2; /* P2 */
+ pMem++;
+
+ pMem->flags = MEM_Int;
+ pMem->u.i = pOp->p3; /* P3 */
+ pMem++;
+
+ if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
+ assert( p->db->mallocFailed );
+ return SQLITE_ERROR;
+ }
+ pMem->flags = MEM_Str|MEM_Term;
+ zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
+ if( zP4!=pMem->z ){
+ pMem->n = 0;
+ sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
}else{
- sqlite3VdbeMemSetInt64(pMem+0, i);
- sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode),
- -1, SQLITE_UTF8, SQLITE_STATIC);
- sqlite3VdbeMemSetInt64(pMem+2, pOp->p1);
- sqlite3VdbeMemSetInt64(pMem+3, pOp->p2);
- sqlite3VdbeMemSetInt64(pMem+4, pOp->p3);
- /* pMem+5 for p4 is done last */
- sqlite3VdbeMemSetInt64(pMem+6, pOp->p5);
+ assert( pMem->z!=0 );
+ pMem->n = sqlite3Strlen30(pMem->z);
+ pMem->enc = SQLITE_UTF8;
+ }
+ pMem++;
+
+ if( p->explain==1 ){
+ if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
+ assert( p->db->mallocFailed );
+ return SQLITE_ERROR;
+ }
+ pMem->flags = MEM_Str|MEM_Term;
+ pMem->n = 2;
+ sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
+ pMem->enc = SQLITE_UTF8;
+ pMem++;
+
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
- {
- char *zCom = sqlite3VdbeDisplayComment(db, pOp, zP4);
- sqlite3VdbeMemSetStr(pMem+7, zCom, -1, SQLITE_UTF8, sqlite3_free);
+ if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
+ assert( p->db->mallocFailed );
+ return SQLITE_ERROR;
}
+ pMem->flags = MEM_Str|MEM_Term;
+ pMem->n = displayComment(pOp, zP4, pMem->z, 500);
+ pMem->enc = SQLITE_UTF8;
#else
- sqlite3VdbeMemSetNull(pMem+7);
+ pMem->flags = MEM_Null; /* Comment */
#endif
- sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
- p->nResColumn = 8;
- }
- p->pResultSet = pMem;
- if( db->mallocFailed ){
- p->rc = SQLITE_NOMEM;
- rc = SQLITE_ERROR;
- }else{
- p->rc = SQLITE_OK;
- rc = SQLITE_ROW;
}
+
+ p->nResColumn = 8 - 4*(p->explain-1);
+ p->pResultSet = &p->aMem[1];
+ p->rc = SQLITE_OK;
+ rc = SQLITE_ROW;
}
}
return rc;
}
#endif /* SQLITE_OMIT_EXPLAIN */
@@ -79924,11 +79664,10 @@
"addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
"id", "parent", "notused", "detail"
};
int iFirst, mx, i;
if( nMem<10 ) nMem = 10;
- p->explain = pParse->explain;
if( pParse->explain==2 ){
sqlite3VdbeSetNumCols(p, 4);
iFirst = 8;
mx = 12;
}else{
@@ -79975,10 +79714,11 @@
}
}
p->pVList = pParse->pVList;
pParse->pVList = 0;
+ p->explain = pParse->explain;
if( db->mallocFailed ){
p->nVar = 0;
p->nCursor = 0;
p->nMem = 0;
}else{
@@ -80286,13 +80026,12 @@
int retryCount = 0;
int nMainFile;
/* Select a master journal file name */
nMainFile = sqlite3Strlen30(zMainFile);
- zMaster = sqlite3MPrintf(db, "%.4c%s%.16c", 0,zMainFile,0);
+ zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz%c%c", zMainFile, 0, 0);
if( zMaster==0 ) return SQLITE_NOMEM_BKPT;
- zMaster += 4;
do {
u32 iRandom;
if( retryCount ){
if( retryCount>100 ){
sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster);
@@ -80318,11 +80057,11 @@
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0
);
}
if( rc!=SQLITE_OK ){
- sqlite3DbFree(db, zMaster-4);
+ 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
@@ -80341,11 +80080,11 @@
rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
offset += sqlite3Strlen30(zFile)+1;
if( rc!=SQLITE_OK ){
sqlite3OsCloseFree(pMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
- sqlite3DbFree(db, zMaster-4);
+ sqlite3DbFree(db, zMaster);
return rc;
}
}
}
@@ -80355,11 +80094,11 @@
if( 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
&& SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
){
sqlite3OsCloseFree(pMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
- sqlite3DbFree(db, zMaster-4);
+ sqlite3DbFree(db, zMaster);
return rc;
}
/* Sync all the db files involved in the transaction. The same call
** sets the master journal pointer in each individual journal. If
@@ -80378,20 +80117,20 @@
}
}
sqlite3OsCloseFree(pMaster);
assert( rc!=SQLITE_BUSY );
if( rc!=SQLITE_OK ){
- sqlite3DbFree(db, zMaster-4);
+ sqlite3DbFree(db, zMaster);
return rc;
}
/* Delete the master journal file. This commits the transaction. After
** doing this the directory is synced again before any individual
** transaction files are deleted.
*/
rc = sqlite3OsDelete(pVfs, zMaster, 1);
- sqlite3DbFree(db, zMaster-4);
+ sqlite3DbFree(db, zMaster);
zMaster = 0;
if( rc ){
return rc;
}
@@ -81093,11 +80832,11 @@
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
VdbeCursor *p = *pp;
assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO );
if( p->deferredMoveto ){
int iMap;
- if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 && !p->nullRow ){
+ if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){
*pp = p->pAltCursor;
*piCol = iMap - 1;
return SQLITE_OK;
}
return sqlite3VdbeFinishMoveto(p);
@@ -82096,11 +81835,11 @@
}
}
/* RHS is a string */
else if( pRhs->flags & MEM_Str ){
- getVarint32NR(&aKey1[idx1], serial_type);
+ getVarint32(&aKey1[idx1], serial_type);
testcase( serial_type==12 );
if( serial_type<12 ){
rc = -1;
}else if( !(serial_type & 0x01) ){
rc = +1;
@@ -82130,11 +81869,11 @@
}
/* RHS is a blob */
else if( pRhs->flags & MEM_Blob ){
assert( (pRhs->flags & MEM_Zero)==0 || pRhs->n==0 );
- getVarint32NR(&aKey1[idx1], serial_type);
+ getVarint32(&aKey1[idx1], serial_type);
testcase( serial_type==12 );
if( serial_type<12 || (serial_type & 0x01) ){
rc = -1;
}else{
int nStr = (serial_type - 12) / 2;
@@ -82319,14 +82058,11 @@
int serial_type;
int res;
assert( pPKey2->aMem[0].flags & MEM_Str );
vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
- serial_type = (u8)(aKey1[1]);
- if( serial_type >= 0x80 ){
- sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type);
- }
+ getVarint32(&aKey1[1], serial_type);
if( serial_type<12 ){
res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */
}else if( !(serial_type & 0x01) ){
res = pPKey2->r2; /* (pKey1/nKey1) is a blob */
}else{
@@ -82443,28 +82179,28 @@
nCellKey = sqlite3BtreePayloadSize(pCur);
assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
/* Read in the complete content of the index entry */
sqlite3VdbeMemInit(&m, db, 0);
- rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
+ rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m);
if( rc ){
return rc;
}
/* The index entry must begin with a header size */
- getVarint32NR((u8*)m.z, szHdr);
+ (void)getVarint32((u8*)m.z, szHdr);
testcase( szHdr==3 );
testcase( szHdr==m.n );
testcase( szHdr>0x7fffffff );
assert( m.n>=0 );
if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){
goto idx_rowid_corruption;
}
/* The last field of the index should be an integer - the ROWID.
** Verify that the last entry really is an integer. */
- getVarint32NR((u8*)&m.z[szHdr-1], typeRowid);
+ (void)getVarint32((u8*)&m.z[szHdr-1], typeRowid);
testcase( typeRowid==1 );
testcase( typeRowid==2 );
testcase( typeRowid==3 );
testcase( typeRowid==4 );
testcase( typeRowid==5 );
@@ -82525,11 +82261,11 @@
if( nCellKey<=0 || nCellKey>0x7fffffff ){
*res = 0;
return SQLITE_CORRUPT_BKPT;
}
sqlite3VdbeMemInit(&m, db, 0);
- rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
+ rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m);
if( rc ){
return rc;
}
*res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0);
sqlite3VdbeMemRelease(&m);
@@ -83438,11 +83174,11 @@
/* If there are no other statements currently running, then
** reset the interrupt flag. This prevents a call to sqlite3_interrupt
** from interrupting a statement that has not yet started.
*/
if( db->nVdbeActive==0 ){
- AtomicStore(&db->u1.isInterrupted, 0);
+ db->u1.isInterrupted = 0;
}
assert( db->nVdbeWrite>0 || db->autoCommit==0
|| (db->nDeferredCons==0 && db->nDeferredImmCons==0)
);
@@ -84130,11 +83866,11 @@
p->db->errCode = SQLITE_OK;
/* If the bit corresponding to this variable in Vdbe.expmask is set, then
** binding a new value to this variable invalidates the current query plan.
**
- ** IMPLEMENTATION-OF: R-57496-20354 If the specific value bound to a host
+ ** 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.
*/
@@ -85823,11 +85559,11 @@
assert( p->bIsReader || p->readOnly!=0 );
p->iCurrentTime = 0;
assert( p->explain==0 );
p->pResultSet = 0;
db->busyHandler.nBusy = 0;
- if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
+ if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
sqlite3VdbeIOTraceSql(p);
#ifdef SQLITE_DEBUG
sqlite3BeginBenignMalloc();
if( p->pc==0
&& (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0
@@ -86007,11 +85743,11 @@
** But that is not due to sloppy coding habits. The code is written this
** way for performance, to avoid having to run the interrupt and progress
** checks on every opcode. This helps sqlite3_step() to run about 1.5%
** faster according to "valgrind --tool=cachegrind" */
check_for_interrupt:
- if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
+ if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/* Call the progress callback if it is configured and the required number
** of VDBE ops have been executed (either since this invocation of
** sqlite3VdbeExec() or since last time the progress callback was called).
** If the progress callback returns non-zero, exit the virtual machine with
@@ -86660,10 +86396,11 @@
u16 flags2; /* Initial flags for P2 */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
pOut = &aMem[pOp->p3];
+ testcase( pIn1==pIn2 );
testcase( pOut==pIn2 );
assert( pIn1!=pOut );
flags1 = pIn1->flags;
testcase( flags1 & MEM_Null );
testcase( pIn2->flags & MEM_Null );
@@ -87190,11 +86927,11 @@
affinity = pOp->p5 & SQLITE_AFF_MASK;
if( affinity>=SQLITE_AFF_NUMERIC ){
if( (flags1 | flags3)&MEM_Str ){
if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
- assert( flags3==pIn3->flags );
+ testcase( flags3!=pIn3->flags );
flags3 = pIn3->flags;
}
if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3,0);
}
@@ -87213,11 +86950,11 @@
testcase( pIn1->flags & MEM_Real );
testcase( pIn1->flags & MEM_IntReal );
sqlite3VdbeMemStringify(pIn1, encoding, 1);
testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
- if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str;
+ if( pIn1==pIn3 ) flags3 = flags1 | MEM_Str;
}
if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn3->flags & MEM_Int );
testcase( pIn3->flags & MEM_Real );
testcase( pIn3->flags & MEM_IntReal );
@@ -87828,11 +87565,11 @@
*/
if( pC->iHdrOffsetaRow==0 ){
memset(&sMem, 0, sizeof(sMem));
- rc = sqlite3VdbeMemFromBtreeZeroOffset(pC->uc.pCursor,aOffset[0],&sMem);
+ rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, 0, aOffset[0], &sMem);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
zData = (u8*)sMem.z;
}else{
zData = pC->aRow;
}
@@ -88303,38 +88040,32 @@
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
REGISTER_TRACE(pOp->p3, pOut);
break;
}
-/* Opcode: Count P1 P2 p3 * *
+/* Opcode: Count P1 P2 * * *
** Synopsis: r[P2]=count()
**
** Store the number of entries (an integer value) in the table or index
-** opened by cursor P1 in register P2.
-**
-** If P3==0, then an exact count is obtained, which involves visiting
-** every btree page of the table. But if P3 is non-zero, an estimate
-** is returned based on the current cursor position.
+** opened by cursor P1 in register P2
*/
+#ifndef SQLITE_OMIT_BTREECOUNT
case OP_Count: { /* out2 */
i64 nEntry;
BtCursor *pCrsr;
assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
pCrsr = p->apCsr[pOp->p1]->uc.pCursor;
assert( pCrsr );
- if( pOp->p3 ){
- nEntry = sqlite3BtreeRowCountEst(pCrsr);
- }else{
- nEntry = 0; /* Not needed. Only used to silence a warning. */
- rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
- if( rc ) goto abort_due_to_error;
- }
+ nEntry = 0; /* Not needed. Only used to silence a warning. */
+ rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
+ if( rc ) goto abort_due_to_error;
pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
goto check_for_interrupt;
}
+#endif
/* Opcode: Savepoint P1 * * P4 *
**
** Open, release or rollback the savepoint named by parameter P4, depending
** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN).
@@ -88786,11 +88517,11 @@
**
** Allowed P5 bits:
**
** - 0x02 OPFLAG_SEEKEQ: This cursor will only be used for
** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
-** of OP_SeekLE/OP_IdxLT)
+** of OP_SeekLE/OP_IdxGT)
**
**
** 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
** object, then table being opened must be an [index b-tree] where the
@@ -88816,11 +88547,11 @@
**
** Allowed P5 bits:
**
** - 0x02 OPFLAG_SEEKEQ: This cursor will only be used for
** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
-** of OP_SeekLE/OP_IdxLT)
+** of OP_SeekLE/OP_IdxGT)
**
**
** See also: OP_OpenRead, OP_OpenWrite
*/
/* Opcode: OpenWrite P1 P2 P3 P4 P5
@@ -88840,11 +88571,11 @@
**
** Allowed P5 bits:
**
** - 0x02 OPFLAG_SEEKEQ: This cursor will only be used for
** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
-** of OP_SeekLE/OP_IdxLT)
+** of OP_SeekLE/OP_IdxGT)
**
- 0x08 OPFLAG_FORDELETE: This cursor is used only to seek
** and subsequently delete entries in an index btree. This is a
** hint to the storage engine that the storage engine is allowed to
** ignore. The hint is not used by the official SQLite b*tree storage
** engine, but is used by COMDB2.
@@ -88952,11 +88683,13 @@
open_cursor_set_hints:
assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ );
testcase( pOp->p5 & OPFLAG_BULKCSR );
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
testcase( pOp->p2 & OPFLAG_SEEKEQ );
+#endif
sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
(pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
if( rc ) goto abort_due_to_error;
break;
}
@@ -89208,17 +88941,15 @@
** 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.
**
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
-** opcode will either land on a record that exactly matches the key, or
-** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ,
-** this opcode must be followed by an IdxLE opcode with the same arguments.
-** The IdxGT opcode will be skipped if this opcode succeeds, but the
-** IdxGT opcode will be used on subsequent loop iterations. The
-** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this
-** is an equality search.
+** opcode will always land on a record that equally equals the key, or
+** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this
+** opcode must be followed by an IdxLE opcode with the same arguments.
+** The IdxLE opcode will be skipped if this opcode succeeds, but the
+** IdxLE opcode will be used on subsequent loop iterations.
**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end. In other words, the cursor is
** configured to use Next, not Prev.
**
@@ -89230,11 +88961,11 @@
** 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
+** 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.
**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end. In other words, the cursor is
@@ -89275,17 +89006,15 @@
** This opcode leaves the cursor configured to move in reverse order,
** from the end toward the beginning. In other words, the cursor is
** configured to use Prev, not Next.
**
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
-** opcode will either land on a record that exactly matches the key, or
-** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ,
-** this opcode must be followed by an IdxLE opcode with the same arguments.
+** opcode will always land on a record that equally equals the key, or
+** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this
+** opcode must be followed by an IdxGE opcode with the same arguments.
** The IdxGE opcode will be skipped if this opcode succeeds, but the
-** IdxGE opcode will be used on subsequent loop iterations. The
-** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this
-** is an equality search.
+** IdxGE opcode will be used on subsequent loop iterations.
**
** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
*/
case OP_SeekLT: /* jump, in3, group */
case OP_SeekLE: /* jump, in3, group */
@@ -89318,11 +89047,11 @@
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
if( pC->isTable ){
u16 flags3, newType;
- /* The OPFLAG_SEEKEQ/BTREE_SEEK_EQ flag is only set on index cursors */
+ /* The BTREE_SEEK_EQ flag is only set on index cursors */
assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
|| CORRUPT_DB );
/* 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
@@ -89377,21 +89106,18 @@
pC->movetoTarget = iKey; /* Used by OP_Delete */
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
}else{
- /* For a cursor with the OPFLAG_SEEKEQ/BTREE_SEEK_EQ hint, only the
- ** OP_SeekGE and OP_SeekLE opcodes are allowed, and these must be
- ** immediately followed by an OP_IdxGT or OP_IdxLT opcode, respectively,
- ** with the same key.
+ /* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and
+ ** OP_SeekLE opcodes are allowed, and these must be immediately followed
+ ** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key.
*/
if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){
eqOnly = 1;
assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
- assert( pOp->opcode==OP_SeekGE || pOp[1].opcode==OP_IdxLT );
- assert( pOp->opcode==OP_SeekLE || pOp[1].opcode==OP_IdxGT );
assert( pOp[1].p1==pOp[0].p1 );
assert( pOp[1].p2==pOp[0].p2 );
assert( pOp[1].p3==pOp[0].p3 );
assert( pOp[1].p4.i==pOp[0].p4.i );
}
@@ -90335,11 +90061,11 @@
n = sqlite3BtreePayloadSize(pCrsr);
if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
testcase( n==0 );
- rc = sqlite3VdbeMemFromBtreeZeroOffset(pCrsr, n, pOut);
+ rc = sqlite3VdbeMemFromBtree(pCrsr, 0, n, pOut);
if( rc ) goto abort_due_to_error;
if( !pOp->p3 ) Deephemeralize(pOut);
UPDATE_MAX_BLOBSIZE(pOut);
REGISTER_TRACE(pOp->p2, pOut);
break;
@@ -90713,78 +90439,58 @@
** to P2.
**
** This instruction only works for indices. The equivalent instruction
** for tables is OP_Insert.
*/
-case OP_IdxInsert: { /* in2 */
- VdbeCursor *pC;
- BtreePayload x;
-
- assert( pOp->p1>=0 && pOp->p1nCursor );
- pC = p->apCsr[pOp->p1];
- sqlite3VdbeIncrWriteCounter(p, pC);
- assert( pC!=0 );
- assert( !isSorter(pC) );
- pIn2 = &aMem[pOp->p2];
- assert( pIn2->flags & MEM_Blob );
- if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- assert( pC->eCurType==CURTYPE_BTREE );
- assert( pC->isTable==0 );
- rc = ExpandBlob(pIn2);
- if( rc ) goto abort_due_to_error;
- x.nKey = pIn2->n;
- x.pKey = pIn2->z;
- x.aMem = aMem + pOp->p3;
- x.nMem = (u16)pOp->p4.i;
- rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
- (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)),
- ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
- );
- assert( pC->deferredMoveto==0 );
- pC->cacheStatus = CACHE_STALE;
- if( rc) goto abort_due_to_error;
- break;
-}
-
/* Opcode: SorterInsert P1 P2 * * *
** Synopsis: key=r[P2]
**
** Register P2 holds an SQL index key made using the
** MakeRecord instructions. This opcode writes that key
** into the sorter P1. Data for the entry is nil.
*/
-case OP_SorterInsert: { /* in2 */
+case OP_SorterInsert: /* in2 */
+case OP_IdxInsert: { /* in2 */
VdbeCursor *pC;
+ BtreePayload x;
assert( pOp->p1>=0 && pOp->p1nCursor );
pC = p->apCsr[pOp->p1];
sqlite3VdbeIncrWriteCounter(p, pC);
assert( pC!=0 );
- assert( isSorter(pC) );
+ assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) );
pIn2 = &aMem[pOp->p2];
assert( pIn2->flags & MEM_Blob );
+ if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
+ assert( pC->eCurType==CURTYPE_BTREE || pOp->opcode==OP_SorterInsert );
assert( pC->isTable==0 );
rc = ExpandBlob(pIn2);
if( rc ) goto abort_due_to_error;
- rc = sqlite3VdbeSorterWrite(pC, pIn2);
+ if( pOp->opcode==OP_SorterInsert ){
+ rc = sqlite3VdbeSorterWrite(pC, pIn2);
+ }else{
+ x.nKey = pIn2->n;
+ x.pKey = pIn2->z;
+ x.aMem = aMem + pOp->p3;
+ x.nMem = (u16)pOp->p4.i;
+ rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
+ (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)),
+ ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
+ );
+ assert( pC->deferredMoveto==0 );
+ pC->cacheStatus = CACHE_STALE;
+ }
if( rc) goto abort_due_to_error;
break;
}
-/* Opcode: IdxDelete P1 P2 P3 * P5
+/* Opcode: IdxDelete P1 P2 P3 * *
** Synopsis: key=r[P2@P3]
**
** The content of P3 registers starting at register P2 form
** an unpacked index key. This opcode removes that entry from the
** index opened by cursor P1.
-**
-** If P5 is not zero, then raise an SQLITE_CORRUPT_INDEX error
-** if no matching index entry is found. This happens when running
-** an UPDATE or DELETE statement and the index entry to be updated
-** or deleted is not found. For some uses of IdxDelete
-** (example: the EXCEPT operator) it does not matter that no matching
-** entry is found. For those cases, P5 is zero.
*/
case OP_IdxDelete: {
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
@@ -90797,22 +90503,20 @@
assert( pC!=0 );
assert( pC->eCurType==CURTYPE_BTREE );
sqlite3VdbeIncrWriteCounter(p, pC);
pCrsr = pC->uc.pCursor;
assert( pCrsr!=0 );
+ assert( pOp->p5==0 );
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p3;
r.default_rc = 0;
r.aMem = &aMem[pOp->p2];
rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
if( rc ) goto abort_due_to_error;
if( res==0 ){
rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
if( rc ) goto abort_due_to_error;
- }else if( pOp->p5 ){
- rc = SQLITE_CORRUPT_INDEX;
- goto abort_due_to_error;
}
assert( pC->deferredMoveto==0 );
pC->cacheStatus = CACHE_STALE;
pC->seekResult = 0;
break;
@@ -91611,11 +91315,11 @@
** try to reuse register values from the first use. */
{
int i;
for(i=0; inMem; i++){
aMem[i].pScopyFrom = 0; /* Prevent false-positive AboutToChange() errs */
- MemSetTypeFlag(&aMem[i], MEM_Undefined); /* Fault if this reg is reused */
+ aMem[i].flags |= MEM_Undefined; /* Cause a fault if this reg is reused */
}
}
#endif
pOp = &aOp[-1];
goto check_for_interrupt;
@@ -92722,11 +92426,11 @@
break;
}
#endif
/* Opcode: Function P1 P2 P3 P4 *
-** Synopsis: r[P3]=func(r[P2@NP])
+** Synopsis: r[P3]=func(r[P2@P5])
**
** Invoke a user function (P4 is a pointer to an sqlite3_context object that
** contains a pointer to the function to be run) with arguments taken
** from register P2 and successors. The number of arguments is in
** the sqlite3_context object that P4 points to.
@@ -92741,11 +92445,11 @@
** invocation of this opcode.
**
** See also: AggStep, AggFinal, PureFunc
*/
/* Opcode: PureFunc P1 P2 P3 P4 *
-** Synopsis: r[P3]=func(r[P2@NP])
+** Synopsis: r[P3]=func(r[P2@P5])
**
** Invoke a user function (P4 is a pointer to an sqlite3_context object that
** contains a pointer to the function to be run) with arguments taken
** from register P2 and successors. The number of arguments is in
** the sqlite3_context object that P4 points to.
@@ -93130,11 +92834,11 @@
/* Jump to here if the sqlite3_interrupt() API sets the interrupt
** flag.
*/
abort_due_to_interrupt:
- assert( AtomicLoad(&db->u1.isInterrupted) );
+ assert( db->u1.isInterrupted );
rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
p->rc = rc;
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
goto abort_due_to_error;
}
@@ -94468,12 +94172,12 @@
int n1;
int n2;
int res;
- getVarint32NR(&p1[1], n1);
- getVarint32NR(&p2[1], n2);
+ getVarint32(&p1[1], n1);
+ getVarint32(&p2[1], n2);
res = memcmp(v1, v2, (MIN(n1, n2) - 13)/2);
if( res==0 ){
res = n1 - n2;
}
@@ -95426,11 +95130,11 @@
int nPMA; /* Bytes of PMA space required */
int t; /* serial type of first record field */
assert( pCsr->eCurType==CURTYPE_SORTER );
pSorter = pCsr->uc.pSorter;
- getVarint32NR((const u8*)&pVal->z[1], t);
+ getVarint32((const u8*)&pVal->z[1], t);
if( t>0 && t<10 && t!=7 ){
pSorter->typeMask &= SORTER_TYPE_INTEGER;
}else if( t>10 && (t & 0x01) ){
pSorter->typeMask &= SORTER_TYPE_TEXT;
}else{
@@ -96413,437 +96117,10 @@
*pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2);
return SQLITE_OK;
}
/************** End of vdbesort.c ********************************************/
-/************** Begin file vdbevtab.c ****************************************/
-/*
-** 2020-03-23
-**
-** 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 implements virtual-tables for examining the bytecode content
-** of a prepared statement.
-*/
-/* #include "sqliteInt.h" */
-#if defined(SQLITE_ENABLE_BYTECODE_VTAB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
-/* #include "vdbeInt.h" */
-
-/* An instance of the bytecode() table-valued function.
-*/
-typedef struct bytecodevtab bytecodevtab;
-struct bytecodevtab {
- sqlite3_vtab base; /* Base class - must be first */
- sqlite3 *db; /* Database connection */
- int bTablesUsed; /* 2 for tables_used(). 0 for bytecode(). */
-};
-
-/* A cursor for scanning through the bytecode
-*/
-typedef struct bytecodevtab_cursor bytecodevtab_cursor;
-struct bytecodevtab_cursor {
- sqlite3_vtab_cursor base; /* Base class - must be first */
- sqlite3_stmt *pStmt; /* The statement whose bytecode is displayed */
- int iRowid; /* The rowid of the output table */
- int iAddr; /* Address */
- int needFinalize; /* Cursors owns pStmt and must finalize it */
- int showSubprograms; /* Provide a listing of subprograms */
- Op *aOp; /* Operand array */
- char *zP4; /* Rendered P4 value */
- const char *zType; /* tables_used.type */
- const char *zSchema; /* tables_used.schema */
- const char *zName; /* tables_used.name */
- Mem sub; /* Subprograms */
-};
-
-/*
-** Create a new bytecode() table-valued function.
-*/
-static int bytecodevtabConnect(
- sqlite3 *db,
- void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVtab,
- char **pzErr
-){
- bytecodevtab *pNew;
- int rc;
- int isTabUsed = pAux!=0;
- const char *azSchema[2] = {
- /* bytecode() schema */
- "CREATE TABLE x("
- "addr INT,"
- "opcode TEXT,"
- "p1 INT,"
- "p2 INT,"
- "p3 INT,"
- "p4 TEXT,"
- "p5 INT,"
- "comment TEXT,"
- "subprog TEXT,"
- "stmt HIDDEN"
- ");",
-
- /* Tables_used() schema */
- "CREATE TABLE x("
- "type TEXT,"
- "schema TEXT,"
- "name TEXT,"
- "wr INT,"
- "subprog TEXT,"
- "stmt HIDDEN"
- ");"
- };
-
- rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]);
- if( rc==SQLITE_OK ){
- pNew = sqlite3_malloc( sizeof(*pNew) );
- *ppVtab = (sqlite3_vtab*)pNew;
- if( pNew==0 ) return SQLITE_NOMEM;
- memset(pNew, 0, sizeof(*pNew));
- pNew->db = db;
- pNew->bTablesUsed = isTabUsed*2;
- }
- return rc;
-}
-
-/*
-** This method is the destructor for bytecodevtab objects.
-*/
-static int bytecodevtabDisconnect(sqlite3_vtab *pVtab){
- bytecodevtab *p = (bytecodevtab*)pVtab;
- sqlite3_free(p);
- return SQLITE_OK;
-}
-
-/*
-** Constructor for a new bytecodevtab_cursor object.
-*/
-static int bytecodevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
- bytecodevtab *pVTab = (bytecodevtab*)p;
- bytecodevtab_cursor *pCur;
- pCur = sqlite3_malloc( sizeof(*pCur) );
- if( pCur==0 ) return SQLITE_NOMEM;
- memset(pCur, 0, sizeof(*pCur));
- sqlite3VdbeMemInit(&pCur->sub, pVTab->db, 1);
- *ppCursor = &pCur->base;
- return SQLITE_OK;
-}
-
-/*
-** Clear all internal content from a bytecodevtab cursor.
-*/
-static void bytecodevtabCursorClear(bytecodevtab_cursor *pCur){
- sqlite3_free(pCur->zP4);
- pCur->zP4 = 0;
- sqlite3VdbeMemRelease(&pCur->sub);
- sqlite3VdbeMemSetNull(&pCur->sub);
- if( pCur->needFinalize ){
- sqlite3_finalize(pCur->pStmt);
- }
- pCur->pStmt = 0;
- pCur->needFinalize = 0;
- pCur->zType = 0;
- pCur->zSchema = 0;
- pCur->zName = 0;
-}
-
-/*
-** Destructor for a bytecodevtab_cursor.
-*/
-static int bytecodevtabClose(sqlite3_vtab_cursor *cur){
- bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
- bytecodevtabCursorClear(pCur);
- sqlite3_free(pCur);
- return SQLITE_OK;
-}
-
-
-/*
-** Advance a bytecodevtab_cursor to its next row of output.
-*/
-static int bytecodevtabNext(sqlite3_vtab_cursor *cur){
- bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
- bytecodevtab *pTab = (bytecodevtab*)cur->pVtab;
- int rc;
- if( pCur->zP4 ){
- sqlite3_free(pCur->zP4);
- pCur->zP4 = 0;
- }
- if( pCur->zName ){
- pCur->zName = 0;
- pCur->zType = 0;
- pCur->zSchema = 0;
- }
- rc = sqlite3VdbeNextOpcode(
- (Vdbe*)pCur->pStmt,
- pCur->showSubprograms ? &pCur->sub : 0,
- pTab->bTablesUsed,
- &pCur->iRowid,
- &pCur->iAddr,
- &pCur->aOp);
- if( rc!=SQLITE_OK ){
- sqlite3VdbeMemSetNull(&pCur->sub);
- pCur->aOp = 0;
- }
- return SQLITE_OK;
-}
-
-/*
-** Return TRUE if the cursor has been moved off of the last
-** row of output.
-*/
-static int bytecodevtabEof(sqlite3_vtab_cursor *cur){
- bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
- return pCur->aOp==0;
-}
-
-/*
-** Return values of columns for the row at which the bytecodevtab_cursor
-** is currently pointing.
-*/
-static int bytecodevtabColumn(
- sqlite3_vtab_cursor *cur, /* The cursor */
- sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
- int i /* Which column to return */
-){
- bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
- bytecodevtab *pVTab = (bytecodevtab*)cur->pVtab;
- Op *pOp = pCur->aOp + pCur->iAddr;
- if( pVTab->bTablesUsed ){
- if( i==4 ){
- i = 8;
- }else{
- if( i<=2 && pCur->zType==0 ){
- Schema *pSchema;
- HashElem *k;
- int iDb = pOp->p3;
- int iRoot = pOp->p2;
- sqlite3 *db = pVTab->db;
- pSchema = db->aDb[iDb].pSchema;
- pCur->zSchema = db->aDb[iDb].zDbSName;
- for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
- Table *pTab = (Table*)sqliteHashData(k);
- if( !IsVirtual(pTab) && pTab->tnum==iRoot ){
- pCur->zName = pTab->zName;
- pCur->zType = "table";
- break;
- }
- }
- if( pCur->zName==0 ){
- for(k=sqliteHashFirst(&pSchema->idxHash); k; k=sqliteHashNext(k)){
- Index *pIdx = (Index*)sqliteHashData(k);
- if( pIdx->tnum==iRoot ){
- pCur->zName = pIdx->zName;
- pCur->zType = "index";
- }
- }
- }
- }
- i += 10;
- }
- }
- switch( i ){
- case 0: /* addr */
- sqlite3_result_int(ctx, pCur->iAddr);
- break;
- case 1: /* opcode */
- sqlite3_result_text(ctx, (char*)sqlite3OpcodeName(pOp->opcode),
- -1, SQLITE_STATIC);
- break;
- case 2: /* p1 */
- sqlite3_result_int(ctx, pOp->p1);
- break;
- case 3: /* p2 */
- sqlite3_result_int(ctx, pOp->p2);
- break;
- case 4: /* p3 */
- sqlite3_result_int(ctx, pOp->p3);
- break;
- case 5: /* p4 */
- case 7: /* comment */
- if( pCur->zP4==0 ){
- pCur->zP4 = sqlite3VdbeDisplayP4(pVTab->db, pOp);
- }
- if( i==5 ){
- sqlite3_result_text(ctx, pCur->zP4, -1, SQLITE_STATIC);
- }else{
-#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
- char *zCom = sqlite3VdbeDisplayComment(pVTab->db, pOp, pCur->zP4);
- sqlite3_result_text(ctx, zCom, -1, sqlite3_free);
-#endif
- }
- break;
- case 6: /* p5 */
- sqlite3_result_int(ctx, pOp->p5);
- break;
- case 8: { /* subprog */
- Op *aOp = pCur->aOp;
- assert( aOp[0].opcode==OP_Init );
- assert( aOp[0].p4.z==0 || strncmp(aOp[0].p4.z,"-" "- ",3)==0 );
- if( pCur->iRowid==pCur->iAddr+1 ){
- break; /* Result is NULL for the main program */
- }else if( aOp[0].p4.z!=0 ){
- sqlite3_result_text(ctx, aOp[0].p4.z+3, -1, SQLITE_STATIC);
- }else{
- sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC);
- }
- break;
- }
- case 10: /* tables_used.type */
- sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC);
- break;
- case 11: /* tables_used.schema */
- sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC);
- break;
- case 12: /* tables_used.name */
- sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC);
- break;
- case 13: /* tables_used.wr */
- sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite);
- break;
- }
- return SQLITE_OK;
-}
-
-/*
-** Return the rowid for the current row. In this implementation, the
-** rowid is the same as the output value.
-*/
-static int bytecodevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
- bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
- *pRowid = pCur->iRowid;
- return SQLITE_OK;
-}
-
-/*
-** Initialize a cursor.
-**
-** idxNum==0 means show all subprograms
-** idxNum==1 means show only the main bytecode and omit subprograms.
-*/
-static int bytecodevtabFilter(
- sqlite3_vtab_cursor *pVtabCursor,
- int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv
-){
- bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor;
- bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab;
- int rc = SQLITE_OK;
-
- bytecodevtabCursorClear(pCur);
- pCur->iRowid = 0;
- pCur->iAddr = 0;
- pCur->showSubprograms = idxNum==0;
- assert( argc==1 );
- if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){
- const char *zSql = (const char*)sqlite3_value_text(argv[0]);
- if( zSql==0 ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pStmt, 0);
- pCur->needFinalize = 1;
- }
- }else{
- pCur->pStmt = (sqlite3_stmt*)sqlite3_value_pointer(argv[0],"stmt-pointer");
- }
- if( pCur->pStmt==0 ){
- pVTab->base.zErrMsg = sqlite3_mprintf(
- "argument to %s() is not a valid SQL statement",
- pVTab->bTablesUsed ? "tables_used" : "bytecode"
- );
- rc = SQLITE_ERROR;
- }else{
- bytecodevtabNext(pVtabCursor);
- }
- return rc;
-}
-
-/*
-** We must have a single stmt=? constraint that will be passed through
-** into the xFilter method. If there is no valid stmt=? constraint,
-** then return an SQLITE_CONSTRAINT error.
-*/
-static int bytecodevtabBestIndex(
- sqlite3_vtab *tab,
- sqlite3_index_info *pIdxInfo
-){
- int i;
- int rc = SQLITE_CONSTRAINT;
- struct sqlite3_index_constraint *p;
- bytecodevtab *pVTab = (bytecodevtab*)tab;
- int iBaseCol = pVTab->bTablesUsed ? 4 : 8;
- pIdxInfo->estimatedCost = (double)100;
- pIdxInfo->estimatedRows = 100;
- pIdxInfo->idxNum = 0;
- for(i=0, p=pIdxInfo->aConstraint; inConstraint; i++, p++){
- if( p->usable==0 ) continue;
- if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==iBaseCol+1 ){
- rc = SQLITE_OK;
- pIdxInfo->aConstraintUsage[i].omit = 1;
- pIdxInfo->aConstraintUsage[i].argvIndex = 1;
- }
- if( p->op==SQLITE_INDEX_CONSTRAINT_ISNULL && p->iColumn==iBaseCol ){
- pIdxInfo->aConstraintUsage[i].omit = 1;
- pIdxInfo->idxNum = 1;
- }
- }
- return rc;
-}
-
-/*
-** This following structure defines all the methods for the
-** virtual table.
-*/
-static sqlite3_module bytecodevtabModule = {
- /* iVersion */ 0,
- /* xCreate */ 0,
- /* xConnect */ bytecodevtabConnect,
- /* xBestIndex */ bytecodevtabBestIndex,
- /* xDisconnect */ bytecodevtabDisconnect,
- /* xDestroy */ 0,
- /* xOpen */ bytecodevtabOpen,
- /* xClose */ bytecodevtabClose,
- /* xFilter */ bytecodevtabFilter,
- /* xNext */ bytecodevtabNext,
- /* xEof */ bytecodevtabEof,
- /* xColumn */ bytecodevtabColumn,
- /* xRowid */ bytecodevtabRowid,
- /* xUpdate */ 0,
- /* xBegin */ 0,
- /* xSync */ 0,
- /* xCommit */ 0,
- /* xRollback */ 0,
- /* xFindMethod */ 0,
- /* xRename */ 0,
- /* xSavepoint */ 0,
- /* xRelease */ 0,
- /* xRollbackTo */ 0,
- /* xShadowName */ 0
-};
-
-
-SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){
- int rc;
- rc = sqlite3_create_module(db, "bytecode", &bytecodevtabModule, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_module(db, "tables_used", &bytecodevtabModule, &db);
- }
- return rc;
-}
-#elif defined(SQLITE_ENABLE_BYTECODE_VTAB)
-SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){ return SQLITE_OK; }
-#endif /* SQLITE_ENABLE_BYTECODE_VTAB */
-
-/************** End of vdbevtab.c ********************************************/
/************** Begin file memjournal.c **************************************/
/*
** 2008 October 7
**
** The author disclaims copyright to this source code. In place of
@@ -97431,20 +96708,19 @@
SrcList *pSrc;
int i;
struct SrcList_item *pItem;
pSrc = p->pSrc;
- if( pSrc ){
- for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
- return WRC_Abort;
- }
- if( pItem->fg.isTabFunc
- && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
- ){
- return WRC_Abort;
- }
+ assert( pSrc!=0 );
+ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
+ if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
+ return WRC_Abort;
+ }
+ if( pItem->fg.isTabFunc
+ && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
+ ){
+ return WRC_Abort;
}
}
return WRC_Continue;
}
@@ -97483,47 +96759,10 @@
p = p->pPrior;
}while( p!=0 );
return WRC_Continue;
}
-/* Increase the walkerDepth when entering a subquery, and
-** descrease when leaving the subquery.
-*/
-SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){
- UNUSED_PARAMETER(pSelect);
- pWalker->walkerDepth++;
- return WRC_Continue;
-}
-SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker *pWalker, Select *pSelect){
- UNUSED_PARAMETER(pSelect);
- pWalker->walkerDepth--;
-}
-
-
-/*
-** No-op routine for the parse-tree walker.
-**
-** 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
-** subquery in the parser tree.
-*/
-SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- return WRC_Continue;
-}
-
-/*
-** No-op routine for the parse-tree walker for SELECT statements.
-** subquery in the parser tree.
-*/
-SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- return WRC_Continue;
-}
-
/************** End of walker.c **********************************************/
/************** Begin file resolve.c *****************************************/
/*
** 2008 August 18
**
@@ -97548,12 +96787,10 @@
** This needs to occur when copying a TK_AGG_FUNCTION node from an
** outer query into an inner subquery.
**
** incrAggFunctionDepth(pExpr,n) is the main routine. incrAggDepth(..)
** is a helper function - a callback for the tree walker.
-**
-** See also the sqlite3WindowExtraAggFuncDepth() routine in window.c
*/
static int incrAggDepth(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n;
return WRC_Continue;
}
@@ -97666,11 +96903,11 @@
const char *zTab,
const char *zDb
){
int n;
const char *zSpan;
- if( pItem->eEName!=ENAME_TAB ) return 0;
+ if( NEVER(pItem->eEName!=ENAME_TAB) ) return 0;
zSpan = pItem->zEName;
for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
return 0;
}
@@ -97701,35 +96938,10 @@
/* Currently parsing a DML statement */
return (db->flags & SQLITE_DqsDML)!=0;
}
}
-/*
-** The argument is guaranteed to be a non-NULL Expr node of type TK_COLUMN.
-** return the appropriate colUsed mask.
-*/
-SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr *pExpr){
- int n;
- Table *pExTab;
-
- n = pExpr->iColumn;
- pExTab = pExpr->y.pTab;
- assert( pExTab!=0 );
- if( (pExTab->tabFlags & TF_HasGenerated)!=0
- && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
- ){
- testcase( pExTab->nCol==BMS-1 );
- testcase( pExTab->nCol==BMS );
- return pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1;
- }else{
- testcase( n==BMS-1 );
- testcase( n==BMS );
- if( n>=BMS ) n = BMS-1;
- return ((Bitmask)1)<aDb[i].zDbSName,zDb)==0 ){
pSchema = db->aDb[i].pSchema;
break;
}
}
- if( i==db->nDb && sqlite3StrICmp("main", zDb)==0 ){
- /* This branch is taken when the main database has been renamed
- ** using SQLITE_DBCONFIG_MAINDBNAME. */
- pSchema = db->aDb[0].pSchema;
- zDb = db->aDb[0].zDbSName;
- }
}
}
/* Start at the inner-most context and move outward until a match is found */
assert( pNC && cnt==0 );
@@ -97820,11 +97026,10 @@
ExprList *pEList;
SrcList *pSrcList = pNC->pSrcList;
if( pSrcList ){
for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){
- u8 hCol;
pTab = pItem->pTab;
assert( pTab!=0 && pTab->zName!=0 );
assert( pTab->nCol>0 );
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
int hit = 0;
@@ -97854,13 +97059,12 @@
}
}
if( 0==(cntTab++) ){
pMatch = pItem;
}
- hCol = sqlite3StrIHash(zCol);
for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){
- if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){
+ if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
/* If there has been exactly one prior match and this match
** is for the right-hand table of a NATURAL JOIN or is in a
** USING clause, then skip this match.
*/
if( cnt==1 ){
@@ -97917,15 +97121,14 @@
}
#endif /* SQLITE_OMIT_UPSERT */
if( pTab ){
int iCol;
- u8 hCol = sqlite3StrIHash(zCol);
pSchema = pTab->pSchema;
cntTab++;
for(iCol=0, pCol=pTab->aCol; iColnCol; iCol++, pCol++){
- if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){
+ if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
if( iCol==pTab->iPKey ){
iCol = -1;
}
break;
}
@@ -98131,11 +97334,26 @@
**
** If a generated column is referenced, set bits for every column
** of the table.
*/
if( pExpr->iColumn>=0 && pMatch!=0 ){
- pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
+ int n = pExpr->iColumn;
+ Table *pExTab = pExpr->y.pTab;
+ assert( pExTab!=0 );
+ assert( pMatch->iCursor==pExpr->iTable );
+ if( (pExTab->tabFlags & TF_HasGenerated)!=0
+ && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
+ ){
+ testcase( pExTab->nCol==BMS-1 );
+ testcase( pExTab->nCol==BMS );
+ pMatch->colUsed = pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1;
+ }else{
+ testcase( n==BMS-1 );
+ testcase( n==BMS );
+ if( n>=BMS ) n = BMS-1;
+ pMatch->colUsed |= ((Bitmask)1)<pLeft);
@@ -98596,11 +97814,11 @@
case TK_ISNOT: {
Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
assert( !ExprHasProperty(pExpr, EP_Reduced) );
/* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
** and "x IS NOT FALSE". */
- if( pRight && pRight->op==TK_ID ){
+ if( pRight->op==TK_ID ){
int rc = resolveExprStep(pWalker, pRight);
if( rc==WRC_Abort ) return WRC_Abort;
if( pRight->op==TK_TRUEFALSE ){
pExpr->op2 = pExpr->op;
pExpr->op = TK_TRUTH;
@@ -98722,11 +97940,11 @@
nc.uNC.pEList = pEList;
nc.ncFlags = NC_AllowAgg|NC_UEList;
nc.nErr = 0;
db = pParse->db;
savedSuppErr = db->suppressErr;
- if( IN_RENAME_OBJECT==0 ) db->suppressErr = 1;
+ db->suppressErr = 1;
rc = sqlite3ResolveExprNames(&nc, pE);
db->suppressErr = savedSuppErr;
if( rc ) return 0;
/* Try to match the ORDER BY expression against an expression
@@ -99357,45 +98575,15 @@
SQLITE_PRIVATE int sqlite3ResolveExprListNames(
NameContext *pNC, /* Namespace to resolve expressions in. */
ExprList *pList /* The expression list to be analyzed. */
){
int i;
- int savedHasAgg = 0;
- Walker w;
- if( pList==0 ) return WRC_Continue;
- w.pParse = pNC->pParse;
- w.xExprCallback = resolveExprStep;
- w.xSelectCallback = resolveSelectStep;
- w.xSelectCallback2 = 0;
- w.u.pNC = pNC;
- savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
- pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
- for(i=0; inExpr; i++){
- Expr *pExpr = pList->a[i].pExpr;
- if( pExpr==0 ) continue;
-#if SQLITE_MAX_EXPR_DEPTH>0
- w.pParse->nHeight += pExpr->nHeight;
- if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
- return WRC_Abort;
- }
-#endif
- sqlite3WalkExpr(&w, pExpr);
-#if SQLITE_MAX_EXPR_DEPTH>0
- w.pParse->nHeight -= pExpr->nHeight;
-#endif
- assert( EP_Agg==NC_HasAgg );
- assert( EP_Win==NC_HasWin );
- testcase( pNC->ncFlags & NC_HasAgg );
- testcase( pNC->ncFlags & NC_HasWin );
- if( pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin) ){
- ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) );
- savedHasAgg |= pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
- pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
+ if( pList ){
+ for(i=0; inExpr; i++){
+ if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort;
}
- if( pNC->nErr>0 || w.pParse->nErr>0 ) return WRC_Abort;
}
- pNC->ncFlags |= savedHasAgg;
return WRC_Continue;
}
/*
** Resolve all names in all expressions of a SELECT and in all
@@ -99522,14 +98710,14 @@
** CREATE TABLE t1(a);
** SELECT * FROM t1 WHERE a;
** SELECT a AS b FROM t1 WHERE b;
** SELECT * FROM t1 WHERE (select a from t1);
*/
-SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){
+SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
int op;
while( ExprHasProperty(pExpr, EP_Skip) ){
- assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
+ assert( pExpr->op==TK_COLLATE );
pExpr = pExpr->pLeft;
assert( pExpr!=0 );
}
op = pExpr->op;
if( op==TK_SELECT ){
@@ -99592,11 +98780,11 @@
/*
** Skip over any TK_COLLATE operators.
*/
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
- assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
+ assert( pExpr->op==TK_COLLATE );
pExpr = pExpr->pLeft;
}
return pExpr;
}
@@ -99611,11 +98799,11 @@
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
assert( pExpr->x.pList->nExpr>0 );
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
}else{
- assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
+ assert( pExpr->op==TK_COLLATE );
pExpr = pExpr->pLeft;
}
}
return pExpr;
}
@@ -99632,14 +98820,14 @@
** The collating sequence might be determined by a COLLATE operator
** or by the presence of a column with a defined collating sequence.
** COLLATE operators take first precedence. Left operands take
** precedence over right operands.
*/
-SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){
+SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
sqlite3 *db = pParse->db;
CollSeq *pColl = 0;
- const Expr *p = pExpr;
+ Expr *p = pExpr;
while( p ){
int op = p->op;
if( op==TK_REGISTER ) op = p->op2;
if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER)
&& p->y.pTab!=0
@@ -99704,32 +98892,32 @@
** See also: sqlite3ExprCollSeq()
**
** The sqlite3ExprCollSeq() routine works the same except that it
** returns NULL if there is no defined collation.
*/
-SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr){
+SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){
CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr);
if( p==0 ) p = pParse->db->pDfltColl;
assert( p!=0 );
return p;
}
/*
** Return TRUE if the two expressions have equivalent collating sequences.
*/
-SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, const Expr *pE1, const Expr *pE2){
+SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){
CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1);
CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2);
return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0;
}
/*
** pExpr is an operand of a comparison operator. aff2 is the
** type affinity of the other operand. This routine returns the
** type affinity that should be used for the comparison operator.
*/
-SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2){
+SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2){
char aff1 = sqlite3ExprAffinity(pExpr);
if( aff1>SQLITE_AFF_NONE && aff2>SQLITE_AFF_NONE ){
/* Both sides of the comparison are columns. If one has numeric
** affinity, use that. Otherwise use no affinity.
*/
@@ -99747,11 +98935,11 @@
/*
** pExpr is a comparison operator. Return the type affinity that should
** be applied to both operands prior to doing the comparison.
*/
-static char comparisonAffinity(const Expr *pExpr){
+static char comparisonAffinity(Expr *pExpr){
char aff;
assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT );
assert( pExpr->pLeft );
@@ -99770,11 +98958,11 @@
** pExpr is a comparison expression, eg. '=', '<', IN(...) etc.
** idx_affinity is the affinity of an indexed column. Return true
** if the index with affinity idx_affinity may be used to implement
** the comparison in pExpr.
*/
-SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity){
+SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
char aff = comparisonAffinity(pExpr);
if( affflags & EP_Collate ){
pColl = sqlite3ExprCollSeq(pParse, pLeft);
@@ -99835,11 +99019,11 @@
** This is normally just a wrapper around sqlite3BinaryCompareCollSeq().
** However, if the OP_Commuted flag is set, then the order of the operands
** is reversed in the sqlite3BinaryCompareCollSeq() call so that the
** correct collating sequence is found.
*/
-SQLITE_PRIVATE CollSeq *sqlite3ExprCompareCollSeq(Parse *pParse, const Expr *p){
+SQLITE_PRIVATE CollSeq *sqlite3ExprCompareCollSeq(Parse *pParse, Expr *p){
if( ExprHasProperty(p, EP_Commuted) ){
return sqlite3BinaryCompareCollSeq(pParse, p->pRight, p->pLeft);
}else{
return sqlite3BinaryCompareCollSeq(pParse, p->pLeft, p->pRight);
}
@@ -100078,11 +99262,10 @@
int regRight = 0;
u8 opx = op;
int addrDone = sqlite3VdbeMakeLabel(pParse);
int isCommuted = ExprHasProperty(pExpr,EP_Commuted);
- assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
if( pParse->nErr ) return;
if( nLeft!=sqlite3ExprVectorSize(pRight) ){
sqlite3ErrorMsg(pParse, "row value misused");
return;
}
@@ -100691,11 +99874,11 @@
nSize = EXPR_FULLSIZE;
}else{
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
assert( !ExprHasProperty(p, EP_FromJoin) );
assert( !ExprHasProperty(p, EP_MemToken) );
- assert( !ExprHasVVAProperty(p, EP_NoReduce) );
+ assert( !ExprHasProperty(p, EP_NoReduce) );
if( p->pLeft || p->x.pList ){
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
}else{
assert( p->pRight==0 );
nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
@@ -100796,14 +99979,10 @@
/* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
pNew->flags |= staticFlag;
- ExprClearVVAProperties(pNew);
- if( dupFlags ){
- ExprSetVVAProperty(pNew, EP_Immutable);
- }
/* Copy the p->u.zToken string, if any. */
if( nToken ){
char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
memcpy(zToken, p->u.zToken, nToken);
@@ -101267,26 +100446,20 @@
ExprList *pList, /* List to which to add the span. */
Token *pName, /* Name to be added */
int dequote /* True to cause the name to be dequoted */
){
assert( pList!=0 || pParse->db->mallocFailed!=0 );
- assert( pParse->eParseMode!=PARSE_MODE_UNMAP || dequote==0 );
if( pList ){
struct ExprList_item *pItem;
assert( pList->nExpr>0 );
pItem = &pList->a[pList->nExpr-1];
assert( pItem->zEName==0 );
assert( pItem->eEName==ENAME_NAME );
pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
- if( dequote ){
- /* If dequote==0, then pName->z does not point to part of a DDL
- ** statement handled by the parser. And so no token need be added
- ** to the token-map. */
- sqlite3Dequote(pItem->zEName);
- if( IN_RENAME_OBJECT ){
- sqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName);
- }
+ if( dequote ) sqlite3Dequote(pItem->zEName);
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName);
}
}
}
/*
@@ -101582,11 +100755,11 @@
** (3) the expression does not contain any EP_FixedCol TK_COLUMN
** operands created by the constant propagation optimization.
**
** When this routine returns true, it indicates that the expression
** can be added to the pParse->pConstExpr list and evaluated once when
-** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce().
+** the prepared statement starts up. See sqlite3ExprCodeAtInit().
*/
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
return exprIsConst(p, 2, 0);
}
@@ -102345,11 +101518,10 @@
return;
}
/* Begin coding the subroutine */
ExprSetProperty(pExpr, EP_Subrtn);
- assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
pExpr->y.sub.regReturn = ++pParse->nMem;
pExpr->y.sub.iAddr =
sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
VdbeComment((v, "return address"));
@@ -102427,12 +101599,10 @@
struct ExprList_item *pItem;
int r1, r2;
affinity = sqlite3ExprAffinity(pLeft);
if( affinity<=SQLITE_AFF_NONE ){
affinity = SQLITE_AFF_BLOB;
- }else if( affinity==SQLITE_AFF_REAL ){
- affinity = SQLITE_AFF_NUMERIC;
}
if( pKeyInfo ){
assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
}
@@ -102667,13 +101837,11 @@
int destStep6 = 0; /* Start of code for Step 6 */
int addrTruthOp; /* Address of opcode that determines the IN is true */
int destNotNull; /* Jump here if a comparison is not true in step 6 */
int addrTop; /* Top of the step-6 loop */
int iTab = 0; /* Index to use */
- u8 okConstFactor = pParse->okConstFactor;
- assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
pLeft = pExpr->pLeft;
if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
zAff = exprINAffinity(pParse, pExpr);
nVector = sqlite3ExprVectorSize(pExpr->pLeft);
aiMap = (int*)sqlite3DbMallocZero(
@@ -102712,18 +101880,12 @@
**
** sqlite3FindInIndex() might have reordered the fields of the LHS vector
** so that the fields are in the same order as an existing index. The
** aiMap[] array contains a mapping from the original LHS field order to
** the field order that matches the RHS index.
- **
- ** Avoid factoring the LHS of the IN(...) expression out of the loop,
- ** even if it is constant, as OP_Affinity may be used on the register
- ** by code generated below. */
- assert( pParse->okConstFactor==okConstFactor );
- pParse->okConstFactor = 0;
+ */
rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
- pParse->okConstFactor = okConstFactor;
for(i=0; ipLeft);
int labelOk = sqlite3VdbeMakeLabel(pParse);
int r2, regToFree;
int regCkNull = 0;
int ii;
+ int bLhsReal; /* True if the LHS of the IN has REAL affinity */
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
if( destIfNull!=destIfFalse ){
regCkNull = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
}
+ bLhsReal = sqlite3ExprAffinity(pExpr->pLeft)==SQLITE_AFF_REAL;
for(ii=0; iinExpr; ii++){
- r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree);
+ if( bLhsReal ){
+ r2 = regToFree = sqlite3GetTempReg(pParse);
+ sqlite3ExprCode(pParse, pList->a[ii].pExpr, r2);
+ sqlite3VdbeAddOp4(v, OP_Affinity, r2, 1, 0, "E", P4_STATIC);
+ }else{
+ r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree);
+ }
if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){
sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull);
}
sqlite3ReleaseTempReg(pParse, regToFree);
if( iinExpr-1 || destIfNull!=destIfFalse ){
@@ -102994,11 +102164,11 @@
if( pParse->iSelfTab>0 ){
iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut);
}else{
iAddr = 0;
}
- sqlite3ExprCodeCopy(pParse, pCol->pDflt, regOut);
+ sqlite3ExprCode(pParse, pCol->pDflt, regOut);
if( pCol->affinity>=SQLITE_AFF_TEXT ){
sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1);
}
if( iAddr ) sqlite3VdbeJumpHere(v, iAddr);
}
@@ -103135,20 +102305,10 @@
}
}
return iResult;
}
-/*
-** If the last opcode is a OP_Copy, then set the do-not-merge flag (p5)
-** so that a subsequent copy will not be merged into this one.
-*/
-static void setDoNotMergeFlagOnCopy(Vdbe *v){
- if( sqlite3VdbeGetOp(v, -1)->opcode==OP_Copy ){
- sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */
- }
-}
-
/*
** Generate code to implement special SQL functions that are implemented
** in-line rather than by using the usual callbacks.
*/
static int exprCodeInlineFunction(
@@ -103176,21 +102336,16 @@
for(i=1; ia[i].pExpr, target);
}
- setDoNotMergeFlagOnCopy(v);
+ if( sqlite3VdbeGetOp(v, -1)->opcode==OP_Copy ){
+ sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */
+ }
sqlite3VdbeResolveLabel(v, endCoalesce);
break;
}
- case INLINEFUNC_iif: {
- Expr caseExpr;
- memset(&caseExpr, 0, sizeof(caseExpr));
- caseExpr.op = TK_CASE;
- caseExpr.x.pList = pFarg;
- return sqlite3ExprCodeTarget(pParse, &caseExpr, target);
- }
default: {
/* The UNLIKELY() function is a no-op. The result is the value
** of the first argument.
*/
@@ -103285,35 +102440,22 @@
expr_code_doover:
if( pExpr==0 ){
op = TK_NULL;
}else{
- assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
op = pExpr->op;
}
switch( op ){
case TK_AGG_COLUMN: {
AggInfo *pAggInfo = pExpr->pAggInfo;
- struct AggInfo_col *pCol;
- assert( pAggInfo!=0 );
- assert( pExpr->iAgg>=0 && pExpr->iAggnColumn );
- pCol = &pAggInfo->aCol[pExpr->iAgg];
+ struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
if( !pAggInfo->directMode ){
assert( pCol->iMem>0 );
return pCol->iMem;
}else if( pAggInfo->useSortingIdx ){
- Table *pTab = pCol->pTab;
sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
pCol->iSorterColumn, target);
- if( pCol->iColumn<0 ){
- VdbeComment((v,"%s.rowid",pTab->zName));
- }else{
- VdbeComment((v,"%s.%s",pTab->zName,pTab->aCol[pCol->iColumn].zName));
- if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){
- sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
- }
- }
return target;
}
/* Otherwise, fall thru into the TK_COLUMN case */
}
case TK_COLUMN: {
@@ -103335,10 +102477,14 @@
}
if( aff>SQLITE_AFF_BLOB ){
static const char zAff[] = "B\000C\000D\000E";
assert( SQLITE_AFF_BLOB=='A' );
assert( SQLITE_AFF_TEXT=='B' );
+ if( iReg!=target ){
+ sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target);
+ iReg = target;
+ }
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0,
&zAff[(aff-'B')*2], P4_STATIC);
}
return iReg;
}
@@ -103548,11 +102694,10 @@
#endif
}else{
tempX.op = TK_INTEGER;
tempX.flags = EP_IntValue|EP_TokenOnly;
tempX.u.iValue = 0;
- ExprClearVVAProperties(&tempX);
r1 = sqlite3ExprCodeTemp(pParse, &tempX, ®Free1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2);
sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
testcase( regFree2==0 );
}
@@ -103594,14 +102739,11 @@
sqlite3VdbeJumpHere(v, addr);
break;
}
case TK_AGG_FUNCTION: {
AggInfo *pInfo = pExpr->pAggInfo;
- if( pInfo==0
- || NEVER(pExpr->iAgg<0)
- || NEVER(pExpr->iAgg>=pInfo->nFunc)
- ){
+ if( pInfo==0 ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
}else{
return pInfo->aFunc[pExpr->iAgg].iMem;
}
@@ -103623,17 +102765,20 @@
return pExpr->y.pWin->regResult;
}
#endif
if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
- /* SQL functions can be expensive. So try to avoid running them
- ** multiple times if we know they always give the same result */
- return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
+ /* SQL functions can be expensive. So try to move constant functions
+ ** out of the inner loop, even if that means an extra OP_Copy. */
+ return sqlite3ExprCodeAtInit(pParse, pExpr, -1);
}
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- assert( !ExprHasProperty(pExpr, EP_TokenOnly) );
- pFarg = pExpr->x.pList;
+ if( ExprHasProperty(pExpr, EP_TokenOnly) ){
+ pFarg = 0;
+ }else{
+ pFarg = pExpr->x.pList;
+ }
nFarg = pFarg ? pFarg->nExpr : 0;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
zId = pExpr->u.zToken;
pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
@@ -103964,22 +103109,21 @@
sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
}
sqlite3ExprDelete(db, pDel);
- setDoNotMergeFlagOnCopy(v);
sqlite3VdbeResolveLabel(v, endLabel);
break;
}
#ifndef SQLITE_OMIT_TRIGGER
case TK_RAISE: {
assert( pExpr->affExpr==OE_Rollback
|| pExpr->affExpr==OE_Abort
|| pExpr->affExpr==OE_Fail
|| pExpr->affExpr==OE_Ignore
);
- if( !pParse->pTriggerTab && !pParse->nested ){
+ if( !pParse->pTriggerTab ){
sqlite3ErrorMsg(pParse,
"RAISE() may only be used within a trigger-program");
return 0;
}
if( pExpr->affExpr==OE_Abort ){
@@ -103989,13 +103133,12 @@
if( pExpr->affExpr==OE_Ignore ){
sqlite3VdbeAddOp4(
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
VdbeCoverage(v);
}else{
- sqlite3HaltConstraint(pParse,
- pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR,
- pExpr->affExpr, pExpr->u.zToken, 0, 0);
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
+ pExpr->affExpr, pExpr->u.zToken, 0, 0);
}
break;
}
#endif
@@ -104004,27 +103147,19 @@
sqlite3ReleaseTempReg(pParse, regFree2);
return inReg;
}
/*
-** Generate code that will evaluate expression pExpr just one time
-** per prepared statement execution.
-**
-** If the expression uses functions (that might throw an exception) then
-** guard them with an OP_Once opcode to ensure that the code is only executed
-** once. If no functions are involved, then factor the code out and put it at
-** the end of the prepared statement in the initialization section.
+** Factor out the code of the given expression to initialization time.
**
** If regDest>=0 then the result is always stored in that register and the
** result is not reusable. If regDest<0 then this routine is free to
** store the value whereever it wants. The register where the expression
-** is stored is returned. When regDest<0, two identical expressions might
-** code to the same register, if they do not contain function calls and hence
-** are factored out into the initialization section at the end of the
-** prepared statement.
+** is stored is returned. When regDest<0, two identical expressions will
+** code to the same register.
*/
-SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(
+SQLITE_PRIVATE int sqlite3ExprCodeAtInit(
Parse *pParse, /* Parsing context */
Expr *pExpr, /* The expression to code when the VDBE initializes */
int regDest /* Store the value in this register */
){
ExprList *p;
@@ -104038,33 +103173,18 @@
return pItem->u.iConstExprReg;
}
}
}
pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
- if( pExpr!=0 && ExprHasProperty(pExpr, EP_HasFunc) ){
- Vdbe *v = pParse->pVdbe;
- int addr;
- assert( v );
- addr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
- pParse->okConstFactor = 0;
- if( !pParse->db->mallocFailed ){
- if( regDest<0 ) regDest = ++pParse->nMem;
- sqlite3ExprCode(pParse, pExpr, regDest);
- }
- pParse->okConstFactor = 1;
- sqlite3ExprDelete(pParse->db, pExpr);
- sqlite3VdbeJumpHere(v, addr);
- }else{
- p = sqlite3ExprListAppend(pParse, p, pExpr);
- if( p ){
- struct ExprList_item *pItem = &p->a[p->nExpr-1];
- pItem->reusable = regDest<0;
- if( regDest<0 ) regDest = ++pParse->nMem;
- pItem->u.iConstExprReg = regDest;
- }
- pParse->pConstExpr = p;
+ p = sqlite3ExprListAppend(pParse, p, pExpr);
+ if( p ){
+ struct ExprList_item *pItem = &p->a[p->nExpr-1];
+ pItem->reusable = regDest<0;
+ if( regDest<0 ) regDest = ++pParse->nMem;
+ pItem->u.iConstExprReg = regDest;
}
+ pParse->pConstExpr = p;
return regDest;
}
/*
** Generate code to evaluate an expression and store the results
@@ -104085,11 +103205,11 @@
if( ConstFactorOk(pParse)
&& pExpr->op!=TK_REGISTER
&& sqlite3ExprIsConstantNotJoin(pExpr)
){
*pReg = 0;
- r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
+ r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1);
}else{
int r1 = sqlite3GetTempReg(pParse);
r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
if( r2==r1 ){
*pReg = r1;
@@ -104107,11 +103227,10 @@
** in register target.
*/
SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
int inReg;
- assert( pExpr==0 || !ExprHasVVAProperty(pExpr,EP_Immutable) );
assert( target>0 && target<=pParse->nMem );
inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
if( inReg!=target && pParse->pVdbe ){
u8 op;
@@ -104142,13 +103261,13 @@
** in register target. If the expression is constant, then this routine
** might choose to code the expression at initialization time.
*/
SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){
- sqlite3ExprCodeRunJustOnce(pParse, pExpr, target);
+ sqlite3ExprCodeAtInit(pParse, pExpr, target);
}else{
- sqlite3ExprCodeCopy(pParse, pExpr, target);
+ sqlite3ExprCode(pParse, pExpr, target);
}
}
/*
** Generate code that pushes the value of every element of the given
@@ -104202,11 +103321,11 @@
sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
}
}else if( (flags & SQLITE_ECEL_FACTOR)!=0
&& sqlite3ExprIsConstantNotJoin(pExpr)
){
- sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i);
+ sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
}else{
int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
if( inReg!=target+i ){
VdbeOp *pOp;
if( copyOp==OP_Copy
@@ -104325,11 +103444,10 @@
int r1, r2;
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
if( NEVER(pExpr==0) ) return; /* No way this can happen */
- assert( !ExprHasVVAProperty(pExpr, EP_Immutable) );
op = pExpr->op;
switch( op ){
case TK_AND:
case TK_OR: {
Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
@@ -104467,11 +103585,10 @@
int r1, r2;
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
if( pExpr==0 ) return;
- assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
/* The value of pExpr->op and op are related as follows:
**
** pExpr->op op
** --------- ----------
@@ -104751,22 +103868,36 @@
return 2;
}
}
if( (pA->flags & (EP_Distinct|EP_Commuted))
!= (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2;
- if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
+ if( (combinedFlags & EP_TokenOnly)==0 ){
if( combinedFlags & EP_xIsSelect ) return 2;
if( (combinedFlags & EP_FixedCol)==0
&& sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
if( pA->op!=TK_STRING
&& pA->op!=TK_TRUEFALSE
- && ALWAYS((combinedFlags & EP_Reduced)==0)
+ && (combinedFlags & EP_Reduced)==0
){
if( pA->iColumn!=pB->iColumn ) return 2;
- if( pA->op2!=pB->op2 && pA->op==TK_TRUTH ) return 2;
+ if( pA->op2!=pB->op2 ){
+ if( pA->op==TK_TRUTH ) return 2;
+ if( pA->op==TK_FUNCTION && iTab<0 ){
+ /* Ex: CREATE TABLE t1(a CHECK( aop!=TK_IN && pA->iTable!=pB->iTable && pA->iTable!=iTab ){
return 2;
}
}
}
@@ -105000,29 +104131,23 @@
case TK_EQ:
case TK_NE:
case TK_LT:
case TK_LE:
case TK_GT:
- case TK_GE: {
- Expr *pLeft = pExpr->pLeft;
- Expr *pRight = pExpr->pRight;
+ case TK_GE:
testcase( pExpr->op==TK_EQ );
testcase( pExpr->op==TK_NE );
testcase( pExpr->op==TK_LT );
testcase( pExpr->op==TK_LE );
testcase( pExpr->op==TK_GT );
testcase( pExpr->op==TK_GE );
- /* The y.pTab=0 assignment in wherecode.c always happens after the
- ** impliesNotNullRow() test */
- if( (pLeft->op==TK_COLUMN && ALWAYS(pLeft->y.pTab!=0)
- && IsVirtual(pLeft->y.pTab))
- || (pRight->op==TK_COLUMN && ALWAYS(pRight->y.pTab!=0)
- && IsVirtual(pRight->y.pTab))
+ if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
+ || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
){
- return WRC_Prune;
+ return WRC_Prune;
}
- }
+
default:
return WRC_Continue;
}
}
@@ -105353,10 +104478,19 @@
}
}
}
return WRC_Continue;
}
+static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
+ UNUSED_PARAMETER(pSelect);
+ pWalker->walkerDepth++;
+ return WRC_Continue;
+}
+static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){
+ UNUSED_PARAMETER(pSelect);
+ pWalker->walkerDepth--;
+}
/*
** Analyze the pExpr expression looking for aggregate functions and
** for variables that need to be added to AggInfo object that pNC->pAggInfo
** points to. Additional entries are made on the AggInfo object as
@@ -105366,12 +104500,12 @@
** analyzed by sqlite3ResolveExprNames().
*/
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
Walker w;
w.xExprCallback = analyzeAggregate;
- w.xSelectCallback = sqlite3WalkerDepthIncrease;
- w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
+ w.xSelectCallback = analyzeAggregatesInSelect;
+ w.xSelectCallback2 = analyzeAggregatesInSelectEnd;
w.walkerDepth = 0;
w.u.pNC = pNC;
w.pParse = 0;
assert( pNC->pSrcList!=0 );
sqlite3WalkExpr(&w, pExpr);
@@ -105606,14 +104740,11 @@
if( !zName ) goto exit_rename_table;
/* Check that a table or index named 'zName' does not already exist
** in database iDb. If so, this is an error.
*/
- if( sqlite3FindTable(db, zName, zDb)
- || sqlite3FindIndex(db, zName, zDb)
- || sqlite3IsShadowTableOf(db, pTab, zName)
- ){
+ if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
sqlite3ErrorMsg(pParse,
"there is already another table or index with this name: %s", zName);
goto exit_rename_table;
}
@@ -105741,26 +104872,10 @@
sqlite3SrcListDelete(db, pSrc);
sqlite3DbFree(db, zName);
db->mDbFlags = savedDbFlags;
}
-/*
-** Write code that will raise an error if the table described by
-** zDb and zTab is not empty.
-*/
-static void sqlite3ErrorIfNotEmpty(
- Parse *pParse, /* Parsing context */
- const char *zDb, /* Schema holding the table */
- const char *zTab, /* Table to check for empty */
- const char *zErr /* Error message text */
-){
- sqlite3NestedParse(pParse,
- "SELECT raise(ABORT,%Q) FROM \"%w\".\"%w\"",
- zErr, zDb, zTab
- );
-}
-
/*
** This function is called after an "ALTER TABLE ... ADD" statement
** has been parsed. Argument pColDef contains the text of the new
** column definition.
**
@@ -105809,12 +104924,11 @@
if( pCol->colFlags & COLFLAG_PRIMKEY ){
sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
return;
}
if( pNew->pIndex ){
- sqlite3ErrorMsg(pParse,
- "Cannot add a UNIQUE column");
+ sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
return;
}
if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){
/* If the default value for the new column was specified with a
** literal NULL, then set pDflt to 0. This simplifies checking
@@ -105823,19 +104937,20 @@
assert( pDflt==0 || pDflt->op==TK_SPAN );
if( pDflt && pDflt->pLeft->op==TK_NULL ){
pDflt = 0;
}
if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
- sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
+ sqlite3ErrorMsg(pParse,
"Cannot add a REFERENCES column with non-NULL default value");
+ return;
}
if( pCol->notNull && !pDflt ){
- sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
+ sqlite3ErrorMsg(pParse,
"Cannot add a NOT NULL column with default value NULL");
+ return;
}
-
/* Ensure the default expression is something that sqlite3ValueFromExpr()
** can handle (i.e. not CURRENT_TIME etc.)
*/
if( pDflt ){
sqlite3_value *pVal = 0;
@@ -105845,17 +104960,18 @@
if( rc!=SQLITE_OK ){
assert( db->mallocFailed == 1 );
return;
}
if( !pVal ){
- sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
- "Cannot add a column with non-constant default");
+ sqlite3ErrorMsg(pParse,"Cannot add a column with non-constant default");
+ return;
}
sqlite3ValueFree(pVal);
}
}else if( pCol->colFlags & COLFLAG_STORED ){
- sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, "cannot add a STORED column");
+ sqlite3ErrorMsg(pParse, "cannot add a STORED column");
+ return;
}
/* Modify the CREATE TABLE statement. */
zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
@@ -105970,11 +105086,10 @@
}
memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
for(i=0; inCol; i++){
Column *pCol = &pNew->aCol[i];
pCol->zName = sqlite3DbStrDup(db, pCol->zName);
- pCol->hName = sqlite3StrIHash(pCol->zName);
pCol->zColl = 0;
pCol->pDflt = 0;
}
pNew->pSchema = db->aDb[iDb].pSchema;
pNew->addColOffset = pTab->addColOffset;
@@ -106199,11 +105314,11 @@
*/
SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
RenameToken *pNew;
assert( pPtr || pParse->db->mallocFailed );
renameTokenCheckAll(pParse, pPtr);
- if( ALWAYS(pParse->eParseMode!=PARSE_MODE_UNMAP) ){
+ if( pParse->eParseMode!=PARSE_MODE_UNMAP ){
pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
if( pNew ){
pNew->p = pPtr;
pNew->t = *pToken;
pNew->pNext = pParse->pRename;
@@ -106257,25 +105372,10 @@
sqlite3RenameExprlistUnmap(pWalker->pParse, pWith->a[i].pCols);
}
}
}
-/*
-** Unmap all tokens in the IdList object passed as the second argument.
-*/
-static void unmapColumnIdlistNames(
- Parse *pParse,
- IdList *pIdList
-){
- if( pIdList ){
- int ii;
- for(ii=0; iinId; ii++){
- sqlite3RenameTokenRemap(pParse, 0, (void*)pIdList->a[ii].zName);
- }
- }
-}
-
/*
** Walker callback used by sqlite3RenameExprUnmap().
*/
static int renameUnmapSelectCb(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
@@ -106293,11 +105393,10 @@
if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */
SrcList *pSrc = p->pSrc;
for(i=0; inSrc; i++){
sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
if( sqlite3WalkExpr(pWalker, pSrc->a[i].pOn) ) return WRC_Abort;
- unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing);
}
}
renameWalkWith(pWalker, p);
return WRC_Continue;
@@ -106502,11 +105601,10 @@
}
}
}
}
-
/*
** Parse the SQL statement zSql using Parse object (*p). The Parse object
** is initialized by this function before it is used.
*/
static int renameParseSql(
@@ -107414,15 +106512,10 @@
sqlite3 *db = pParse->db;
Db *pDb;
Vdbe *v = sqlite3GetVdbe(pParse);
int aRoot[ArraySize(aTable)];
u8 aCreateTbl[ArraySize(aTable)];
-#ifdef SQLITE_ENABLE_STAT4
- const int nToOpen = OptimizationEnabled(db,SQLITE_Stat4) ? 2 : 1;
-#else
- const int nToOpen = 1;
-#endif
if( v==0 ) return;
assert( sqlite3BtreeHoldsAllMutexes(db) );
assert( sqlite3VdbeDb(v)==db );
pDb = &db->aDb[iDb];
@@ -107431,13 +106524,12 @@
** if they do already exist.
*/
for(i=0; izDbSName))==0 ){
- if( iregRoot. This is important
** because the OpenWrite opcode below will be needing it. */
sqlite3NestedParse(pParse,
@@ -107449,10 +106541,11 @@
}else{
/* 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;
+ aCreateTbl[i] = 0;
sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
if( zWhere ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE %s=%Q",
pDb->zDbSName, zTab, zWhereType, zWhere
@@ -107467,11 +106560,11 @@
}
}
}
/* Open the sqlite_stat[134] tables for writing. */
- for(i=0; inRowid ){
sqlite3DbFree(db, p->u.aRowid);
p->nRowid = 0;
}
@@ -107541,11 +106629,11 @@
#endif
/* Initialize the BLOB value of a ROWID
*/
#ifdef SQLITE_ENABLE_STAT4
-static void sampleSetRowid(sqlite3 *db, StatSample *p, int n, const u8 *pData){
+static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
assert( db!=0 );
if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
p->u.aRowid = sqlite3DbMallocRawNN(db, n);
if( p->u.aRowid ){
p->nRowid = n;
@@ -107557,11 +106645,11 @@
#endif
/* Initialize the INTEGER value of a ROWID.
*/
#ifdef SQLITE_ENABLE_STAT4
-static void sampleSetRowidInt64(sqlite3 *db, StatSample *p, i64 iRowid){
+static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
assert( db!=0 );
if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
p->nRowid = 0;
p->u.iRowid = iRowid;
}
@@ -107570,11 +106658,11 @@
/*
** Copy the contents of object (*pFrom) into (*pTo).
*/
#ifdef SQLITE_ENABLE_STAT4
-static void sampleCopy(StatAccum *p, StatSample *pTo, StatSample *pFrom){
+static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
pTo->isPSample = pFrom->isPSample;
pTo->iCol = pFrom->iCol;
pTo->iHash = pFrom->iHash;
memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol);
memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol);
@@ -107586,61 +106674,59 @@
}
}
#endif
/*
-** Reclaim all memory of a StatAccum structure.
+** Reclaim all memory of a Stat4Accum structure.
*/
-static void statAccumDestructor(void *pOld){
- StatAccum *p = (StatAccum*)pOld;
+static void stat4Destructor(void *pOld){
+ Stat4Accum *p = (Stat4Accum*)pOld;
#ifdef SQLITE_ENABLE_STAT4
- if( p->mxSample ){
- int i;
- for(i=0; inCol; i++) sampleClear(p->db, p->aBest+i);
- for(i=0; imxSample; i++) sampleClear(p->db, p->a+i);
- sampleClear(p->db, &p->current);
- }
+ int i;
+ for(i=0; inCol; i++) sampleClear(p->db, p->aBest+i);
+ for(i=0; imxSample; i++) sampleClear(p->db, p->a+i);
+ sampleClear(p->db, &p->current);
#endif
sqlite3DbFree(p->db, p);
}
/*
-** Implementation of the stat_init(N,K,C,L) SQL function. The four parameters
+** Implementation of the stat_init(N,K,C) SQL function. The three parameters
** are:
** N: The number of columns in the index including the rowid/pk (note 1)
** K: The number of columns in the index excluding the rowid/pk.
-** C: Estimated number of rows in the index
-** L: A limit on the number of rows to scan, or 0 for no-limit
+** C: The number of rows in the index (note 2)
**
** Note 1: In the special case of the covering index that implements a
** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
** total number of columns in the table.
**
+** Note 2: C is only used for STAT4.
+**
** For indexes on ordinary rowid tables, N==K+1. But for indexes on
** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
** PRIMARY KEY of the table. The covering index that implements the
** original WITHOUT ROWID table as N==K as a special case.
**
-** This routine allocates the StatAccum object in heap memory. The return
-** value is a pointer to the StatAccum object. The datatype of the
-** return value is BLOB, but it is really just a pointer to the StatAccum
+** This routine allocates the Stat4Accum object in heap memory. The return
+** value is a pointer to the Stat4Accum object. The datatype of the
+** return value is BLOB, but it is really just a pointer to the Stat4Accum
** object.
*/
static void statInit(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
- StatAccum *p;
+ Stat4Accum *p;
int nCol; /* Number of columns in index being sampled */
int nKeyCol; /* Number of key columns */
int nColUp; /* nCol rounded up for alignment */
int n; /* Bytes of space to allocate */
- sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */
+ sqlite3 *db; /* Database connection */
#ifdef SQLITE_ENABLE_STAT4
- /* Maximum number of samples. 0 if STAT4 data is not collected */
- int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0;
+ int mxSample = SQLITE_STAT4_SAMPLES;
#endif
/* Decode the three function arguments */
UNUSED_PARAMETER(argc);
nCol = sqlite3_value_int(argv[0]);
@@ -107648,51 +106734,47 @@
nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol;
nKeyCol = sqlite3_value_int(argv[1]);
assert( nKeyCol<=nCol );
assert( nKeyCol>0 );
- /* Allocate the space required for the StatAccum object */
+ /* Allocate the space required for the Stat4Accum object */
n = sizeof(*p)
- + sizeof(tRowcnt)*nColUp /* StatAccum.anEq */
- + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */
+ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
+ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
#ifdef SQLITE_ENABLE_STAT4
- if( mxSample ){
- n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
- + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
- + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample);
- }
+ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */
+ + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */
+ + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
#endif
+ ;
db = sqlite3_context_db_handle(context);
p = sqlite3DbMallocZero(db, n);
if( p==0 ){
sqlite3_result_error_nomem(context);
return;
}
p->db = db;
- p->nEst = sqlite3_value_int64(argv[2]);
p->nRow = 0;
- p->nLimit = sqlite3_value_int64(argv[3]);
p->nCol = nCol;
p->nKeyCol = nKeyCol;
- p->nSkipAhead = 0;
p->current.anDLt = (tRowcnt*)&p[1];
p->current.anEq = &p->current.anDLt[nColUp];
#ifdef SQLITE_ENABLE_STAT4
- p->mxSample = p->nLimit==0 ? mxSample : 0;
- if( mxSample ){
+ {
u8 *pSpace; /* Allocated space not yet assigned */
int i; /* Used to iterate through p->aSample[] */
p->iGet = -1;
- p->nPSample = (tRowcnt)(p->nEst/(mxSample/3+1) + 1);
+ p->mxSample = mxSample;
+ p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
p->current.anLt = &p->current.anEq[nColUp];
p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
- /* Set up the StatAccum.a[] and aBest[] arrays */
- p->a = (struct StatSample*)&p->current.anLt[nColUp];
+ /* Set up the Stat4Accum.a[] and aBest[] arrays */
+ p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
p->aBest = &p->a[mxSample];
pSpace = (u8*)(&p->a[mxSample+nCol]);
for(i=0; i<(mxSample+nCol); i++){
p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
@@ -107708,14 +106790,14 @@
/* Return a pointer to the allocated object to the caller. Note that
** only the pointer (the 2nd parameter) matters. The size of the object
** (given by the 3rd parameter) is never used and can be any positive
** value. */
- sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor);
+ sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor);
}
static const FuncDef statInitFuncdef = {
- 4, /* nArg */
+ 2+IsStat4, /* nArg */
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
statInit, /* xSFunc */
0, /* xFinalize */
@@ -107735,13 +106817,13 @@
**
** This function assumes that for each argument sample, the contents of
** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid.
*/
static int sampleIsBetterPost(
- StatAccum *pAccum,
- StatSample *pNew,
- StatSample *pOld
+ Stat4Accum *pAccum,
+ Stat4Sample *pNew,
+ Stat4Sample *pOld
){
int nCol = pAccum->nCol;
int i;
assert( pNew->iCol==pOld->iCol );
for(i=pNew->iCol+1; ianEq[pSample->iCol] onwards are valid.
*/
static int sampleIsBetter(
- StatAccum *pAccum,
- StatSample *pNew,
- StatSample *pOld
+ Stat4Accum *pAccum,
+ Stat4Sample *pNew,
+ Stat4Sample *pOld
){
tRowcnt nEqNew = pNew->anEq[pNew->iCol];
tRowcnt nEqOld = pOld->anEq[pOld->iCol];
assert( pOld->isPSample==0 && pNew->isPSample==0 );
@@ -107781,34 +106863,34 @@
/*
** Copy the contents of sample *pNew into the p->a[] array. If necessary,
** remove the least desirable sample from p->a[] to make room.
*/
-static void sampleInsert(StatAccum *p, StatSample *pNew, int nEqZero){
- StatSample *pSample = 0;
+static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
+ Stat4Sample *pSample = 0;
int i;
assert( IsStat4 || nEqZero==0 );
- /* StatAccum.nMaxEqZero is set to the maximum number of leading 0
- ** values in the anEq[] array of any sample in StatAccum.a[]. In
+ /* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
+ ** values in the anEq[] array of any sample in Stat4Accum.a[]. In
** other words, if nMaxEqZero is n, then it is guaranteed that there
- ** are no samples with StatSample.anEq[m]==0 for (m>=n). */
+ ** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */
if( nEqZero>p->nMaxEqZero ){
p->nMaxEqZero = nEqZero;
}
if( pNew->isPSample==0 ){
- StatSample *pUpgrade = 0;
+ Stat4Sample *pUpgrade = 0;
assert( pNew->anEq[pNew->iCol]>0 );
/* This sample is being added because the prefix that ends in column
** iCol occurs many times in the table. However, if we have already
** added a sample that shares this prefix, there is no need to add
** this one. Instead, upgrade the priority of the highest priority
** existing sample that shares this prefix. */
for(i=p->nSample-1; i>=0; i--){
- StatSample *pOld = &p->a[i];
+ Stat4Sample *pOld = &p->a[i];
if( pOld->anEq[pNew->iCol]==0 ){
if( pOld->isPSample ) return;
assert( pOld->iCol>pNew->iCol );
assert( sampleIsBetter(p, pNew, pOld) );
if( pUpgrade==0 || sampleIsBetter(p, pOld, pUpgrade) ){
@@ -107823,11 +106905,11 @@
}
}
/* If necessary, remove sample iMin to make room for the new sample. */
if( p->nSample>=p->mxSample ){
- StatSample *pMin = &p->a[p->iMin];
+ Stat4Sample *pMin = &p->a[p->iMin];
tRowcnt *anEq = pMin->anEq;
tRowcnt *anLt = pMin->anLt;
tRowcnt *anDLt = pMin->anDLt;
sampleClear(p->db, pMin);
memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1));
@@ -107866,24 +106948,24 @@
p->iMin = iMin;
}
}
#endif /* SQLITE_ENABLE_STAT4 */
-#ifdef SQLITE_ENABLE_STAT4
/*
** Field iChng of the index being scanned has changed. So at this point
** p->current contains a sample that reflects the previous row of the
** index. The value of anEq[iChng] and subsequent anEq[] elements are
** correct at this point.
*/
-static void samplePushPrevious(StatAccum *p, int iChng){
+static void samplePushPrevious(Stat4Accum *p, int iChng){
+#ifdef SQLITE_ENABLE_STAT4
int i;
/* Check if any samples from the aBest[] array should be pushed
** into IndexSample.a[] at this point. */
for(i=(p->nCol-2); i>=iChng; i--){
- StatSample *pBest = &p->aBest[i];
+ Stat4Sample *pBest = &p->aBest[i];
pBest->anEq[i] = p->current.anEq[i];
if( p->nSamplemxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){
sampleInsert(p, pBest, i);
}
}
@@ -107903,29 +106985,31 @@
if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
}
}
p->nMaxEqZero = iChng;
}
+#endif
+
+#ifndef SQLITE_ENABLE_STAT4
+ UNUSED_PARAMETER( p );
+ UNUSED_PARAMETER( iChng );
+#endif
}
-#endif /* SQLITE_ENABLE_STAT4 */
/*
** Implementation of the stat_push SQL function: stat_push(P,C,R)
** Arguments:
**
-** P Pointer to the StatAccum object created by stat_init()
+** P Pointer to the Stat4Accum object created by stat_init()
** C Index of left-most column to differ from previous row
** R Rowid for the current row. Might be a key record for
** WITHOUT ROWID tables.
**
-** The purpose of this routine is to collect statistical data and/or
-** samples from the index being analyzed into the StatAccum object.
-** The stat_get() SQL function will be used afterwards to
-** retrieve the information gathered.
-**
-** This SQL function usually returns NULL, but might return an integer
-** if it wants the byte-code to do special processing.
+** This SQL function always returns NULL. It's purpose it to accumulate
+** statistical data and/or samples in the Stat4Accum object about the
+** index being analyzed. The stat_get() SQL function will later be used to
+** extract relevant information for constructing the sqlite_statN tables.
**
** The R parameter is only used for STAT4
*/
static void statPush(
sqlite3_context *context,
@@ -107933,11 +107017,11 @@
sqlite3_value **argv
){
int i;
/* The three function arguments */
- StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]);
+ Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
int iChng = sqlite3_value_int(argv[1]);
UNUSED_PARAMETER( argc );
UNUSED_PARAMETER( context );
assert( p->nCol>0 );
@@ -107946,41 +107030,40 @@
if( p->nRow==0 ){
/* This is the first call to this function. Do initialization. */
for(i=0; inCol; i++) p->current.anEq[i] = 1;
}else{
/* Second and subsequent calls get processed here */
-#ifdef SQLITE_ENABLE_STAT4
- if( p->mxSample ) samplePushPrevious(p, iChng);
-#endif
+ samplePushPrevious(p, iChng);
/* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
** to the current row of the index. */
for(i=0; icurrent.anEq[i]++;
}
for(i=iChng; inCol; i++){
p->current.anDLt[i]++;
#ifdef SQLITE_ENABLE_STAT4
- if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i];
+ p->current.anLt[i] += p->current.anEq[i];
#endif
p->current.anEq[i] = 1;
}
}
-
p->nRow++;
#ifdef SQLITE_ENABLE_STAT4
- if( p->mxSample ){
- tRowcnt nLt;
- if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
- sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
- }else{
- sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
- sqlite3_value_blob(argv[2]));
- }
- p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
+ if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
+ sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
+ }else{
+ sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
+ sqlite3_value_blob(argv[2]));
+ }
+ p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
+#endif
+
+#ifdef SQLITE_ENABLE_STAT4
+ {
+ tRowcnt nLt = p->current.anLt[p->nCol-1];
- nLt = p->current.anLt[p->nCol-1];
/* Check if this is to be a periodic sample. If so, add it. */
if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
p->current.isPSample = 1;
p->current.iCol = 0;
sampleInsert(p, &p->current, p->nCol-1);
@@ -107992,18 +107075,13 @@
p->current.iCol = i;
if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){
sampleCopy(p, &p->aBest[i], &p->current);
}
}
- }else
-#endif
- if( p->nLimit && p->nRow>(tRowcnt)p->nLimit*(p->nSkipAhead+1) ){
- p->nSkipAhead++;
- sqlite3_result_int(context, p->current.anDLt[0]>0);
}
+#endif
}
-
static const FuncDef statPushFuncdef = {
2+IsStat4, /* nArg */
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
@@ -108021,19 +107099,19 @@
#define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */
/*
** Implementation of the stat_get(P,J) SQL function. This routine is
** used to query statistical information that has been gathered into
-** the StatAccum object by prior calls to stat_push(). The P parameter
-** has type BLOB but it is really just a pointer to the StatAccum object.
+** the Stat4Accum object by prior calls to stat_push(). The P parameter
+** has type BLOB but it is really just a pointer to the Stat4Accum object.
** The content to returned is determined by the parameter J
** which is one of the STAT_GET_xxxx values defined above.
**
** The stat_get(P,J) function is not available to generic SQL. It is
** inserted as part of a manually constructed bytecode program. (See
** the callStatGet() routine below.) It is guaranteed that the P
-** parameter will always be a pointer to a StatAccum object, never a
+** parameter will always be a poiner to a Stat4Accum object, never a
** NULL.
**
** If STAT4 is not enabled, then J is always
** STAT_GET_STAT1 and is hence omitted and this routine becomes
** a one-parameter function, stat_get(P), that always returns the
@@ -108042,20 +107120,19 @@
static void statGet(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
- StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]);
+ Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
#ifdef SQLITE_ENABLE_STAT4
/* STAT4 has a parameter on this routine. */
int eCall = sqlite3_value_int(argv[1]);
assert( argc==2 );
assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ
|| eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
|| eCall==STAT_GET_NDLT
);
- assert( eCall==STAT_GET_STAT1 || p->mxSample );
if( eCall==STAT_GET_STAT1 )
#else
assert( argc==1 );
#endif
{
@@ -108064,11 +107141,11 @@
**
** The value is a string composed of a list of integers describing
** the index. The first integer in the list is the total number of
** entries in the index. There is one additional integer in the list
** for each indexed column. This additional integer is an estimate of
- ** the number of rows matched by a equality query on the index using
+ ** the number of rows matched by a stabbing query on the index using
** a key with the corresponding number of fields. In other words,
** if the index is on columns (a,b) and the sqlite_stat1 value is
** "100 10 2", then SQLite estimates that:
**
** * the index contains 100 rows,
@@ -108087,12 +107164,11 @@
if( zRet==0 ){
sqlite3_result_error_nomem(context);
return;
}
- sqlite3_snprintf(24, zRet, "%llu",
- p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
+ sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
z = zRet + sqlite3Strlen30(zRet);
for(i=0; inKeyCol; i++){
u64 nDistinct = p->current.anDLt[i] + 1;
u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
sqlite3_snprintf(24, z, " %llu", iVal);
@@ -108108,11 +107184,11 @@
if( p->iGet<0 ){
samplePushPrevious(p, 0);
p->iGet = 0;
}
if( p->iGetnSample ){
- StatSample *pS = p->a + p->iGet;
+ Stat4Sample *pS = p->a + p->iGet;
if( pS->nRowid==0 ){
sqlite3_result_int64(context, pS->u.iRowid);
}else{
sqlite3_result_blob(context, pS->u.aRowid, pS->nRowid,
SQLITE_TRANSIENT);
@@ -108164,20 +107240,20 @@
0, 0, /* xValue, xInverse */
"stat_get", /* zName */
{0}
};
-static void callStatGet(Parse *pParse, int regStat, int iParam, int regOut){
+static void callStatGet(Parse *pParse, int regStat4, int iParam, int regOut){
#ifdef SQLITE_ENABLE_STAT4
- sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat+1);
+ sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat4+1);
#elif SQLITE_DEBUG
assert( iParam==STAT_GET_STAT1 );
#else
UNUSED_PARAMETER( iParam );
#endif
- assert( regOut!=regStat && regOut!=regStat+1 );
- sqlite3VdbeAddFunctionCall(pParse, 0, regStat, regOut, 1+IsStat4,
+ assert( regOut!=regStat4 && regOut!=regStat4+1 );
+ sqlite3VdbeAddFunctionCall(pParse, 0, regStat4, regOut, 1+IsStat4,
&statGetFuncdef, 0);
}
/*
** Generate code to do an analysis of all indices associated with
@@ -108199,15 +107275,16 @@
int i; /* Loop counter */
int jZeroRows = -1; /* Jump from here if number of rows is zero */
int iDb; /* Index of database containing pTab */
u8 needTableCnt = 1; /* True to count the table */
int regNewRowid = iMem++; /* Rowid for the inserted record */
- int regStat = iMem++; /* Register to hold StatAccum object */
+ int regStat4 = iMem++; /* Register to hold Stat4Accum object */
int regChng = iMem++; /* Index of changed index field */
+#ifdef SQLITE_ENABLE_STAT4
int regRowid = iMem++; /* Rowid argument passed to stat_push() */
+#endif
int regTemp = iMem++; /* Temporary use register */
- int regTemp2 = iMem++; /* Second temporary use register */
int regTabname = iMem++; /* Register containing table name */
int regIdxname = iMem++; /* Register containing index name */
int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
int regPrev = iMem; /* MUST BE LAST (see below) */
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -108331,40 +107408,33 @@
/* Invoke the stat_init() function. The arguments are:
**
** (1) the number of columns in the index including the rowid
** (or for a WITHOUT ROWID table, the number of PK columns),
** (2) the number of columns in the key without the rowid/pk
- ** (3) estimated number of rows in the index,
+ ** (3) the number of rows in the index,
+ **
+ **
+ ** The third argument is only used for STAT4
*/
- sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1);
- assert( regRowid==regStat+2 );
- sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid);
#ifdef SQLITE_ENABLE_STAT4
- if( OptimizationEnabled(db, SQLITE_Stat4) ){
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp);
- addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
- VdbeCoverage(v);
- }else
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
#endif
- {
- addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
- VdbeCoverage(v);
- sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1);
- }
- assert( regTemp2==regStat+4 );
- sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2);
- sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4,
+ sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
+ sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
+ sqlite3VdbeAddFunctionCall(pParse, 0, regStat4+1, regStat4, 2+IsStat4,
&statInitFuncdef, 0);
/* Implementation of the following:
**
** Rewind csr
** if eof(csr) goto end_of_scan;
** regChng = 0
** goto next_push_0;
**
*/
+ addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
+ VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
addrNextRow = sqlite3VdbeCurrentAddr(v);
if( nColTest>0 ){
int endDistinctTest = sqlite3VdbeMakeLabel(pParse);
@@ -108393,11 +107463,10 @@
}
for(i=0; iazColl[i]);
sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
- VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
aGotoChng[i] =
sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
VdbeCoverage(v);
}
@@ -108414,11 +107483,10 @@
*/
sqlite3VdbeJumpHere(v, addrNextRow-1);
for(i=0; izName, i));
}
sqlite3VdbeResolveLabel(v, endDistinctTest);
sqlite3DbFree(db, aGotoChng);
}
@@ -108428,50 +107496,34 @@
** stat_push(P, regChng, regRowid) // 3rd parameter STAT4 only
** Next csr
** if !eof(csr) goto next_row;
*/
#ifdef SQLITE_ENABLE_STAT4
- if( OptimizationEnabled(db, SQLITE_Stat4) ){
- assert( regRowid==(regStat+2) );
- if( HasRowid(pTab) ){
- sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
- }else{
- Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
- int j, k, regKey;
- regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
- for(j=0; jnKeyCol; j++){
- k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
- assert( k>=0 && knColumn );
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
- VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
- }
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
- sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
+ assert( regRowid==(regStat4+2) );
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
+ int j, k, regKey;
+ regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
+ for(j=0; jnKeyCol; j++){
+ k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
+ assert( k>=0 && knColumn );
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
+ VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
}
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
+ sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
}
#endif
- assert( regChng==(regStat+1) );
- {
- sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
- &statPushFuncdef, 0);
- if( db->nAnalysisLimit ){
- int j1, j2, j3;
- j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp); VdbeCoverage(v);
- j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp); VdbeCoverage(v);
- j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1);
- VdbeCoverage(v);
- sqlite3VdbeJumpHere(v, j1);
- sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
- sqlite3VdbeJumpHere(v, j2);
- sqlite3VdbeJumpHere(v, j3);
- }else{
- sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
- }
- }
+ assert( regChng==(regStat4+1) );
+ sqlite3VdbeAddFunctionCall(pParse, 1, regStat4, regTemp, 2+IsStat4,
+ &statPushFuncdef, 0);
+ sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
/* Add the entry to the stat1 table. */
- callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);
+ callStatGet(pParse, regStat4, STAT_GET_STAT1, regStat1);
assert( "BBB"[0]==SQLITE_AFF_TEXT );
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -108479,11 +107531,11 @@
#endif
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
/* Add the entries to the stat4 table. */
#ifdef SQLITE_ENABLE_STAT4
- if( OptimizationEnabled(db, SQLITE_Stat4) && db->nAnalysisLimit==0 ){
+ {
int regEq = regStat1;
int regLt = regStat1+1;
int regDLt = regStat1+2;
int regSample = regStat1+3;
int regCol = regStat1+4;
@@ -108493,16 +107545,16 @@
u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
pParse->nMem = MAX(pParse->nMem, regCol+nCol);
addrNext = sqlite3VdbeCurrentAddr(v);
- callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid);
+ callStatGet(pParse, regStat4, STAT_GET_ROWID, regSampleRowid);
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
VdbeCoverage(v);
- callStatGet(pParse, regStat, STAT_GET_NEQ, regEq);
- callStatGet(pParse, regStat, STAT_GET_NLT, regLt);
- callStatGet(pParse, regStat, STAT_GET_NDLT, regDLt);
+ callStatGet(pParse, regStat4, STAT_GET_NEQ, regEq);
+ callStatGet(pParse, regStat4, STAT_GET_NLT, regLt);
+ callStatGet(pParse, regStat4, STAT_GET_NDLT, regDLt);
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
VdbeCoverage(v);
for(i=0; iaDb[iDb].zDbSName, zName)==0
- || (iDb==0 && sqlite3StrICmp("main", zName)==0)
- );
-}
-
/*
** An SQL user-function registered to do the work of an ATTACH statement. The
** three arguments to the function come directly from an attach statement:
**
** ATTACH DATABASE x AS y KEY z
@@ -109275,12 +108316,13 @@
db->aLimit[SQLITE_LIMIT_ATTACHED]
);
goto attach_error;
}
for(i=0; inDb; i++){
- assert( zName );
- if( sqlite3DbIsNamed(db, i, zName) ){
+ char *z = db->aDb[i].zDbSName;
+ assert( z && zName );
+ if( sqlite3StrICmp(z, zName)==0 ){
zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
goto attach_error;
}
}
@@ -109344,11 +108386,47 @@
}
pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
if( rc==SQLITE_OK && pNew->zDbSName==0 ){
rc = SQLITE_NOMEM_BKPT;
}
- sqlite3_free_filename( zPath );
+
+
+#ifdef SQLITE_HAS_CODEC
+ if( rc==SQLITE_OK ){
+ extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
+ extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
+ int nKey;
+ char *zKey;
+ int t = sqlite3_value_type(argv[2]);
+ switch( t ){
+ case SQLITE_INTEGER:
+ case SQLITE_FLOAT:
+ zErrDyn = sqlite3DbStrDup(db, "Invalid key value");
+ rc = SQLITE_ERROR;
+ break;
+
+ case SQLITE_TEXT:
+ case SQLITE_BLOB:
+ nKey = sqlite3_value_bytes(argv[2]);
+ zKey = (char *)sqlite3_value_blob(argv[2]);
+ rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
+ break;
+
+ case SQLITE_NULL:
+ /* No key specified. Use the key from URI filename, or if none,
+ ** use the key from the main database. */
+ if( sqlite3CodecQueryParameters(db, zName, zPath)==0 ){
+ sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
+ if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
+ rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
+ }
+ }
+ break;
+ }
+ }
+#endif
+ sqlite3_free( zPath );
/* 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
** remove the entry from the db->aDb[] array. i.e. put everything back the
** way we found it.
@@ -109429,11 +108507,11 @@
if( zName==0 ) zName = "";
for(i=0; inDb; i++){
pDb = &db->aDb[i];
if( pDb->pBt==0 ) continue;
- if( sqlite3DbIsNamed(db, i, zName) ) break;
+ if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break;
}
if( i>=db->nDb ){
sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName);
goto detach_error;
@@ -109620,25 +108698,24 @@
SQLITE_PRIVATE int sqlite3FixSrcList(
DbFixer *pFix, /* Context of the fixation */
SrcList *pList /* The Source list to check and modify */
){
int i;
+ const char *zDb;
struct SrcList_item *pItem;
- sqlite3 *db = pFix->pParse->db;
- int iDb = sqlite3FindDbName(db, pFix->zDb);
if( NEVER(pList==0) ) return 0;
-
+ zDb = pFix->zDb;
for(i=0, pItem=pList->a; inSrc; i++, pItem++){
if( pFix->bTemp==0 ){
- if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){
+ if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
sqlite3ErrorMsg(pFix->pParse,
"%s %T cannot reference objects in database %s",
pFix->zType, pFix->pName, pItem->zDatabase);
return 1;
}
- sqlite3DbFree(db, pItem->zDatabase);
+ sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
pItem->zDatabase = 0;
pItem->pSchema = pFix->pSchema;
pItem->fg.fromDDL = 1;
}
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
@@ -110356,43 +109433,26 @@
** exists */
if( db->auth.authLevelnDb; i++){
- if( sqlite3StrICmp(zDatabase, db->aDb[i].zDbSName)==0 ) break;
- }
- if( i>=db->nDb ){
- /* No match against the official names. But always match "main"
- ** to schema 0 as a legacy fallback. */
- if( sqlite3StrICmp(zDatabase,"main")==0 ){
- i = 0;
- }else{
- return 0;
+ while(1){
+ for(i=OMIT_TEMPDB; inDb; i++){
+ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
+ if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){
+ assert( sqlite3SchemaMutexHeld(db, j, 0) );
+ p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
+ if( p ) return p;
}
}
- p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
- if( p==0 && i==1 && sqlite3StrICmp(zName, MASTER_NAME)==0 ){
- /* All temp.sqlite_master to be an alias for sqlite_temp_master */
- p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, TEMP_MASTER_NAME);
- }
- }else{
- /* Match against TEMP first */
- p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, zName);
- if( p ) return p;
- /* The main database is second */
- p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, zName);
- if( p ) return p;
- /* Attached databases are in order of attachment */
- for(i=2; inDb; i++){
- assert( sqlite3SchemaMutexHeld(db, i, 0) );
- p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
- if( p ) break;
- }
+ /* Not found. If the name we were looking for was temp.sqlite_master
+ ** then change the name to sqlite_temp_master and try again. */
+ if( sqlite3StrICmp(zName, MASTER_NAME)!=0 ) break;
+ if( sqlite3_stricmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break;
+ zName = TEMP_MASTER_NAME;
}
- return p;
+ return 0;
}
/*
** Locate the in-memory structure that describes a particular database
** table given the name of that table and (optionally) the name of the
@@ -110498,11 +109558,11 @@
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; inDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
Schema *pSchema = db->aDb[j].pSchema;
assert( pSchema );
- if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
+ if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
p = sqlite3HashFind(&pSchema->idxHash, zName);
if( p ) break;
}
return p;
@@ -110651,11 +109711,10 @@
int i;
Column *pCol;
assert( pTable!=0 );
if( (pCol = pTable->aCol)!=0 ){
for(i=0; inCol; i++, pCol++){
- assert( pCol->zName==0 || pCol->hName==sqlite3StrIHash(pCol->zName) );
sqlite3DbFree(db, pCol->zName);
sqlite3ExprDelete(db, pCol->pDflt);
sqlite3DbFree(db, pCol->zColl);
}
sqlite3DbFree(db, pTable->aCol);
@@ -111300,11 +110359,10 @@
p->aCol = aNew;
}
pCol = &p->aCol[p->nCol];
memset(pCol, 0, sizeof(p->aCol[0]));
pCol->zName = z;
- pCol->hName = sqlite3StrIHash(z);
sqlite3ColumnPropertiesFromName(p, pCol);
if( pType->n==0 ){
/* If there is no type specified, columns have the default affinity
** 'BLOB' with a default size of 4 bytes. */
@@ -112192,32 +111250,10 @@
assert( pPk->nColumn==j );
assert( pTab->nNVCol<=j );
recomputeColumnsNotIndexed(pPk);
}
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/*
-** Return true if pTab is a virtual table and zName is a shadow table name
-** for that virtual table.
-*/
-SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char *zName){
- int nName; /* Length of zName */
- Module *pMod; /* Module for the virtual table */
-
- if( !IsVirtual(pTab) ) return 0;
- nName = sqlite3Strlen30(pTab->zName);
- if( sqlite3_strnicmp(zName, pTab->zName, nName)!=0 ) return 0;
- if( zName[nName]!='_' ) return 0;
- pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
- if( pMod==0 ) return 0;
- if( pMod->pModule->iVersion<3 ) return 0;
- if( pMod->pModule->xShadowName==0 ) return 0;
- return pMod->pModule->xShadowName(zName+nName+1);
-}
-#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
-
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Return true if zName is a shadow table name in the current database
** connection.
**
@@ -112225,48 +111261,27 @@
** restored to its original value prior to this routine returning.
*/
SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
char *zTail; /* Pointer to the last "_" in zName */
Table *pTab; /* Table that zName is a shadow of */
+ Module *pMod; /* Module for the virtual table */
+
zTail = strrchr(zName, '_');
if( zTail==0 ) return 0;
*zTail = 0;
pTab = sqlite3FindTable(db, zName, 0);
*zTail = '_';
if( pTab==0 ) return 0;
if( !IsVirtual(pTab) ) return 0;
- return sqlite3IsShadowTableOf(db, pTab, zName);
+ pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
+ if( pMod==0 ) return 0;
+ if( pMod->pModule->iVersion<3 ) return 0;
+ if( pMod->pModule->xShadowName==0 ) return 0;
+ return pMod->pModule->xShadowName(zTail+1);
}
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
-
-#ifdef SQLITE_DEBUG
-/*
-** Mark all nodes of an expression as EP_Immutable, indicating that
-** they should not be changed. Expressions attached to a table or
-** index definition are tagged this way to help ensure that we do
-** not pass them into code generator routines by mistake.
-*/
-static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){
- ExprSetVVAProperty(pExpr, EP_Immutable);
- return WRC_Continue;
-}
-static void markExprListImmutable(ExprList *pList){
- if( pList ){
- Walker w;
- memset(&w, 0, sizeof(w));
- w.xExprCallback = markImmutableExprStep;
- w.xSelectCallback = sqlite3SelectWalkNoop;
- w.xSelectCallback2 = 0;
- sqlite3WalkExprList(&w, pList);
- }
-}
-#else
-#define markExprListImmutable(X) /* no-op */
-#endif /* SQLITE_DEBUG */
-
-
/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
** The table structure that other action routines have been building
@@ -112355,12 +111370,10 @@
if( pParse->nErr ){
/* If errors are seen, delete the CHECK constraints now, else they might
** actually be used if PRAGMA writable_schema=ON is set. */
sqlite3ExprListDelete(db, p->pCheck);
p->pCheck = 0;
- }else{
- markExprListImmutable(p->pCheck);
}
}
#endif /* !defined(SQLITE_OMIT_CHECK) */
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
if( p->tabFlags & TF_HasGenerated ){
@@ -114708,11 +113721,11 @@
pParse->rc = rc;
return 1;
}
db->aDb[1].pBt = pBt;
assert( db->aDb[1].pSchema );
- if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, 0, 0) ){
+ if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){
sqlite3OomFault(db);
return 1;
}
}
return 0;
@@ -114819,11 +113832,11 @@
char *p4, /* Error message */
i8 p4type, /* P4_STATIC or P4_TRANSIENT */
u8 p5Errmsg /* P5_ErrMsg type */
){
Vdbe *v = sqlite3GetVdbe(pParse);
- assert( (errCode&0xff)==SQLITE_CONSTRAINT || pParse->nested );
+ assert( (errCode&0xff)==SQLITE_CONSTRAINT );
if( onError==OE_Abort ){
sqlite3MayAbort(pParse);
}
sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
sqlite3VdbeChangeP5(v, p5Errmsg);
@@ -115298,34 +114311,21 @@
u8 enc, /* Desired text encoding */
const char *zName, /* Name of the collating sequence. Might be NULL */
int create /* True to create CollSeq if doesn't already exist */
){
CollSeq *pColl;
- assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
- assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
if( zName ){
pColl = findCollSeqEntry(db, zName, create);
- if( pColl ) pColl += enc-1;
}else{
pColl = db->pDfltColl;
}
+ assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
+ assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
+ if( pColl ) pColl += enc-1;
return pColl;
}
-/*
-** Change the text encoding for a database connection. This means that
-** the pDfltColl must change as well.
-*/
-SQLITE_PRIVATE void sqlite3SetTextEncoding(sqlite3 *db, u8 enc){
- assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
- db->enc = enc;
- /* EVIDENCE-OF: R-08308-17224 The default collating function for all
- ** strings is BINARY.
- */
- db->pDfltColl = sqlite3FindCollSeq(db, enc, sqlite3StrBINARY, 0);
-}
-
/*
** 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.
**
@@ -116207,13 +115207,11 @@
testcase( IsVirtual(pTab) );
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE,
iTabCur, aToOpen, &iDataCur, &iIdxCur);
assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
- if( eOnePass==ONEPASS_MULTI ){
- sqlite3VdbeJumpHereOrPopInst(v, iAddrOnce);
- }
+ if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);
}
/* Set up a loop over the rowids/primary-keys that were found in the
** where-clause loop above.
*/
@@ -116532,11 +115530,10 @@
VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
&iPartIdxLabel, pPrior, r1);
sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
- sqlite3VdbeChangeP5(v, 1); /* Cause IdxDelete to error if no entry found */
sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
pPrior = pIdx;
}
}
@@ -117496,11 +116493,10 @@
const unsigned char *zA, *zB;
u32 escape;
int nPat;
sqlite3 *db = sqlite3_context_db_handle(context);
struct compareInfo *pInfo = sqlite3_user_data(context);
- struct compareInfo backupInfo;
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( sqlite3_value_type(argv[0])==SQLITE_BLOB
|| sqlite3_value_type(argv[1])==SQLITE_BLOB
){
@@ -117532,16 +116528,10 @@
sqlite3_result_error(context,
"ESCAPE expression must be a single character", -1);
return;
}
escape = sqlite3Utf8Read(&zEsc);
- if( escape==pInfo->matchAll || escape==pInfo->matchOne ){
- memcpy(&backupInfo, pInfo, sizeof(backupInfo));
- pInfo = &backupInfo;
- if( escape==pInfo->matchAll ) pInfo->matchAll = 0;
- if( escape==pInfo->matchOne ) pInfo->matchOne = 0;
- }
}else{
escape = pInfo->matchSet;
}
zB = sqlite3_value_text(argv[0]);
zA = sqlite3_value_text(argv[1]);
@@ -117926,11 +116916,11 @@
if( (cntExpand&(cntExpand-1))==0 ){
/* Grow the size of the output buffer only on substitutions
** whose index is a power of two: 1, 2, 4, 8, 16, 32, ... */
u8 *zOld;
zOld = zOut;
- zOut = sqlite3Realloc(zOut, (int)nOut + (nOut - nStr - 1));
+ zOut = sqlite3_realloc64(zOut, (int)nOut + (nOut - nStr - 1));
if( zOut==0 ){
sqlite3_result_error_nomem(context);
sqlite3_free(zOld);
return;
}
@@ -118520,33 +117510,29 @@
if( pDef==0 ) return 0;
#endif
if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
return 0;
}
-
- /* The memcpy() statement assumes that the wildcard characters are
- ** the first three statements in the compareInfo structure. The
- ** asserts() that follow verify that assumption
- */
- memcpy(aWc, pDef->pUserData, 3);
- assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
- assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
- assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
-
if( nExpr<3 ){
aWc[3] = 0;
}else{
Expr *pEscape = pExpr->x.pList->a[2].pExpr;
char *zEscape;
if( pEscape->op!=TK_STRING ) return 0;
zEscape = pEscape->u.zToken;
if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
- if( zEscape[0]==aWc[0] ) return 0;
- if( zEscape[0]==aWc[1] ) return 0;
aWc[3] = zEscape[0];
}
+ /* The memcpy() statement assumes that the wildcard characters are
+ ** the first three statements in the compareInfo structure. The
+ ** asserts() that follow verify that assumption
+ */
+ memcpy(aWc, pDef->pUserData, 3);
+ assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
+ assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
+ assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
*pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0;
return 1;
}
/*
@@ -118623,11 +117609,11 @@
FUNCTION(round, 2, 0, 0, roundFunc ),
#endif
FUNCTION(upper, 1, 0, 0, upperFunc ),
FUNCTION(lower, 1, 0, 0, lowerFunc ),
FUNCTION(hex, 1, 0, 0, hexFunc ),
- INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, 0 ),
+ INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, SQLITE_FUNC_COALESCE),
VFUNCTION(random, 0, 0, 0, randomFunc ),
VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
@@ -118663,12 +117649,11 @@
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
FUNCTION(unknown, -1, 0, 0, unknownFunc ),
#endif
FUNCTION(coalesce, 1, 0, 0, 0 ),
FUNCTION(coalesce, 0, 0, 0, 0 ),
- INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ),
- INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ),
+ INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, SQLITE_FUNC_COALESCE),
};
#ifndef SQLITE_OMIT_ALTERTABLE
sqlite3AlterFunctions();
#endif
sqlite3WindowFunctions();
@@ -119352,11 +118337,11 @@
}
/* Clean up the WHERE clause constructed above. */
sqlite3ExprDelete(db, pWhere);
if( iFkIfZero ){
- sqlite3VdbeJumpHereOrPopInst(v, iFkIfZero);
+ sqlite3VdbeJumpHere(v, iFkIfZero);
}
}
/*
** This function returns a linked list of FKey objects (connected by
@@ -121751,11 +120736,11 @@
case OE_Replace: {
int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, iReg);
VdbeCoverage(v);
assert( (pCol->colFlags & COLFLAG_GENERATED)==0 );
nSeenReplace++;
- sqlite3ExprCodeCopy(pParse, pCol->pDflt, iReg);
+ sqlite3ExprCode(pParse, pCol->pDflt, iReg);
sqlite3VdbeJumpHere(v, addr1);
break;
}
case OE_Abort:
sqlite3MayAbort(pParse);
@@ -121806,30 +120791,21 @@
ExprList *pCheck = pTab->pCheck;
pParse->iSelfTab = -(regNewData+1);
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
for(i=0; inExpr; i++){
int allOk;
- Expr *pCopy;
Expr *pExpr = pCheck->a[i].pExpr;
if( aiChng
&& !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
){
/* The check constraints do not reference any of the columns being
** updated so there is no point it verifying the check constraint */
continue;
}
- if( bAffinityDone==0 ){
- sqlite3TableAffinity(v, pTab, regNewData+1);
- bAffinityDone = 1;
- }
allOk = sqlite3VdbeMakeLabel(pParse);
sqlite3VdbeVerifyAbortable(v, onError);
- pCopy = sqlite3ExprDup(db, pExpr, 0);
- if( !db->mallocFailed ){
- sqlite3ExprIfTrue(pParse, pCopy, allOk, SQLITE_JUMPIFNULL);
- }
- sqlite3ExprDelete(db, pCopy);
+ sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
if( onError==OE_Ignore ){
sqlite3VdbeGoto(v, ignoreDest);
}else{
char *zName = pCheck->a[i].zEName;
if( zName==0 ) zName = pTab->zName;
@@ -122089,11 +121065,11 @@
}
if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
sqlite3TableAffinity(v, pTab, regNewData+1);
bAffinityDone = 1;
}
- VdbeNoopComment((v, "prep index %s", pIdx->zName));
+ VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName));
iThisCur = iIdxCur+ix;
/* Skip partial indices for which the WHERE clause is not true */
if( pIdx->pPartIdxWhere ){
@@ -122324,18 +121300,16 @@
** Hence, make a complete copy of the opcode, rather than using
** a pointer to the opcode. */
x = *sqlite3VdbeGetOp(v, addrConflictCk);
if( x.opcode!=OP_IdxRowid ){
int p2; /* New P2 value for copied conflict check opcode */
- const char *zP4;
if( sqlite3OpcodeProperty[x.opcode]&OPFLG_JUMP ){
p2 = lblRecheckOk;
}else{
p2 = x.p2;
}
- zP4 = x.p4type==P4_INT32 ? SQLITE_INT_TO_PTR(x.p4.i) : x.p4.z;
- sqlite3VdbeAddOp4(v, x.opcode, x.p1, p2, x.p3, zP4, x.p4type);
+ sqlite3VdbeAddOp4(v, x.opcode, x.p1, p2, x.p3, x.p4.z, x.p4type);
sqlite3VdbeChangeP5(v, x.p5);
VdbeCoverageIf(v, p2!=x.p2);
}
nConflictCk--;
addrConflictCk++;
@@ -122939,17 +121913,18 @@
addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
}else{
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
assert( (pDest->tabFlags & TF_Autoincrement)==0 );
}
+ sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
if( db->mDbFlags & DBFLAG_Vacuum ){
sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
- insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT;
+ insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|
+ OPFLAG_APPEND|OPFLAG_USESEEKRESULT;
}else{
insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND;
}
- sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid,
(char*)pDest, P4_TABLE);
sqlite3VdbeChangeP5(v, insFlags);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
@@ -122970,10 +121945,11 @@
sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest);
sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
VdbeComment((v, "%s", pDestIdx->zName));
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
if( db->mDbFlags & DBFLAG_Vacuum ){
/* This INSERT command is part of a VACUUM operation, which guarantees
** that the destination table is empty. If all indexed columns use
** collation sequence BINARY, then it can also be assumed that the
** index will be populated by inserting keys in strictly sorted
@@ -122993,14 +121969,14 @@
}
if( i==pSrcIdx->nColumn ){
idxInsFlags = OPFLAG_USESEEKRESULT;
sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
}
- }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
+ }
+ if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
idxInsFlags |= OPFLAG_NCHANGE;
}
- sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData);
sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
@@ -123517,15 +122493,10 @@
sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
const char *(*uri_key)(const char*,int);
const char *(*filename_database)(const char*);
const char *(*filename_journal)(const char*);
const char *(*filename_wal)(const char*);
- /* Version 3.32.0 and later */
- char *(*create_filename)(const char*,const char*,const char*,
- int,const char**);
- void (*free_filename)(char*);
- sqlite3_file *(*database_file_object)(const char*);
};
/*
** This is the function signature used for all extension entry points. It
** is also defined in the file "loadext.c".
@@ -123822,14 +122793,10 @@
#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64
#define sqlite3_uri_key sqlite3_api->uri_key
#define sqlite3_filename_database sqlite3_api->filename_database
#define sqlite3_filename_journal sqlite3_api->filename_journal
#define sqlite3_filename_wal sqlite3_api->filename_wal
-/* Version 3.32.0 and later */
-#define sqlite3_create_filename sqlite3_api->create_filename
-#define sqlite3_free_filename sqlite3_api->free_filename
-#define sqlite3_database_file_object sqlite3_api->database_file_object
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
/* This case when the file really is being compiled as a loadable
** extension */
@@ -124304,24 +123271,12 @@
sqlite3_hard_heap_limit64,
sqlite3_uri_key,
sqlite3_filename_database,
sqlite3_filename_journal,
sqlite3_filename_wal,
- /* Version 3.32.0 and later */
- sqlite3_create_filename,
- sqlite3_free_filename,
- sqlite3_database_file_object,
};
-/* True if x is the directory separator character
-*/
-#if SQLITE_OS_WIN
-# define DirSep(X) ((X)=='/'||(X)=='\\')
-#else
-# define DirSep(X) ((X)=='/')
-#endif
-
/*
** Attempt to load an SQLite extension library contained in the file
** zFile. The entry point is zProc. zProc may be 0 in which case a
** default entry point name (sqlite3_extension_init) is used. Use
** of the default name is recommended.
@@ -124419,11 +123374,11 @@
if( zAltEntry==0 ){
sqlite3OsDlClose(pVfs, handle);
return SQLITE_NOMEM_BKPT;
}
memcpy(zAltEntry, "sqlite3_", 8);
- for(iFile=ncFile-1; iFile>=0 && !DirSep(zFile[iFile]); iFile--){}
+ for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
iFile++;
if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3;
for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){
if( sqlite3Isalpha(c) ){
zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c];
@@ -124722,53 +123677,53 @@
** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
** that script and rerun it.
*/
/* The various pragma types */
-#define PragTyp_ACTIVATE_EXTENSIONS 0
-#define PragTyp_ANALYSIS_LIMIT 1
-#define PragTyp_HEADER_VALUE 2
-#define PragTyp_AUTO_VACUUM 3
-#define PragTyp_FLAG 4
-#define PragTyp_BUSY_TIMEOUT 5
-#define PragTyp_CACHE_SIZE 6
-#define PragTyp_CACHE_SPILL 7
-#define PragTyp_CASE_SENSITIVE_LIKE 8
-#define PragTyp_COLLATION_LIST 9
-#define PragTyp_COMPILE_OPTIONS 10
-#define PragTyp_DATA_STORE_DIRECTORY 11
-#define PragTyp_DATABASE_LIST 12
-#define PragTyp_DEFAULT_CACHE_SIZE 13
-#define PragTyp_ENCODING 14
-#define PragTyp_FOREIGN_KEY_CHECK 15
-#define PragTyp_FOREIGN_KEY_LIST 16
-#define PragTyp_FUNCTION_LIST 17
-#define PragTyp_HARD_HEAP_LIMIT 18
-#define PragTyp_INCREMENTAL_VACUUM 19
-#define PragTyp_INDEX_INFO 20
-#define PragTyp_INDEX_LIST 21
-#define PragTyp_INTEGRITY_CHECK 22
-#define PragTyp_JOURNAL_MODE 23
-#define PragTyp_JOURNAL_SIZE_LIMIT 24
-#define PragTyp_LOCK_PROXY_FILE 25
-#define PragTyp_LOCKING_MODE 26
-#define PragTyp_PAGE_COUNT 27
-#define PragTyp_MMAP_SIZE 28
-#define PragTyp_MODULE_LIST 29
-#define PragTyp_OPTIMIZE 30
-#define PragTyp_PAGE_SIZE 31
-#define PragTyp_PRAGMA_LIST 32
-#define PragTyp_SECURE_DELETE 33
-#define PragTyp_SHRINK_MEMORY 34
-#define PragTyp_SOFT_HEAP_LIMIT 35
-#define PragTyp_SYNCHRONOUS 36
-#define PragTyp_TABLE_INFO 37
-#define PragTyp_TEMP_STORE 38
-#define PragTyp_TEMP_STORE_DIRECTORY 39
-#define PragTyp_THREADS 40
-#define PragTyp_WAL_AUTOCHECKPOINT 41
-#define PragTyp_WAL_CHECKPOINT 42
+#define PragTyp_HEADER_VALUE 0
+#define PragTyp_AUTO_VACUUM 1
+#define PragTyp_FLAG 2
+#define PragTyp_BUSY_TIMEOUT 3
+#define PragTyp_CACHE_SIZE 4
+#define PragTyp_CACHE_SPILL 5
+#define PragTyp_CASE_SENSITIVE_LIKE 6
+#define PragTyp_COLLATION_LIST 7
+#define PragTyp_COMPILE_OPTIONS 8
+#define PragTyp_DATA_STORE_DIRECTORY 9
+#define PragTyp_DATABASE_LIST 10
+#define PragTyp_DEFAULT_CACHE_SIZE 11
+#define PragTyp_ENCODING 12
+#define PragTyp_FOREIGN_KEY_CHECK 13
+#define PragTyp_FOREIGN_KEY_LIST 14
+#define PragTyp_FUNCTION_LIST 15
+#define PragTyp_HARD_HEAP_LIMIT 16
+#define PragTyp_INCREMENTAL_VACUUM 17
+#define PragTyp_INDEX_INFO 18
+#define PragTyp_INDEX_LIST 19
+#define PragTyp_INTEGRITY_CHECK 20
+#define PragTyp_JOURNAL_MODE 21
+#define PragTyp_JOURNAL_SIZE_LIMIT 22
+#define PragTyp_LOCK_PROXY_FILE 23
+#define PragTyp_LOCKING_MODE 24
+#define PragTyp_PAGE_COUNT 25
+#define PragTyp_MMAP_SIZE 26
+#define PragTyp_MODULE_LIST 27
+#define PragTyp_OPTIMIZE 28
+#define PragTyp_PAGE_SIZE 29
+#define PragTyp_PRAGMA_LIST 30
+#define PragTyp_SECURE_DELETE 31
+#define PragTyp_SHRINK_MEMORY 32
+#define PragTyp_SOFT_HEAP_LIMIT 33
+#define PragTyp_SYNCHRONOUS 34
+#define PragTyp_TABLE_INFO 35
+#define PragTyp_TEMP_STORE 36
+#define PragTyp_TEMP_STORE_DIRECTORY 37
+#define PragTyp_THREADS 38
+#define PragTyp_WAL_AUTOCHECKPOINT 39
+#define PragTyp_WAL_CHECKPOINT 40
+#define PragTyp_ACTIVATE_EXTENSIONS 41
+#define PragTyp_KEY 42
#define PragTyp_LOCK_STATUS 43
#define PragTyp_STATS 44
/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
@@ -124850,22 +123805,17 @@
u8 iPragCName; /* Start of column names in pragCName[] */
u8 nPragCName; /* Num of col names. 0 means use pragma name */
u64 iArg; /* Extra argument */
} PragmaName;
static const PragmaName aPragmaName[] = {
-#if defined(SQLITE_ENABLE_CEROD)
+#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
{/* zName: */ "activate_extensions",
/* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
- {/* zName: */ "analysis_limit",
- /* ePragTyp: */ PragTyp_ANALYSIS_LIMIT,
- /* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
{/* zName: */ "application_id",
/* ePragTyp: */ PragTyp_HEADER_VALUE,
/* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
/* ColNames: */ 0, 0,
@@ -125051,10 +124001,22 @@
{/* zName: */ "hard_heap_limit",
/* ePragTyp: */ PragTyp_HARD_HEAP_LIMIT,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
+#if defined(SQLITE_HAS_CODEC)
+ {/* zName: */ "hexkey",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 2 },
+ {/* zName: */ "hexrekey",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 3 },
+#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_CHECK)
{/* zName: */ "ignore_check_constraints",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -125103,10 +124065,17 @@
/* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
/* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
+#if defined(SQLITE_HAS_CODEC)
+ {/* zName: */ "key",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{/* zName: */ "legacy_alter_table",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
@@ -125210,10 +124179,19 @@
{/* zName: */ "recursive_triggers",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ SQLITE_RecTriggers },
+#endif
+#if defined(SQLITE_HAS_CODEC)
+ {/* zName: */ "rekey",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 1 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{/* zName: */ "reverse_unordered_selects",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ SQLITE_ReverseOrder },
@@ -125293,10 +124271,22 @@
{/* zName: */ "temp_store_directory",
/* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
/* ePragFlg: */ PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
+#endif
+#if defined(SQLITE_HAS_CODEC)
+ {/* zName: */ "textkey",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 4 },
+ {/* zName: */ "textrekey",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 5 },
#endif
{/* zName: */ "threads",
/* ePragTyp: */ PragTyp_THREADS,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 0, 0,
@@ -125362,11 +124352,11 @@
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
-/* Number of pragmas: 67 on by default, 77 total. */
+/* Number of pragmas: 66 on by default, 82 total. */
/************** End of pragma.h **********************************************/
/************** Continuing where we left off in pragma.c *********************/
/*
@@ -125892,11 +124882,11 @@
}else{
/* Malloc may fail when setting the page-size, as there is an internal
** buffer that the pager module resizes using sqlite3_realloc().
*/
db->nextPagesize = sqlite3Atoi(zRight);
- if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,0,0) ){
+ if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){
sqlite3OomFault(db);
}
}
break;
}
@@ -127066,10 +126056,11 @@
sqlite3ResolvePartIdxLabel(pParse, jmp3);
}
}
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, loopTop-1);
+#ifndef SQLITE_OMIT_BTREECOUNT
if( !isQuick ){
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
if( pPk==pIdx ) continue;
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
@@ -127079,10 +126070,11 @@
sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3);
integrityCheckResultRow(v);
sqlite3VdbeJumpHere(v, addr);
}
}
+#endif /* SQLITE_OMIT_BTREECOUNT */
}
}
{
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList endCode[] = {
@@ -127159,16 +126151,25 @@
/* Only change the value of sqlite.enc if the database handle is not
** initialized. If the main database exists, the new sqlite.enc value
** 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( (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){
+ int canChangeEnc = 1; /* True if allowed to change the encoding */
+ int i; /* For looping over all attached databases */
+ for(i=0; inDb; i++){
+ if( db->aDb[i].pBt!=0
+ && DbHasProperty(db,i,DB_SchemaLoaded)
+ && !DbHasProperty(db,i,DB_Empty)
+ ){
+ canChangeEnc = 0;
+ }
+ }
+ if( canChangeEnc ){
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
- u8 enc = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
- SCHEMA_ENC(db) = enc;
- sqlite3SetTextEncoding(db, enc);
+ SCHEMA_ENC(db) = ENC(db) =
+ pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
break;
}
}
if( !pEnc->zName ){
sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
@@ -127513,29 +126514,10 @@
}
returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
break;
}
- /*
- ** PRAGMA analysis_limit
- ** PRAGMA analysis_limit = N
- **
- ** Configure the maximum number of rows that ANALYZE will examine
- ** in each index that it looks at. Return the new limit.
- */
- case PragTyp_ANALYSIS_LIMIT: {
- sqlite3_int64 N;
- if( zRight
- && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
- && N>=0
- ){
- db->nAnalysisLimit = (int)(N&0x7fffffff);
- }
- returnSingleInt(v, db->nAnalysisLimit);
- break;
- }
-
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Report the current state of file logs for all databases
*/
case PragTyp_LOCK_STATUS: {
@@ -127560,15 +126542,63 @@
}
break;
}
#endif
-#if defined(SQLITE_ENABLE_CEROD)
+#ifdef SQLITE_HAS_CODEC
+ /* Pragma iArg
+ ** ---------- ------
+ ** key 0
+ ** rekey 1
+ ** hexkey 2
+ ** hexrekey 3
+ ** textkey 4
+ ** textrekey 5
+ */
+ case PragTyp_KEY: {
+ if( zRight ){
+ char zBuf[40];
+ const char *zKey = zRight;
+ int n;
+ if( pPragma->iArg==2 || pPragma->iArg==3 ){
+ u8 iByte;
+ int i;
+ for(i=0, iByte=0; iiArg<4 ? sqlite3Strlen30(zRight) : -1;
+ }
+ if( (pPragma->iArg & 1)==0 ){
+ rc = sqlite3_key_v2(db, zDb, zKey, n);
+ }else{
+ rc = sqlite3_rekey_v2(db, zDb, zKey, n);
+ }
+ if( rc==SQLITE_OK && n!=0 ){
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "ok", SQLITE_STATIC);
+ returnSingleText(v, "ok");
+ }
+ }
+ break;
+ }
+#endif
+#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
case PragTyp_ACTIVATE_EXTENSIONS: if( zRight ){
+#ifdef SQLITE_HAS_CODEC
+ if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){
+ sqlite3_activate_see(&zRight[4]);
+ }
+#endif
+#ifdef SQLITE_ENABLE_CEROD
if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){
sqlite3_activate_cerod(&zRight[6]);
}
+#endif
}
break;
#endif
} /* End of the PRAGMA switch */
@@ -127992,11 +127022,11 @@
int iDb = pData->iDb;
assert( argc==5 );
UNUSED_PARAMETER2(NotUsed, argc);
assert( sqlite3_mutex_held(db->mutex) );
- db->mDbFlags |= DBFLAG_EncodingFixed;
+ DbClearProperty(db, iDb, DB_Empty);
pData->nInitRow++;
if( db->mallocFailed ){
corruptSchema(pData, argv[1], 0);
return 1;
}
@@ -128080,11 +127110,10 @@
char const *azArg[6];
int meta[5];
InitData initData;
const char *zMasterName;
int openedTransaction = 0;
- int mask = ((db->mDbFlags & DBFLAG_EncodingFixed) | ~DBFLAG_EncodingFixed);
assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 );
assert( iDb>=0 && iDbnDb );
assert( db->aDb[iDb].pSchema );
assert( sqlite3_mutex_held(db->mutex) );
@@ -128109,11 +127138,10 @@
initData.rc = SQLITE_OK;
initData.pzErrMsg = pzErrMsg;
initData.mInitFlags = mFlags;
initData.nInitRow = 0;
sqlite3InitCallback(&initData, 5, (char **)azArg, 0);
- db->mDbFlags &= mask;
if( initData.rc ){
rc = initData.rc;
goto error_out;
}
@@ -128169,29 +127197,31 @@
** main database, set sqlite3.enc to the encoding of the main database.
** For an attached db, it is an error if the encoding is not the same
** as sqlite3.enc.
*/
if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */
- if( iDb==0 && (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){
- u8 encoding;
+ if( iDb==0 ){
#ifndef SQLITE_OMIT_UTF16
+ u8 encoding;
/* If opening the main database, set ENC(db). */
encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
if( encoding==0 ) encoding = SQLITE_UTF8;
+ ENC(db) = encoding;
#else
- encoding = SQLITE_UTF8;
+ ENC(db) = SQLITE_UTF8;
#endif
- sqlite3SetTextEncoding(db, encoding);
}else{
/* If opening an attached database, the encoding much match ENC(db) */
- if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){
+ if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
" text encoding as main database");
rc = SQLITE_ERROR;
goto initone_error_out;
}
}
+ }else{
+ DbSetProperty(db, iDb, DB_Empty);
}
pDb->pSchema->enc = ENC(db);
if( pDb->pSchema->cache_size==0 ){
#ifndef SQLITE_OMIT_DEPRECATED
@@ -128299,11 +127329,12 @@
** used to store temporary tables, and any additional database files
** created using ATTACH statements. Return a success code. If an
** error occurs, write an error message into *pzErrMsg.
**
** After a database is initialized, the DB_SchemaLoaded bit is set
-** bit is set in the flags field of the Db structure.
+** bit is set in the flags field of the Db structure. If the database
+** file was of zero-length, then the DB_Empty flag is also set.
*/
SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
int i, rc;
int commit_internal = !(db->mDbFlags&DBFLAG_SchemaChange);
@@ -128935,10 +127966,11 @@
sqlite3ExprDelete(db, p->pLimit);
#ifndef SQLITE_OMIT_WINDOWFUNC
if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
sqlite3WindowListDelete(db, p->pWinDefn);
}
+ assert( p->pWin==0 );
#endif
if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
if( bFree ) sqlite3DbFreeNN(db, p);
p = pPrior;
bFree = 1;
@@ -130855,11 +129887,10 @@
}
zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt);
if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt);
}
pCol->zName = zName;
- pCol->hName = sqlite3StrIHash(zName);
sqlite3ColumnPropertiesFromName(0, pCol);
if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){
sqlite3OomFault(db);
}
}
@@ -131638,11 +130669,10 @@
p->pLimit = pLimit;
/* Generate code to take the intersection of the two temporary
** tables.
*/
- if( rc ) break;
assert( p->pEList );
iBreak = sqlite3VdbeMakeLabel(pParse);
iCont = sqlite3VdbeMakeLabel(pParse);
computeLimitRegisters(pParse, p, iBreak);
sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
@@ -132309,14 +131339,11 @@
if( ExprHasProperty(pExpr, EP_FromJoin)
&& pExpr->iRightJoinTable==pSubst->iTable
){
pExpr->iRightJoinTable = pSubst->iNewTable;
}
- if( pExpr->op==TK_COLUMN
- && pExpr->iTable==pSubst->iTable
- && !ExprHasProperty(pExpr, EP_FixedCol)
- ){
+ if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable ){
if( pExpr->iColumn<0 ){
pExpr->op = TK_NULL;
}else{
Expr *pNew;
Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr;
@@ -132330,11 +131357,10 @@
if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
memset(&ifNullRow, 0, sizeof(ifNullRow));
ifNullRow.op = TK_IF_NULL_ROW;
ifNullRow.pLeft = pCopy;
ifNullRow.iTable = pSubst->iNewTable;
- ifNullRow.flags = EP_Skip;
pCopy = &ifNullRow;
}
testcase( ExprHasProperty(pCopy, EP_Subquery) );
pNew = sqlite3ExprDup(db, pCopy, 0);
if( pNew && pSubst->isLeftJoin ){
@@ -132417,42 +131443,10 @@
}
}while( doPrior && (p = p->pPrior)!=0 );
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
-#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
-/*
-** pSelect is a SELECT statement and pSrcItem is one item in the FROM
-** clause of that SELECT.
-**
-** This routine scans the entire SELECT statement and recomputes the
-** pSrcItem->colUsed mask.
-*/
-static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){
- struct SrcList_item *pItem;
- if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
- pItem = pWalker->u.pSrcItem;
- if( pItem->iCursor!=pExpr->iTable ) return WRC_Continue;
- if( pExpr->iColumn<0 ) return WRC_Continue;
- pItem->colUsed |= sqlite3ExprColUsed(pExpr);
- return WRC_Continue;
-}
-static void recomputeColumnsUsed(
- Select *pSelect, /* The complete SELECT statement */
- struct SrcList_item *pSrcItem /* Which FROM clause item to recompute */
-){
- Walker w;
- if( NEVER(pSrcItem->pTab==0) ) return;
- memset(&w, 0, sizeof(w));
- w.xExprCallback = recomputeColumnsUsedExpr;
- w.xSelectCallback = sqlite3SelectWalkNoop;
- w.u.pSrcItem = pSrcItem;
- pSrcItem->colUsed = 0;
- sqlite3WalkSelect(&w, pSelect);
-}
-#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
-
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** This routine attempts to flatten subqueries as a performance optimization.
** This routine returns 1 if it makes changes and 0 if no flattening occurs.
**
@@ -132987,16 +131981,10 @@
*/
if( pSub->pLimit ){
pParent->pLimit = pSub->pLimit;
pSub->pLimit = 0;
}
-
- /* Recompute the SrcList_item.colUsed masks for the flattened
- ** tables. */
- for(i=0; ia[i+iFrom]);
- }
}
/* Finially, delete what is left of the subquery and return
** success.
*/
@@ -133041,12 +132029,13 @@
){
int i;
assert( pColumn->op==TK_COLUMN );
assert( sqlite3ExprIsConstant(pValue) );
- if( ExprHasProperty(pColumn, EP_FixedCol) ) return;
- if( sqlite3ExprAffinity(pValue)!=0 ) return;
+ if( !ExprHasProperty(pValue, EP_FixedCol) && sqlite3ExprAffinity(pValue)!=0 ){
+ return;
+ }
if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){
return;
}
/* 2018-10-25 ticket [cf5ed20f]
@@ -133065,10 +132054,13 @@
pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr,
pConst->nConst*2*sizeof(Expr*));
if( pConst->apExpr==0 ){
pConst->nConst = 0;
}else{
+ if( ExprHasProperty(pValue, EP_FixedCol) ){
+ pValue = pValue->pLeft;
+ }
pConst->apExpr[pConst->nConst*2-2] = pColumn;
pConst->apExpr[pConst->nConst*2-1] = pValue;
}
}
@@ -133340,24 +132332,22 @@
static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */
const char *zFunc; /* Name of aggregate function pFunc */
ExprList *pOrderBy;
- u8 sortFlags = 0;
+ u8 sortFlags;
assert( *ppMinMax==0 );
assert( pFunc->op==TK_AGG_FUNCTION );
assert( !IsWindowFunc(pFunc) );
if( pEList==0 || pEList->nExpr!=1 || ExprHasProperty(pFunc, EP_WinFunc) ){
return eRet;
}
zFunc = pFunc->u.zToken;
if( sqlite3StrICmp(zFunc, "min")==0 ){
eRet = WHERE_ORDERBY_MIN;
- if( sqlite3ExprCanBeNull(pEList->a[0].pExpr) ){
- sortFlags = KEYINFO_ORDER_BIGNULL;
- }
+ sortFlags = KEYINFO_ORDER_BIGNULL;
}else if( sqlite3StrICmp(zFunc, "max")==0 ){
eRet = WHERE_ORDERBY_MAX;
sortFlags = KEYINFO_ORDER_DESC;
}else{
return eRet;
@@ -134021,11 +133011,11 @@
pExpr = pRight;
}
pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
sqlite3TokenInit(&sColname, zColname);
sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
- if( pNew && (p->selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
+ if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
sqlite3DbFree(db, pX->zEName);
if( pSub ){
pX->zEName = sqlite3DbStrDup(db, pSub->pEList->a[j].zEName);
testcase( pX->zEName==0 );
@@ -134061,10 +133051,33 @@
}
}
return WRC_Continue;
}
+/*
+** No-op routine for the parse-tree walker.
+**
+** 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
+** subquery in the parser tree.
+*/
+SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
+ return WRC_Continue;
+}
+
+/*
+** No-op routine for the parse-tree walker for SELECT statements.
+** subquery in the parser tree.
+*/
+SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
+ return WRC_Continue;
+}
+
#if SQLITE_DEBUG
/*
** Always assert. This xSelectCallback2 implementation proves that the
** xSelectCallback2 is never invoked.
*/
@@ -134202,11 +133215,10 @@
Vdbe *v = pParse->pVdbe;
int i;
struct AggInfo_func *pFunc;
int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
if( nReg==0 ) return;
- if( pParse->nErr ) return;
#ifdef SQLITE_DEBUG
/* Verify that all AggInfo registers are within the range specified by
** AggInfo.mnReg..AggInfo.mxReg */
assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 );
for(i=0; inColumn; i++){
@@ -134344,11 +133356,11 @@
sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
}
pAggInfo->directMode = 0;
if( addrHitTest ){
- sqlite3VdbeJumpHereOrPopInst(v, addrHitTest);
+ sqlite3VdbeJumpHere(v, addrHitTest);
}
}
/*
** Add a single OP_Explain instruction to the VDBE to explain a simple
@@ -135231,11 +134243,11 @@
sAggInfo.mxReg = pParse->nMem;
if( db->mallocFailed ) goto select_end;
#if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x400 ){
int ii;
- SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", &sAggInfo));
+ SELECTTRACE(0x400,pParse,p,("After aggregate analysis:\n"));
sqlite3TreeViewSelect(0, p, 0);
for(ii=0; iipSrc->a[0].fg.notIndexed ){
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->bUnordered==0
- && pIdx->szIdxRowszTabRow
- && pIdx->pPartIdxWhere==0
- && (!pBest || pIdx->szIdxRowszIdxRow)
- ){
- pBest = pIdx;
- }
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->bUnordered==0
+ && pIdx->szIdxRowszTabRow
+ && pIdx->pPartIdxWhere==0
+ && (!pBest || pIdx->szIdxRowszIdxRow)
+ ){
+ pBest = pIdx;
}
}
if( pBest ){
iRoot = pBest->tnum;
pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest);
@@ -135531,11 +134542,13 @@
sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
}
sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
sqlite3VdbeAddOp1(v, OP_Close, iCsr);
explainSimpleCount(pParse, pTab, pBest);
- }else{
+ }else
+#endif /* SQLITE_OMIT_BTREECOUNT */
+ {
int regAcc = 0; /* "populate accumulators" flag */
/* If there are accumulator registers but no min() or max() functions
** without FILTER clauses, allocate register regAcc. Register regAcc
** will contain 0 the first time the inner loop runs, and 1 thereafter.
@@ -135694,11 +134707,11 @@
need = nCol;
}
if( p->nData + need > p->nAlloc ){
char **azNew;
p->nAlloc = p->nAlloc*2 + need;
- azNew = sqlite3Realloc( p->azResult, sizeof(char*)*p->nAlloc );
+ azNew = sqlite3_realloc64( p->azResult, sizeof(char*)*p->nAlloc );
if( azNew==0 ) goto malloc_failed;
p->azResult = azNew;
}
/* If this is the first row, then generate an extra row containing
@@ -135803,11 +134816,11 @@
sqlite3_free_table(&res.azResult[1]);
return rc;
}
if( res.nAlloc>res.nData ){
char **azNew;
- azNew = sqlite3Realloc( res.azResult, sizeof(char*)*res.nData );
+ azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData );
if( azNew==0 ){
sqlite3_free_table(&res.azResult[1]);
db->errCode = SQLITE_NOMEM;
return SQLITE_NOMEM_BKPT;
}
@@ -136419,11 +135432,11 @@
zDb = pName->a[0].zDatabase;
zName = pName->a[0].zName;
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; inDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
- if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
+ if( zDb && sqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName);
if( pTrigger ) break;
}
if( !pTrigger ){
@@ -137093,14 +136106,14 @@
** Therefore, the P4 parameter is only required if the default value for
** the column is a literal number, string or null. The sqlite3ValueFromExpr()
** function is capable of transforming these types of expressions into
** sqlite3_value objects.
**
-** If column as REAL affinity and the table is an ordinary b-tree table
-** (not a virtual table) then the value might have been stored as an
-** integer. In that case, add an OP_RealAffinity opcode to make sure
-** it has been converted into REAL.
+** 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
+** space.
*/
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
assert( pTab!=0 );
if( !pTab->pSelect ){
sqlite3_value *pValue = 0;
@@ -137113,11 +136126,11 @@
if( pValue ){
sqlite3VdbeAppendP4(v, pValue, P4_MEM);
}
}
#ifndef SQLITE_OMIT_FLOATING_POINT
- if( pTab->aCol[i].affinity==SQLITE_AFF_REAL && !IsVirtual(pTab) ){
+ if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
}
#endif
}
@@ -137656,13 +136669,11 @@
if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur,
aToOpen, 0, 0);
- if( addrOnce ){
- sqlite3VdbeJumpHereOrPopInst(v, addrOnce);
- }
+ if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
}
/* Top of the update loop */
if( eOnePass!=ONEPASS_OFF ){
if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){
@@ -138611,11 +137622,22 @@
sqlite3SetString(pzErrMsg, db, "output file already exists");
goto end_of_vacuum;
}
db->mDbFlags |= DBFLAG_VacuumInto;
}
- nRes = sqlite3BtreeGetRequestedReserve(pMain);
+ nRes = sqlite3BtreeGetOptimalReserve(pMain);
+
+ /* A VACUUM cannot change the pagesize of an encrypted database. */
+#ifdef SQLITE_HAS_CODEC
+ if( db->nextPagesize ){
+ extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
+ int nKey;
+ char *zKey;
+ sqlite3CodecGetKey(db, iDb, (void**)&zKey, &nKey);
+ if( nKey ) db->nextPagesize = 0;
+ }
+#endif
sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL);
@@ -138755,11 +137777,11 @@
db->mDbFlags = saved_mDbFlags;
db->flags = saved_flags;
db->nChange = saved_nChange;
db->nTotalChange = saved_nTotalChange;
db->mTrace = saved_mTrace;
- sqlite3BtreeSetPageSize(pMain, -1, 0, 1);
+ 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
** was committed at the btree level). So it safe to end the transaction
** by manually setting the autoCommit flag to true and detaching the
@@ -139962,11 +138984,11 @@
assert( IsVirtual(pTab) );
for(i=0; inVtabLock; i++){
if( pTab==pToplevel->apVtabLock[i] ) return;
}
n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
- apVtabLock = sqlite3Realloc(pToplevel->apVtabLock, n);
+ apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n);
if( apVtabLock ){
pToplevel->apVtabLock = apVtabLock;
pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
}else{
sqlite3OomFault(pToplevel->db);
@@ -140419,16 +139441,10 @@
#define TERM_LIKEOPT 0x0100 /* Virtual terms from the LIKE optimization */
#define TERM_LIKECOND 0x0200 /* Conditionally this LIKE operator term */
#define TERM_LIKE 0x0400 /* The original LIKE operator */
#define TERM_IS 0x0800 /* Term.pExpr is an IS operator */
#define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */
-#define TERM_HEURTRUTH 0x2000 /* Heuristic truthProb used */
-#ifdef SQLITE_ENABLE_STAT4
-# define TERM_HIGHTRUTH 0x4000 /* Term excludes few rows */
-#else
-# define TERM_HIGHTRUTH 0 /* Only used with STAT4 */
-#endif
/*
** An instance of the WhereScan object is used as an iterator for locating
** terms in the WHERE clause that are useful to the query planner.
*/
@@ -140539,20 +139555,17 @@
WhereOrSet *pOrSet; /* Record best loops here, if not NULL */
#ifdef SQLITE_ENABLE_STAT4
UnpackedRecord *pRec; /* Probe for stat4 (if required) */
int nRecValid; /* Number of valid fields currently in pRec */
#endif
- unsigned char bldFlags1; /* First set of SQLITE_BLDF_* flags */
- unsigned char bldFlags2; /* Second set of SQLITE_BLDF_* flags */
+ unsigned int bldFlags; /* SQLITE_BLDF_* flags */
unsigned int iPlanLimit; /* Search limiter */
};
/* Allowed values for WhereLoopBuider.bldFlags */
-#define SQLITE_BLDF1_INDEXED 0x0001 /* An index is used */
-#define SQLITE_BLDF1_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
-
-#define SQLITE_BLDF2_2NDPASS 0x0004 /* Second builder pass needed */
+#define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */
+#define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
/* The WhereLoopBuilder.iPlanLimit is used to limit the number of
** index+constraint combinations the query planner will consider for a
** particular query. If this parameter is unlimited, then certain
** pathological queries can spend excess time in the sqlite3WhereBegin()
@@ -142162,13 +141175,11 @@
if( pCompare ){
pCompare->pLeft = pTerm->pExpr->pLeft;
pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
if( pRight ){
pRight->iTable = iReg+j+2;
- sqlite3ExprIfFalse(
- pParse, pCompare, pLevel->addrCont, SQLITE_JUMPIFNULL
- );
+ sqlite3ExprIfFalse(pParse, pCompare, pLevel->addrCont, 0);
}
pCompare->pLeft = 0;
sqlite3ExprDelete(db, pCompare);
}
}
@@ -142441,13 +141452,10 @@
assert( pRangeEnd==0 && pRangeStart==0 );
testcase( pLoop->nSkip>0 );
nExtraReg = 1;
bSeekPastNull = 1;
pLevel->regBignull = regBignull = ++pParse->nMem;
- if( pLevel->iLeftJoin ){
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regBignull);
- }
pLevel->addrBignull = sqlite3VdbeMakeLabel(pParse);
}
/* If we are doing a reverse order scan on an ascending index, or
** a forward order scan on a descending index, interchange the
@@ -143581,12 +142589,11 @@
**
** vtab_column MATCH expression
** MATCH(expression,vtab_column)
*/
pCol = pList->a[1].pExpr;
- testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
- if( ExprIsVtab(pCol) ){
+ if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
for(i=0; iu.zToken, aOp[i].zOp)==0 ){
*peOp2 = aOp[i].eOp2;
*ppRight = pList->a[0].pExpr;
*ppLeft = pCol;
@@ -143604,12 +142611,11 @@
** Historically, xFindFunction expected to see lower-case function
** names. But for this use case, xFindFunction is expected to deal
** with function names in an arbitrary case.
*/
pCol = pList->a[0].pExpr;
- testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
- if( ExprIsVtab(pCol) ){
+ if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
sqlite3_vtab *pVtab;
sqlite3_module *pMod;
void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
void *pNotUsed;
pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
@@ -143628,16 +142634,14 @@
}
}else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
int res = 0;
Expr *pLeft = pExpr->pLeft;
Expr *pRight = pExpr->pRight;
- testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 );
- if( ExprIsVtab(pLeft) ){
+ if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){
res++;
}
- testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 );
- if( pRight && ExprIsVtab(pRight) ){
+ if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){
res++;
SWAP(Expr*, pLeft, pRight);
}
*ppLeft = pLeft;
*ppRight = pRight;
@@ -147117,25 +146121,20 @@
pLoop->nOut += pTerm->truthProb;
}else{
/* In the absence of explicit truth probabilities, use heuristics to
** guess a reasonable truth probability. */
pLoop->nOut--;
- if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0
- && (pTerm->wtFlags & TERM_HIGHTRUTH)==0 /* tag-20200224-1 */
- ){
+ if( pTerm->eOperator&(WO_EQ|WO_IS) ){
Expr *pRight = pTerm->pExpr->pRight;
int k = 0;
testcase( pTerm->pExpr->op==TK_IS );
if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
k = 10;
}else{
k = 20;
}
- if( iReducewtFlags |= TERM_HEURTRUTH;
- iReduce = k;
- }
+ if( iReducenOut > nRow-iReduce ) pLoop->nOut = nRow - iReduce;
@@ -147313,13 +146312,13 @@
){
continue;
}
if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
- pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE;
+ pBuilder->bldFlags |= SQLITE_BLDF_UNIQUE;
}else{
- pBuilder->bldFlags1 |= SQLITE_BLDF1_INDEXED;
+ pBuilder->bldFlags |= SQLITE_BLDF_INDEXED;
}
pNew->wsFlags = saved_wsFlags;
pNew->u.btree.nEq = saved_nEq;
pNew->u.btree.nBtm = saved_nBtm;
pNew->u.btree.nTop = saved_nTop;
@@ -147480,31 +146479,10 @@
}
if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */
if( nOut ){
pNew->nOut = sqlite3LogEst(nOut);
- if( nEq==1
- /* TUNING: Mark terms as "low selectivity" if they seem likely
- ** to be true for half or more of the rows in the table.
- ** See tag-202002240-1 */
- && pNew->nOut+10 > pProbe->aiRowLogEst[0]
- ){
-#if WHERETRACE_ENABLED /* 0x01 */
- if( sqlite3WhereTrace & 0x01 ){
- sqlite3DebugPrintf(
- "STAT4 determines term has low selectivity:\n");
- sqlite3WhereTermPrint(pTerm, 999);
- }
-#endif
- pTerm->wtFlags |= TERM_HIGHTRUTH;
- if( pTerm->wtFlags & TERM_HEURTRUTH ){
- /* If the term has previously been used with an assumption of
- ** higher selectivity, then set the flag to rerun the
- ** loop computations. */
- pBuilder->bldFlags2 |= SQLITE_BLDF2_2NDPASS;
- }
- }
if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut;
pNew->nOut -= nIn;
}
}
if( nOut==0 )
@@ -147577,11 +146555,10 @@
assert( 42==sqlite3LogEst(18) );
if( saved_nEq==saved_nSkip
&& saved_nEq+1nKeyCol
&& saved_nEq==pNew->nLTerm
&& pProbe->noSkipScan==0
- && pProbe->hasStat1!=0
&& OptimizationEnabled(db, SQLITE_SkipScan)
&& pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */
&& (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
){
LogEst nIter;
@@ -147925,13 +146902,13 @@
pNew->nOut = rSize;
if( rc ) break;
}
}
- pBuilder->bldFlags1 = 0;
+ pBuilder->bldFlags = 0;
rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
- if( pBuilder->bldFlags1==SQLITE_BLDF1_INDEXED ){
+ if( pBuilder->bldFlags==SQLITE_BLDF_INDEXED ){
/* If a non-unique index is used, or if a prefix of the key for
** unique index is used (making the index functionally non-unique)
** then the sqlite_stat1 data becomes important for scoring the
** plan */
pTab->tabFlags |= TF_StatsUsed;
@@ -148598,15 +147575,12 @@
assert( wctrlFlags & WHERE_ORDERBY_LIMIT );
for(j=0; jnLTerm && pTerm!=pLoop->aLTerm[j]; j++){}
if( j>=pLoop->nLTerm ) continue;
}
if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){
- Parse *pParse = pWInfo->pParse;
- CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[i].pExpr);
- CollSeq *pColl2 = sqlite3ExprCompareCollSeq(pParse, pTerm->pExpr);
- assert( pColl1 );
- if( pColl2==0 || sqlite3StrICmp(pColl1->zName, pColl2->zName) ){
+ if( sqlite3ExprCollSeqMatch(pWInfo->pParse,
+ pOrderBy->a[i].pExpr, pTerm->pExpr)==0 ){
continue;
}
testcase( pTerm->pExpr->op==TK_IS );
}
obSat |= MASKBIT(i);
@@ -149382,32 +148356,10 @@
w.xSelectCallback = sqlite3SelectWalkFail;
sqlite3WalkExpr(&w, p);
return w.eCode;
}
-
-#ifdef WHERETRACE_ENABLED
-/*
-** Display all WhereLoops in pWInfo
-*/
-static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){
- if( sqlite3WhereTrace ){ /* Display all of the WhereLoop objects */
- WhereLoop *p;
- int i;
- static const char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
- "ABCDEFGHIJKLMNOPQRSTUVWYXZ";
- for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){
- p->cId = zLabel[i%(sizeof(zLabel)-1)];
- sqlite3WhereLoopPrint(p, pWC);
- }
- }
-}
-# define WHERETRACE_ALL_LOOPS(W,C) showAllWhereLoops(W,C)
-#else
-# define WHERETRACE_ALL_LOOPS(W,C)
-#endif
-
/*
** Generate the beginning of the loop used for WHERE clause processing.
** The return value is a pointer to an opaque structure that contains
** information needed to terminate the loop. Later, the calling routine
** should invoke sqlite3WhereEnd() with the return value of this function
@@ -149705,32 +148657,23 @@
#endif
if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
rc = whereLoopAddAll(&sWLB);
if( rc ) goto whereBeginError;
-
-#ifdef SQLITE_ENABLE_STAT4
- /* If one or more WhereTerm.truthProb values were used in estimating
- ** loop parameters, but then those truthProb values were subsequently
- ** changed based on STAT4 information while computing subsequent loops,
- ** then we need to rerun the whole loop building process so that all
- ** loops will be built using the revised truthProb values. */
- if( sWLB.bldFlags2 & SQLITE_BLDF2_2NDPASS ){
- WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC);
- WHERETRACE(0xffff,
- ("**** Redo all loop computations due to"
- " TERM_HIGHTRUTH changes ****\n"));
- while( pWInfo->pLoops ){
- WhereLoop *p = pWInfo->pLoops;
- pWInfo->pLoops = p->pNextLoop;
- whereLoopDelete(db, p);
- }
- rc = whereLoopAddAll(&sWLB);
- if( rc ) goto whereBeginError;
- }
-#endif
- WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC);
+
+#ifdef WHERETRACE_ENABLED
+ if( sqlite3WhereTrace ){ /* Display all of the WhereLoop objects */
+ WhereLoop *p;
+ int i;
+ static const char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
+ "ABCDEFGHIJKLMNOPQRSTUVWYXZ";
+ for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){
+ p->cId = zLabel[i%(sizeof(zLabel)-1)];
+ sqlite3WhereLoopPrint(p, sWLB.pWC);
+ }
+ }
+#endif
wherePathSolver(pWInfo, 0);
if( db->mallocFailed ) goto whereBeginError;
if( pWInfo->pOrderBy ){
wherePathSolver(pWInfo, pWInfo->nRowOut+1);
@@ -149997,11 +148940,11 @@
&& (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0
&& (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0
&& (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
&& pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
){
- sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ);
+ sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */
}
VdbeComment((v, "%s", pIx->zName));
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
{
u64 colUsed = 0;
@@ -150155,31 +149098,30 @@
for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
if( pIn->eEndLoopOp!=OP_Noop ){
if( pIn->nPrefix ){
assert( pLoop->wsFlags & WHERE_IN_EARLYOUT );
+ if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){
+ sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur,
+ sqlite3VdbeCurrentAddr(v)+2+(pLevel->iLeftJoin!=0),
+ pIn->iBase, pIn->nPrefix);
+ VdbeCoverage(v);
+ }
if( pLevel->iLeftJoin ){
/* For LEFT JOIN queries, cursor pIn->iCur may not have been
** opened yet. This occurs for WHERE clauses such as
** "a = ? AND b IN (...)", where the index is on (a, b). If
** the RHS of the (a=?) is NULL, then the "b IN (...)" may
** never have been coded, but the body of the loop run to
** return the null-row. So, if the cursor is not open yet,
** jump over the OP_Next or OP_Prev instruction about to
** be coded. */
sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur,
- sqlite3VdbeCurrentAddr(v) + 2 +
- ((pLoop->wsFlags & WHERE_VIRTUALTABLE)==0)
+ sqlite3VdbeCurrentAddr(v) + 2
);
VdbeCoverage(v);
}
- if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){
- sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur,
- sqlite3VdbeCurrentAddr(v)+2,
- pIn->iBase, pIn->nPrefix);
- VdbeCoverage(v);
- }
}
sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
VdbeCoverage(v);
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Prev);
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Next);
@@ -151254,48 +150196,25 @@
){
if( pAppend ){
int i;
int nInit = pList ? pList->nExpr : 0;
for(i=0; inExpr; i++){
+ int iDummy;
Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
assert( pDup==0 || !ExprHasProperty(pDup, EP_MemToken) );
- if( bIntToNull && pDup ){
- int iDummy;
- Expr *pSub;
- for(pSub=pDup; ExprHasProperty(pSub, EP_Skip); pSub=pSub->pLeft){
- assert( pSub );
- }
- if( sqlite3ExprIsInteger(pSub, &iDummy) ){
- pSub->op = TK_NULL;
- pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
- pSub->u.zToken = 0;
- }
+ if( bIntToNull && pDup && sqlite3ExprIsInteger(pDup, &iDummy) ){
+ pDup->op = TK_NULL;
+ pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
+ pDup->u.zToken = 0;
}
pList = sqlite3ExprListAppend(pParse, pList, pDup);
if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags;
}
}
return pList;
}
-/*
-** When rewriting a query, if the new subquery in the FROM clause
-** contains TK_AGG_FUNCTION nodes that refer to an outer query,
-** then we have to increase the Expr->op2 values of those nodes
-** due to the extra subquery layer that was added.
-**
-** See also the incrAggDepth() routine in resolve.c
-*/
-static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){
- if( pExpr->op==TK_AGG_FUNCTION
- && pExpr->op2>=pWalker->walkerDepth
- ){
- pExpr->op2++;
- }
- return WRC_Continue;
-}
-
/*
** If the SELECT statement passed as the second argument does not invoke
** any SQL window functions, this function is a no-op. Otherwise, it
** rewrites the SELECT statement so that window function xStep functions
** are invoked in the correct order as described under "SELECT REWRITING"
@@ -151315,11 +150234,10 @@
ExprList *pSublist = 0; /* Expression list for sub-query */
Window *pMWin = p->pWin; /* Master window object */
Window *pWin; /* Window object iterator */
Table *pTab;
- u32 selFlags = p->selFlags;
pTab = sqlite3DbMallocZero(db, sizeof(Table));
if( pTab==0 ){
return sqlite3ErrorToParser(db, SQLITE_NOMEM);
}
@@ -151401,31 +150319,24 @@
pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
);
p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( p->pSrc ){
Table *pTab2;
- Walker w;
p->pSrc->a[0].pSelect = pSub;
sqlite3SrcListAssignCursors(pParse, p->pSrc);
pSub->selFlags |= SF_Expanded;
pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
- pSub->selFlags |= (selFlags & SF_Aggregate);
if( pTab2==0 ){
/* Might actually be some other kind of error, but in that case
** pParse->nErr will be set, so if SQLITE_NOMEM is set, we will get
** the correct error message regardless. */
rc = SQLITE_NOMEM;
}else{
memcpy(pTab, pTab2, sizeof(Table));
pTab->tabFlags |= TF_Ephemeral;
p->pSrc->a[0].pTab = pTab;
pTab = pTab2;
- memset(&w, 0, sizeof(w));
- w.xExprCallback = sqlite3WindowExtraAggFuncDepth;
- w.xSelectCallback = sqlite3WalkerDepthIncrease;
- w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
- sqlite3WalkSelect(&w, pSub);
}
}else{
sqlite3SelectDelete(db, pSub);
}
if( db->mallocFailed ) rc = SQLITE_NOMEM;
@@ -152300,11 +151211,10 @@
int regArg;
int nArg = 0;
Window *pWin;
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
FuncDef *pFunc = pWin->pFunc;
- assert( pWin->regAccum );
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
nArg = MAX(nArg, windowArgCount(pWin));
if( pMWin->regStartRowid==0 ){
if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){
sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
@@ -152679,14 +151589,10 @@
pNew->eFrmType = p->eFrmType;
pNew->eEnd = p->eEnd;
pNew->eStart = p->eStart;
pNew->eExclude = p->eExclude;
pNew->regResult = p->regResult;
- pNew->regAccum = p->regAccum;
- pNew->iArgCol = p->iArgCol;
- pNew->iEphCsr = p->iEphCsr;
- pNew->bExprArgs = p->bExprArgs;
pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
pNew->pOwner = pOwner;
pNew->bImplicitFrame = p->bImplicitFrame;
}
@@ -153520,11 +152426,10 @@
if( p ){
/* memset(p, 0, sizeof(Expr)); */
p->op = (u8)op;
p->affExpr = 0;
p->flags = EP_Leaf;
- ExprClearVVAProperties(p);
p->iAgg = -1;
p->pLeft = p->pRight = 0;
p->x.pList = 0;
p->pAggInfo = 0;
p->y.pTab = 0;
@@ -157589,17 +156494,10 @@
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy202);
yymsp[-4].minor.yy202 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy192 ? "1" : "0");
- }else if( yymsp[-1].minor.yy242->nExpr==1 && sqlite3ExprIsConstant(yymsp[-1].minor.yy242->a[0].pExpr) ){
- Expr *pRHS = yymsp[-1].minor.yy242->a[0].pExpr;
- yymsp[-1].minor.yy242->a[0].pExpr = 0;
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy242);
- pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0);
- yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy202, pRHS);
- if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0);
}else{
yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy202, 0);
if( yymsp[-4].minor.yy202 ){
yymsp[-4].minor.yy202->x.pList = yymsp[-1].minor.yy242;
sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy202);
@@ -158867,21 +157765,16 @@
const char *zKW;
if( n>=2 ){
i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) % 127;
for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){
if( aKWLen[i]!=n ) continue;
+ j = 0;
zKW = &zKWText[aKWOffset[i]];
#ifdef SQLITE_ASCII
- if( (z[0]&~0x20)!=zKW[0] ) continue;
- if( (z[1]&~0x20)!=zKW[1] ) continue;
- j = 2;
while( jmallocFailed );
assert( zSql!=0 );
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
if( db->nVdbeActive==0 ){
- AtomicStore(&db->u1.isInterrupted, 0);
+ db->u1.isInterrupted = 0;
}
pParse->rc = SQLITE_OK;
pParse->zTail = zSql;
assert( pzErrMsg!=0 );
#ifdef SQLITE_DEBUG
@@ -159520,11 +158413,11 @@
);
#else
if( tokenType>=TK_SPACE ){
assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
#endif /* SQLITE_OMIT_WINDOWFUNC */
- if( AtomicLoad(&db->u1.isInterrupted) ){
+ if( db->u1.isInterrupted ){
pParse->rc = SQLITE_INTERRUPT;
break;
}
if( tokenType==TK_SPACE ){
zSql += n;
@@ -160187,82 +159080,19 @@
/************** End of sqliteicu.h *******************************************/
/************** Continuing where we left off in main.c ***********************/
#endif
-
-/*
-** This is an extension initializer that is a no-op and always
-** succeeds, except that it fails if the fault-simulation is set
-** to 500.
-*/
-static int sqlite3TestExtInit(sqlite3 *db){
- (void)db;
- return sqlite3FaultSim(500);
-}
-
-
-/*
-** Forward declarations of external module initializer functions
-** for modules that need them.
-*/
-#ifdef SQLITE_ENABLE_FTS1
-SQLITE_PRIVATE int sqlite3Fts1Init(sqlite3*);
-#endif
-#ifdef SQLITE_ENABLE_FTS2
-SQLITE_PRIVATE int sqlite3Fts2Init(sqlite3*);
-#endif
-#ifdef SQLITE_ENABLE_FTS5
-SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*);
-#endif
#ifdef SQLITE_ENABLE_JSON1
SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_STMTVTAB
SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*);
#endif
-
-/*
-** An array of pointers to extension initializer functions for
-** built-in extensions.
-*/
-static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = {
-#ifdef SQLITE_ENABLE_FTS1
- sqlite3Fts1Init,
-#endif
-#ifdef SQLITE_ENABLE_FTS2
- sqlite3Fts2Init,
-#endif
-#ifdef SQLITE_ENABLE_FTS3
- sqlite3Fts3Init,
-#endif
#ifdef SQLITE_ENABLE_FTS5
- sqlite3Fts5Init,
-#endif
-#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
- sqlite3IcuInit,
-#endif
-#ifdef SQLITE_ENABLE_RTREE
- sqlite3RtreeInit,
-#endif
-#ifdef SQLITE_ENABLE_DBPAGE_VTAB
- sqlite3DbpageRegister,
-#endif
-#ifdef SQLITE_ENABLE_DBSTAT_VTAB
- sqlite3DbstatRegister,
-#endif
- sqlite3TestExtInit,
-#ifdef SQLITE_ENABLE_JSON1
- sqlite3Json1Init,
-#endif
-#ifdef SQLITE_ENABLE_STMTVTAB
- sqlite3StmtVtabInit,
-#endif
-#ifdef SQLITE_ENABLE_BYTECODE_VTAB
- sqlite3VdbeBytecodeVtabInit,
+SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*);
#endif
-};
#ifndef SQLITE_AMALGAMATION
/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
** contains the text of SQLITE_VERSION macro.
*/
@@ -160386,14 +159216,11 @@
/* If SQLite is already completely initialized, then this call
** to sqlite3_initialize() should be a no-op. But the initialization
** must be complete. So isInit must not be set until the very end
** of this routine.
*/
- if( sqlite3GlobalConfig.isInit ){
- sqlite3MemoryBarrier();
- return SQLITE_OK;
- }
+ if( sqlite3GlobalConfig.isInit ) return SQLITE_OK;
/* 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.
@@ -160475,11 +159302,10 @@
}
#endif
if( rc==SQLITE_OK ){
sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage,
sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
- sqlite3MemoryBarrier();
sqlite3GlobalConfig.isInit = 1;
#ifdef SQLITE_EXTRA_INIT
bRunExtraInit = 1;
#endif
}
@@ -161777,11 +160603,12 @@
** Return non-zero to retry the lock. Return zero to stop trying
** and cause SQLite to return SQLITE_BUSY.
*/
static int sqliteDefaultBusyCallback(
void *ptr, /* Database connection */
- int count /* Number of times table has been busy */
+ int count, /* Number of times table has been busy */
+ sqlite3_file *pFile /* The file on which the lock occurred */
){
#if SQLITE_OS_WIN || HAVE_USLEEP
/* This case is for systems that have support for sleeping for fractions of
** a second. Examples: All windows systems, unix systems with usleep() */
static const u8 delays[] =
@@ -161791,10 +160618,23 @@
# define NDELAY ArraySize(delays)
sqlite3 *db = (sqlite3 *)ptr;
int tmout = db->busyTimeout;
int delay, prior;
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+ if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){
+ if( count ){
+ tmout = 0;
+ sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout);
+ return 0;
+ }else{
+ return 1;
+ }
+ }
+#else
+ UNUSED_PARAMETER(pFile);
+#endif
assert( count>=0 );
if( count < NDELAY ){
delay = delays[count];
prior = totals[count];
}else{
@@ -161810,10 +160650,11 @@
#else
/* This case for unix systems that lack usleep() support. Sleeping
** must be done in increments of whole seconds */
sqlite3 *db = (sqlite3 *)ptr;
int tmout = ((sqlite3 *)ptr)->busyTimeout;
+ UNUSED_PARAMETER(pFile);
if( (count+1)*1000 > tmout ){
return 0;
}
sqlite3OsSleep(db->pVfs, 1000000);
return 1;
@@ -161827,14 +160668,23 @@
** lock on VFS file pFile.
**
** If this routine returns non-zero, the lock is retried. If it
** returns 0, the operation aborts with an SQLITE_BUSY error.
*/
-SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
+SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p, sqlite3_file *pFile){
int rc;
if( p->xBusyHandler==0 || p->nBusy<0 ) return 0;
- rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
+ if( p->bExtraFileArg ){
+ /* Add an extra parameter with the pFile pointer to the end of the
+ ** callback argument list */
+ int (*xTra)(void*,int,sqlite3_file*);
+ xTra = (int(*)(void*,int,sqlite3_file*))p->xBusyHandler;
+ rc = xTra(p->pBusyArg, p->nBusy, pFile);
+ }else{
+ /* Legacy style busy handler callback */
+ rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
+ }
if( rc==0 ){
p->nBusy = -1;
}else{
p->nBusy++;
}
@@ -161855,10 +160705,11 @@
#endif
sqlite3_mutex_enter(db->mutex);
db->busyHandler.xBusyHandler = xBusy;
db->busyHandler.pBusyArg = pArg;
db->busyHandler.nBusy = 0;
+ db->busyHandler.bExtraFileArg = 0;
db->busyTimeout = 0;
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
@@ -161905,10 +160756,11 @@
#endif
if( ms>0 ){
sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
(void*)db);
db->busyTimeout = ms;
+ db->busyHandler.bExtraFileArg = 1;
}else{
sqlite3_busy_handler(db, 0, 0);
}
return SQLITE_OK;
}
@@ -161921,11 +160773,11 @@
if( !sqlite3SafetyCheckOk(db) && (db==0 || db->magic!=SQLITE_MAGIC_ZOMBIE) ){
(void)SQLITE_MISUSE_BKPT;
return;
}
#endif
- AtomicStore(&db->u1.isInterrupted, 1);
+ db->u1.isInterrupted = 1;
}
/*
** This function is exactly the same as sqlite3_create_function(), except
@@ -162543,11 +161395,11 @@
rc = sqlite3ApiExit(db, rc);
/* If there are no active statements, clear the interrupt flag at this
** point. */
if( db->nVdbeActive==0 ){
- AtomicStore(&db->u1.isInterrupted, 0);
+ db->u1.isInterrupted = 0;
}
sqlite3_mutex_leave(db->mutex);
return rc;
#endif
@@ -162953,15 +161805,13 @@
** *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. The value
-** stored in *pzFile is a database name acceptable to sqlite3_uri_parameter()
-** and is in the same format as names created using sqlite3_create_filename().
-** The caller must invoke sqlite3_free_filename() (not sqlite3_free()!) on
-** the value returned in *pzFile to avoid a memory leak.
+** 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().
@@ -162989,23 +161839,20 @@
){
char *zOpt;
int eState; /* Parser state when parsing URI */
int iIn; /* Input character index */
int iOut = 0; /* Output character index */
- u64 nByte = nUri+8; /* Bytes of space to allocate */
+ u64 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; iInaCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3HashInit(&db->aModule);
@@ -163403,10 +162264,15 @@
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0);
if( db->mallocFailed ){
goto opendb_out;
}
+ /* EVIDENCE-OF: R-08308-17224 The default collating function for all
+ ** strings is BINARY.
+ */
+ db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0);
+ assert( db->pDfltColl!=0 );
/* Parse the filename/URI argument
**
** Only allow sensible combinations of bits in the flags argument.
** Throw an error if any non-sense combination is used. If we
@@ -163424,11 +162290,11 @@
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 ){
- rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */
+ rc = SQLITE_MISUSE_BKPT; /* IMP: R-65497-44594 */
}else{
rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
}
if( rc!=SQLITE_OK ){
if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
@@ -163447,13 +162313,11 @@
sqlite3Error(db, rc);
goto opendb_out;
}
sqlite3BtreeEnter(db->aDb[0].pBt);
db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
- if( !db->mallocFailed ){
- sqlite3SetTextEncoding(db, SCHEMA_ENC(db));
- }
+ if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db);
sqlite3BtreeLeave(db->aDb[0].pBt);
db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
/* The default safety_level for the main database is FULL; for the temp
** database it is OFF. This matches the pager layer defaults.
@@ -163474,15 +162338,18 @@
*/
sqlite3Error(db, SQLITE_OK);
sqlite3RegisterPerConnectionBuiltinFunctions(db);
rc = sqlite3_errcode(db);
-
- /* Load compiled-in extensions */
- for(i=0; rc==SQLITE_OK && imallocFailed && rc==SQLITE_OK ){
+ rc = sqlite3Fts5Init(db);
}
+#endif
/* Load automatic extensions - extensions that have been registered
** using the sqlite3_automatic_extension() API.
*/
if( rc==SQLITE_OK ){
@@ -163491,10 +162358,66 @@
if( rc!=SQLITE_OK ){
goto opendb_out;
}
}
+#ifdef SQLITE_ENABLE_FTS1
+ if( !db->mallocFailed ){
+ extern int sqlite3Fts1Init(sqlite3*);
+ rc = sqlite3Fts1Init(db);
+ }
+#endif
+
+#ifdef SQLITE_ENABLE_FTS2
+ if( !db->mallocFailed && rc==SQLITE_OK ){
+ extern int sqlite3Fts2Init(sqlite3*);
+ rc = sqlite3Fts2Init(db);
+ }
+#endif
+
+#ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */
+ if( !db->mallocFailed && rc==SQLITE_OK ){
+ rc = sqlite3Fts3Init(db);
+ }
+#endif
+
+#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
+ if( !db->mallocFailed && rc==SQLITE_OK ){
+ rc = sqlite3IcuInit(db);
+ }
+#endif
+
+#ifdef SQLITE_ENABLE_RTREE
+ if( !db->mallocFailed && rc==SQLITE_OK){
+ rc = sqlite3RtreeInit(db);
+ }
+#endif
+
+#ifdef SQLITE_ENABLE_DBPAGE_VTAB
+ if( !db->mallocFailed && rc==SQLITE_OK){
+ rc = sqlite3DbpageRegister(db);
+ }
+#endif
+
+#ifdef SQLITE_ENABLE_DBSTAT_VTAB
+ if( !db->mallocFailed && rc==SQLITE_OK){
+ rc = sqlite3DbstatRegister(db);
+ }
+#endif
+
+#ifdef SQLITE_ENABLE_JSON1
+ if( !db->mallocFailed && rc==SQLITE_OK){
+ rc = sqlite3Json1Init(db);
+ }
+#endif
+
+#ifdef SQLITE_ENABLE_STMTVTAB
+ if( !db->mallocFailed && rc==SQLITE_OK){
+ rc = sqlite3StmtVtabInit(db);
+ }
+#endif
+
#ifdef SQLITE_ENABLE_INTERNAL_FUNCTIONS
/* Testing use only!!! The -DSQLITE_ENABLE_INTERNAL_FUNCTIONS=1 compile-time
** option gives access to internal functions by default.
** Testing use only!!! */
db->mDbFlags |= DBFLAG_InternalFunc;
@@ -163538,11 +162461,14 @@
/* Opening a db handle. Fourth parameter is passed 0. */
void *pArg = sqlite3GlobalConfig.pSqllogArg;
sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
}
#endif
- sqlite3_free_filename(zOpen);
+#if defined(SQLITE_HAS_CODEC)
+ if( rc==SQLITE_OK ) sqlite3CodecQueryParameters(db, 0, zOpen);
+#endif
+ sqlite3_free(zOpen);
return rc & 0xff;
}
/*
@@ -163765,19 +162691,17 @@
}
SQLITE_PRIVATE int sqlite3CantopenError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
return sqlite3ReportError(SQLITE_CANTOPEN, lineno, "cannot open file");
}
-#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_CORRUPT_PGNO)
+#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3CorruptPgnoError(int lineno, Pgno pgno){
char zMsg[100];
sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno);
testcase( sqlite3GlobalConfig.xLog!=0 );
return sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
}
-#endif
-#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3NomemError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
return sqlite3ReportError(SQLITE_NOMEM, lineno, "OOM");
}
SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){
@@ -163976,17 +162900,10 @@
*(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager);
rc = SQLITE_OK;
}else if( op==SQLITE_FCNTL_DATA_VERSION ){
*(unsigned int*)pArg = sqlite3PagerDataVersion(pPager);
rc = SQLITE_OK;
- }else if( op==SQLITE_FCNTL_RESERVE_BYTES ){
- int iNew = *(int*)pArg;
- *(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree);
- if( iNew>=0 && iNew<=255 ){
- sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0);
- }
- rc = SQLITE_OK;
}else{
rc = sqlite3OsFileControl(fd, op, pArg);
}
sqlite3BtreeLeave(pBtree);
}
@@ -164199,10 +163116,24 @@
case SQLITE_TESTCTRL_BYTEORDER: {
rc = SQLITE_BYTEORDER*100 + SQLITE_LITTLEENDIAN*10 + SQLITE_BIGENDIAN;
break;
}
+ /* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N)
+ **
+ ** Set the nReserve size to N for the main database on the database
+ ** connection db.
+ */
+ case SQLITE_TESTCTRL_RESERVE: {
+ sqlite3 *db = va_arg(ap, sqlite3*);
+ int x = va_arg(ap,int);
+ sqlite3_mutex_enter(db->mutex);
+ sqlite3BtreeSetPageSize(db->aDb[0].pBt, 0, x, 0);
+ sqlite3_mutex_leave(db->mutex);
+ break;
+ }
+
/* sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N)
**
** 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
@@ -164382,72 +163313,10 @@
zName--;
}
return zName;
}
-/*
-** Append text z[] to the end of p[]. Return a pointer to the first
-** character after then zero terminator on the new text in p[].
-*/
-static char *appendText(char *p, const char *z){
- size_t n = strlen(z);
- memcpy(p, z, n+1);
- return p+n+1;
-}
-
-/*
-** Allocate memory to hold names for a database, journal file, WAL file,
-** and query parameters. The pointer returned is valid for use by
-** sqlite3_filename_database() and sqlite3_uri_parameter() and related
-** functions.
-**
-** Memory layout must be compatible with that generated by the pager
-** and expected by sqlite3_uri_parameter() and databaseName().
-*/
-SQLITE_API char *sqlite3_create_filename(
- const char *zDatabase,
- const char *zJournal,
- const char *zWal,
- int nParam,
- const char **azParam
-){
- sqlite3_int64 nByte;
- int i;
- char *pResult, *p;
- nByte = strlen(zDatabase) + strlen(zJournal) + strlen(zWal) + 10;
- for(i=0; i='0' && z[i]<='9'; i++){
- iVal = iVal*10 + (z[i] - '0');
- if( iVal>0x7FFFFFFF ) return -1;
- }
- *pnOut = (int)iVal;
- return i;
-}
-
/*
** 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.
@@ -167024,21 +165884,23 @@
**
** This function is used when parsing the "prefix=" FTS4 parameter.
*/
static int fts3GobbleInt(const char **pp, int *pnOut){
const int MAX_NPREFIX = 10000000;
+ const char *p; /* Iterator pointer */
int nInt = 0; /* Output value */
- int nByte;
- nByte = sqlite3Fts3ReadInt(*pp, &nInt);
- if( nInt>MAX_NPREFIX ){
- nInt = 0;
- }
- if( nByte==0 ){
- return SQLITE_ERROR;
+
+ for(p=*pp; p[0]>='0' && p[0]<='9'; p++){
+ nInt = nInt * 10 + (p[0] - '0');
+ if( nInt>MAX_NPREFIX ){
+ nInt = 0;
+ break;
+ }
}
+ if( p==*pp ) return SQLITE_ERROR;
*pnOut = nInt;
- *pp += nByte;
+ *pp = p;
return SQLITE_OK;
}
/*
** This function is called to allocate an array of Fts3Index structures
@@ -167929,11 +166791,10 @@
const char *zEnd = &zCsr[nNode];/* End of interior node buffer */
char *zBuffer = 0; /* Buffer to load terms into */
i64 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 */
- int nBuffer = 0; /* Total term size */
/* 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.
**
@@ -167954,19 +166815,16 @@
while( zCsrnBuffer ){
- rc = FTS_CORRUPT_VTAB;
- goto finish_scan;
- }
}
isFirstTerm = 0;
zCsr += fts3GetVarint32(zCsr, &nSuffix);
assert( nPrefix>=0 && nSuffix>=0 );
@@ -168216,13 +167074,11 @@
static void fts3ReadNextPos(
char **pp, /* IN/OUT: Pointer into position-list buffer */
sqlite3_int64 *pi /* IN/OUT: Value read from position-list */
){
if( (**pp)&0xFE ){
- int iVal;
- *pp += fts3GetVarint32((*pp), &iVal);
- *pi += iVal;
+ fts3GetDeltaVarint(pp, pi);
*pi -= 2;
}else{
*pi = POSITION_LIST_END;
}
}
@@ -171348,11 +170204,10 @@
while( *pRc==SQLITE_OK && pLeft->bEof==0 ){
memset(pDl->pList, 0, pDl->nList);
fts3EvalNextRow(pCsr, pLeft, pRc);
}
}
- pRight->bEof = pLeft->bEof = 1;
}
}
break;
}
@@ -173119,11 +171974,14 @@
/* If this is a "NEAR" keyword, check for an explicit nearness. */
if( pKey->eType==FTSQUERY_NEAR ){
assert( nKey==4 );
if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){
- nKey += 1+sqlite3Fts3ReadInt(&zInput[nKey+1], &nNear);
+ nNear = 0;
+ for(nKey=5; zInput[nKey]>='0' && zInput[nKey]<='9'; nKey++){
+ nNear = nNear * 10 + (zInput[nKey] - '0');
+ }
}
}
/* 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
@@ -176125,11 +174983,11 @@
int nByte = sqlite3_value_bytes(apVal[0]);
pCsr->zInput = sqlite3_malloc64(nByte+1);
if( pCsr->zInput==0 ){
rc = SQLITE_NOMEM;
}else{
- if( nByte>0 ) memcpy(pCsr->zInput, zByte, nByte);
+ memcpy(pCsr->zInput, zByte, nByte);
pCsr->zInput[nByte] = 0;
rc = pTab->pMod->xOpen(pTab->pTok, pCsr->zInput, nByte, &pCsr->pCsr);
if( rc==SQLITE_OK ){
pCsr->pCsr->pTokenizer = pTab->pTok;
}
@@ -177648,11 +176506,10 @@
** 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->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode)
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
- || pReader->nDoclist==0
){
return FTS_CORRUPT_VTAB;
}
return SQLITE_OK;
}
@@ -178736,11 +177593,11 @@
sqlite3_stmt *pStmt;
int rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0);
if( rc!=SQLITE_OK ) return rc;
sqlite3_bind_int64(pStmt, 1, iAbsLevel+1);
sqlite3_bind_int64(pStmt, 2,
- (((u64)iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL
+ ((iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL
);
*pbMax = 0;
if( SQLITE_ROW==sqlite3_step(pStmt) ){
*pbMax = sqlite3_column_type(pStmt, 0)==SQLITE_NULL;
@@ -179302,25 +178159,25 @@
){
const unsigned char *zText = sqlite3_column_text(pStmt, iCol);
if( zText ){
int i;
int iMul = 1;
- u64 iVal = 0;
+ i64 iVal = 0;
for(i=0; zText[i]>='0' && zText[i]<='9'; i++){
iVal = iVal*10 + (zText[i] - '0');
}
- *piEndBlock = (i64)iVal;
+ *piEndBlock = iVal;
while( zText[i]==' ' ) i++;
iVal = 0;
if( zText[i]=='-' ){
i++;
iMul = -1;
}
for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){
iVal = iVal*10 + (zText[i] - '0');
}
- *pnByte = ((i64)iVal * (i64)iMul);
+ *pnByte = (iVal * (i64)iMul);
}
}
/*
@@ -181187,16 +180044,10 @@
/* If nSeg is less that zero, then there is no level with at least
** nMin segments and no hint in the %_stat table. No work to do.
** Exit early in this case. */
if( nSeg<=0 ) break;
- assert( nMod<=0x7FFFFFFF );
- if( iAbsLevel<0 || iAbsLevel>(nMod<<32) ){
- rc = FTS_CORRUPT_VTAB;
- break;
- }
-
/* Open a cursor to iterate through the contents of the oldest nSeg
** indexes of absolute level iAbsLevel. If this cursor is opened using
** the 'hint' parameters, it is possible that there are less than nSeg
** segments available in level iAbsLevel. In this case, no work is
** done on iAbsLevel - fall through to the next iteration of the loop
@@ -182894,11 +181745,11 @@
iStart = pExpr->iPhrase * p->nCol;
}else{
iStart = pExpr->iPhrase * ((p->nCol + 31) / 32);
}
- if( pIter ) while( 1 ){
+ while( 1 ){
int nHit = fts3ColumnlistCount(&pIter);
if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
if( p->flag==FTS3_MATCHINFO_LHITS ){
p->aMatchinfo[iStart + iCol] = (u32)nHit;
}else if( nHit ){
@@ -184808,11 +183659,10 @@
}
/* Append N bytes from zIn onto the end of the JsonString string.
*/
static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
- if( N==0 ) return;
if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
memcpy(p->zBuf+p->nUsed, zIn, N);
p->nUsed += N;
}
@@ -190929,14 +189779,12 @@
pRtree->nAux++;
sqlite3_str_appendf(pSql, ",%.*s", rtreeTokenLength(zArg+1), zArg+1);
}else if( pRtree->nAux>0 ){
break;
}else{
- static const char *azFormat[] = {",%.*s REAL", ",%.*s INT"};
pRtree->nDim2++;
- sqlite3_str_appendf(pSql, azFormat[eCoordType],
- rtreeTokenLength(zArg), zArg);
+ sqlite3_str_appendf(pSql, ",%.*s NUM", rtreeTokenLength(zArg), zArg);
}
}
sqlite3_str_appendf(pSql, ");");
zSql = sqlite3_str_finish(pSql);
if( !zSql ){
@@ -193668,11 +192516,11 @@
** 1. uPattern is an unescaped match-all character "%",
** 2. uPattern is an unescaped match-one character "_",
** 3. uPattern is an unescaped escape character, or
** 4. uPattern is to be handled as an ordinary character
*/
- if( uPattern==MATCH_ALL && !prevEscape && uPattern!=(uint32_t)uEsc ){
+ if( !prevEscape && uPattern==MATCH_ALL ){
/* Case 1. */
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
@@ -193694,16 +192542,16 @@
}
SQLITE_ICU_SKIP_UTF8(zString);
}
return 0;
- }else if( uPattern==MATCH_ONE && !prevEscape && uPattern!=(uint32_t)uEsc ){
+ }else if( !prevEscape && uPattern==MATCH_ONE ){
/* Case 2. */
if( *zString==0 ) return 0;
SQLITE_ICU_SKIP_UTF8(zString);
- }else if( uPattern==(uint32_t)uEsc && !prevEscape ){
+ }else if( !prevEscape && uPattern==(uint32_t)uEsc){
/* Case 3. */
prevEscape = 1;
}else{
/* Case 4. */
@@ -200501,11 +199349,10 @@
}
}
i = 0;
if( iSchema>=0 ){
pIdxInfo->aConstraintUsage[iSchema].argvIndex = ++i;
- pIdxInfo->aConstraintUsage[iSchema].omit = 1;
pIdxInfo->idxNum |= 0x01;
}
if( iName>=0 ){
pIdxInfo->aConstraintUsage[iName].argvIndex = ++i;
pIdxInfo->idxNum |= 0x02;
@@ -200716,13 +199563,11 @@
assert( nPayload>=(u32)nLocal );
assert( nLocal<=(nUsable-35) );
if( nPayload>(u32)nLocal ){
int j;
int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
- if( iOff+nLocal>nUsable || nPayload>0x7fffffff ){
- goto statPageIsCorrupt;
- }
+ if( iOff+nLocal>nUsable ) goto statPageIsCorrupt;
pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
pCell->nOvfl = nOvfl;
pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
@@ -205051,11 +203896,11 @@
const char *zSep = "";
int rc = SQLITE_OK;
SessionBuffer buf = {0, 0, 0};
int nPk = 0;
- sessionAppendStr(&buf, "DELETE FROM main.", &rc);
+ sessionAppendStr(&buf, "DELETE FROM ", &rc);
sessionAppendIdent(&buf, zTab, &rc);
sessionAppendStr(&buf, " WHERE ", &rc);
for(i=0; inCol; i++){
if( p->abPK[i] ){
@@ -205134,11 +203979,11 @@
int i;
const char *zSep = "";
SessionBuffer buf = {0, 0, 0};
/* Append "UPDATE tbl SET " */
- sessionAppendStr(&buf, "UPDATE main.", &rc);
+ sessionAppendStr(&buf, "UPDATE ", &rc);
sessionAppendIdent(&buf, zTab, &rc);
sessionAppendStr(&buf, " SET ", &rc);
/* Append the assignments */
for(i=0; inCol; i++){
@@ -224820,11 +223665,11 @@
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
- sqlite3_result_text(pCtx, "fts5: 2020-05-25 16:19:56 0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba83350", -1, SQLITE_TRANSIENT);
+ sqlite3_result_text(pCtx, "fts5: 2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837bb4d6", -1, SQLITE_TRANSIENT);
}
/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
@@ -228563,11 +227408,10 @@
char *zFts5Tbl; /* Name of fts5 table */
char *zFts5Db; /* Db containing fts5 table */
sqlite3 *db; /* Database handle */
Fts5Global *pGlobal; /* FTS5 global object for this database */
int eType; /* FTS5_VOCAB_COL, ROW or INSTANCE */
- unsigned bBusy; /* True if busy */
};
struct Fts5VocabCursor {
sqlite3_vtab_cursor base;
sqlite3_stmt *pStmt; /* Statement holding lock on pIndex */
@@ -228846,16 +227690,10 @@
Fts5VocabCursor *pCsr = 0;
int rc = SQLITE_OK;
sqlite3_stmt *pStmt = 0;
char *zSql = 0;
- if( pTab->bBusy ){
- pVTab->zErrMsg = sqlite3_mprintf(
- "recursive definition for %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
- );
- return SQLITE_ERROR;
- }
zSql = sqlite3Fts5Mprintf(&rc,
"SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'",
pTab->zFts5Tbl, pTab->zFts5Db, pTab->zFts5Tbl, pTab->zFts5Tbl
);
if( zSql ){
@@ -228863,16 +227701,14 @@
}
sqlite3_free(zSql);
assert( rc==SQLITE_OK || pStmt==0 );
if( rc==SQLITE_ERROR ) rc = SQLITE_OK;
- pTab->bBusy = 1;
if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
i64 iId = sqlite3_column_int64(pStmt, 0);
pFts5 = sqlite3Fts5TableFromCsrid(pTab->pGlobal, iId);
}
- pTab->bBusy = 0;
if( rc==SQLITE_OK ){
if( pFts5==0 ){
rc = sqlite3_finalize(pStmt);
pStmt = 0;
@@ -229471,12 +228307,11 @@
}
case STMT_COLUMN_BUSY: {
sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
break;
}
- default: {
- assert( i==STMT_COLUMN_MEM );
+ case STMT_COLUMN_MEM: {
i = SQLITE_STMTSTATUS_MEMUSED +
STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
/* Fall thru */
}
case STMT_COLUMN_NSCAN:
@@ -229603,12 +228438,12 @@
}
#endif /* SQLITE_CORE */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
/************** End of stmt.c ************************************************/
-#if __LINE__!=229608
+#if __LINE__!=228443
#undef SQLITE_SOURCE_ID
-#define SQLITE_SOURCE_ID "2020-05-25 16:19:56 0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba8alt2"
+#define SQLITE_SOURCE_ID "2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837balt2"
#endif
/* Return the source-id for this library */
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
/************************** End of sqlite3.c ******************************/