@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.8.10. By combining all the individual C code files into this
+** version 3.8.8.3. 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
@@ -22,6 +22,9 @@
#ifndef SQLITE_PRIVATE
# define SQLITE_PRIVATE static
#endif
+#ifndef SQLITE_API
+# define SQLITE_API
+#endif
/************** Begin file sqliteInt.h ***************************************/
/*
** 2001 September 15
@@ -70,7 +73,6 @@
#pragma warning(disable : 4055)
#pragma warning(disable : 4100)
#pragma warning(disable : 4127)
-#pragma warning(disable : 4130)
#pragma warning(disable : 4152)
#pragma warning(disable : 4189)
#pragma warning(disable : 4206)
@@ -89,44 +91,6 @@
/************** Continuing where we left off in sqliteInt.h ******************/
/*
-** Special setup for VxWorks
-*/
-/************** Include vxworks.h in the middle of sqliteInt.h ***************/
-/************** Begin file vxworks.h *****************************************/
-/*
-** 2015-03-02
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains code that is specific to Wind River's VxWorks
-*/
-#if defined(__RTP__) || defined(_WRS_KERNEL)
-/* This is VxWorks. Set up things specially for that OS
-*/
-#include <vxWorks.h>
-#include <pthread.h> /* amalgamator: dontcache */
-#define OS_VXWORKS 1
-#define SQLITE_OS_OTHER 0
-#define SQLITE_HOMEGROWN_RECURSIVE_MUTEX 1
-#define SQLITE_OMIT_LOAD_EXTENSION 1
-#define SQLITE_ENABLE_LOCKING_STYLE 0
-#define HAVE_UTIME 1
-#else
-/* This is not VxWorks. */
-#define OS_VXWORKS 0
-#endif /* defined(_WRS_KERNEL) */
-
-/************** End of vxworks.h *********************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-
-/*
** These #defines should enable >2GB file support on POSIX if the
** underlying operating system supports it. If the OS lacks
** large file support, or if the OS is windows, these should be no-ops.
@@ -250,20 +214,16 @@ extern "C" {
/*
-** Provide the ability to override linkage features of the interface.
+** Add the ability to override 'extern'
*/
#ifndef SQLITE_EXTERN
# define SQLITE_EXTERN extern
#endif
+
#ifndef SQLITE_API
# define SQLITE_API
#endif
-#ifndef SQLITE_CDECL
-# define SQLITE_CDECL
-#endif
-#ifndef SQLITE_STDCALL
-# define SQLITE_STDCALL
-#endif
+
/*
** These no-op macros are used in front of interfaces to mark those
@@ -318,9 +278,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.8.10"
-#define SQLITE_VERSION_NUMBER 3008010
-#define SQLITE_SOURCE_ID "2015-05-07 11:53:08 cf975957b9ae671f34bb65f049acf351e650d437"
+#define SQLITE_VERSION "3.8.8.3"
+#define SQLITE_VERSION_NUMBER 3008008
+#define SQLITE_SOURCE_ID "2015-02-25 13:29:11 9d6c1880fb75660bbabd693175579529785f8a6b"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -353,9 +313,9 @@ extern "C" {
** See also: [sqlite_version()] and [sqlite_source_id()].
*/
SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
-SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void);
-SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void);
+SQLITE_API const char *sqlite3_libversion(void);
+SQLITE_API const char *sqlite3_sourceid(void);
+SQLITE_API int sqlite3_libversion_number(void);
/*
** CAPI3REF: Run-Time Library Compilation Options Diagnostics
@@ -380,8 +340,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void);
** [sqlite_compileoption_get()] and the [compile_options pragma].
*/
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N);
+SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
+SQLITE_API const char *sqlite3_compileoption_get(int N);
#endif
/*
@@ -420,7 +380,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N);
**
** See the [threading mode] documentation for additional information.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void);
+SQLITE_API int sqlite3_threadsafe(void);
/*
** CAPI3REF: Database Connection Handle
@@ -477,7 +437,6 @@ typedef sqlite_uint64 sqlite3_uint64;
/*
** CAPI3REF: Closing A Database Connection
-** DESTRUCTOR: sqlite3
**
** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
** for the [sqlite3] object.
@@ -517,8 +476,8 @@ typedef sqlite_uint64 sqlite3_uint64;
** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
** argument is a harmless no-op.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*);
-SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*);
+SQLITE_API int sqlite3_close(sqlite3*);
+SQLITE_API int sqlite3_close_v2(sqlite3*);
/*
** The type for a callback function.
@@ -529,7 +488,6 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
/*
** CAPI3REF: One-Step Query Execution Interface
-** METHOD: sqlite3
**
** The sqlite3_exec() interface is a convenience wrapper around
** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
@@ -589,7 +547,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
** </ul>
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_exec(
+SQLITE_API int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
@@ -969,16 +927,14 @@ struct sqlite3_io_methods {
** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
** interface.
**
-** <ul>
-** <li>[[SQLITE_FCNTL_LOCKSTATE]]
** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This
** opcode causes the xFileControl method to write the current state of
** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
** into an integer that the pArg argument points to. This capability
-** is used during testing and is only available when the SQLITE_TEST
-** compile-time option is used.
-**
+** is used during testing and only needs to be supported when SQLITE_TEST
+** is defined.
+** <ul>
** <li>[[SQLITE_FCNTL_SIZE_HINT]]
** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
** layer a hint of how large the database file will grow to be during the
@@ -1103,9 +1059,7 @@ struct sqlite3_io_methods {
** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA]
** file control returns [SQLITE_OK], then the parser assumes that the
** VFS has handled the PRAGMA itself and the parser generates a no-op
-** prepared statement if result string is NULL, or that returns a copy
-** of the result string if the string is non-NULL.
-** ^If the [SQLITE_FCNTL_PRAGMA] file control returns
+** prepared statement. ^If the [SQLITE_FCNTL_PRAGMA] file control returns
** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
** that the VFS encountered an error while handling the [PRAGMA] and the
** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA]
@@ -1163,19 +1117,12 @@ struct sqlite3_io_methods {
** pointed to by the pArg argument. This capability is used during testing
** and only needs to be supported when SQLITE_TEST is defined.
**
-** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
-** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
-** be advantageous to block on the next WAL lock if the lock is not immediately
-** available. The WAL subsystem issues this signal during rare
-** circumstances in order to fix a problem with priority inversion.
-** Applications should <em>not</em> use this file-control.
-**
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
-#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
-#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
-#define SQLITE_FCNTL_LAST_ERRNO 4
+#define SQLITE_GET_LOCKPROXYFILE 2
+#define SQLITE_SET_LOCKPROXYFILE 3
+#define SQLITE_LAST_ERRNO 4
#define SQLITE_FCNTL_SIZE_HINT 5
#define SQLITE_FCNTL_CHUNK_SIZE 6
#define SQLITE_FCNTL_FILE_POINTER 7
@@ -1194,13 +1141,6 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_SYNC 21
#define SQLITE_FCNTL_COMMIT_PHASETWO 22
#define SQLITE_FCNTL_WIN32_SET_HANDLE 23
-#define SQLITE_FCNTL_WAL_BLOCK 24
-
-/* 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
-
/*
** CAPI3REF: Mutex Handle
@@ -1549,10 +1489,10 @@ struct sqlite3_vfs {
** must return [SQLITE_OK] on success and some other [error code] upon
** failure.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void);
-SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void);
-SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void);
-SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void);
+SQLITE_API int sqlite3_initialize(void);
+SQLITE_API int sqlite3_shutdown(void);
+SQLITE_API int sqlite3_os_init(void);
+SQLITE_API int sqlite3_os_end(void);
/*
** CAPI3REF: Configuring The SQLite Library
@@ -1583,11 +1523,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void);
** ^If the option is unknown or SQLite is unable to set the option
** then this routine returns a non-zero [error code].
*/
-SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...);
+SQLITE_API int sqlite3_config(int, ...);
/*
** CAPI3REF: Configure database connections
-** METHOD: sqlite3
**
** The sqlite3_db_config() interface is used to make configuration
** changes to a [database connection]. The interface is similar to
@@ -1602,7 +1541,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...);
** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
** the call is considered successful.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...);
+SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Memory Allocation Routines
@@ -1762,7 +1701,7 @@ struct sqlite3_mem_methods {
** <li> [sqlite3_memory_used()]
** <li> [sqlite3_memory_highwater()]
** <li> [sqlite3_soft_heap_limit64()]
-** <li> [sqlite3_status64()]
+** <li> [sqlite3_status()]
** </ul>)^
** ^Memory allocation statistics are enabled by default unless SQLite is
** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
@@ -1973,6 +1912,7 @@ struct sqlite3_mem_methods {
** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro
** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
** that specifies the maximum size of the created heap.
+** </dl>
**
** [[SQLITE_CONFIG_PCACHE_HDRSZ]]
** <dt>SQLITE_CONFIG_PCACHE_HDRSZ
@@ -2085,17 +2025,15 @@ struct sqlite3_mem_methods {
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
-** METHOD: sqlite3
**
** ^The sqlite3_extended_result_codes() routine enables or disables the
** [extended result codes] feature of SQLite. ^The extended result
** codes are disabled by default for historical compatibility.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff);
+SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
** CAPI3REF: Last Insert Rowid
-** METHOD: sqlite3
**
** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
** has a unique 64-bit signed
@@ -2143,11 +2081,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff)
** unpredictable and might not equal either the old or the new
** last insert [rowid].
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*);
+SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
/*
** CAPI3REF: Count The Number Of Rows Modified
-** METHOD: sqlite3
**
** ^This function returns the number of rows modified, inserted or
** deleted by the most recently completed INSERT, UPDATE or DELETE
@@ -2196,11 +2133,10 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*);
** while [sqlite3_changes()] is running then the value returned
** is unpredictable and not meaningful.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*);
+SQLITE_API int sqlite3_changes(sqlite3*);
/*
** CAPI3REF: Total Number Of Rows Modified
-** METHOD: sqlite3
**
** ^This function returns the total number of rows inserted, modified or
** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed
@@ -2220,11 +2156,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*);
** while [sqlite3_total_changes()] is running then the value
** returned is unpredictable and not meaningful.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*);
+SQLITE_API int sqlite3_total_changes(sqlite3*);
/*
** CAPI3REF: Interrupt A Long-Running Query
-** METHOD: sqlite3
**
** ^This function causes any pending database operation to abort and
** return at its earliest opportunity. This routine is typically
@@ -2260,7 +2195,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*);
** If the database connection closes while [sqlite3_interrupt()]
** is running then bad things will likely happen.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*);
+SQLITE_API void sqlite3_interrupt(sqlite3*);
/*
** CAPI3REF: Determine If An SQL Statement Is Complete
@@ -2295,13 +2230,12 @@ SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*);
** The input to [sqlite3_complete16()] must be a zero-terminated
** UTF-16 string in native byte order.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql);
-SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql);
+SQLITE_API int sqlite3_complete(const char *sql);
+SQLITE_API int sqlite3_complete16(const void *sql);
/*
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
** KEYWORDS: {busy-handler callback} {busy handler}
-** METHOD: sqlite3
**
** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
** that might be invoked with argument P whenever
@@ -2357,11 +2291,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql);
** A busy handler must not close the database connection
** or [prepared statement] that invoked the busy handler.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
+SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
/*
** CAPI3REF: Set A Busy Timeout
-** METHOD: sqlite3
**
** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
** for a specified amount of time when a table is locked. ^The handler
@@ -2380,11 +2313,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int),
**
** See also: [PRAGMA busy_timeout]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms);
+SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
/*
** CAPI3REF: Convenience Routines For Running Queries
-** METHOD: sqlite3
**
** This is a legacy interface that is preserved for backwards compatibility.
** Use of this interface is not recommended.
@@ -2455,7 +2387,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms);
** reflected in subsequent calls to [sqlite3_errcode()] or
** [sqlite3_errmsg()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
+SQLITE_API int sqlite3_get_table(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
char ***pazResult, /* Results of the query */
@@ -2463,17 +2395,13 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
int *pnColumn, /* Number of result columns written here */
char **pzErrmsg /* Error msg written here */
);
-SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result);
+SQLITE_API void sqlite3_free_table(char **result);
/*
** CAPI3REF: Formatted String Printing Functions
**
** These routines are work-alikes of the "printf()" family of functions
** from the standard C library.
-** These routines understand most of the common K&R formatting options,
-** plus some additional non-standard formats, detailed below.
-** Note that some of the more obscure formatting options from recent
-** C-library standards are omitted from this implementation.
**
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
** results into memory obtained from [sqlite3_malloc()].
@@ -2506,7 +2434,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result);
** These routines all implement some additional formatting
** options that are useful for constructing SQL statements.
** All of the usual printf() formatting options apply. In addition, there
-** is are "%q", "%Q", "%w" and "%z" options.
+** is are "%q", "%Q", and "%z" options.
**
** ^(The %q option works like %s in that it substitutes a nul-terminated
** string from the argument list. But %q also doubles every '\'' character.
@@ -2559,20 +2487,14 @@ SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result);
** The code above will render a correct SQL statement in the zSQL
** variable even if the zText variable is a NULL pointer.
**
-** ^(The "%w" formatting option is like "%q" except that it expects to
-** be contained within double-quotes instead of single quotes, and it
-** escapes the double-quote character instead of the single-quote
-** character.)^ The "%w" formatting option is intended for safely inserting
-** table and column names into a constructed SQL statement.
-**
** ^(The "%z" formatting option works like "%s" but with the
** addition that after the string has been read and copied into
** the result, [sqlite3_free()] is called on the input string.)^
*/
-SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...);
-SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list);
-SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...);
-SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list);
+SQLITE_API char *sqlite3_mprintf(const char*,...);
+SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
+SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
+SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
/*
** CAPI3REF: Memory Allocation Subsystem
@@ -2662,12 +2584,12 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list
** a block of memory after it has been released using
** [sqlite3_free()] or [sqlite3_realloc()].
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int);
-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64);
-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int);
-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64);
-SQLITE_API void SQLITE_STDCALL sqlite3_free(void*);
-SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*);
+SQLITE_API void *sqlite3_malloc(int);
+SQLITE_API void *sqlite3_malloc64(sqlite3_uint64);
+SQLITE_API void *sqlite3_realloc(void*, int);
+SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64);
+SQLITE_API void sqlite3_free(void*);
+SQLITE_API sqlite3_uint64 sqlite3_msize(void*);
/*
** CAPI3REF: Memory Allocator Statistics
@@ -2692,8 +2614,8 @@ SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*);
** by [sqlite3_memory_highwater(1)] is the high-water mark
** prior to the reset.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void);
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag);
+SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
+SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
/*
** CAPI3REF: Pseudo-Random Number Generator
@@ -2716,11 +2638,10 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag);
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P);
+SQLITE_API void sqlite3_randomness(int N, void *P);
/*
** CAPI3REF: Compile-Time Authorization Callbacks
-** METHOD: sqlite3
**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
@@ -2799,7 +2720,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P);
** as stated in the previous paragraph, sqlite3_step() invokes
** sqlite3_prepare_v2() to reprepare a statement after a schema change.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
+SQLITE_API int sqlite3_set_authorizer(
sqlite3*,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pUserData
@@ -2877,7 +2798,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
/*
** CAPI3REF: Tracing And Profiling Functions
-** METHOD: sqlite3
**
** These routines register callback functions that can be used for
** tracing and profiling the execution of SQL statements.
@@ -2904,13 +2824,12 @@ SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
** sqlite3_profile() function is considered experimental and is
** subject to change in future versions of SQLite.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
-SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*,
+SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
+SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
/*
** CAPI3REF: Query Progress Callbacks
-** METHOD: sqlite3
**
** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
** function X to be invoked periodically during long running calls to
@@ -2940,11 +2859,10 @@ SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*,
** database connections for the meaning of "modify" in this paragraph.
**
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
/*
** CAPI3REF: Opening A New Database Connection
-** CONSTRUCTOR: sqlite3
**
** ^These routines open an SQLite database file as specified by the
** filename argument. ^The filename argument is interpreted as UTF-8 for
@@ -3169,15 +3087,15 @@ SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(vo
**
** See also: [sqlite3_temp_directory]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_open(
+SQLITE_API int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_open16(
+SQLITE_API int sqlite3_open16(
const void *filename, /* Database filename (UTF-16) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
+SQLITE_API int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
@@ -3223,22 +3141,19 @@ SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
** VFS method, then the behavior of this routine is undefined and probably
** undesirable.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam);
-SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
+SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
+SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
+SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
/*
** CAPI3REF: Error Codes And Messages
-** METHOD: sqlite3
-**
-** ^If the most recent sqlite3_* API call associated with
-** [database connection] D failed, then the sqlite3_errcode(D) interface
-** returns the numeric [result code] or [extended result code] for that
-** API call.
-** If the most recent API call was successful,
-** then the return value from sqlite3_errcode() is undefined.
-** ^The sqlite3_extended_errcode()
+**
+** ^The sqlite3_errcode() interface returns the numeric [result code] or
+** [extended result code] for the most recent failed sqlite3_* API call
+** associated with a [database connection]. If a prior API call failed
+** but the most recent API call succeeded, the return value from
+** sqlite3_errcode() is undefined. ^The sqlite3_extended_errcode()
** interface is the same except that it always returns the
** [extended result code] even when extended result codes are
** disabled.
@@ -3269,41 +3184,40 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const cha
** was invoked incorrectly by the application. In that case, the
** error code and message may or may not be set.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db);
-SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int);
+SQLITE_API int sqlite3_errcode(sqlite3 *db);
+SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
+SQLITE_API const char *sqlite3_errmsg(sqlite3*);
+SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
+SQLITE_API const char *sqlite3_errstr(int);
/*
-** CAPI3REF: Prepared Statement Object
+** CAPI3REF: SQL Statement Object
** KEYWORDS: {prepared statement} {prepared statements}
**
-** An instance of this object represents a single SQL statement that
-** has been compiled into binary form and is ready to be evaluated.
+** An instance of this object represents a single SQL statement.
+** This object is variously known as a "prepared statement" or a
+** "compiled SQL statement" or simply as a "statement".
**
-** Think of each SQL statement as a separate computer program. The
-** original SQL text is source code. A prepared statement object
-** is the compiled object code. All SQL must be converted into a
-** prepared statement before it can be run.
-**
-** The life-cycle of a prepared statement object usually goes like this:
+** The life of a statement object goes something like this:
**
** <ol>
-** <li> Create the prepared statement object using [sqlite3_prepare_v2()].
-** <li> Bind values to [parameters] using the sqlite3_bind_*()
+** <li> Create the object using [sqlite3_prepare_v2()] or a related
+** function.
+** <li> Bind values to [host parameters] using the sqlite3_bind_*()
** interfaces.
** <li> Run the SQL by calling [sqlite3_step()] one or more times.
-** <li> Reset the prepared statement using [sqlite3_reset()] then go back
+** <li> Reset the statement using [sqlite3_reset()] then go back
** to step 2. Do this zero or more times.
** <li> Destroy the object using [sqlite3_finalize()].
** </ol>
+**
+** Refer to documentation on individual methods above for additional
+** information.
*/
typedef struct sqlite3_stmt sqlite3_stmt;
/*
** CAPI3REF: Run-time Limits
-** METHOD: sqlite3
**
** ^(This interface allows the size of various constructs to be limited
** on a connection by connection basis. The first parameter is the
@@ -3341,7 +3255,7 @@ typedef struct sqlite3_stmt sqlite3_stmt;
**
** New run-time limit categories may be added in future releases.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
+SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
/*
** CAPI3REF: Run-Time Limit Categories
@@ -3415,8 +3329,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
-** METHOD: sqlite3
-** CONSTRUCTOR: sqlite3_stmt
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
@@ -3430,14 +3342,16 @@ SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
** use UTF-16.
**
-** ^If the nByte argument is negative, then zSql is read up to the
-** first zero terminator. ^If nByte is positive, then it is the
-** number of bytes read from zSql. ^If nByte is zero, then no prepared
-** statement is generated.
-** If the caller knows that the supplied string is nul-terminated, then
-** there is a small performance advantage to passing an nByte parameter that
-** is the number of bytes in the input string <i>including</i>
-** the nul-terminator.
+** ^If the nByte argument is less than zero, then zSql is read up to the
+** first zero terminator. ^If nByte is non-negative, then it is the maximum
+** number of bytes read from zSql. ^When nByte is non-negative, the
+** zSql string ends at either the first '\000' or '\u0000' character or
+** the nByte-th byte, whichever comes first. If the caller knows
+** that the supplied string is nul-terminated, then there is a small
+** performance advantage to be gained by passing an nByte parameter that
+** is equal to the number of bytes in the input string <i>including</i>
+** the nul-terminator bytes as this saves SQLite from having to
+** make a copy of the input string.
**
** ^If pzTail is not NULL then *pzTail is made to point to the first byte
** past the end of the first SQL statement in zSql. These routines only
@@ -3493,28 +3407,28 @@ SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
** </li>
** </ol>
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
+SQLITE_API int sqlite3_prepare(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
+SQLITE_API int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
+SQLITE_API int sqlite3_prepare16(
sqlite3 *db, /* Database handle */
const void *zSql, /* SQL statement, UTF-16 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const void **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
+SQLITE_API int sqlite3_prepare16_v2(
sqlite3 *db, /* Database handle */
const void *zSql, /* SQL statement, UTF-16 encoded */
int nByte, /* Maximum length of zSql in bytes. */
@@ -3524,17 +3438,15 @@ SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
/*
** CAPI3REF: Retrieving Statement SQL
-** METHOD: sqlite3_stmt
**
** ^This interface can be used to retrieve a saved copy of the original
** SQL text used to create a [prepared statement] if that statement was
** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt);
+SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If An SQL Statement Writes The Database
-** METHOD: sqlite3_stmt
**
** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
** and only if the [prepared statement] X makes no direct changes to
@@ -3562,11 +3474,10 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt);
** change the configuration of a database connection, they do not make
** changes to the content of the database files on disk.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If A Prepared Statement Has Been Reset
-** METHOD: sqlite3_stmt
**
** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
** [prepared statement] S has been stepped at least once using
@@ -3582,7 +3493,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
** for example, in diagnostic routines to search for prepared
** statements that are holding a transaction open.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*);
+SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
/*
** CAPI3REF: Dynamically Typed Value Object
@@ -3641,7 +3552,6 @@ typedef struct sqlite3_context sqlite3_context;
** CAPI3REF: Binding Values To Prepared Statements
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
-** METHOD: sqlite3_stmt
**
** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
** literals may be replaced by a [parameter] that matches one of following
@@ -3744,23 +3654,22 @@ typedef struct sqlite3_context sqlite3_context;
** See also: [sqlite3_bind_parameter_count()],
** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
+SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
+SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
void(*)(void*));
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
+SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
+SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
+SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
+SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
+SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
+SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
void(*)(void*), unsigned char encoding);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
+SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
/*
** CAPI3REF: Number Of SQL Parameters
-** METHOD: sqlite3_stmt
**
** ^This routine can be used to find the number of [SQL parameters]
** in a [prepared statement]. SQL parameters are tokens of the
@@ -3777,11 +3686,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
** [sqlite3_bind_parameter_name()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
+SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
/*
** CAPI3REF: Name Of A Host Parameter
-** METHOD: sqlite3_stmt
**
** ^The sqlite3_bind_parameter_name(P,N) interface returns
** the name of the N-th [SQL parameter] in the [prepared statement] P.
@@ -3805,11 +3713,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
/*
** CAPI3REF: Index Of A Parameter With A Given Name
-** METHOD: sqlite3_stmt
**
** ^Return the index of an SQL parameter given its name. ^The
** index value returned is suitable for use as the second
@@ -3822,21 +3729,19 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*,
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
/*
** CAPI3REF: Reset All Bindings On A Prepared Statement
-** METHOD: sqlite3_stmt
**
** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset
** the [sqlite3_bind_blob | bindings] on a [prepared statement].
** ^Use this routine to reset all host parameters to NULL.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*);
+SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
/*
** CAPI3REF: Number Of Columns In A Result Set
-** METHOD: sqlite3_stmt
**
** ^Return the number of columns in the result set returned by the
** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
@@ -3844,11 +3749,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*);
**
** See also: [sqlite3_data_count()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Column Names In A Result Set
-** METHOD: sqlite3_stmt
**
** ^These routines return the name assigned to a particular column
** in the result set of a [SELECT] statement. ^The sqlite3_column_name()
@@ -3873,12 +3777,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt);
** then the name of the column is unspecified and may change from
** one release of SQLite to the next.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N);
+SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
+SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
/*
** CAPI3REF: Source Of Data In A Query Result
-** METHOD: sqlite3_stmt
**
** ^These routines provide a means to determine the database, table, and
** table column that is the origin of a particular result column in
@@ -3922,16 +3825,15 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N
** for the same [prepared statement] and result column
** at the same time then the results are undefined.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
/*
** CAPI3REF: Declared Datatype Of A Query Result
-** METHOD: sqlite3_stmt
**
** ^(The first parameter is a [prepared statement].
** If this statement is a [SELECT] statement and the Nth column of the
@@ -3959,12 +3861,11 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*
** is associated with individual values, not with the containers
** used to hold those values.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
/*
** CAPI3REF: Evaluate An SQL Statement
-** METHOD: sqlite3_stmt
**
** After a [prepared statement] has been prepared using either
** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
@@ -4040,11 +3941,10 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,in
** then the more specific [error codes] are returned directly
** by sqlite3_step(). The use of the "v2" interface is recommended.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*);
+SQLITE_API int sqlite3_step(sqlite3_stmt*);
/*
** CAPI3REF: Number of columns in a result set
-** METHOD: sqlite3_stmt
**
** ^The sqlite3_data_count(P) interface returns the number of columns in the
** current row of the result set of [prepared statement] P.
@@ -4061,7 +3961,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*);
**
** See also: [sqlite3_column_count()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Fundamental Datatypes
@@ -4098,7 +3998,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Result Values From A Query
** KEYWORDS: {column access functions}
-** METHOD: sqlite3_stmt
**
** These routines form the "result set" interface.
**
@@ -4258,20 +4157,19 @@ SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt);
** pointer. Subsequent calls to [sqlite3_errcode()] will return
** [SQLITE_NOMEM].)^
*/
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol);
-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol);
-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
-SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol);
-SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol);
-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol);
-SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol);
+SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
+SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
+SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
+SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
/*
** CAPI3REF: Destroy A Prepared Statement Object
-** DESTRUCTOR: sqlite3_stmt
**
** ^The sqlite3_finalize() function is called to delete a [prepared statement].
** ^If the most recent evaluation of the statement encountered no errors
@@ -4295,11 +4193,10 @@ SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int
** statement after it has been finalized can result in undefined and
** undesirable behavior such as segfaults and heap corruption.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Reset A Prepared Statement Object
-** METHOD: sqlite3_stmt
**
** The sqlite3_reset() function is called to reset a [prepared statement]
** object back to its initial state, ready to be re-executed.
@@ -4322,14 +4219,13 @@ SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt);
** ^The [sqlite3_reset(S)] interface does not change the values
** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Create Or Redefine SQL Functions
** KEYWORDS: {function creation routines}
** KEYWORDS: {application-defined SQL function}
** KEYWORDS: {application-defined SQL functions}
-** METHOD: sqlite3
**
** ^These functions (collectively known as "function creation routines")
** are used to add SQL functions or aggregates or to redefine the behavior
@@ -4422,7 +4318,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt);
** close the database connection nor finalize or reset the prepared
** statement in which the function is running.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
+SQLITE_API int sqlite3_create_function(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -4432,7 +4328,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
+SQLITE_API int sqlite3_create_function16(
sqlite3 *db,
const void *zFunctionName,
int nArg,
@@ -4442,7 +4338,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
+SQLITE_API int sqlite3_create_function_v2(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -4484,22 +4380,21 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
** These functions are [deprecated]. In order to maintain
** backwards compatibility with older code, these functions continue
** to be supported. However, new applications should avoid
-** the use of these functions. To encourage programmers to avoid
-** these functions, we will not explain what they do.
+** the use of these functions. To help encourage people to avoid
+** using these functions, we are not going to tell you what they do.
*/
#ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*);
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void);
-SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void);
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
+SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
+SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
void*,sqlite3_int64);
#endif
/*
** CAPI3REF: Obtaining SQL Function Parameter Values
-** METHOD: sqlite3_value
**
** The C-language implementation of SQL functions and aggregates uses
** this set of interface routines to access the parameter values on
@@ -4543,22 +4438,21 @@ SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(voi
** These routines must be called from the same thread as
** the SQL function that supplied the [sqlite3_value*] parameters.
*/
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*);
-SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*);
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*);
-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
+SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
+SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
+SQLITE_API double sqlite3_value_double(sqlite3_value*);
+SQLITE_API int sqlite3_value_int(sqlite3_value*);
+SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
+SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
+SQLITE_API int sqlite3_value_type(sqlite3_value*);
+SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
/*
** CAPI3REF: Obtain Aggregate Function Context
-** METHOD: sqlite3_context
**
** Implementations of aggregate SQL functions use this
** routine to allocate memory for storing their state.
@@ -4599,11 +4493,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
** This routine must be called from the same thread in which
** the aggregate SQL function is running.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes);
+SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
/*
** CAPI3REF: User Data For Functions
-** METHOD: sqlite3_context
**
** ^The sqlite3_user_data() interface returns a copy of
** the pointer that was the pUserData parameter (the 5th parameter)
@@ -4614,11 +4507,10 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int
** This routine must be called from the same thread in which
** the application-defined function is running.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*);
+SQLITE_API void *sqlite3_user_data(sqlite3_context*);
/*
** CAPI3REF: Database Connection For Functions
-** METHOD: sqlite3_context
**
** ^The sqlite3_context_db_handle() interface returns a copy of
** the pointer to the [database connection] (the 1st parameter)
@@ -4626,11 +4518,10 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*);
** and [sqlite3_create_function16()] routines that originally
** registered the application defined function.
*/
-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*);
+SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
/*
** CAPI3REF: Function Auxiliary Data
-** METHOD: sqlite3_context
**
** These functions may be used by (non-aggregate) SQL functions to
** associate metadata with argument values. If the same value is passed to
@@ -4679,8 +4570,8 @@ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*);
** These routines must be called from the same thread in which
** the SQL function is running.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N);
-SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
+SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
+SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
/*
@@ -4703,7 +4594,6 @@ typedef void (*sqlite3_destructor_type)(void*);
/*
** CAPI3REF: Setting The Result Of An SQL Function
-** METHOD: sqlite3_context
**
** These routines are used by the xFunc or xFinal callbacks that
** implement SQL functions and aggregates. See
@@ -4816,30 +4706,29 @@ typedef void (*sqlite3_destructor_type)(void*);
** than the one containing the application-defined function that received
** the [sqlite3_context] pointer, the results are undefined.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*,
+SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
sqlite3_uint64,void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
+SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
+SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
+SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
+SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
+SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
+SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
+SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
+SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
+SQLITE_API void sqlite3_result_null(sqlite3_context*);
+SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
void(*)(void*), unsigned char encoding);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n);
+SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
/*
** CAPI3REF: Define New Collating Sequences
-** METHOD: sqlite3
**
** ^These functions add, remove, or modify a [collation] associated
** with the [database connection] specified as the first argument.
@@ -4917,14 +4806,14 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n);
**
** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
+SQLITE_API int sqlite3_create_collation(
sqlite3*,
const char *zName,
int eTextRep,
void *pArg,
int(*xCompare)(void*,int,const void*,int,const void*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
+SQLITE_API int sqlite3_create_collation_v2(
sqlite3*,
const char *zName,
int eTextRep,
@@ -4932,7 +4821,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
int(*xCompare)(void*,int,const void*,int,const void*),
void(*xDestroy)(void*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
+SQLITE_API int sqlite3_create_collation16(
sqlite3*,
const void *zName,
int eTextRep,
@@ -4942,7 +4831,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
/*
** CAPI3REF: Collation Needed Callbacks
-** METHOD: sqlite3
**
** ^To avoid having to register all collation sequences before a database
** can be used, a single callback function may be registered with the
@@ -4967,12 +4855,12 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
** [sqlite3_create_collation_v2()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
+SQLITE_API int sqlite3_collation_needed(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const char*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
+SQLITE_API int sqlite3_collation_needed16(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const void*)
@@ -4986,11 +4874,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
** The code to implement this API is not available in the public release
** of SQLite.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_key(
+SQLITE_API int sqlite3_key(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The key */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(
+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 */
@@ -5004,11 +4892,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(
** The code to implement this API is not available in the public release
** of SQLite.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_rekey(
+SQLITE_API int sqlite3_rekey(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The new key */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(
+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 */
@@ -5018,7 +4906,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(
** Specify the activation key for a SEE database. Unless
** activated, none of the SEE routines will work.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(
+SQLITE_API void sqlite3_activate_see(
const char *zPassPhrase /* Activation phrase */
);
#endif
@@ -5028,7 +4916,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(
** Specify the activation key for a CEROD database. Unless
** activated, none of the CEROD routines will work.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod(
+SQLITE_API void sqlite3_activate_cerod(
const char *zPassPhrase /* Activation phrase */
);
#endif
@@ -5050,7 +4938,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod(
** all, then the behavior of sqlite3_sleep() may deviate from the description
** in the previous paragraphs.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int);
+SQLITE_API int sqlite3_sleep(int);
/*
** CAPI3REF: Name Of The Folder Holding Temporary Files
@@ -5150,7 +5038,6 @@ SQLITE_API char *sqlite3_data_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
-** METHOD: sqlite3
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
@@ -5169,11 +5056,10 @@ SQLITE_API char *sqlite3_data_directory;
** connection while this routine is running, then the return value
** is undefined.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
+SQLITE_API int sqlite3_get_autocommit(sqlite3*);
/*
** CAPI3REF: Find The Database Handle Of A Prepared Statement
-** METHOD: sqlite3_stmt
**
** ^The sqlite3_db_handle interface returns the [database connection] handle
** to which a [prepared statement] belongs. ^The [database connection]
@@ -5182,11 +5068,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
** create the statement in the first place.
*/
-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
+SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
/*
** CAPI3REF: Return The Filename For A Database Connection
-** METHOD: sqlite3
**
** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
** associated with database N of connection D. ^The main database file
@@ -5199,21 +5084,19 @@ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
** will be an absolute pathname, even if the filename used
** to open the database originally was a URI or relative pathname.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName);
+SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Determine if a database is read-only
-** METHOD: sqlite3
**
** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N
** of connection D is read-only, 0 if it is read/write, or -1 if N is not
** the name of a database on connection D.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
+SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Find the next prepared statement
-** METHOD: sqlite3
**
** ^This interface returns a pointer to the next [prepared statement] after
** pStmt associated with the [database connection] pDb. ^If pStmt is NULL
@@ -5225,11 +5108,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbNa
** [sqlite3_next_stmt(D,S)] must refer to an open database
** connection and in particular must not be a NULL pointer.
*/
-SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
+SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
/*
** CAPI3REF: Commit And Rollback Notification Callbacks
-** METHOD: sqlite3
**
** ^The sqlite3_commit_hook() interface registers a callback
** function to be invoked whenever a transaction is [COMMIT | committed].
@@ -5274,12 +5156,11 @@ SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_
**
** See also the [sqlite3_update_hook()] interface.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
-SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
+SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
+SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
/*
** CAPI3REF: Data Change Notification Callbacks
-** METHOD: sqlite3
**
** ^The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
@@ -5326,7 +5207,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *),
** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
** interfaces.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
+SQLITE_API void *sqlite3_update_hook(
sqlite3*,
void(*)(void *,int ,char const *,char const *,sqlite3_int64),
void*
@@ -5356,17 +5237,12 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
** future releases of SQLite. Applications that care about shared
** cache setting should set it explicitly.
**
-** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0
-** and will always return SQLITE_MISUSE. On those systems,
-** shared cache mode should be enabled per-database connection via
-** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE].
-**
** This interface is threadsafe on processors where writing a
** 32-bit integer is atomic.
**
** See Also: [SQLite Shared-Cache Mode]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int);
+SQLITE_API int sqlite3_enable_shared_cache(int);
/*
** CAPI3REF: Attempt To Free Heap Memory
@@ -5382,11 +5258,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int);
**
** See also: [sqlite3_db_release_memory()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int);
+SQLITE_API int sqlite3_release_memory(int);
/*
** CAPI3REF: Free Memory Used By A Database Connection
-** METHOD: sqlite3
**
** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
** memory as possible from database connection D. Unlike the
@@ -5396,7 +5271,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int);
**
** See also: [sqlite3_release_memory()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
+SQLITE_API int sqlite3_db_release_memory(sqlite3*);
/*
** CAPI3REF: Impose A Limit On Heap Size
@@ -5448,7 +5323,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
** The circumstances under which SQLite will enforce the soft heap limit may
** changes in future releases of SQLite.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N);
+SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
/*
** CAPI3REF: Deprecated Soft Heap Limit Interface
@@ -5459,12 +5334,11 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64
** only. All new applications should use the
** [sqlite3_soft_heap_limit64()] interface rather than this one.
*/
-SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N);
+SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
/*
** CAPI3REF: Extract Metadata About A Column Of A Table
-** METHOD: sqlite3
**
** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
** information about column C of table T in database D
@@ -5529,7 +5403,7 @@ SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N);
** parsed, if that has not already been done, and returns an error if
** any errors are encountered while loading the schema.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
+SQLITE_API int sqlite3_table_column_metadata(
sqlite3 *db, /* Connection handle */
const char *zDbName, /* Database name or NULL */
const char *zTableName, /* Table name */
@@ -5543,7 +5417,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
/*
** CAPI3REF: Load An Extension
-** METHOD: sqlite3
**
** ^This interface loads an SQLite extension library from the named file.
**
@@ -5576,7 +5449,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
**
** See also the [load_extension() SQL function].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
+SQLITE_API int sqlite3_load_extension(
sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Derived from zFile if 0 */
@@ -5585,7 +5458,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
/*
** CAPI3REF: Enable Or Disable Extension Loading
-** METHOD: sqlite3
**
** ^So as not to open security holes in older applications that are
** unprepared to deal with [extension loading], and as a means of disabling
@@ -5597,7 +5469,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
** to turn extension loading on and call it with onoff==0 to turn
** it back off again.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff);
+SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
/*
** CAPI3REF: Automatically Load Statically Linked Extensions
@@ -5635,7 +5507,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int ono
** See also: [sqlite3_reset_auto_extension()]
** and [sqlite3_cancel_auto_extension()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void));
+SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
/*
** CAPI3REF: Cancel Automatic Extension Loading
@@ -5647,7 +5519,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void));
** unregistered and it returns 0 if X was not on the list of initialization
** routines.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
+SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
/*
** CAPI3REF: Reset Automatic Extension Loading
@@ -5655,7 +5527,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(
** ^This interface disables all automatic extensions previously
** registered using [sqlite3_auto_extension()].
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void);
+SQLITE_API void sqlite3_reset_auto_extension(void);
/*
** The interface to the virtual-table mechanism is currently considered
@@ -5835,7 +5707,6 @@ struct sqlite3_index_info {
/*
** CAPI3REF: Register A Virtual Table Implementation
-** METHOD: sqlite3
**
** ^These routines are used to register a new [virtual table module] name.
** ^Module names must be registered before
@@ -5859,13 +5730,13 @@ struct sqlite3_index_info {
** interface is equivalent to sqlite3_create_module_v2() with a NULL
** destructor.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
+SQLITE_API int sqlite3_create_module(
sqlite3 *db, /* SQLite connection to register module with */
const char *zName, /* Name of the module */
const sqlite3_module *p, /* Methods for the module */
void *pClientData /* Client data for xCreate/xConnect */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2(
+SQLITE_API int sqlite3_create_module_v2(
sqlite3 *db, /* SQLite connection to register module with */
const char *zName, /* Name of the module */
const sqlite3_module *p, /* Methods for the module */
@@ -5893,7 +5764,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2(
*/
struct sqlite3_vtab {
const sqlite3_module *pModule; /* The module for this virtual table */
- int nRef; /* Number of open cursors */
+ int nRef; /* NO LONGER USED */
char *zErrMsg; /* Error message from sqlite3_mprintf() */
/* Virtual table implementations will typically add additional fields */
};
@@ -5928,11 +5799,10 @@ struct sqlite3_vtab_cursor {
** to declare the format (the names and datatypes of the columns) of
** the virtual tables they implement.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL);
+SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
/*
** CAPI3REF: Overload A Function For A Virtual Table
-** METHOD: sqlite3
**
** ^(Virtual tables can provide alternative implementations of functions
** using the [xFindFunction] method of the [virtual table module].
@@ -5947,7 +5817,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL);
** purpose is to be a placeholder function that can be overloaded
** by a [virtual table].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
/*
** The interface to the virtual-table mechanism defined above (back up
@@ -5975,8 +5845,6 @@ typedef struct sqlite3_blob sqlite3_blob;
/*
** CAPI3REF: Open A BLOB For Incremental I/O
-** METHOD: sqlite3
-** CONSTRUCTOR: sqlite3_blob
**
** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
** in row iRow, column zColumn, table zTable in database zDb;
@@ -6046,7 +5914,7 @@ typedef struct sqlite3_blob sqlite3_blob;
** To avoid a resource leak, every open [BLOB handle] should eventually
** be released by a call to [sqlite3_blob_close()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
+SQLITE_API int sqlite3_blob_open(
sqlite3*,
const char *zDb,
const char *zTable,
@@ -6058,7 +5926,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
/*
** CAPI3REF: Move a BLOB Handle to a New Row
-** METHOD: sqlite3_blob
**
** ^This function is used to move an existing blob handle so that it points
** to a different row of the same database table. ^The new row is identified
@@ -6079,11 +5946,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
**
** ^This function sets the database handle error code and message.
*/
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
/*
** CAPI3REF: Close A BLOB Handle
-** DESTRUCTOR: sqlite3_blob
**
** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
** unconditionally. Even if this routine returns an error code, the
@@ -6102,11 +5968,10 @@ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_bl
** is passed a valid open blob handle, the values returned by the
** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *);
+SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
/*
** CAPI3REF: Return The Size Of An Open BLOB
-** METHOD: sqlite3_blob
**
** ^Returns the size in bytes of the BLOB accessible via the
** successfully opened [BLOB handle] in its only argument. ^The
@@ -6118,11 +5983,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *);
** been closed by [sqlite3_blob_close()]. Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *);
+SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
/*
** CAPI3REF: Read Data From A BLOB Incrementally
-** METHOD: sqlite3_blob
**
** ^(This function is used to read data from an open [BLOB handle] into a
** caller-supplied buffer. N bytes of data are copied into buffer Z
@@ -6147,11 +6011,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *);
**
** See also: [sqlite3_blob_write()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
+SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
/*
** CAPI3REF: Write Data Into A BLOB Incrementally
-** METHOD: sqlite3_blob
**
** ^(This function is used to write data into an open [BLOB handle] from a
** caller-supplied buffer. N bytes of data are copied from the buffer Z
@@ -6189,7 +6052,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N,
**
** See also: [sqlite3_blob_read()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
+SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
/*
** CAPI3REF: Virtual File System Objects
@@ -6220,9 +6083,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z,
** ^(If the default VFS is unregistered, another VFS is chosen as
** the default. The choice for the new VFS is arbitrary.)^
*/
-SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName);
-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*);
+SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
+SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
+SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
/*
** CAPI3REF: Mutexes
@@ -6335,11 +6198,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*);
**
** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
*/
-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int);
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*);
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*);
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*);
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*);
+SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
+SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
+SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
+SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
/*
** CAPI3REF: Mutex Methods Object
@@ -6449,8 +6312,8 @@ struct sqlite3_mutex_methods {
** interface should also return 1 when given a NULL pointer.
*/
#ifndef NDEBUG
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*);
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#endif
/*
@@ -6479,7 +6342,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
/*
** CAPI3REF: Retrieve the mutex for a database connection
-** METHOD: sqlite3
**
** ^This interface returns a pointer the [sqlite3_mutex] object that
** serializes access to the [database connection] given in the argument
@@ -6487,11 +6349,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
** ^If the [threading mode] is Single-thread or Multi-thread then this
** routine returns a NULL pointer.
*/
-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*);
+SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
/*
** CAPI3REF: Low-Level Control Of Database Files
-** METHOD: sqlite3
**
** ^The [sqlite3_file_control()] interface makes a direct call to the
** xFileControl method for the [sqlite3_io_methods] object associated
@@ -6522,7 +6383,7 @@ SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*);
**
** See also: [SQLITE_FCNTL_LOCKSTATE]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
/*
** CAPI3REF: Testing Interface
@@ -6541,7 +6402,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName
** Unlike most of the SQLite API, this function is not guaranteed to
** operate consistently from one release to the next.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
+SQLITE_API int sqlite3_test_control(int op, ...);
/*
** CAPI3REF: Testing Interface Operation Codes
@@ -6575,13 +6436,12 @@ SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_BYTEORDER 22
#define SQLITE_TESTCTRL_ISINIT 23
#define SQLITE_TESTCTRL_SORTER_MMAP 24
-#define SQLITE_TESTCTRL_IMPOSTER 25
-#define SQLITE_TESTCTRL_LAST 25
+#define SQLITE_TESTCTRL_LAST 24
/*
** CAPI3REF: SQLite Runtime Status
**
-** ^These interfaces are used to retrieve runtime status information
+** ^This interface is used to retrieve runtime status information
** about the performance of SQLite, and optionally to reset various
** highwater marks. ^The first argument is an integer code for
** the specific parameter to measure. ^(Recognized integer codes
@@ -6595,22 +6455,19 @@ SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
** ^(Other parameters record only the highwater mark and not the current
** value. For these latter parameters nothing is written into *pCurrent.)^
**
-** ^The sqlite3_status() and sqlite3_status64() routines return
-** SQLITE_OK on success and a non-zero [error code] on failure.
+** ^The sqlite3_status() routine returns SQLITE_OK on success and a
+** non-zero [error code] on failure.
**
-** If either the current value or the highwater mark is too large to
-** be represented by a 32-bit integer, then the values returned by
-** sqlite3_status() are undefined.
+** This routine is threadsafe but is not atomic. This routine can be
+** called while other threads are running the same or different SQLite
+** interfaces. However the values returned in *pCurrent and
+** *pHighwater reflect the status of SQLite at different points in time
+** and it is possible that another thread might change the parameter
+** in between the times when *pCurrent and *pHighwater are written.
**
** See also: [sqlite3_db_status()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
-SQLITE_API int SQLITE_STDCALL sqlite3_status64(
- int op,
- sqlite3_int64 *pCurrent,
- sqlite3_int64 *pHighwater,
- int resetFlag
-);
+SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
/*
@@ -6708,7 +6565,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_status64(
/*
** CAPI3REF: Database Connection Status
-** METHOD: sqlite3
**
** ^This interface is used to retrieve runtime status information
** about a single [database connection]. ^The first argument is the
@@ -6729,7 +6585,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_status64(
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
/*
** CAPI3REF: Status Parameters for database connections
@@ -6837,7 +6693,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int
/*
** CAPI3REF: Prepared Statement Status
-** METHOD: sqlite3_stmt
**
** ^(Each prepared statement maintains various
** [SQLITE_STMTSTATUS counters] that measure the number
@@ -6859,7 +6714,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int
**
** See also: [sqlite3_status()] and [sqlite3_db_status()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
/*
** CAPI3REF: Status Parameters for prepared statements
@@ -7282,20 +7137,20 @@ typedef struct sqlite3_backup sqlite3_backup;
** is not a permanent error and does not affect the return value of
** sqlite3_backup_finish().
**
-** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]]
+** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]]
** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b>
**
-** ^The sqlite3_backup_remaining() routine returns the number of pages still
-** to be backed up at the conclusion of the most recent sqlite3_backup_step().
-** ^The sqlite3_backup_pagecount() routine returns the total number of pages
-** in the source database at the conclusion of the most recent
-** sqlite3_backup_step().
-** ^(The values returned by these functions are only updated by
-** sqlite3_backup_step(). If the source database is modified in a way that
-** changes the size of the source database or the number of pages remaining,
-** those changes are not reflected in the output of sqlite3_backup_pagecount()
-** and sqlite3_backup_remaining() until after the next
-** sqlite3_backup_step().)^
+** ^Each call to sqlite3_backup_step() sets two values inside
+** the [sqlite3_backup] object: the number of pages still to be backed
+** up and the total number of pages in the source database file.
+** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces
+** retrieve these two values, respectively.
+**
+** ^The values returned by these functions are only updated by
+** sqlite3_backup_step(). ^If the source database is modified during a backup
+** operation, then the values are not updated to account for any extra
+** pages that need to be updated or the size of the source database file
+** changing.
**
** <b>Concurrent Usage of Database Handles</b>
**
@@ -7328,20 +7183,19 @@ typedef struct sqlite3_backup sqlite3_backup;
** same time as another thread is invoking sqlite3_backup_step() it is
** possible that they return invalid values.
*/
-SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
+SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3 *pDest, /* Destination database handle */
const char *zDestName, /* Destination database name */
sqlite3 *pSource, /* Source database handle */
const char *zSourceName /* Source database name */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage);
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p);
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p);
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
+SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
/*
** CAPI3REF: Unlock Notification
-** METHOD: sqlite3
**
** ^When running in shared-cache mode, a database operation may fail with
** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
@@ -7454,7 +7308,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p);
** the special "DROP TABLE/INDEX" case, the extended error code is just
** SQLITE_LOCKED.)^
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
+SQLITE_API int sqlite3_unlock_notify(
sqlite3 *pBlocked, /* Waiting connection */
void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */
void *pNotifyArg /* Argument to pass to xNotify */
@@ -7469,8 +7323,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
** strings in a case-independent fashion, using the same definition of "case
** independence" that SQLite uses internally when comparing identifiers.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *);
-SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int);
+SQLITE_API int sqlite3_stricmp(const char *, const char *);
+SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
/*
** CAPI3REF: String Globbing
@@ -7485,7 +7339,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int);
** Note that this routine returns zero on a match and non-zero if the strings
** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr);
+SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
/*
** CAPI3REF: Error Logging Interface
@@ -7508,11 +7362,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zSt
** a few hundred characters, it will be truncated to the length of the
** buffer.
*/
-SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...);
+SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
/*
** CAPI3REF: Write-Ahead Log Commit Hook
-** METHOD: sqlite3
**
** ^The [sqlite3_wal_hook()] function is used to register a callback that
** is invoked each time data is committed to a database in wal mode.
@@ -7544,7 +7397,7 @@ SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...)
** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
** those overwrite any prior [sqlite3_wal_hook()] settings.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
+SQLITE_API void *sqlite3_wal_hook(
sqlite3*,
int(*)(void *,sqlite3*,const char*,int),
void*
@@ -7552,7 +7405,6 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
/*
** CAPI3REF: Configure an auto-checkpoint
-** METHOD: sqlite3
**
** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
** [sqlite3_wal_hook()] that causes any database on [database connection] D
@@ -7579,11 +7431,10 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
** is only necessary if the default setting is found to be suboptimal
** for a particular application.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
+SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
/*
** CAPI3REF: Checkpoint a database
-** METHOD: sqlite3
**
** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to
** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^
@@ -7601,11 +7452,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
** start a callback but which do not need the full power (and corresponding
** complication) of [sqlite3_wal_checkpoint_v2()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
+SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
/*
** CAPI3REF: Checkpoint a database
-** METHOD: sqlite3
**
** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint
** operation on database X of [database connection] D in mode M. Status
@@ -7695,7 +7545,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zD
** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
** from SQL.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
+SQLITE_API int sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -7731,7 +7581,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options
** may be added in the future.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...);
+SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Virtual Table Configuration Options
@@ -7784,7 +7634,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...);
** of the SQL statement that triggered the call to the [xUpdate] method of the
** [virtual table].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
+SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
/*
** CAPI3REF: Conflict resolution modes
@@ -7860,7 +7710,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
/*
** CAPI3REF: Prepared Statement Scan Status
-** METHOD: sqlite3_stmt
**
** This interface returns information about the predicted and measured
** performance for pStmt. Advanced applications can use this
@@ -7889,7 +7738,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
**
** See also: [sqlite3_stmt_scanstatus_reset()]
*/
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus(
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
int idx, /* Index of loop to report on */
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
@@ -7898,14 +7747,13 @@ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus(
/*
** CAPI3REF: Zero Scan-Status Counters
-** METHOD: sqlite3_stmt
**
** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
**
** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
*/
-SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
+SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
/*
@@ -7960,7 +7808,7 @@ typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info;
**
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
+SQLITE_API int sqlite3_rtree_geometry_callback(
sqlite3 *db,
const char *zGeom,
int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
@@ -7986,7 +7834,7 @@ struct sqlite3_rtree_geometry {
**
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
+SQLITE_API int sqlite3_rtree_query_callback(
sqlite3 *db,
const char *zQueryFunc,
int (*xQueryFunc)(sqlite3_rtree_query_info*),
@@ -8150,17 +7998,15 @@ struct sqlite3_rtree_query_info {
#endif
/*
-** The suggested maximum number of in-memory pages to use for
-** the main database table and for temporary tables.
-**
-** IMPLEMENTATION-OF: R-31093-59126 The default suggested cache size
-** is 2000 pages.
-** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be
-** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options.
+** The maximum number of in-memory pages to use for the main database
+** table and for temporary tables. The SQLITE_DEFAULT_CACHE_SIZE
*/
#ifndef SQLITE_DEFAULT_CACHE_SIZE
# define SQLITE_DEFAULT_CACHE_SIZE 2000
#endif
+#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE
+# define SQLITE_DEFAULT_TEMP_CACHE_SIZE 500
+#endif
/*
** The default number of frames to accumulate in the log file before
@@ -8510,32 +8356,6 @@ SQLITE_PRIVATE void sqlite3Coverage(int);
#endif
/*
-** Declarations used for tracing the operating system interfaces.
-*/
-#if defined(SQLITE_FORCE_OS_TRACE) || defined(SQLITE_TEST) || \
- (defined(SQLITE_DEBUG) && SQLITE_OS_WIN)
- extern int sqlite3OSTrace;
-# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X
-# define SQLITE_HAVE_OS_TRACE
-#else
-# define OSTRACE(X)
-# undef SQLITE_HAVE_OS_TRACE
-#endif
-
-/*
-** Is the sqlite3ErrName() function needed in the build? Currently,
-** it is needed by "mutex_w32.c" (when debugging), "os_win.c" (when
-** OSTRACE is enabled), and by several "test*.c" files (which are
-** compiled using SQLITE_TEST).
-*/
-#if defined(SQLITE_HAVE_OS_TRACE) || defined(SQLITE_TEST) || \
- (defined(SQLITE_DEBUG) && SQLITE_OS_WIN)
-# define SQLITE_NEED_ERR_NAME
-#else
-# undef SQLITE_NEED_ERR_NAME
-#endif
-
-/*
** Return true (non-zero) if the input is an integer that is too large
** to fit in 32-bits. This macro is used inside of various testcase()
** macros to verify that we have tested SQLite for large-file support.
@@ -9031,20 +8851,6 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */
typedef INT16_TYPE LogEst;
/*
-** Set the SQLITE_PTRSIZE macro to the number of bytes in a pointer
-*/
-#ifndef SQLITE_PTRSIZE
-# if defined(__SIZEOF_POINTER__)
-# define SQLITE_PTRSIZE __SIZEOF_POINTER__
-# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \
- defined(_M_ARM) || defined(__arm__) || defined(__x86)
-# define SQLITE_PTRSIZE 4
-# else
-# define SQLITE_PTRSIZE 8
-# endif
-#endif
-
-/*
** Macros to determine whether the machine is big or little endian,
** and whether or not that determination is run-time or compile-time.
**
@@ -9256,8 +9062,8 @@ struct BusyHandler {
#define SQLITE_WSD const
#define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v)))
#define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config)
-SQLITE_API int SQLITE_STDCALL sqlite3_wsd_init(int N, int J);
-SQLITE_API void *SQLITE_STDCALL sqlite3_wsd_find(void *K, int L);
+SQLITE_API int sqlite3_wsd_init(int N, int J);
+SQLITE_API void *sqlite3_wsd_find(void *K, int L);
#else
#define SQLITE_WSD
#define GLOBAL(t,v) v
@@ -9415,8 +9221,10 @@ 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 sqlite3BtreeGetOptimalReserve(Btree*);
+SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*);
+#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p);
+#endif
SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
@@ -9494,18 +9302,8 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);
/*
** Values that may be OR'd together to form the second argument of an
** sqlite3BtreeCursorHints() call.
-**
-** The BTREE_BULKLOAD flag is set on index cursors when the index is going
-** to be filled with content that is already in sorted order.
-**
-** The BTREE_SEEK_EQ flag is set on cursors that will get OP_SeekGE or
-** OP_SeekLE opcodes for a range search, but where the range of entries
-** selected will all have the same key. In other words, the cursor will
-** be used only for equality key searches.
-**
*/
-#define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */
-#define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */
+#define BTREE_BULKLOAD 0x00000001
SQLITE_PRIVATE int sqlite3BtreeCursor(
Btree*, /* BTree containing table to open */
@@ -9551,9 +9349,6 @@ SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *);
SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
-#endif
SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt);
SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void);
@@ -9920,25 +9715,23 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_MemMax 136 /* synopsis: r[P1]=max(r[P1],r[P2]) */
#define OP_IfPos 137 /* synopsis: if r[P1]>0 goto P2 */
#define OP_IfNeg 138 /* synopsis: r[P1]+=P3, if r[P1]<0 goto P2 */
-#define OP_IfNotZero 139 /* synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2 */
-#define OP_DecrJumpZero 140 /* synopsis: if (--r[P1])==0 goto P2 */
-#define OP_JumpZeroIncr 141 /* synopsis: if (r[P1]++)==0 ) goto P2 */
-#define OP_AggFinal 142 /* synopsis: accum=r[P1] N=P2 */
-#define OP_IncrVacuum 143
-#define OP_Expire 144
-#define OP_TableLock 145 /* synopsis: iDb=P1 root=P2 write=P3 */
-#define OP_VBegin 146
-#define OP_VCreate 147
-#define OP_VDestroy 148
-#define OP_VOpen 149
-#define OP_VColumn 150 /* synopsis: r[P3]=vcolumn(P2) */
-#define OP_VNext 151
-#define OP_VRename 152
-#define OP_Pagecount 153
-#define OP_MaxPgcnt 154
-#define OP_Init 155 /* synopsis: Start at P2 */
-#define OP_Noop 156
-#define OP_Explain 157
+#define OP_IfZero 139 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */
+#define OP_AggFinal 140 /* synopsis: accum=r[P1] N=P2 */
+#define OP_IncrVacuum 141
+#define OP_Expire 142
+#define OP_TableLock 143 /* synopsis: iDb=P1 root=P2 write=P3 */
+#define OP_VBegin 144
+#define OP_VCreate 145
+#define OP_VDestroy 146
+#define OP_VOpen 147
+#define OP_VColumn 148 /* synopsis: r[P3]=vcolumn(P2) */
+#define OP_VNext 149
+#define OP_VRename 150
+#define OP_Pagecount 151
+#define OP_MaxPgcnt 152
+#define OP_Init 153 /* synopsis: Start at P2 */
+#define OP_Noop 154
+#define OP_Explain 155
/* Properties such as "out2" or "jump" that are specified in
@@ -9946,32 +9739,33 @@ typedef struct VdbeOpList VdbeOpList;
** are encoded into bitvectors as follows:
*/
#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */
-#define OPFLG_IN1 0x0002 /* in1: P1 is an input */
-#define OPFLG_IN2 0x0004 /* in2: P2 is an input */
-#define OPFLG_IN3 0x0008 /* in3: P3 is an input */
-#define OPFLG_OUT2 0x0010 /* out2: P2 is an output */
-#define OPFLG_OUT3 0x0020 /* out3: P3 is an output */
+#define OPFLG_OUT2_PRERELEASE 0x0002 /* out2-prerelease: */
+#define OPFLG_IN1 0x0004 /* in1: P1 is an input */
+#define OPFLG_IN2 0x0008 /* in2: P2 is an input */
+#define OPFLG_IN3 0x0010 /* in3: P3 is an input */
+#define OPFLG_OUT2 0x0020 /* out2: P2 is an output */
+#define OPFLG_OUT3 0x0040 /* out3: P3 is an output */
#define OPFLG_INITIALIZER {\
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\
-/* 8 */ 0x01, 0x01, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\
-/* 16 */ 0x01, 0x01, 0x02, 0x12, 0x01, 0x02, 0x03, 0x08,\
-/* 24 */ 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10,\
-/* 32 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x03, 0x02,\
-/* 40 */ 0x02, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x00,\
-/* 48 */ 0x00, 0x00, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00,\
-/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09,\
-/* 64 */ 0x09, 0x09, 0x04, 0x09, 0x09, 0x09, 0x09, 0x26,\
-/* 72 */ 0x26, 0x10, 0x10, 0x00, 0x03, 0x03, 0x0b, 0x0b,\
-/* 80 */ 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x26, 0x26, 0x26,\
-/* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00,\
-/* 96 */ 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
-/* 104 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x00,\
-/* 112 */ 0x10, 0x01, 0x01, 0x01, 0x01, 0x10, 0x00, 0x00,\
-/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 128 */ 0x06, 0x23, 0x0b, 0x01, 0x10, 0x10, 0x00, 0x01,\
-/* 136 */ 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x01,\
-/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\
-/* 152 */ 0x00, 0x10, 0x10, 0x01, 0x00, 0x00,}
+/* 8 */ 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,\
+/* 16 */ 0x01, 0x01, 0x04, 0x24, 0x01, 0x04, 0x05, 0x10,\
+/* 24 */ 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02,\
+/* 32 */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x05, 0x04,\
+/* 40 */ 0x04, 0x00, 0x00, 0x01, 0x01, 0x05, 0x05, 0x00,\
+/* 48 */ 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00,\
+/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\
+/* 64 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x4c,\
+/* 72 */ 0x4c, 0x02, 0x02, 0x00, 0x05, 0x05, 0x15, 0x15,\
+/* 80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\
+/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\
+/* 96 */ 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,\
+/* 104 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x08, 0x08, 0x00,\
+/* 112 */ 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x00,\
+/* 120 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 128 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x02, 0x00, 0x01,\
+/* 136 */ 0x08, 0x05, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00,\
+/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,\
+/* 152 */ 0x02, 0x01, 0x00, 0x00,}
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
@@ -10030,7 +9824,6 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
-SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int);
SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);
@@ -11048,13 +10841,11 @@ struct sqlite3 {
u8 iDb; /* Which db file is being initialized */
u8 busy; /* TRUE if currently initializing */
u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
- u8 imposterTable; /* Building an imposter table */
} init;
int nVdbeActive; /* Number of VDBEs currently running */
int nVdbeRead; /* Number of active VDBEs that read or write */
int nVdbeWrite; /* Number of active VDBEs that read and write */
int nVdbeExec; /* Number of nested calls to VdbeExec() */
- int nVDestroy; /* Number of active OP_VDestroy operations */
int nExtension; /* Number of loaded extensions */
void **aExtension; /* Array of shared library handles */
void (*xTrace)(void*,const char*); /* Trace function */
@@ -11168,7 +10959,6 @@ struct sqlite3 {
#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */
-#define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */
/*
@@ -11499,8 +11289,34 @@ struct VTable {
};
/*
-** The schema for each SQL table and view is represented in memory
-** by an instance of the following structure.
+** Each SQL table is represented in memory by an instance of the
+** following structure.
+**
+** Table.zName is the name of the table. The case of the original
+** CREATE TABLE statement is stored, but case is not significant for
+** comparisons.
+**
+** Table.nCol is the number of columns in this table. Table.aCol is a
+** pointer to an array of Column structures, one for each column.
+**
+** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of
+** the column that is that key. Otherwise Table.iPKey is negative. Note
+** that the datatype of the PRIMARY KEY must be INTEGER for this field to
+** be set. An INTEGER PRIMARY KEY is used as the rowid for each row of
+** the table. If a table has no INTEGER PRIMARY KEY, then a random rowid
+** is generated for each row of the table. TF_HasPrimaryKey is set if
+** the table has any PRIMARY KEY, INTEGER or otherwise.
+**
+** Table.tnum is the page number for the root BTree page of the table in the
+** database file. If Table.iDb is the index of the database table backend
+** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that
+** holds temporary tables and indices. If TF_Ephemeral is set
+** then the table is stored in a file that is automatically deleted
+** when the VDBE cursor to the table is closed. In this case Table.tnum
+** refers VDBE cursor number that holds the table open, not to the root
+** page number. Transient tables are used to hold the results of a
+** sub-query that appears instead of a real table name in the FROM clause
+** of a SELECT statement.
*/
struct Table {
char *zName; /* Name of the table or view */
@@ -11512,11 +11328,11 @@ struct Table {
#ifndef SQLITE_OMIT_CHECK
ExprList *pCheck; /* All CHECK constraints */
#endif
- int tnum; /* Root BTree page for this table */
- i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */
+ LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */
+ int tnum; /* Root BTree node for this table (see note above) */
+ i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */
i16 nCol; /* Number of columns in this table */
u16 nRef; /* Number of pointers to this Table */
- LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */
LogEst szTabRow; /* Estimated size of each table row in bytes */
#ifdef SQLITE_ENABLE_COSTMULT
LogEst costMult; /* Cost multiplier for using this table */
@@ -11538,12 +11354,6 @@ struct Table {
/*
** Allowed values for Table.tabFlags.
-**
-** TF_OOOHidden applies to virtual tables that have hidden columns that are
-** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING
-** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden,
-** the TF_OOOHidden attribute would apply in this case. Such tables require
-** special handling during INSERT processing.
*/
#define TF_Readonly 0x01 /* Read-only system table */
#define TF_Ephemeral 0x02 /* An ephemeral table */
@@ -11551,7 +11361,6 @@ struct Table {
#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
#define TF_Virtual 0x10 /* Is a virtual table */
#define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */
-#define TF_OOOHidden 0x40 /* Out-of-Order hidden columns */
/*
@@ -11988,14 +11797,8 @@ struct Expr {
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
-#define EP_ConstFunc 0x080000 /* Node is a SQLITE_FUNC_CONSTANT function */
+#define EP_Constant 0x080000 /* Node is a constant */
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
-#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
-
-/*
-** Combinations of two or more EP_* flags
-*/
-#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
/*
** These macros can be used to test, set, or clear bits in the
@@ -12194,7 +11997,7 @@ struct SrcList {
#define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */
#define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */
#define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */
-#define WHERE_NO_AUTOINDEX 0x0080 /* Disallow automatic indexes */
+ /* 0x0080 // not currently used */
#define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */
#define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */
#define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */
@@ -12308,12 +12111,11 @@ struct Select {
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
#define SF_Compound 0x0040 /* Part of a compound query */
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
-#define SF_MultiValue 0x0100 /* Single VALUES term with multiple rows */
+#define SF_AllValues 0x0100 /* All terms of compound are VALUES */
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
#define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */
#define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */
-#define SF_Converted 0x2000 /* By convertCompoundSelectToSubquery() */
/*
@@ -12632,8 +12434,7 @@ struct AuthContext {
#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
-#define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */
-#define OPFLAG_P2ISREG 0x04 /* P2 to OP_Open** is a register number */
+#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
/*
@@ -12692,7 +12493,7 @@ struct Trigger {
* orconf -> stores the ON CONFLICT algorithm
* pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
* this stores a pointer to the SELECT statement. Otherwise NULL.
- * zTarget -> Dequoted name of the table to insert into.
+ * target -> A token holding the quoted name of the table to insert into.
* pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
* this stores values to be inserted. Otherwise NULL.
* pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
@@ -12700,12 +12501,12 @@ struct Trigger {
* inserted into.
*
* (op == TK_DELETE)
- * zTarget -> Dequoted name of the table to delete from.
+ * target -> A token holding the quoted name of the table to delete from.
* pWhere -> The WHERE clause of the DELETE statement if one is specified.
* Otherwise NULL.
*
* (op == TK_UPDATE)
- * zTarget -> Dequoted name of the table to update.
+ * target -> A token holding the quoted name of the table to update rows of.
* pWhere -> The WHERE clause of the UPDATE statement if one is specified.
* Otherwise NULL.
* pExprList -> A list of the columns to update and the expressions to update
@@ -12717,8 +12518,8 @@ struct TriggerStep {
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
u8 orconf; /* OE_Rollback etc. */
Trigger *pTrig; /* The trigger that this step is a part of */
- Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */
- char *zTarget; /* Target table for DELETE, UPDATE, INSERT */
+ Select *pSelect; /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
+ Token target; /* Target table for DELETE, UPDATE, INSERT */
Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */
ExprList *pExprList; /* SET clause for UPDATE. */
IdList *pIdList; /* Column names for INSERT */
@@ -12751,7 +12552,8 @@ struct StrAccum {
char *zText; /* The string collected so far */
int nChar; /* Length of the string so far */
int nAlloc; /* Amount of space allocated in zText */
- int mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
+ int mxAlloc; /* Maximum allowed string length */
+ u8 useMalloc; /* 0: none, 1: sqlite3DbMalloc, 2: sqlite3_malloc */
u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
};
#define STRACCUM_NOMEM 1
@@ -13036,15 +12838,10 @@ SQLITE_PRIVATE int sqlite3MutexInit(void);
SQLITE_PRIVATE int sqlite3MutexEnd(void);
#endif
-SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int);
-SQLITE_PRIVATE void sqlite3StatusUp(int, int);
-SQLITE_PRIVATE void sqlite3StatusDown(int, int);
+SQLITE_PRIVATE int sqlite3StatusValue(int);
+SQLITE_PRIVATE void sqlite3StatusAdd(int, int);
SQLITE_PRIVATE void sqlite3StatusSet(int, int);
-/* Access to mutexes used by sqlite3_status() */
-SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void);
-SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void);
-
#ifndef SQLITE_OMIT_FLOATING_POINT
SQLITE_PRIVATE int sqlite3IsNaN(double);
#else
@@ -13068,7 +12865,7 @@ SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
-#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
+#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...);
#endif
#if defined(SQLITE_TEST)
@@ -13109,7 +12906,6 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
-SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
@@ -13415,7 +13211,7 @@ SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
SQLITE_PRIVATE u8 sqlite3HexToInt(int h);
SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
-#if defined(SQLITE_NEED_ERR_NAME)
+#if defined(SQLITE_TEST)
SQLITE_PRIVATE const char *sqlite3ErrName(int);
#endif
@@ -13424,7 +13220,7 @@ SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
-SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*);
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
@@ -13509,7 +13305,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
-SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
+SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*);
SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char);
@@ -13693,11 +13489,12 @@ SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *);
SQLITE_PRIVATE int sqlite3MemJournalSize(void);
SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *);
-SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
#if SQLITE_MAX_EXPR_DEPTH>0
+SQLITE_PRIVATE void sqlite3ExprSetHeight(Parse *pParse, Expr *p);
SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *);
SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse*, int);
#else
+ #define sqlite3ExprSetHeight(x,y)
#define sqlite3SelectExprHeight(x) 0
#define sqlite3ExprCheckHeight(x,y)
#endif
@@ -13727,7 +13524,7 @@ SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *);
#ifdef SQLITE_ENABLE_IOTRACE
# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; }
SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*);
-SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...);
+void (*sqlite3IoTrace)(const char*,...);
#else
# define IOTRACE(A)
# define sqlite3VdbeIOTraceSql(X)
@@ -13786,6 +13583,3629 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**);
#endif /* _SQLITEINT_H_ */
/************** End of sqliteInt.h *******************************************/
+/************** Begin file crypto.c ******************************************/
+/*
+** SQLCipher
+** http://sqlcipher.net
+**
+** Copyright (c) 2008 - 2013, ZETETIC LLC
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of the ZETETIC LLC nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*/
+/* BEGIN SQLCIPHER */
+#ifdef SQLITE_HAS_CODEC
+
+/* #include <assert.h> */
+/************** Include btreeInt.h in the middle of crypto.c *****************/
+/************** Begin file btreeInt.h ****************************************/
+/*
+** 2004 April 6
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file implements an external (disk-based) database using BTrees.
+** For a detailed discussion of BTrees, refer to
+**
+** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
+** "Sorting And Searching", pages 473-480. Addison-Wesley
+** Publishing Company, Reading, Massachusetts.
+**
+** The basic idea is that each page of the file contains N database
+** entries and N+1 pointers to subpages.
+**
+** ----------------------------------------------------------------
+** | Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) |
+** ----------------------------------------------------------------
+**
+** All of the keys on the page that Ptr(0) points to have values less
+** than Key(0). All of the keys on page Ptr(1) and its subpages have
+** values greater than Key(0) and less than Key(1). All of the keys
+** on Ptr(N) and its subpages have values greater than Key(N-1). And
+** so forth.
+**
+** Finding a particular key requires reading O(log(M)) pages from the
+** disk where M is the number of entries in the tree.
+**
+** In this implementation, a single file can hold one or more separate
+** BTrees. Each BTree is identified by the index of its root page. The
+** key and data for any entry are combined to form the "payload". A
+** fixed amount of payload can be carried directly on the database
+** page. If the payload is larger than the preset amount then surplus
+** bytes are stored on overflow pages. The payload for an entry
+** and the preceding pointer are combined to form a "Cell". Each
+** page has a small header which contains the Ptr(N) pointer and other
+** information such as the size of key and data.
+**
+** FORMAT DETAILS
+**
+** The file is divided into pages. The first page is called page 1,
+** the second is page 2, and so forth. A page number of zero indicates
+** "no such page". The page size can be any power of 2 between 512 and 65536.
+** Each page can be either a btree page, a freelist page, an overflow
+** page, or a pointer-map page.
+**
+** The first page is always a btree page. The first 100 bytes of the first
+** page contain a special header (the "file header") that describes the file.
+** The format of the file header is as follows:
+**
+** OFFSET SIZE DESCRIPTION
+** 0 16 Header string: "SQLite format 3\000"
+** 16 2 Page size in bytes. (1 means 65536)
+** 18 1 File format write version
+** 19 1 File format read version
+** 20 1 Bytes of unused space at the end of each page
+** 21 1 Max embedded payload fraction (must be 64)
+** 22 1 Min embedded payload fraction (must be 32)
+** 23 1 Min leaf payload fraction (must be 32)
+** 24 4 File change counter
+** 28 4 Reserved for future use
+** 32 4 First freelist page
+** 36 4 Number of freelist pages in the file
+** 40 60 15 4-byte meta values passed to higher layers
+**
+** 40 4 Schema cookie
+** 44 4 File format of schema layer
+** 48 4 Size of page cache
+** 52 4 Largest root-page (auto/incr_vacuum)
+** 56 4 1=UTF-8 2=UTF16le 3=UTF16be
+** 60 4 User version
+** 64 4 Incremental vacuum mode
+** 68 4 Application-ID
+** 72 20 unused
+** 92 4 The version-valid-for number
+** 96 4 SQLITE_VERSION_NUMBER
+**
+** All of the integer values are big-endian (most significant byte first).
+**
+** The file change counter is incremented when the database is changed
+** This counter allows other processes to know when the file has changed
+** and thus when they need to flush their cache.
+**
+** The max embedded payload fraction is the amount of the total usable
+** space in a page that can be consumed by a single cell for standard
+** B-tree (non-LEAFDATA) tables. A value of 255 means 100%. The default
+** is to limit the maximum cell size so that at least 4 cells will fit
+** on one page. Thus the default max embedded payload fraction is 64.
+**
+** If the payload for a cell is larger than the max payload, then extra
+** payload is spilled to overflow pages. Once an overflow page is allocated,
+** as many bytes as possible are moved into the overflow pages without letting
+** the cell size drop below the min embedded payload fraction.
+**
+** The min leaf payload fraction is like the min embedded payload fraction
+** except that it applies to leaf nodes in a LEAFDATA tree. The maximum
+** payload fraction for a LEAFDATA tree is always 100% (or 255) and it
+** not specified in the header.
+**
+** Each btree pages is divided into three sections: The header, the
+** cell pointer array, and the cell content area. Page 1 also has a 100-byte
+** file header that occurs before the page header.
+**
+** |----------------|
+** | file header | 100 bytes. Page 1 only.
+** |----------------|
+** | page header | 8 bytes for leaves. 12 bytes for interior nodes
+** |----------------|
+** | cell pointer | | 2 bytes per cell. Sorted order.
+** | array | | Grows downward
+** | | v
+** |----------------|
+** | unallocated |
+** | space |
+** |----------------| ^ Grows upwards
+** | cell content | | Arbitrary order interspersed with freeblocks.
+** | area | | and free space fragments.
+** |----------------|
+**
+** The page headers looks like this:
+**
+** OFFSET SIZE DESCRIPTION
+** 0 1 Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf
+** 1 2 byte offset to the first freeblock
+** 3 2 number of cells on this page
+** 5 2 first byte of the cell content area
+** 7 1 number of fragmented free bytes
+** 8 4 Right child (the Ptr(N) value). Omitted on leaves.
+**
+** The flags define the format of this btree page. The leaf flag means that
+** this page has no children. The zerodata flag means that this page carries
+** only keys and no data. The intkey flag means that the key is an integer
+** which is stored in the key size entry of the cell header rather than in
+** the payload area.
+**
+** The cell pointer array begins on the first byte after the page header.
+** The cell pointer array contains zero or more 2-byte numbers which are
+** offsets from the beginning of the page to the cell content in the cell
+** content area. The cell pointers occur in sorted order. The system strives
+** to keep free space after the last cell pointer so that new cells can
+** be easily added without having to defragment the page.
+**
+** Cell content is stored at the very end of the page and grows toward the
+** beginning of the page.
+**
+** Unused space within the cell content area is collected into a linked list of
+** freeblocks. Each freeblock is at least 4 bytes in size. The byte offset
+** to the first freeblock is given in the header. Freeblocks occur in
+** increasing order. Because a freeblock must be at least 4 bytes in size,
+** any group of 3 or fewer unused bytes in the cell content area cannot
+** exist on the freeblock chain. A group of 3 or fewer free bytes is called
+** a fragment. The total number of bytes in all fragments is recorded.
+** in the page header at offset 7.
+**
+** SIZE DESCRIPTION
+** 2 Byte offset of the next freeblock
+** 2 Bytes in this freeblock
+**
+** Cells are of variable length. Cells are stored in the cell content area at
+** the end of the page. Pointers to the cells are in the cell pointer array
+** that immediately follows the page header. Cells is not necessarily
+** contiguous or in order, but cell pointers are contiguous and in order.
+**
+** Cell content makes use of variable length integers. A variable
+** length integer is 1 to 9 bytes where the lower 7 bits of each
+** byte are used. The integer consists of all bytes that have bit 8 set and
+** the first byte with bit 8 clear. The most significant byte of the integer
+** appears first. A variable-length integer may not be more than 9 bytes long.
+** As a special case, all 8 bytes of the 9th byte are used as data. This
+** allows a 64-bit integer to be encoded in 9 bytes.
+**
+** 0x00 becomes 0x00000000
+** 0x7f becomes 0x0000007f
+** 0x81 0x00 becomes 0x00000080
+** 0x82 0x00 becomes 0x00000100
+** 0x80 0x7f becomes 0x0000007f
+** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678
+** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081
+**
+** Variable length integers are used for rowids and to hold the number of
+** bytes of key and data in a btree cell.
+**
+** The content of a cell looks like this:
+**
+** SIZE DESCRIPTION
+** 4 Page number of the left child. Omitted if leaf flag is set.
+** var Number of bytes of data. Omitted if the zerodata flag is set.
+** var Number of bytes of key. Or the key itself if intkey flag is set.
+** * Payload
+** 4 First page of the overflow chain. Omitted if no overflow
+**
+** Overflow pages form a linked list. Each page except the last is completely
+** filled with data (pagesize - 4 bytes). The last page can have as little
+** as 1 byte of data.
+**
+** SIZE DESCRIPTION
+** 4 Page number of next overflow page
+** * Data
+**
+** Freelist pages come in two subtypes: trunk pages and leaf pages. The
+** file header points to the first in a linked list of trunk page. Each trunk
+** page points to multiple leaf pages. The content of a leaf page is
+** unspecified. A trunk page looks like this:
+**
+** SIZE DESCRIPTION
+** 4 Page number of next trunk page
+** 4 Number of leaf pointers on this page
+** * zero or more pages numbers of leaves
+*/
+
+
+/* The following value is the maximum cell size assuming a maximum page
+** size give above.
+*/
+#define MX_CELL_SIZE(pBt) ((int)(pBt->pageSize-8))
+
+/* The maximum number of cells on a single page of the database. This
+** assumes a minimum cell size of 6 bytes (4 bytes for the cell itself
+** plus 2 bytes for the index to the cell in the page header). Such
+** small cells will be rare, but they are possible.
+*/
+#define MX_CELL(pBt) ((pBt->pageSize-8)/6)
+
+/* Forward declarations */
+typedef struct MemPage MemPage;
+typedef struct BtLock BtLock;
+
+/*
+** This is a magic string that appears at the beginning of every
+** SQLite database in order to identify the file as a real database.
+**
+** You can change this value at compile-time by specifying a
+** -DSQLITE_FILE_HEADER="..." on the compiler command-line. The
+** header must be exactly 16 bytes including the zero-terminator so
+** the string itself should be 15 characters long. If you change
+** the header, then your custom library will not be able to read
+** databases generated by the standard tools and the standard tools
+** will not be able to read databases created by your custom library.
+*/
+#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */
+# define SQLITE_FILE_HEADER "SQLite format 3"
+#endif
+
+/*
+** Page type flags. An ORed combination of these flags appear as the
+** first byte of on-disk image of every BTree page.
+*/
+#define PTF_INTKEY 0x01
+#define PTF_ZERODATA 0x02
+#define PTF_LEAFDATA 0x04
+#define PTF_LEAF 0x08
+
+/*
+** As each page of the file is loaded into memory, an instance of the following
+** structure is appended and initialized to zero. This structure stores
+** information about the page that is decoded from the raw file page.
+**
+** The pParent field points back to the parent page. This allows us to
+** walk up the BTree from any leaf to the root. Care must be taken to
+** unref() the parent page pointer when this page is no longer referenced.
+** The pageDestructor() routine handles that chore.
+**
+** Access to all fields of this structure is controlled by the mutex
+** stored in MemPage.pBt->mutex.
+*/
+struct MemPage {
+ u8 isInit; /* True if previously initialized. MUST BE FIRST! */
+ u8 nOverflow; /* Number of overflow cell bodies in aCell[] */
+ u8 intKey; /* True if table b-trees. False for index b-trees */
+ u8 intKeyLeaf; /* True if the leaf of an intKey table */
+ u8 noPayload; /* True if internal intKey page (thus w/o data) */
+ u8 leaf; /* True if a leaf page */
+ u8 hdrOffset; /* 100 for page 1. 0 otherwise */
+ u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */
+ u8 max1bytePayload; /* min(maxLocal,127) */
+ u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
+ u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */
+ u16 cellOffset; /* Index in aData of first cell pointer */
+ u16 nFree; /* Number of free bytes on the page */
+ u16 nCell; /* Number of cells on this page, local and ovfl */
+ u16 maskPage; /* Mask for page offset */
+ u16 aiOvfl[5]; /* Insert the i-th overflow cell before the aiOvfl-th
+ ** non-overflow cell */
+ u8 *apOvfl[5]; /* Pointers to the body of overflow cells */
+ BtShared *pBt; /* Pointer to BtShared that this page is part of */
+ u8 *aData; /* Pointer to disk image of the page data */
+ u8 *aDataEnd; /* One byte past the end of usable data */
+ u8 *aCellIdx; /* The cell index area */
+ DbPage *pDbPage; /* Pager page handle */
+ Pgno pgno; /* Page number for this page */
+};
+
+/*
+** The in-memory image of a disk page has the auxiliary information appended
+** to the end. EXTRA_SIZE is the number of bytes of space needed to hold
+** that extra information.
+*/
+#define EXTRA_SIZE sizeof(MemPage)
+
+/*
+** A linked list of the following structures is stored at BtShared.pLock.
+** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor
+** is opened on the table with root page BtShared.iTable. Locks are removed
+** from this list when a transaction is committed or rolled back, or when
+** a btree handle is closed.
+*/
+struct BtLock {
+ Btree *pBtree; /* Btree handle holding this lock */
+ Pgno iTable; /* Root page of table */
+ u8 eLock; /* READ_LOCK or WRITE_LOCK */
+ BtLock *pNext; /* Next in BtShared.pLock list */
+};
+
+/* Candidate values for BtLock.eLock */
+#define READ_LOCK 1
+#define WRITE_LOCK 2
+
+/* A Btree handle
+**
+** A database connection contains a pointer to an instance of
+** this object for every database file that it has open. This structure
+** is opaque to the database connection. The database connection cannot
+** see the internals of this structure and only deals with pointers to
+** this structure.
+**
+** For some database files, the same underlying database cache might be
+** shared between multiple connections. In that case, each connection
+** has it own instance of this object. But each instance of this object
+** points to the same BtShared object. The database cache and the
+** schema associated with the database file are all contained within
+** the BtShared object.
+**
+** All fields in this structure are accessed under sqlite3.mutex.
+** The pBt pointer itself may not be changed while there exists cursors
+** in the referenced BtShared that point back to this Btree since those
+** cursors have to go through this Btree to find their BtShared and
+** they often do so without holding sqlite3.mutex.
+*/
+struct Btree {
+ sqlite3 *db; /* The database connection holding this btree */
+ BtShared *pBt; /* Sharable content of this btree */
+ u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
+ u8 sharable; /* True if we can share pBt with another db */
+ u8 locked; /* True if db currently has pBt locked */
+ int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
+ int nBackup; /* Number of backup operations reading this btree */
+ u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */
+ Btree *pNext; /* List of other sharable Btrees from the same db */
+ Btree *pPrev; /* Back pointer of the same list */
+#ifndef SQLITE_OMIT_SHARED_CACHE
+ BtLock lock; /* Object used to lock page 1 */
+#endif
+};
+
+/*
+** Btree.inTrans may take one of the following values.
+**
+** If the shared-data extension is enabled, there may be multiple users
+** of the Btree structure. At most one of these may open a write transaction,
+** but any number may have active read transactions.
+*/
+#define TRANS_NONE 0
+#define TRANS_READ 1
+#define TRANS_WRITE 2
+
+/*
+** An instance of this object represents a single database file.
+**
+** A single database file can be in use at the same time by two
+** or more database connections. When two or more connections are
+** sharing the same database file, each connection has it own
+** private Btree object for the file and each of those Btrees points
+** to this one BtShared object. BtShared.nRef is the number of
+** connections currently sharing this database file.
+**
+** Fields in this structure are accessed under the BtShared.mutex
+** mutex, except for nRef and pNext which are accessed under the
+** global SQLITE_MUTEX_STATIC_MASTER mutex. The pPager field
+** may not be modified once it is initially set as long as nRef>0.
+** The pSchema field may be set once under BtShared.mutex and
+** thereafter is unchanged as long as nRef>0.
+**
+** isPending:
+**
+** If a BtShared client fails to obtain a write-lock on a database
+** table (because there exists one or more read-locks on the table),
+** the shared-cache enters 'pending-lock' state and isPending is
+** set to true.
+**
+** The shared-cache leaves the 'pending lock' state when either of
+** the following occur:
+**
+** 1) The current writer (BtShared.pWriter) concludes its transaction, OR
+** 2) The number of locks held by other connections drops to zero.
+**
+** while in the 'pending-lock' state, no connection may start a new
+** transaction.
+**
+** This feature is included to help prevent writer-starvation.
+*/
+struct BtShared {
+ Pager *pPager; /* The page cache */
+ sqlite3 *db; /* Database connection currently using this Btree */
+ BtCursor *pCursor; /* A list of all open cursors */
+ MemPage *pPage1; /* First page of the database */
+ u8 openFlags; /* Flags to sqlite3BtreeOpen() */
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ u8 autoVacuum; /* True if auto-vacuum is enabled */
+ u8 incrVacuum; /* True if incr-vacuum is enabled */
+ 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 */
+ 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 */
+ u32 pageSize; /* Total number of bytes on a page */
+ u32 usableSize; /* Number of usable bytes on each page */
+ int nTransaction; /* Number of open transactions (read + write) */
+ u32 nPage; /* Number of pages in the database */
+ void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */
+ void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */
+ sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */
+ Bitvec *pHasContent; /* Set of pages moved to free-list this transaction */
+#ifndef SQLITE_OMIT_SHARED_CACHE
+ int nRef; /* Number of references to this structure */
+ BtShared *pNext; /* Next on a list of sharable BtShared structs */
+ BtLock *pLock; /* List of locks held on this shared-btree struct */
+ Btree *pWriter; /* Btree with currently open write transaction */
+#endif
+ u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */
+};
+
+/*
+** Allowed values for BtShared.btsFlags
+*/
+#define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */
+#define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */
+#define BTS_SECURE_DELETE 0x0004 /* PRAGMA secure_delete is enabled */
+#define BTS_INITIALLY_EMPTY 0x0008 /* Database was empty at trans start */
+#define BTS_NO_WAL 0x0010 /* Do not open write-ahead-log files */
+#define BTS_EXCLUSIVE 0x0020 /* pWriter has an exclusive lock */
+#define BTS_PENDING 0x0040 /* Waiting for read-locks to clear */
+
+/*
+** An instance of the following structure is used to hold information
+** about a cell. The parseCellPtr() function fills in this structure
+** based on information extract from the raw disk page.
+*/
+typedef struct CellInfo CellInfo;
+struct CellInfo {
+ i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */
+ u8 *pPayload; /* Pointer to the start of payload */
+ u32 nPayload; /* Bytes of payload */
+ u16 nLocal; /* Amount of payload held locally, not on overflow */
+ u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */
+ u16 nSize; /* Size of the cell content on the main b-tree page */
+};
+
+/*
+** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than
+** this will be declared corrupt. This value is calculated based on a
+** maximum database size of 2^31 pages a minimum fanout of 2 for a
+** root-node and 3 for all other internal nodes.
+**
+** If a tree that appears to be taller than this is encountered, it is
+** assumed that the database is corrupt.
+*/
+#define BTCURSOR_MAX_DEPTH 20
+
+/*
+** A cursor is a pointer to a particular entry within a particular
+** b-tree within a database file.
+**
+** The entry is identified by its MemPage and the index in
+** MemPage.aCell[] of the entry.
+**
+** A single database file can be shared by two more database connections,
+** but cursors cannot be shared. Each cursor is associated with a
+** particular database connection identified BtCursor.pBtree.db.
+**
+** Fields in this structure are accessed under the BtShared.mutex
+** found at self->pBt->mutex.
+**
+** skipNext meaning:
+** eState==SKIPNEXT && skipNext>0: Next sqlite3BtreeNext() is no-op.
+** eState==SKIPNEXT && skipNext<0: Next sqlite3BtreePrevious() is no-op.
+** eState==FAULT: Cursor fault with skipNext as error code.
+*/
+struct BtCursor {
+ Btree *pBtree; /* The Btree to which this cursor belongs */
+ BtShared *pBt; /* The BtShared this cursor points to */
+ BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */
+ struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
+ Pgno *aOverflow; /* Cache of overflow page locations */
+ CellInfo info; /* A parse of the cell we are pointing at */
+ i64 nKey; /* Size of pKey, or last integer key */
+ void *pKey; /* Saved key that was cursor last known position */
+ Pgno pgnoRoot; /* The root page of this tree */
+ int nOvflAlloc; /* Allocated size of aOverflow[] array */
+ int skipNext; /* Prev() is noop if negative. Next() is noop if positive.
+ ** Error code if eState==CURSOR_FAULT */
+ u8 curFlags; /* zero or more BTCF_* flags defined below */
+ u8 eState; /* One of the CURSOR_XXX constants (see below) */
+ u8 hints; /* As configured by CursorSetHints() */
+ i16 iPage; /* Index of current page in apPage */
+ u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
+ MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
+};
+
+/*
+** Legal values for BtCursor.curFlags
+*/
+#define BTCF_WriteFlag 0x01 /* True if a write cursor */
+#define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */
+#define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */
+#define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */
+#define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */
+
+/*
+** Potential values for BtCursor.eState.
+**
+** CURSOR_INVALID:
+** Cursor does not point to a valid entry. This can happen (for example)
+** because the table is empty or because BtreeCursorFirst() has not been
+** called.
+**
+** CURSOR_VALID:
+** Cursor points to a valid entry. getPayload() etc. may be called.
+**
+** CURSOR_SKIPNEXT:
+** Cursor is valid except that the Cursor.skipNext field is non-zero
+** indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious()
+** operation should be a no-op.
+**
+** CURSOR_REQUIRESEEK:
+** The table that this cursor was opened on still exists, but has been
+** modified since the cursor was last used. The cursor position is saved
+** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in
+** this state, restoreCursorPosition() can be called to attempt to
+** seek the cursor to the saved position.
+**
+** CURSOR_FAULT:
+** An unrecoverable error (an I/O error or a malloc failure) has occurred
+** on a different connection that shares the BtShared cache with this
+** cursor. The error has left the cache in an inconsistent state.
+** Do nothing else with this cursor. Any attempt to use the cursor
+** should return the error code stored in BtCursor.skipNext
+*/
+#define CURSOR_INVALID 0
+#define CURSOR_VALID 1
+#define CURSOR_SKIPNEXT 2
+#define CURSOR_REQUIRESEEK 3
+#define CURSOR_FAULT 4
+
+/*
+** The database page the PENDING_BYTE occupies. This page is never used.
+*/
+# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
+
+/*
+** These macros define the location of the pointer-map entry for a
+** database page. The first argument to each is the number of usable
+** bytes on each page of the database (often 1024). The second is the
+** page number to look up in the pointer map.
+**
+** PTRMAP_PAGENO returns the database page number of the pointer-map
+** page that stores the required pointer. PTRMAP_PTROFFSET returns
+** the offset of the requested map entry.
+**
+** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page,
+** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be
+** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
+** this test.
+*/
+#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno)
+#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1))
+#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))
+
+/*
+** The pointer map is a lookup table that identifies the parent page for
+** each child page in the database file. The parent page is the page that
+** contains a pointer to the child. Every page in the database contains
+** 0 or 1 parent pages. (In this context 'database page' refers
+** to any page that is not part of the pointer map itself.) Each pointer map
+** entry consists of a single byte 'type' and a 4 byte parent page number.
+** The PTRMAP_XXX identifiers below are the valid types.
+**
+** The purpose of the pointer map is to facility moving pages from one
+** position in the file to another as part of autovacuum. When a page
+** is moved, the pointer in its parent must be updated to point to the
+** new location. The pointer map is used to locate the parent page quickly.
+**
+** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not
+** used in this case.
+**
+** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number
+** is not used in this case.
+**
+** PTRMAP_OVERFLOW1: The database page is the first page in a list of
+** overflow pages. The page number identifies the page that
+** contains the cell with a pointer to this overflow page.
+**
+** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of
+** overflow pages. The page-number identifies the previous
+** page in the overflow page list.
+**
+** PTRMAP_BTREE: The database page is a non-root btree page. The page number
+** identifies the parent page in the btree.
+*/
+#define PTRMAP_ROOTPAGE 1
+#define PTRMAP_FREEPAGE 2
+#define PTRMAP_OVERFLOW1 3
+#define PTRMAP_OVERFLOW2 4
+#define PTRMAP_BTREE 5
+
+/* A bunch of assert() statements to check the transaction state variables
+** of handle p (type Btree*) are internally consistent.
+*/
+#define btreeIntegrity(p) \
+ assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \
+ assert( p->pBt->inTransaction>=p->inTrans );
+
+
+/*
+** The ISAUTOVACUUM macro is used within balance_nonroot() to determine
+** if the database supports auto-vacuum or not. Because it is used
+** within an expression that is an argument to another macro
+** (sqliteMallocRaw), it is not possible to use conditional compilation.
+** So, this macro is defined instead.
+*/
+#ifndef SQLITE_OMIT_AUTOVACUUM
+#define ISAUTOVACUUM (pBt->autoVacuum)
+#else
+#define ISAUTOVACUUM 0
+#endif
+
+
+/*
+** This structure is passed around through all the sanity checking routines
+** in order to keep track of some global state information.
+**
+** The aRef[] array is allocated so that there is 1 bit for each page in
+** the database. As the integrity-check proceeds, for each page used in
+** the database the corresponding bit is set. This allows integrity-check to
+** detect pages that are used twice and orphaned pages (both of which
+** indicate corruption).
+*/
+typedef struct IntegrityCk IntegrityCk;
+struct IntegrityCk {
+ BtShared *pBt; /* The tree being checked out */
+ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */
+ u8 *aPgRef; /* 1 bit per page in the db (see above) */
+ Pgno nPage; /* Number of pages in the database */
+ int mxErr; /* Stop accumulating errors when this reaches zero */
+ int nErr; /* Number of messages written to zErrMsg so far */
+ int mallocFailed; /* A memory allocation error has occurred */
+ const char *zPfx; /* Error message prefix */
+ int v1, v2; /* Values for up to two %d fields in zPfx */
+ StrAccum errMsg; /* Accumulate the error message text here */
+};
+
+/*
+** Routines to read or write a two- and four-byte big-endian integer values.
+*/
+#define get2byte(x) ((x)[0]<<8 | (x)[1])
+#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v))
+#define get4byte sqlite3Get4byte
+#define put4byte sqlite3Put4byte
+
+/************** End of btreeInt.h ********************************************/
+/************** Continuing where we left off in crypto.c *********************/
+/************** Include crypto.h in the middle of crypto.c *******************/
+/************** Begin file crypto.h ******************************************/
+/*
+** SQLCipher
+** crypto.h developed by Stephen Lombardo (Zetetic LLC)
+** sjlombardo at zetetic dot net
+** http://zetetic.net
+**
+** Copyright (c) 2008, ZETETIC LLC
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of the ZETETIC LLC nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*/
+/* BEGIN SQLCIPHER */
+#ifdef SQLITE_HAS_CODEC
+#ifndef CRYPTO_H
+#define CRYPTO_H
+
+#if !defined (SQLCIPHER_CRYPTO_CC) \
+ && !defined (SQLCIPHER_CRYPTO_LIBTOMCRYPT) \
+ && !defined (SQLCIPHER_CRYPTO_OPENSSL)
+#define SQLCIPHER_CRYPTO_OPENSSL
+#endif
+
+#define FILE_HEADER_SZ 16
+
+#ifndef CIPHER_VERSION
+#ifdef SQLCIPHER_FIPS
+#define CIPHER_VERSION "3.3.0 FIPS"
+#else
+#define CIPHER_VERSION "3.3.0"
+#endif
+#endif
+
+#ifndef CIPHER
+#define CIPHER "aes-256-cbc"
+#endif
+
+#define CIPHER_DECRYPT 0
+#define CIPHER_ENCRYPT 1
+
+#define CIPHER_READ_CTX 0
+#define CIPHER_WRITE_CTX 1
+#define CIPHER_READWRITE_CTX 2
+
+#ifndef PBKDF2_ITER
+#define PBKDF2_ITER 64000
+#endif
+
+/* possible flags for cipher_ctx->flags */
+#define CIPHER_FLAG_HMAC 0x01
+#define CIPHER_FLAG_LE_PGNO 0x02
+#define CIPHER_FLAG_BE_PGNO 0x04
+
+#ifndef DEFAULT_CIPHER_FLAGS
+#define DEFAULT_CIPHER_FLAGS CIPHER_FLAG_HMAC | CIPHER_FLAG_LE_PGNO
+#endif
+
+
+/* by default, sqlcipher will use a reduced number of iterations to generate
+ the HMAC key / or transform a raw cipher key
+ */
+#ifndef FAST_PBKDF2_ITER
+#define FAST_PBKDF2_ITER 2
+#endif
+
+/* this if a fixed random array that will be xor'd with the database salt to ensure that the
+ salt passed to the HMAC key derivation function is not the same as that used to derive
+ the encryption key. This can be overridden at compile time but it will make the resulting
+ binary incompatible with the default builds when using HMAC. A future version of SQLcipher
+ will likely allow this to be defined at runtime via pragma */
+#ifndef HMAC_SALT_MASK
+#define HMAC_SALT_MASK 0x3a
+#endif
+
+#ifndef CIPHER_MAX_IV_SZ
+#define CIPHER_MAX_IV_SZ 16
+#endif
+
+#ifndef CIPHER_MAX_KEY_SZ
+#define CIPHER_MAX_KEY_SZ 64
+#endif
+
+
+#ifdef CODEC_DEBUG
+#define CODEC_TRACE(X) {printf X;fflush(stdout);}
+#else
+#define CODEC_TRACE(X)
+#endif
+
+#ifdef CODEC_DEBUG_PAGEDATA
+#define CODEC_HEXDUMP(DESC,BUFFER,LEN) \
+ { \
+ int __pctr; \
+ printf(DESC); \
+ for(__pctr=0; __pctr < LEN; __pctr++) { \
+ if(__pctr % 16 == 0) printf("\n%05x: ",__pctr); \
+ printf("%02x ",((unsigned char*) BUFFER)[__pctr]); \
+ } \
+ printf("\n"); \
+ fflush(stdout); \
+ }
+#else
+#define CODEC_HEXDUMP(DESC,BUFFER,LEN)
+#endif
+
+/* extensions defined in pager.c */
+SQLITE_PRIVATE void sqlite3pager_get_codec(Pager *pPager, void **ctx);
+SQLITE_PRIVATE int sqlite3pager_is_mj_pgno(Pager *pPager, Pgno pgno);
+SQLITE_PRIVATE sqlite3_file *sqlite3Pager_get_fd(Pager *pPager);
+SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetCodec(
+ Pager *pPager,
+ void *(*xCodec)(void*,void*,Pgno,int),
+ void (*xCodecSizeChng)(void*,int,int),
+ void (*xCodecFree)(void*),
+ void *pCodec
+);
+SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetError(Pager *pPager, int error);
+/* end extensions defined in pager.c */
+
+/*
+** Simple shared routines for converting hex char strings to binary data
+ */
+static int cipher_hex2int(char c) {
+ return (c>='0' && c<='9') ? (c)-'0' :
+ (c>='A' && c<='F') ? (c)-'A'+10 :
+ (c>='a' && c<='f') ? (c)-'a'+10 : 0;
+}
+
+static void cipher_hex2bin(const unsigned char *hex, int sz, unsigned char *out){
+ int i;
+ for(i = 0; i < sz; i += 2){
+ out[i/2] = (cipher_hex2int(hex[i])<<4) | cipher_hex2int(hex[i+1]);
+ }
+}
+
+static void cipher_bin2hex(const unsigned char* in, int sz, char *out) {
+ int i;
+ for(i=0; i < sz; i++) {
+ sqlite3_snprintf(3, out + (i*2), "%02x ", in[i]);
+ }
+}
+
+/* extensions defined in crypto_impl.c */
+typedef struct codec_ctx codec_ctx;
+
+/* activation and initialization */
+void sqlcipher_activate();
+void sqlcipher_deactivate();
+int sqlcipher_codec_ctx_init(codec_ctx **, Db *, Pager *, sqlite3_file *, const void *, int);
+void sqlcipher_codec_ctx_free(codec_ctx **);
+int sqlcipher_codec_key_derive(codec_ctx *);
+int sqlcipher_codec_key_copy(codec_ctx *, int);
+
+/* page cipher implementation */
+int sqlcipher_page_cipher(codec_ctx *, int, Pgno, int, int, unsigned char *, unsigned char *);
+
+/* context setters & getters */
+void sqlcipher_codec_ctx_set_error(codec_ctx *, int);
+
+int sqlcipher_codec_ctx_set_pass(codec_ctx *, const void *, int, int);
+void sqlcipher_codec_get_keyspec(codec_ctx *, void **zKey, int *nKey);
+
+int sqlcipher_codec_ctx_set_pagesize(codec_ctx *, int);
+int sqlcipher_codec_ctx_get_pagesize(codec_ctx *);
+int sqlcipher_codec_ctx_get_reservesize(codec_ctx *);
+
+void sqlcipher_set_default_pagesize(int page_size);
+int sqlcipher_get_default_pagesize();
+
+void sqlcipher_set_default_kdf_iter(int iter);
+int sqlcipher_get_default_kdf_iter();
+
+int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *, int, int);
+int sqlcipher_codec_ctx_get_kdf_iter(codec_ctx *ctx, int);
+
+void* sqlcipher_codec_ctx_get_kdf_salt(codec_ctx *ctx);
+
+int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *, int, int);
+int sqlcipher_codec_ctx_get_fast_kdf_iter(codec_ctx *, int);
+
+int sqlcipher_codec_ctx_set_cipher(codec_ctx *, const char *, int);
+const char* sqlcipher_codec_ctx_get_cipher(codec_ctx *ctx, int for_ctx);
+
+void* sqlcipher_codec_ctx_get_data(codec_ctx *);
+
+void sqlcipher_exportFunc(sqlite3_context *, int, sqlite3_value **);
+
+void sqlcipher_set_default_use_hmac(int use);
+int sqlcipher_get_default_use_hmac();
+
+void sqlcipher_set_hmac_salt_mask(unsigned char mask);
+unsigned char sqlcipher_get_hmac_salt_mask();
+
+int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use);
+int sqlcipher_codec_ctx_get_use_hmac(codec_ctx *ctx, int for_ctx);
+
+int sqlcipher_codec_ctx_set_flag(codec_ctx *ctx, unsigned int flag);
+int sqlcipher_codec_ctx_unset_flag(codec_ctx *ctx, unsigned int flag);
+int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int flag, int for_ctx);
+
+const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx);
+int sqlcipher_codec_ctx_migrate(codec_ctx *ctx);
+int sqlcipher_codec_add_random(codec_ctx *ctx, const char *data, int random_sz);
+int sqlcipher_cipher_profile(sqlite3 *db, const char *destination);
+static void sqlcipher_profile_callback(void *file, const char *sql, sqlite3_uint64 run_time);
+static int sqlcipher_codec_get_store_pass(codec_ctx *ctx);
+static void sqlcipher_codec_get_pass(codec_ctx *ctx, void **zKey, int *nKey);
+static void sqlcipher_codec_set_store_pass(codec_ctx *ctx, int value);
+int sqlcipher_codec_fips_status(codec_ctx *ctx);
+
+#endif
+#endif
+/* END SQLCIPHER */
+
+/************** End of crypto.h **********************************************/
+/************** Continuing where we left off in crypto.c *********************/
+
+static const char* codec_get_cipher_version() {
+ return CIPHER_VERSION;
+}
+
+/* Generate code to return a string value */
+static void codec_vdbe_return_static_string(Parse *pParse, const char *zLabel, const char *value){
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, value, 0);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+}
+
+static int codec_set_btree_to_codec_pagesize(sqlite3 *db, Db *pDb, codec_ctx *ctx) {
+ int rc, page_sz, reserve_sz;
+
+ page_sz = sqlcipher_codec_ctx_get_pagesize(ctx);
+ reserve_sz = sqlcipher_codec_ctx_get_reservesize(ctx);
+
+ sqlite3_mutex_enter(db->mutex);
+ db->nextPagesize = page_sz;
+
+ /* before forcing the page size we need to unset the BTS_PAGESIZE_FIXED flag, else
+ sqliteBtreeSetPageSize will block the change */
+ pDb->pBt->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED;
+ CODEC_TRACE(("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=%d reserve=%d\n", page_sz, reserve_sz));
+ rc = sqlite3BtreeSetPageSize(pDb->pBt, page_sz, reserve_sz, 0);
+ sqlite3_mutex_leave(db->mutex);
+ return rc;
+}
+
+static int codec_set_pass_key(sqlite3* db, int nDb, const void *zKey, int nKey, int for_ctx) {
+ struct Db *pDb = &db->aDb[nDb];
+ CODEC_TRACE(("codec_set_pass_key: entered db=%p nDb=%d zKey=%s nKey=%d for_ctx=%d\n", db, nDb, (char *)zKey, nKey, for_ctx));
+ if(pDb->pBt) {
+ codec_ctx *ctx;
+ sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
+ if(ctx) return sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, for_ctx);
+ }
+ return SQLITE_ERROR;
+}
+
+int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const char *zRight) {
+ struct Db *pDb = &db->aDb[iDb];
+ codec_ctx *ctx = NULL;
+ int rc;
+
+ if(pDb->pBt) {
+ sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
+ }
+
+ CODEC_TRACE(("sqlcipher_codec_pragma: entered db=%p iDb=%d pParse=%p zLeft=%s zRight=%s ctx=%p\n", db, iDb, pParse, zLeft, zRight, ctx));
+
+ if( sqlite3StrICmp(zLeft, "cipher_fips_status")== 0 && !zRight ){
+ if(ctx) {
+ char *fips_mode_status = sqlite3_mprintf("%d", sqlcipher_codec_fips_status(ctx));
+ codec_vdbe_return_static_string(pParse, "cipher_fips_status", fips_mode_status);
+ sqlite3_free(fips_mode_status);
+ }
+ } else
+ if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && zRight ) {
+ sqlcipher_codec_set_store_pass(ctx, sqlite3GetBoolean(zRight, 1));
+ } else
+ if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && !zRight ) {
+ char *store_pass_value = sqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx));
+ codec_vdbe_return_static_string(pParse, "cipher_store_pass", store_pass_value);
+ sqlite3_free(store_pass_value);
+ }
+ if( sqlite3StrICmp(zLeft, "cipher_profile")== 0 && zRight ){
+ char *profile_status = sqlite3_mprintf("%d", sqlcipher_cipher_profile(db, zRight));
+ codec_vdbe_return_static_string(pParse, "cipher_profile", profile_status);
+ sqlite3_free(profile_status);
+ } else
+ if( sqlite3StrICmp(zLeft, "cipher_add_random")==0 && zRight ){
+ if(ctx) {
+ char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight, sqlite3Strlen30(zRight)));
+ codec_vdbe_return_static_string(pParse, "cipher_add_random", add_random_status);
+ sqlite3_free(add_random_status);
+ }
+ } else
+ if( sqlite3StrICmp(zLeft, "cipher_migrate")==0 && !zRight ){
+ if(ctx){
+ char *migrate_status = sqlite3_mprintf("%d", sqlcipher_codec_ctx_migrate(ctx));
+ codec_vdbe_return_static_string(pParse, "cipher_migrate", migrate_status);
+ sqlite3_free(migrate_status);
+ }
+ } else
+ if( sqlite3StrICmp(zLeft, "cipher_provider")==0 && !zRight ){
+ if(ctx) { codec_vdbe_return_static_string(pParse, "cipher_provider",
+ sqlcipher_codec_get_cipher_provider(ctx));
+ }
+ } else
+ if( sqlite3StrICmp(zLeft, "cipher_version")==0 && !zRight ){
+ codec_vdbe_return_static_string(pParse, "cipher_version", codec_get_cipher_version());
+ }else
+ if( sqlite3StrICmp(zLeft, "cipher")==0 ){
+ if(ctx) {
+ if( zRight ) {
+ sqlcipher_codec_ctx_set_cipher(ctx, zRight, 2); // change cipher for both
+ }else {
+ codec_vdbe_return_static_string(pParse, "cipher",
+ sqlcipher_codec_ctx_get_cipher(ctx, 2));
+ }
+ }
+ }else
+ if( sqlite3StrICmp(zLeft, "rekey_cipher")==0 && zRight ){
+ if(ctx) sqlcipher_codec_ctx_set_cipher(ctx, zRight, 1); // change write cipher only
+ }else
+ if( sqlite3StrICmp(zLeft,"cipher_default_kdf_iter")==0 ){
+ if( zRight ) {
+ sqlcipher_set_default_kdf_iter(atoi(zRight)); // change default KDF iterations
+ } else {
+ char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter());
+ codec_vdbe_return_static_string(pParse, "cipher_default_kdf_iter", kdf_iter);
+ sqlite3_free(kdf_iter);
+ }
+ }else
+ if( sqlite3StrICmp(zLeft, "kdf_iter")==0 ){
+ if(ctx) {
+ if( zRight ) {
+ sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight), 2); // change of RW PBKDF2 iteration
+ } else {
+ char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_kdf_iter(ctx, 2));
+ codec_vdbe_return_static_string(pParse, "kdf_iter", kdf_iter);
+ sqlite3_free(kdf_iter);
+ }
+ }
+ }else
+ if( sqlite3StrICmp(zLeft, "fast_kdf_iter")==0){
+ if(ctx) {
+ if( zRight ) {
+ sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, atoi(zRight), 2); // change of RW PBKDF2 iteration
+ } else {
+ char *fast_kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_fast_kdf_iter(ctx, 2));
+ codec_vdbe_return_static_string(pParse, "fast_kdf_iter", fast_kdf_iter);
+ sqlite3_free(fast_kdf_iter);
+ }
+ }
+ }else
+ if( sqlite3StrICmp(zLeft, "rekey_kdf_iter")==0 && zRight ){
+ if(ctx) sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight), 1); // write iterations only
+ }else
+ if( sqlite3StrICmp(zLeft,"cipher_page_size")==0 ){
+ if(ctx) {
+ if( zRight ) {
+ int size = atoi(zRight);
+ rc = sqlcipher_codec_ctx_set_pagesize(ctx, size);
+ if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
+ rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
+ if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
+ } else {
+ char * page_size = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_pagesize(ctx));
+ codec_vdbe_return_static_string(pParse, "cipher_page_size", page_size);
+ sqlite3_free(page_size);
+ }
+ }
+ }else
+ if( sqlite3StrICmp(zLeft,"cipher_default_page_size")==0 ){
+ if( zRight ) {
+ sqlcipher_set_default_pagesize(atoi(zRight));
+ } else {
+ char *default_page_size = sqlite3_mprintf("%d", sqlcipher_get_default_pagesize());
+ codec_vdbe_return_static_string(pParse, "cipher_default_page_size", default_page_size);
+ sqlite3_free(default_page_size);
+ }
+ }else
+ if( sqlite3StrICmp(zLeft,"cipher_default_use_hmac")==0 ){
+ if( zRight ) {
+ sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight,1));
+ } else {
+ char *default_use_hmac = sqlite3_mprintf("%d", sqlcipher_get_default_use_hmac());
+ codec_vdbe_return_static_string(pParse, "cipher_default_use_hmac", default_use_hmac);
+ sqlite3_free(default_use_hmac);
+ }
+ }else
+ if( sqlite3StrICmp(zLeft,"cipher_use_hmac")==0 ){
+ if(ctx) {
+ if( zRight ) {
+ rc = sqlcipher_codec_ctx_set_use_hmac(ctx, sqlite3GetBoolean(zRight,1));
+ if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
+ /* since the use of hmac has changed, the page size may also change */
+ rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
+ if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
+ } else {
+ char *hmac_flag = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_use_hmac(ctx, 2));
+ codec_vdbe_return_static_string(pParse, "cipher_use_hmac", hmac_flag);
+ sqlite3_free(hmac_flag);
+ }
+ }
+ }else
+ if( sqlite3StrICmp(zLeft,"cipher_hmac_pgno")==0 ){
+ if(ctx) {
+ if(zRight) {
+ // clear both pgno endian flags
+ if(sqlite3StrICmp(zRight, "le") == 0) {
+ sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
+ sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_LE_PGNO);
+ } else if(sqlite3StrICmp(zRight, "be") == 0) {
+ sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
+ sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_BE_PGNO);
+ } else if(sqlite3StrICmp(zRight, "native") == 0) {
+ sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
+ sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
+ }
+ } else {
+ if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_LE_PGNO, 2)) {
+ codec_vdbe_return_static_string(pParse, "cipher_hmac_pgno", "le");
+ } else if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_BE_PGNO, 2)) {
+ codec_vdbe_return_static_string(pParse, "cipher_hmac_pgno", "be");
+ } else {
+ codec_vdbe_return_static_string(pParse, "cipher_hmac_pgno", "native");
+ }
+ }
+ }
+ }else
+ if( sqlite3StrICmp(zLeft,"cipher_hmac_salt_mask")==0 ){
+ if(ctx) {
+ if(zRight) {
+ if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == 5) {
+ unsigned char mask = 0;
+ const unsigned char *hex = (const unsigned char *)zRight+2;
+ cipher_hex2bin(hex,2,&mask);
+ sqlcipher_set_hmac_salt_mask(mask);
+ }
+ } else {
+ char *hmac_salt_mask = sqlite3_mprintf("%02x", sqlcipher_get_hmac_salt_mask());
+ codec_vdbe_return_static_string(pParse, "cipher_hmac_salt_mask", hmac_salt_mask);
+ sqlite3_free(hmac_salt_mask);
+ }
+ }
+ }else {
+ return 0;
+ }
+ return 1;
+}
+
+
+/*
+ * sqlite3Codec can be called in multiple modes.
+ * encrypt mode - expected to return a pointer to the
+ * encrypted data without altering pData.
+ * decrypt mode - expected to return a pointer to pData, with
+ * the data decrypted in the input buffer
+ */
+void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) {
+ codec_ctx *ctx = (codec_ctx *) iCtx;
+ int offset = 0, rc = 0;
+ int page_sz = sqlcipher_codec_ctx_get_pagesize(ctx);
+ unsigned char *pData = (unsigned char *) data;
+ void *buffer = sqlcipher_codec_ctx_get_data(ctx);
+ void *kdf_salt = sqlcipher_codec_ctx_get_kdf_salt(ctx);
+ CODEC_TRACE(("sqlite3Codec: entered pgno=%d, mode=%d, page_sz=%d\n", pgno, mode, page_sz));
+
+ /* call to derive keys if not present yet */
+ if((rc = sqlcipher_codec_key_derive(ctx)) != SQLITE_OK) {
+ sqlcipher_codec_ctx_set_error(ctx, rc);
+ return NULL;
+ }
+
+ if(pgno == 1) offset = FILE_HEADER_SZ; /* adjust starting pointers in data page for header offset on first page*/
+
+ CODEC_TRACE(("sqlite3Codec: switch mode=%d offset=%d\n", mode, offset));
+ switch(mode) {
+ case 0: /* decrypt */
+ case 2:
+ case 3:
+ if(pgno == 1) memcpy(buffer, SQLITE_FILE_HEADER, FILE_HEADER_SZ); /* copy file header to the first 16 bytes of the page */
+ rc = sqlcipher_page_cipher(ctx, CIPHER_READ_CTX, pgno, CIPHER_DECRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset);
+ if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
+ memcpy(pData, buffer, page_sz); /* copy buffer data back to pData and return */
+ return pData;
+ break;
+ case 6: /* encrypt */
+ if(pgno == 1) memcpy(buffer, kdf_salt, FILE_HEADER_SZ); /* copy salt to output buffer */
+ rc = sqlcipher_page_cipher(ctx, CIPHER_WRITE_CTX, pgno, CIPHER_ENCRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset);
+ if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
+ return buffer; /* return persistent buffer data, pData remains intact */
+ break;
+ case 7:
+ if(pgno == 1) memcpy(buffer, kdf_salt, FILE_HEADER_SZ); /* copy salt to output buffer */
+ rc = sqlcipher_page_cipher(ctx, CIPHER_READ_CTX, pgno, CIPHER_ENCRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset);
+ if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
+ return buffer; /* return persistent buffer data, pData remains intact */
+ break;
+ default:
+ return pData;
+ break;
+ }
+}
+
+SQLITE_PRIVATE void sqlite3FreeCodecArg(void *pCodecArg) {
+ codec_ctx *ctx = (codec_ctx *) pCodecArg;
+ if(pCodecArg == NULL) return;
+ sqlcipher_codec_ctx_free(&ctx); // wipe and free allocated memory for the context
+ sqlcipher_deactivate(); /* cleanup related structures, OpenSSL etc, when codec is detatched */
+}
+
+SQLITE_PRIVATE int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
+ struct Db *pDb = &db->aDb[nDb];
+
+ CODEC_TRACE(("sqlite3CodecAttach: entered nDb=%d zKey=%s, nKey=%d\n", nDb, (char *)zKey, nKey));
+
+
+ if(nKey && zKey && pDb->pBt) {
+ int rc;
+ Pager *pPager = pDb->pBt->pBt->pPager;
+ sqlite3_file *fd = sqlite3Pager_get_fd(pPager);
+ codec_ctx *ctx;
+
+ sqlcipher_activate(); /* perform internal initialization for sqlcipher */
+
+ sqlite3_mutex_enter(db->mutex);
+
+ /* point the internal codec argument against the contet to be prepared */
+ rc = sqlcipher_codec_ctx_init(&ctx, pDb, pDb->pBt->pBt->pPager, fd, zKey, nKey);
+
+ if(rc != SQLITE_OK) return rc; /* initialization failed, do not attach potentially corrupted context */
+
+ sqlite3pager_sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, (void *) ctx);
+
+ codec_set_btree_to_codec_pagesize(db, pDb, ctx);
+
+ /* force secure delete. This has the benefit of wiping internal data when deleted
+ and also ensures that all pages are written to disk (i.e. not skipped by
+ sqlite3PagerDontWrite optimizations) */
+ sqlite3BtreeSecureDelete(pDb->pBt, 1);
+
+ /* if fd is null, then this is an in-memory database and
+ we dont' want to overwrite the AutoVacuum settings
+ if not null, then set to the default */
+ if(fd != NULL) {
+ sqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM);
+ }
+ sqlite3_mutex_leave(db->mutex);
+ }
+ return SQLITE_OK;
+}
+
+SQLITE_API void sqlite3_activate_see(const char* in) {
+ /* do nothing, security enhancements are always active */
+}
+
+static int sqlcipher_find_db_index(sqlite3 *db, const char *zDb) {
+ int db_index;
+ if(zDb == NULL){
+ return 0;
+ }
+ for(db_index = 0; db_index < db->nDb; db_index++) {
+ struct Db *pDb = &db->aDb[db_index];
+ if(strcmp(pDb->zName, zDb) == 0) {
+ return db_index;
+ }
+ }
+ return 0;
+}
+
+SQLITE_API int sqlite3_key(sqlite3 *db, const void *pKey, int nKey) {
+ CODEC_TRACE(("sqlite3_key entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey));
+ return sqlite3_key_v2(db, "main", pKey, nKey);
+}
+
+SQLITE_API int sqlite3_key_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
+ CODEC_TRACE(("sqlite3_key_v2: entered db=%p zDb=%s pKey=%s nKey=%d\n", db, zDb, (char *)pKey, nKey));
+ /* attach key if db and pKey are not null and nKey is > 0 */
+ if(db && pKey && nKey) {
+ int db_index = sqlcipher_find_db_index(db, zDb);
+ return sqlite3CodecAttach(db, db_index, pKey, nKey);
+ }
+ return SQLITE_ERROR;
+}
+
+SQLITE_API int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
+ CODEC_TRACE(("sqlite3_rekey entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey));
+ return sqlite3_rekey_v2(db, "main", pKey, nKey);
+}
+
+/* sqlite3_rekey_v2
+** Given a database, this will reencrypt the database using a new key.
+** There is only one possible modes of operation - to encrypt a database
+** that is already encrpyted. If the database is not already encrypted
+** this should do nothing
+** The proposed logic for this function follows:
+** 1. Determine if the database is already encryptped
+** 2. If there is NOT already a key present do nothing
+** 3. If there is a key present, re-encrypt the database with the new key
+*/
+SQLITE_API int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
+ CODEC_TRACE(("sqlite3_rekey_v2: entered db=%p zDb=%s pKey=%s, nKey=%d\n", db, zDb, (char *)pKey, nKey));
+ if(db && pKey && nKey) {
+ int db_index = sqlcipher_find_db_index(db, zDb);
+ struct Db *pDb = &db->aDb[db_index];
+ CODEC_TRACE(("sqlite3_rekey_v2: database pDb=%p db_index:%d\n", pDb, db_index));
+ if(pDb->pBt) {
+ codec_ctx *ctx;
+ int rc, page_count;
+ Pgno pgno;
+ PgHdr *page;
+ Pager *pPager = pDb->pBt->pBt->pPager;
+
+ sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
+
+ if(ctx == NULL) {
+ /* there was no codec attached to this database, so this should do nothing! */
+ CODEC_TRACE(("sqlite3_rekey_v2: no codec attached to db, exiting\n"));
+ return SQLITE_OK;
+ }
+
+ sqlite3_mutex_enter(db->mutex);
+
+ codec_set_pass_key(db, db_index, pKey, nKey, CIPHER_WRITE_CTX);
+
+ /* do stuff here to rewrite the database
+ ** 1. Create a transaction on the database
+ ** 2. Iterate through each page, reading it and then writing it.
+ ** 3. If that goes ok then commit and put ctx->rekey into ctx->key
+ ** note: don't deallocate rekey since it may be used in a subsequent iteration
+ */
+ rc = sqlite3BtreeBeginTrans(pDb->pBt, 1); /* begin write transaction */
+ sqlite3PagerPagecount(pPager, &page_count);
+ for(pgno = 1; rc == SQLITE_OK && pgno <= (unsigned int)page_count; pgno++) { /* pgno's start at 1 see pager.c:pagerAcquire */
+ if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */
+ rc = sqlite3PagerGet(pPager, pgno, &page);
+ if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */
+ rc = sqlite3PagerWrite(page);
+ if(rc == SQLITE_OK) {
+ sqlite3PagerUnref(page);
+ } else {
+ CODEC_TRACE(("sqlite3_rekey_v2: error %d occurred writing page %d\n", rc, pgno));
+ }
+ } else {
+ CODEC_TRACE(("sqlite3_rekey_v2: error %d occurred getting page %d\n", rc, pgno));
+ }
+ }
+ }
+
+ /* if commit was successful commit and copy the rekey data to current key, else rollback to release locks */
+ if(rc == SQLITE_OK) {
+ CODEC_TRACE(("sqlite3_rekey_v2: committing\n"));
+ rc = sqlite3BtreeCommit(pDb->pBt);
+ sqlcipher_codec_key_copy(ctx, CIPHER_WRITE_CTX);
+ } else {
+ CODEC_TRACE(("sqlite3_rekey_v2: rollback\n"));
+ sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK, 0);
+ }
+
+ sqlite3_mutex_leave(db->mutex);
+ }
+ return SQLITE_OK;
+ }
+ return SQLITE_ERROR;
+}
+
+SQLITE_PRIVATE void sqlite3CodecGetKey(sqlite3* db, int nDb, void **zKey, int *nKey) {
+ struct Db *pDb = &db->aDb[nDb];
+ CODEC_TRACE(("sqlite3CodecGetKey: entered db=%p, nDb=%d\n", db, nDb));
+ if( pDb->pBt ) {
+ codec_ctx *ctx;
+ sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
+ if(ctx) {
+ if(sqlcipher_codec_get_store_pass(ctx) == 1) {
+ sqlcipher_codec_get_pass(ctx, zKey, nKey);
+ } else {
+ sqlcipher_codec_get_keyspec(ctx, zKey, nKey);
+ }
+ } else {
+ *zKey = NULL;
+ *nKey = 0;
+ }
+ }
+}
+
+#ifndef OMIT_EXPORT
+
+/*
+ * Implementation of an "export" function that allows a caller
+ * to duplicate the main database to an attached database. This is intended
+ * as a conveneince for users who need to:
+ *
+ * 1. migrate from an non-encrypted database to an encrypted database
+ * 2. move from an encrypted database to a non-encrypted database
+ * 3. convert beween the various flavors of encrypted databases.
+ *
+ * This implementation is based heavily on the procedure and code used
+ * in vacuum.c, but is exposed as a function that allows export to any
+ * named attached database.
+ */
+
+/*
+** Finalize a prepared statement. If there was an error, store the
+** text of the error message in *pzErrMsg. Return the result code.
+**
+** Based on vacuumFinalize from vacuum.c
+*/
+static int sqlcipher_finalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
+ int rc;
+ rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
+ if( rc ){
+ sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
+ }
+ return rc;
+}
+
+/*
+** Execute zSql on database db. Return an error code.
+**
+** Based on execSql from vacuum.c
+*/
+static int sqlcipher_execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
+ sqlite3_stmt *pStmt;
+ VVA_ONLY( int rc; )
+ if( !zSql ){
+ return SQLITE_NOMEM;
+ }
+ if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
+ sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
+ return sqlite3_errcode(db);
+ }
+ VVA_ONLY( rc = ) sqlite3_step(pStmt);
+ assert( rc!=SQLITE_ROW );
+ return sqlcipher_finalize(db, pStmt, pzErrMsg);
+}
+
+/*
+** Execute zSql on database db. The statement returns exactly
+** one column. Execute this as SQL on the same database.
+**
+** Based on execExecSql from vacuum.c
+*/
+static int sqlcipher_execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
+ sqlite3_stmt *pStmt;
+ int rc;
+
+ rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
+ if( rc!=SQLITE_OK ) return rc;
+
+ while( SQLITE_ROW==sqlite3_step(pStmt) ){
+ rc = sqlcipher_execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
+ if( rc!=SQLITE_OK ){
+ sqlcipher_finalize(db, pStmt, pzErrMsg);
+ return rc;
+ }
+ }
+
+ return sqlcipher_finalize(db, pStmt, pzErrMsg);
+}
+
+/*
+ * copy database and schema from the main database to an attached database
+ *
+ * Based on sqlite3RunVacuum from vacuum.c
+*/
+void sqlcipher_exportFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ const char* attachedDb = (const char*) sqlite3_value_text(argv[0]);
+ int saved_flags; /* Saved value of the db->flags */
+ int saved_nChange; /* Saved value of db->nChange */
+ int saved_nTotalChange; /* Saved value of db->nTotalChange */
+ void (*saved_xTrace)(void*,const char*); /* Saved db->xTrace */
+ int rc = SQLITE_OK; /* Return code from service routines */
+ char *zSql = NULL; /* SQL statements */
+ char *pzErrMsg = NULL;
+
+ saved_flags = db->flags;
+ saved_nChange = db->nChange;
+ saved_nTotalChange = db->nTotalChange;
+ saved_xTrace = db->xTrace;
+ db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
+ db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
+ db->xTrace = 0;
+
+ /* Query the schema of the main database. Create a mirror schema
+ ** in the temporary database.
+ */
+ zSql = sqlite3_mprintf(
+ "SELECT 'CREATE TABLE %s.' || substr(sql,14) "
+ " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
+ " AND rootpage>0"
+ , attachedDb);
+ rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
+ if( rc!=SQLITE_OK ) goto end_of_export;
+ sqlite3_free(zSql);
+
+ zSql = sqlite3_mprintf(
+ "SELECT 'CREATE INDEX %s.' || substr(sql,14)"
+ " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %%' "
+ , attachedDb);
+ rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
+ if( rc!=SQLITE_OK ) goto end_of_export;
+ sqlite3_free(zSql);
+
+ zSql = sqlite3_mprintf(
+ "SELECT 'CREATE UNIQUE INDEX %s.' || substr(sql,21) "
+ " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %%'"
+ , attachedDb);
+ rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
+ if( rc!=SQLITE_OK ) goto end_of_export;
+ sqlite3_free(zSql);
+
+ /* Loop through the tables in the main database. For each, do
+ ** an "INSERT INTO rekey_db.xxx SELECT * FROM main.xxx;" to copy
+ ** the contents to the temporary database.
+ */
+ zSql = sqlite3_mprintf(
+ "SELECT 'INSERT INTO %s.' || quote(name) "
+ "|| ' SELECT * FROM main.' || quote(name) || ';'"
+ "FROM main.sqlite_master "
+ "WHERE type = 'table' AND name!='sqlite_sequence' "
+ " AND rootpage>0"
+ , attachedDb);
+ rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
+ if( rc!=SQLITE_OK ) goto end_of_export;
+ sqlite3_free(zSql);
+
+ /* Copy over the sequence table
+ */
+ zSql = sqlite3_mprintf(
+ "SELECT 'DELETE FROM %s.' || quote(name) || ';' "
+ "FROM %s.sqlite_master WHERE name='sqlite_sequence' "
+ , attachedDb, attachedDb);
+ rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
+ if( rc!=SQLITE_OK ) goto end_of_export;
+ sqlite3_free(zSql);
+
+ zSql = sqlite3_mprintf(
+ "SELECT 'INSERT INTO %s.' || quote(name) "
+ "|| ' SELECT * FROM main.' || quote(name) || ';' "
+ "FROM %s.sqlite_master WHERE name=='sqlite_sequence';"
+ , attachedDb, attachedDb);
+ rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
+ if( rc!=SQLITE_OK ) goto end_of_export;
+ sqlite3_free(zSql);
+
+ /* Copy the triggers, views, and virtual tables from the main database
+ ** over to the temporary database. None of these objects has any
+ ** associated storage, so all we have to do is copy their entries
+ ** from the SQLITE_MASTER table.
+ */
+ zSql = sqlite3_mprintf(
+ "INSERT INTO %s.sqlite_master "
+ " SELECT type, name, tbl_name, rootpage, sql"
+ " FROM main.sqlite_master"
+ " WHERE type='view' OR type='trigger'"
+ " OR (type='table' AND rootpage=0)"
+ , attachedDb);
+ rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execSql(db, &pzErrMsg, zSql);
+ if( rc!=SQLITE_OK ) goto end_of_export;
+ sqlite3_free(zSql);
+
+ zSql = NULL;
+end_of_export:
+ db->flags = saved_flags;
+ db->nChange = saved_nChange;
+ db->nTotalChange = saved_nTotalChange;
+ db->xTrace = saved_xTrace;
+
+ sqlite3_free(zSql);
+
+ if(rc) {
+ if(pzErrMsg != NULL) {
+ sqlite3_result_error(context, pzErrMsg, -1);
+ sqlite3DbFree(db, pzErrMsg);
+ } else {
+ sqlite3_result_error(context, sqlite3ErrStr(rc), -1);
+ }
+ }
+}
+
+#endif
+
+/* END SQLCIPHER */
+#endif
+
+/************** End of crypto.c **********************************************/
+/************** Begin file crypto_impl.c *************************************/
+/*
+** SQLCipher
+** http://sqlcipher.net
+**
+** Copyright (c) 2008 - 2013, ZETETIC LLC
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of the ZETETIC LLC nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*/
+/* BEGIN SQLCIPHER */
+#ifdef SQLITE_HAS_CODEC
+
+/************** Include sqlcipher.h in the middle of crypto_impl.c ***********/
+/************** Begin file sqlcipher.h ***************************************/
+/*
+** SQLCipher
+** sqlcipher.h developed by Stephen Lombardo (Zetetic LLC)
+** sjlombardo at zetetic dot net
+** http://zetetic.net
+**
+** Copyright (c) 2008, ZETETIC LLC
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of the ZETETIC LLC nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*/
+/* BEGIN SQLCIPHER */
+#ifdef SQLITE_HAS_CODEC
+#ifndef SQLCIPHER_H
+#define SQLCIPHER_H
+
+
+typedef struct {
+ int (*activate)(void *ctx);
+ int (*deactivate)(void *ctx);
+ const char* (*get_provider_name)(void *ctx);
+ int (*add_random)(void *ctx, void *buffer, int length);
+ int (*random)(void *ctx, void *buffer, int length);
+ int (*hmac)(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out);
+ int (*kdf)(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key);
+ int (*cipher)(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out);
+ int (*set_cipher)(void *ctx, const char *cipher_name);
+ const char* (*get_cipher)(void *ctx);
+ int (*get_key_sz)(void *ctx);
+ int (*get_iv_sz)(void *ctx);
+ int (*get_block_sz)(void *ctx);
+ int (*get_hmac_sz)(void *ctx);
+ int (*ctx_copy)(void *target_ctx, void *source_ctx);
+ int (*ctx_cmp)(void *c1, void *c2);
+ int (*ctx_init)(void **ctx);
+ int (*ctx_free)(void **ctx);
+ int (*fips_status)(void *ctx);
+} sqlcipher_provider;
+
+/* utility functions */
+void sqlcipher_free(void *ptr, int sz);
+void* sqlcipher_malloc(int sz);
+void* sqlcipher_memset(void *v, unsigned char value, int len);
+int sqlcipher_ismemset(const void *v, unsigned char value, int len);
+int sqlcipher_memcmp(const void *v0, const void *v1, int len);
+void sqlcipher_free(void *, int);
+
+/* provider interfaces */
+int sqlcipher_register_provider(sqlcipher_provider *p);
+sqlcipher_provider* sqlcipher_get_provider();
+
+#endif
+#endif
+/* END SQLCIPHER */
+
+
+/************** End of sqlcipher.h *******************************************/
+/************** Continuing where we left off in crypto_impl.c ****************/
+#ifndef OMIT_MEMLOCK
+#if defined(__unix__) || defined(__APPLE__) || defined(_AIX)
+#include <sys/mman.h>
+#elif defined(_WIN32)
+# include <windows.h>
+#endif
+#endif
+
+/* the default implementation of SQLCipher uses a cipher_ctx
+ to keep track of read / write state separately. The following
+ struct and associated functions are defined here */
+typedef struct {
+ int store_pass;
+ int derive_key;
+ int kdf_iter;
+ int fast_kdf_iter;
+ int key_sz;
+ int iv_sz;
+ int block_sz;
+ int pass_sz;
+ int reserve_sz;
+ int hmac_sz;
+ int keyspec_sz;
+ unsigned int flags;
+ unsigned char *key;
+ unsigned char *hmac_key;
+ unsigned char *pass;
+ char *keyspec;
+ sqlcipher_provider *provider;
+ void *provider_ctx;
+} cipher_ctx;
+
+static unsigned int default_flags = DEFAULT_CIPHER_FLAGS;
+static unsigned char hmac_salt_mask = HMAC_SALT_MASK;
+static int default_kdf_iter = PBKDF2_ITER;
+static int default_page_size = SQLITE_DEFAULT_PAGE_SIZE;
+static unsigned int sqlcipher_activate_count = 0;
+static sqlite3_mutex* sqlcipher_provider_mutex = NULL;
+static sqlcipher_provider *default_provider = NULL;
+
+struct codec_ctx {
+ int kdf_salt_sz;
+ int page_sz;
+ unsigned char *kdf_salt;
+ unsigned char *hmac_kdf_salt;
+ unsigned char *buffer;
+ Btree *pBt;
+ cipher_ctx *read_ctx;
+ cipher_ctx *write_ctx;
+ unsigned int skip_read_hmac;
+ unsigned int need_kdf_salt;
+};
+
+int sqlcipher_register_provider(sqlcipher_provider *p) {
+ sqlite3_mutex_enter(sqlcipher_provider_mutex);
+ if(default_provider != NULL && default_provider != p) {
+ /* only free the current registerd provider if it has been initialized
+ and it isn't a pointer to the same provider passed to the function
+ (i.e. protect against a caller calling register twice for the same provider) */
+ sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
+ }
+ default_provider = p;
+ sqlite3_mutex_leave(sqlcipher_provider_mutex);
+ return SQLITE_OK;
+}
+
+/* return a pointer to the currently registered provider. This will
+ allow an application to fetch the current registered provider and
+ make minor changes to it */
+sqlcipher_provider* sqlcipher_get_provider() {
+ return default_provider;
+}
+
+void sqlcipher_activate() {
+ sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+
+ if(sqlcipher_provider_mutex == NULL) {
+ /* allocate a new mutex to guard access to the provider */
+ sqlcipher_provider_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+ }
+
+ /* check to see if there is a provider registered at this point
+ if there no provider registered at this point, register the
+ default provider */
+ if(sqlcipher_get_provider() == NULL) {
+ sqlcipher_provider *p = sqlcipher_malloc(sizeof(sqlcipher_provider));
+#if defined (SQLCIPHER_CRYPTO_CC)
+ extern int sqlcipher_cc_setup(sqlcipher_provider *p);
+ sqlcipher_cc_setup(p);
+#elif defined (SQLCIPHER_CRYPTO_LIBTOMCRYPT)
+ extern int sqlcipher_ltc_setup(sqlcipher_provider *p);
+ sqlcipher_ltc_setup(p);
+#elif defined (SQLCIPHER_CRYPTO_OPENSSL)
+ extern int sqlcipher_openssl_setup(sqlcipher_provider *p);
+ sqlcipher_openssl_setup(p);
+#else
+#error "NO DEFAULT SQLCIPHER CRYPTO PROVIDER DEFINED"
+#endif
+ sqlcipher_register_provider(p);
+ }
+
+ sqlcipher_activate_count++; /* increment activation count */
+
+ sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+}
+
+void sqlcipher_deactivate() {
+ sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+ sqlcipher_activate_count--;
+ /* if no connections are using sqlcipher, cleanup globals */
+ if(sqlcipher_activate_count < 1) {
+ sqlite3_mutex_enter(sqlcipher_provider_mutex);
+ if(default_provider != NULL) {
+ sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
+ default_provider = NULL;
+ }
+ sqlite3_mutex_leave(sqlcipher_provider_mutex);
+
+ /* last connection closed, free provider mutex*/
+ sqlite3_mutex_free(sqlcipher_provider_mutex);
+ sqlcipher_provider_mutex = NULL;
+
+ sqlcipher_activate_count = 0; /* reset activation count */
+ }
+ sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+}
+
+/* constant time memset using volitile to avoid having the memset
+ optimized out by the compiler.
+ Note: As suggested by Joachim Schipper (joachim.schipper@fox-it.com)
+*/
+void* sqlcipher_memset(void *v, unsigned char value, int len) {
+ int i = 0;
+ volatile unsigned char *a = v;
+
+ if (v == NULL) return v;
+
+ for(i = 0; i < len; i++) {
+ a[i] = value;
+ }
+
+ return v;
+}
+
+/* constant time memory check tests every position of a memory segement
+ matches a single value (i.e. the memory is all zeros)
+ returns 0 if match, 1 of no match */
+int sqlcipher_ismemset(const void *v, unsigned char value, int len) {
+ const unsigned char *a = v;
+ int i = 0, result = 0;
+
+ for(i = 0; i < len; i++) {
+ result |= a[i] ^ value;
+ }
+
+ return (result != 0);
+}
+
+/* constant time memory comparison routine.
+ returns 0 if match, 1 if no match */
+int sqlcipher_memcmp(const void *v0, const void *v1, int len) {
+ const unsigned char *a0 = v0, *a1 = v1;
+ int i = 0, result = 0;
+
+ for(i = 0; i < len; i++) {
+ result |= a0[i] ^ a1[i];
+ }
+
+ return (result != 0);
+}
+
+/**
+ * Free and wipe memory. Uses SQLites internal sqlite3_free so that memory
+ * can be countend and memory leak detection works in the test suite.
+ * If ptr is not null memory will be freed.
+ * If sz is greater than zero, the memory will be overwritten with zero before it is freed
+ * If sz is > 0, and not compiled with OMIT_MEMLOCK, system will attempt to unlock the
+ * memory segment so it can be paged
+ */
+void sqlcipher_free(void *ptr, int sz) {
+ if(ptr) {
+ if(sz > 0) {
+ sqlcipher_memset(ptr, 0, sz);
+#ifndef OMIT_MEMLOCK
+#if defined(__unix__) || defined(__APPLE__)
+ munlock(ptr, sz);
+#elif defined(_WIN32)
+#if !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == WINAPI_FAMILY_APP))
+VirtualUnlock(ptr, sz);
+#endif
+#endif
+#endif
+ }
+ sqlite3_free(ptr);
+ }
+}
+
+/**
+ * allocate memory. Uses sqlite's internall malloc wrapper so memory can be
+ * reference counted and leak detection works. Unless compiled with OMIT_MEMLOCK
+ * attempts to lock the memory pages so sensitive information won't be swapped
+ */
+void* sqlcipher_malloc(int sz) {
+ void *ptr = sqlite3Malloc(sz);
+ sqlcipher_memset(ptr, 0, sz);
+#ifndef OMIT_MEMLOCK
+ if(ptr) {
+#if defined(__unix__) || defined(__APPLE__)
+ mlock(ptr, sz);
+#elif defined(_WIN32)
+#if !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == WINAPI_FAMILY_APP))
+ VirtualLock(ptr, sz);
+#endif
+#endif
+ }
+#endif
+ return ptr;
+}
+
+
+/**
+ * Initialize new cipher_ctx struct. This function will allocate memory
+ * for the cipher context and for the key
+ *
+ * returns SQLITE_OK if initialization was successful
+ * returns SQLITE_NOMEM if an error occured allocating memory
+ */
+static int sqlcipher_cipher_ctx_init(cipher_ctx **iCtx) {
+ int rc;
+ cipher_ctx *ctx;
+ *iCtx = (cipher_ctx *) sqlcipher_malloc(sizeof(cipher_ctx));
+ ctx = *iCtx;
+ if(ctx == NULL) return SQLITE_NOMEM;
+
+ ctx->provider = (sqlcipher_provider *) sqlcipher_malloc(sizeof(sqlcipher_provider));
+ if(ctx->provider == NULL) return SQLITE_NOMEM;
+
+ /* make a copy of the provider to be used for the duration of the context */
+ sqlite3_mutex_enter(sqlcipher_provider_mutex);
+ memcpy(ctx->provider, default_provider, sizeof(sqlcipher_provider));
+ sqlite3_mutex_leave(sqlcipher_provider_mutex);
+
+ if((rc = ctx->provider->ctx_init(&ctx->provider_ctx)) != SQLITE_OK) return rc;
+ ctx->key = (unsigned char *) sqlcipher_malloc(CIPHER_MAX_KEY_SZ);
+ ctx->hmac_key = (unsigned char *) sqlcipher_malloc(CIPHER_MAX_KEY_SZ);
+ if(ctx->key == NULL) return SQLITE_NOMEM;
+ if(ctx->hmac_key == NULL) return SQLITE_NOMEM;
+
+ /* setup default flags */
+ ctx->flags = default_flags;
+
+ return SQLITE_OK;
+}
+
+/**
+ * Free and wipe memory associated with a cipher_ctx
+ */
+static void sqlcipher_cipher_ctx_free(cipher_ctx **iCtx) {
+ cipher_ctx *ctx = *iCtx;
+ CODEC_TRACE(("cipher_ctx_free: entered iCtx=%p\n", iCtx));
+ ctx->provider->ctx_free(&ctx->provider_ctx);
+ sqlcipher_free(ctx->provider, sizeof(sqlcipher_provider));
+ sqlcipher_free(ctx->key, ctx->key_sz);
+ sqlcipher_free(ctx->hmac_key, ctx->key_sz);
+ sqlcipher_free(ctx->pass, ctx->pass_sz);
+ sqlcipher_free(ctx->keyspec, ctx->keyspec_sz);
+ sqlcipher_free(ctx, sizeof(cipher_ctx));
+}
+
+/**
+ * Compare one cipher_ctx to another.
+ *
+ * returns 0 if all the parameters (except the derived key data) are the same
+ * returns 1 otherwise
+ */
+static int sqlcipher_cipher_ctx_cmp(cipher_ctx *c1, cipher_ctx *c2) {
+ int are_equal = (
+ c1->iv_sz == c2->iv_sz
+ && c1->kdf_iter == c2->kdf_iter
+ && c1->fast_kdf_iter == c2->fast_kdf_iter
+ && c1->key_sz == c2->key_sz
+ && c1->pass_sz == c2->pass_sz
+ && c1->flags == c2->flags
+ && c1->hmac_sz == c2->hmac_sz
+ && c1->provider->ctx_cmp(c1->provider_ctx, c2->provider_ctx)
+ && (
+ c1->pass == c2->pass
+ || !sqlcipher_memcmp((const unsigned char*)c1->pass,
+ (const unsigned char*)c2->pass,
+ c1->pass_sz)
+ ));
+
+ CODEC_TRACE(("sqlcipher_cipher_ctx_cmp: entered \
+ c1=%p c2=%p \
+ c1->iv_sz=%d c2->iv_sz=%d \
+ c1->kdf_iter=%d c2->kdf_iter=%d \
+ c1->fast_kdf_iter=%d c2->fast_kdf_iter=%d \
+ c1->key_sz=%d c2->key_sz=%d \
+ c1->pass_sz=%d c2->pass_sz=%d \
+ c1->flags=%d c2->flags=%d \
+ c1->hmac_sz=%d c2->hmac_sz=%d \
+ c1->provider_ctx=%p c2->provider_ctx=%p \
+ c1->pass=%p c2->pass=%p \
+ c1->pass=%s c2->pass=%s \
+ provider->ctx_cmp=%d \
+ sqlcipher_memcmp=%d \
+ are_equal=%d \
+ \n",
+ c1, c2,
+ c1->iv_sz, c2->iv_sz,
+ c1->kdf_iter, c2->kdf_iter,
+ c1->fast_kdf_iter, c2->fast_kdf_iter,
+ c1->key_sz, c2->key_sz,
+ c1->pass_sz, c2->pass_sz,
+ c1->flags, c2->flags,
+ c1->hmac_sz, c2->hmac_sz,
+ c1->provider_ctx, c2->provider_ctx,
+ c1->pass, c2->pass,
+ c1->pass, c2->pass,
+ c1->provider->ctx_cmp(c1->provider_ctx, c2->provider_ctx),
+ sqlcipher_memcmp((const unsigned char*)c1->pass,
+ (const unsigned char*)c2->pass,
+ c1->pass_sz),
+ are_equal
+ ));
+
+ return !are_equal; /* return 0 if they are the same, 1 otherwise */
+}
+
+/**
+ * Copy one cipher_ctx to another. For instance, assuming that read_ctx is a
+ * fully initialized context, you could copy it to write_ctx and all yet data
+ * and pass information across
+ *
+ * returns SQLITE_OK if initialization was successful
+ * returns SQLITE_NOMEM if an error occured allocating memory
+ */
+static int sqlcipher_cipher_ctx_copy(cipher_ctx *target, cipher_ctx *source) {
+ void *key = target->key;
+ void *hmac_key = target->hmac_key;
+ void *provider = target->provider;
+ void *provider_ctx = target->provider_ctx;
+
+ CODEC_TRACE(("sqlcipher_cipher_ctx_copy: entered target=%p, source=%p\n", target, source));
+ sqlcipher_free(target->pass, target->pass_sz);
+ sqlcipher_free(target->keyspec, target->keyspec_sz);
+ memcpy(target, source, sizeof(cipher_ctx));
+
+ target->key = key; //restore pointer to previously allocated key data
+ memcpy(target->key, source->key, CIPHER_MAX_KEY_SZ);
+
+ target->hmac_key = hmac_key; //restore pointer to previously allocated hmac key data
+ memcpy(target->hmac_key, source->hmac_key, CIPHER_MAX_KEY_SZ);
+
+ target->provider = provider; // restore pointer to previouly allocated provider;
+ memcpy(target->provider, source->provider, sizeof(sqlcipher_provider));
+
+ target->provider_ctx = provider_ctx; // restore pointer to previouly allocated provider context;
+ target->provider->ctx_copy(target->provider_ctx, source->provider_ctx);
+
+ if(source->pass && source->pass_sz) {
+ target->pass = sqlcipher_malloc(source->pass_sz);
+ if(target->pass == NULL) return SQLITE_NOMEM;
+ memcpy(target->pass, source->pass, source->pass_sz);
+ }
+ if(source->keyspec && source->keyspec_sz) {
+ target->keyspec = sqlcipher_malloc(source->keyspec_sz);
+ if(target->keyspec == NULL) return SQLITE_NOMEM;
+ memcpy(target->keyspec, source->keyspec, source->keyspec_sz);
+ }
+ return SQLITE_OK;
+}
+
+/**
+ * Set the keyspec for the cipher_ctx
+ *
+ * returns SQLITE_OK if assignment was successfull
+ * returns SQLITE_NOMEM if an error occured allocating memory
+ */
+static int sqlcipher_cipher_ctx_set_keyspec(cipher_ctx *ctx, const unsigned char *key, int key_sz, const unsigned char *salt, int salt_sz) {
+
+ /* free, zero existing pointers and size */
+ sqlcipher_free(ctx->keyspec, ctx->keyspec_sz);
+ ctx->keyspec = NULL;
+ ctx->keyspec_sz = 0;
+
+ /* establic a hex-formated key specification, containing the raw encryption key and
+ the salt used to generate it */
+ ctx->keyspec_sz = ((key_sz + salt_sz) * 2) + 3;
+ ctx->keyspec = sqlcipher_malloc(ctx->keyspec_sz);
+ if(ctx->keyspec == NULL) return SQLITE_NOMEM;
+
+ ctx->keyspec[0] = 'x';
+ ctx->keyspec[1] = '\'';
+ cipher_bin2hex(key, key_sz, ctx->keyspec + 2);
+ cipher_bin2hex(salt, salt_sz, ctx->keyspec + (key_sz * 2) + 2);
+ ctx->keyspec[ctx->keyspec_sz - 1] = '\'';
+ return SQLITE_OK;
+}
+
+int sqlcipher_codec_get_store_pass(codec_ctx *ctx) {
+ return ctx->read_ctx->store_pass;
+}
+
+void sqlcipher_codec_set_store_pass(codec_ctx *ctx, int value) {
+ ctx->read_ctx->store_pass = value;
+}
+
+void sqlcipher_codec_get_pass(codec_ctx *ctx, void **zKey, int *nKey) {
+ *zKey = ctx->read_ctx->pass;
+ *nKey = ctx->read_ctx->pass_sz;
+}
+
+/**
+ * Set the passphrase for the cipher_ctx
+ *
+ * returns SQLITE_OK if assignment was successfull
+ * returns SQLITE_NOMEM if an error occured allocating memory
+ */
+static int sqlcipher_cipher_ctx_set_pass(cipher_ctx *ctx, const void *zKey, int nKey) {
+
+ /* free, zero existing pointers and size */
+ sqlcipher_free(ctx->pass, ctx->pass_sz);
+ ctx->pass = NULL;
+ ctx->pass_sz = 0;
+
+ if(zKey && nKey) { /* if new password is provided, copy it */
+ ctx->pass_sz = nKey;
+ ctx->pass = sqlcipher_malloc(nKey);
+ if(ctx->pass == NULL) return SQLITE_NOMEM;
+ memcpy(ctx->pass, zKey, nKey);
+ }
+ return SQLITE_OK;
+}
+
+int sqlcipher_codec_ctx_set_pass(codec_ctx *ctx, const void *zKey, int nKey, int for_ctx) {
+ cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
+ int rc;
+
+ if((rc = sqlcipher_cipher_ctx_set_pass(c_ctx, zKey, nKey)) != SQLITE_OK) return rc;
+ c_ctx->derive_key = 1;
+
+ if(for_ctx == 2)
+ if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK)
+ return rc;
+
+ return SQLITE_OK;
+}
+
+int sqlcipher_codec_ctx_set_cipher(codec_ctx *ctx, const char *cipher_name, int for_ctx) {
+ cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
+ int rc;
+
+ c_ctx->provider->set_cipher(c_ctx->provider_ctx, cipher_name);
+
+ c_ctx->key_sz = c_ctx->provider->get_key_sz(c_ctx->provider_ctx);
+ c_ctx->iv_sz = c_ctx->provider->get_iv_sz(c_ctx->provider_ctx);
+ c_ctx->block_sz = c_ctx->provider->get_block_sz(c_ctx->provider_ctx);
+ c_ctx->hmac_sz = c_ctx->provider->get_hmac_sz(c_ctx->provider_ctx);
+ c_ctx->derive_key = 1;
+
+ if(for_ctx == 2)
+ if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK)
+ return rc;
+
+ return SQLITE_OK;
+}
+
+const char* sqlcipher_codec_ctx_get_cipher(codec_ctx *ctx, int for_ctx) {
+ cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
+ return c_ctx->provider->get_cipher(c_ctx->provider_ctx);
+}
+
+/* set the global default KDF iteration */
+void sqlcipher_set_default_kdf_iter(int iter) {
+ default_kdf_iter = iter;
+}
+
+int sqlcipher_get_default_kdf_iter() {
+ return default_kdf_iter;
+}
+
+int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *ctx, int kdf_iter, int for_ctx) {
+ cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
+ int rc;
+
+ c_ctx->kdf_iter = kdf_iter;
+ c_ctx->derive_key = 1;
+
+ if(for_ctx == 2)
+ if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK)
+ return rc;
+
+ return SQLITE_OK;
+}
+
+int sqlcipher_codec_ctx_get_kdf_iter(codec_ctx *ctx, int for_ctx) {
+ cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
+ return c_ctx->kdf_iter;
+}
+
+int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *ctx, int fast_kdf_iter, int for_ctx) {
+ cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
+ int rc;
+
+ c_ctx->fast_kdf_iter = fast_kdf_iter;
+ c_ctx->derive_key = 1;
+
+ if(for_ctx == 2)
+ if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK)
+ return rc;
+
+ return SQLITE_OK;
+}
+
+int sqlcipher_codec_ctx_get_fast_kdf_iter(codec_ctx *ctx, int for_ctx) {
+ cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
+ return c_ctx->fast_kdf_iter;
+}
+
+/* set the global default flag for HMAC */
+void sqlcipher_set_default_use_hmac(int use) {
+ if(use) default_flags |= CIPHER_FLAG_HMAC;
+ else default_flags &= ~CIPHER_FLAG_HMAC;
+}
+
+int sqlcipher_get_default_use_hmac() {
+ return (default_flags & CIPHER_FLAG_HMAC) != 0;
+}
+
+void sqlcipher_set_hmac_salt_mask(unsigned char mask) {
+ hmac_salt_mask = mask;
+}
+
+unsigned char sqlcipher_get_hmac_salt_mask() {
+ return hmac_salt_mask;
+}
+
+/* set the codec flag for whether this individual database should be using hmac */
+int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use) {
+ int reserve = CIPHER_MAX_IV_SZ; /* base reserve size will be IV only */
+
+ if(use) reserve += ctx->read_ctx->hmac_sz; /* if reserve will include hmac, update that size */
+
+ /* calculate the amount of reserve needed in even increments of the cipher block size */
+
+ reserve = ((reserve % ctx->read_ctx->block_sz) == 0) ? reserve :
+ ((reserve / ctx->read_ctx->block_sz) + 1) * ctx->read_ctx->block_sz;
+
+ CODEC_TRACE(("sqlcipher_codec_ctx_set_use_hmac: use=%d block_sz=%d md_size=%d reserve=%d\n",
+ use, ctx->read_ctx->block_sz, ctx->read_ctx->hmac_sz, reserve));
+
+
+ if(use) {
+ sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_HMAC);
+ } else {
+ sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_HMAC);
+ }
+
+ ctx->write_ctx->reserve_sz = ctx->read_ctx->reserve_sz = reserve;
+
+ return SQLITE_OK;
+}
+
+int sqlcipher_codec_ctx_get_use_hmac(codec_ctx *ctx, int for_ctx) {
+ cipher_ctx * c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
+ return (c_ctx->flags & CIPHER_FLAG_HMAC) != 0;
+}
+
+int sqlcipher_codec_ctx_set_flag(codec_ctx *ctx, unsigned int flag) {
+ ctx->write_ctx->flags |= flag;
+ ctx->read_ctx->flags |= flag;
+ return SQLITE_OK;
+}
+
+int sqlcipher_codec_ctx_unset_flag(codec_ctx *ctx, unsigned int flag) {
+ ctx->write_ctx->flags &= ~flag;
+ ctx->read_ctx->flags &= ~flag;
+ return SQLITE_OK;
+}
+
+int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int flag, int for_ctx) {
+ cipher_ctx * c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
+ return (c_ctx->flags & flag) != 0;
+}
+
+void sqlcipher_codec_ctx_set_error(codec_ctx *ctx, int error) {
+ CODEC_TRACE(("sqlcipher_codec_ctx_set_error: ctx=%p, error=%d\n", ctx, error));
+ sqlite3pager_sqlite3PagerSetError(ctx->pBt->pBt->pPager, error);
+ ctx->pBt->pBt->db->errCode = error;
+}
+
+int sqlcipher_codec_ctx_get_reservesize(codec_ctx *ctx) {
+ return ctx->read_ctx->reserve_sz;
+}
+
+void* sqlcipher_codec_ctx_get_data(codec_ctx *ctx) {
+ return ctx->buffer;
+}
+
+void* sqlcipher_codec_ctx_get_kdf_salt(codec_ctx *ctx) {
+ return ctx->kdf_salt;
+}
+
+void sqlcipher_codec_get_keyspec(codec_ctx *ctx, void **zKey, int *nKey) {
+ *zKey = ctx->read_ctx->keyspec;
+ *nKey = ctx->read_ctx->keyspec_sz;
+}
+
+int sqlcipher_codec_ctx_set_pagesize(codec_ctx *ctx, int size) {
+ /* attempt to free the existing page buffer */
+ sqlcipher_free(ctx->buffer,ctx->page_sz);
+ ctx->page_sz = size;
+
+ /* pre-allocate a page buffer of PageSize bytes. This will
+ be used as a persistent buffer for encryption and decryption
+ operations to avoid overhead of multiple memory allocations*/
+ ctx->buffer = sqlcipher_malloc(size);
+ if(ctx->buffer == NULL) return SQLITE_NOMEM;
+
+ return SQLITE_OK;
+}
+
+int sqlcipher_codec_ctx_get_pagesize(codec_ctx *ctx) {
+ return ctx->page_sz;
+}
+
+void sqlcipher_set_default_pagesize(int page_size) {
+ default_page_size = page_size;
+}
+
+int sqlcipher_get_default_pagesize() {
+ return default_page_size;
+}
+
+int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_file *fd, const void *zKey, int nKey) {
+ int rc;
+ codec_ctx *ctx;
+ *iCtx = sqlcipher_malloc(sizeof(codec_ctx));
+ ctx = *iCtx;
+
+ if(ctx == NULL) return SQLITE_NOMEM;
+
+ ctx->pBt = pDb->pBt; /* assign pointer to database btree structure */
+
+ /* allocate space for salt data. Then read the first 16 bytes
+ directly off the database file. This is the salt for the
+ key derivation function. If we get a short read allocate
+ a new random salt value */
+ ctx->kdf_salt_sz = FILE_HEADER_SZ;
+ ctx->kdf_salt = sqlcipher_malloc(ctx->kdf_salt_sz);
+ if(ctx->kdf_salt == NULL) return SQLITE_NOMEM;
+
+ /* allocate space for separate hmac salt data. We want the
+ HMAC derivation salt to be different than the encryption
+ key derivation salt */
+ ctx->hmac_kdf_salt = sqlcipher_malloc(ctx->kdf_salt_sz);
+ if(ctx->hmac_kdf_salt == NULL) return SQLITE_NOMEM;
+
+
+ /*
+ Always overwrite page size and set to the default because the first page of the database
+ in encrypted and thus sqlite can't effectively determine the pagesize. this causes an issue in
+ cases where bytes 16 & 17 of the page header are a power of 2 as reported by John Lehman
+ */
+ if((rc = sqlcipher_codec_ctx_set_pagesize(ctx, default_page_size)) != SQLITE_OK) return rc;
+
+ if((rc = sqlcipher_cipher_ctx_init(&ctx->read_ctx)) != SQLITE_OK) return rc;
+ if((rc = sqlcipher_cipher_ctx_init(&ctx->write_ctx)) != SQLITE_OK) return rc;
+
+ if(fd == NULL || sqlite3OsRead(fd, ctx->kdf_salt, FILE_HEADER_SZ, 0) != SQLITE_OK) {
+ ctx->need_kdf_salt = 1;
+ }
+
+ if((rc = sqlcipher_codec_ctx_set_cipher(ctx, CIPHER, 0)) != SQLITE_OK) return rc;
+ if((rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, default_kdf_iter, 0)) != SQLITE_OK) return rc;
+ if((rc = sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, FAST_PBKDF2_ITER, 0)) != SQLITE_OK) return rc;
+ if((rc = sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, 0)) != SQLITE_OK) return rc;
+
+ /* Note that use_hmac is a special case that requires recalculation of page size
+ so we call set_use_hmac to perform setup */
+ if((rc = sqlcipher_codec_ctx_set_use_hmac(ctx, default_flags & CIPHER_FLAG_HMAC)) != SQLITE_OK) return rc;
+
+ if((rc = sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx)) != SQLITE_OK) return rc;
+
+ return SQLITE_OK;
+}
+
+/**
+ * Free and wipe memory associated with a cipher_ctx, including the allocated
+ * read_ctx and write_ctx.
+ */
+void sqlcipher_codec_ctx_free(codec_ctx **iCtx) {
+ codec_ctx *ctx = *iCtx;
+ CODEC_TRACE(("codec_ctx_free: entered iCtx=%p\n", iCtx));
+ sqlcipher_free(ctx->kdf_salt, ctx->kdf_salt_sz);
+ sqlcipher_free(ctx->hmac_kdf_salt, ctx->kdf_salt_sz);
+ sqlcipher_free(ctx->buffer, 0);
+ sqlcipher_cipher_ctx_free(&ctx->read_ctx);
+ sqlcipher_cipher_ctx_free(&ctx->write_ctx);
+ sqlcipher_free(ctx, sizeof(codec_ctx));
+}
+
+/** convert a 32bit unsigned integer to little endian byte ordering */
+static void sqlcipher_put4byte_le(unsigned char *p, u32 v) {
+ p[0] = (u8)v;
+ p[1] = (u8)(v>>8);
+ p[2] = (u8)(v>>16);
+ p[3] = (u8)(v>>24);
+}
+
+static int sqlcipher_page_hmac(cipher_ctx *ctx, Pgno pgno, unsigned char *in, int in_sz, unsigned char *out) {
+ unsigned char pgno_raw[sizeof(pgno)];
+ /* we may convert page number to consistent representation before calculating MAC for
+ compatibility across big-endian and little-endian platforms.
+
+ Note: The public release of sqlcipher 2.0.0 to 2.0.6 had a bug where the bytes of pgno
+ were used directly in the MAC. SQLCipher convert's to little endian by default to preserve
+ backwards compatibility on the most popular platforms, but can optionally be configured
+ to use either big endian or native byte ordering via pragma. */
+
+ if(ctx->flags & CIPHER_FLAG_LE_PGNO) { /* compute hmac using little endian pgno*/
+ sqlcipher_put4byte_le(pgno_raw, pgno);
+ } else if(ctx->flags & CIPHER_FLAG_BE_PGNO) { /* compute hmac using big endian pgno */
+ sqlite3Put4byte(pgno_raw, pgno); /* sqlite3Put4byte converts 32bit uint to big endian */
+ } else { /* use native byte ordering */
+ memcpy(pgno_raw, &pgno, sizeof(pgno));
+ }
+
+ /* include the encrypted page data, initialization vector, and page number in HMAC. This will
+ prevent both tampering with the ciphertext, manipulation of the IV, or resequencing otherwise
+ valid pages out of order in a database */
+ ctx->provider->hmac(
+ ctx->provider_ctx, ctx->hmac_key,
+ ctx->key_sz, in,
+ in_sz, (unsigned char*) &pgno_raw,
+ sizeof(pgno), out);
+ return SQLITE_OK;
+}
+
+/*
+ * ctx - codec context
+ * pgno - page number in database
+ * size - size in bytes of input and output buffers
+ * mode - 1 to encrypt, 0 to decrypt
+ * in - pointer to input bytes
+ * out - pouter to output bytes
+ */
+int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mode, int page_sz, unsigned char *in, unsigned char *out) {
+ cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
+ unsigned char *iv_in, *iv_out, *hmac_in, *hmac_out, *out_start;
+ int size;
+
+ /* calculate some required positions into various buffers */
+ size = page_sz - c_ctx->reserve_sz; /* adjust size to useable size and memset reserve at end of page */
+ iv_out = out + size;
+ iv_in = in + size;
+
+ /* hmac will be written immediately after the initialization vector. the remainder of the page reserve will contain
+ random bytes. note, these pointers are only valid when using hmac */
+ hmac_in = in + size + c_ctx->iv_sz;
+ hmac_out = out + size + c_ctx->iv_sz;
+ out_start = out; /* note the original position of the output buffer pointer, as out will be rewritten during encryption */
+
+ CODEC_TRACE(("codec_cipher:entered pgno=%d, mode=%d, size=%d\n", pgno, mode, size));
+ CODEC_HEXDUMP("codec_cipher: input page data", in, page_sz);
+
+ /* the key size should never be zero. If it is, error out. */
+ if(c_ctx->key_sz == 0) {
+ CODEC_TRACE(("codec_cipher: error possible context corruption, key_sz is zero for pgno=%d\n", pgno));
+ sqlcipher_memset(out, 0, page_sz);
+ return SQLITE_ERROR;
+ }
+
+ if(mode == CIPHER_ENCRYPT) {
+ /* start at front of the reserve block, write random data to the end */
+ if(c_ctx->provider->random(c_ctx->provider_ctx, iv_out, c_ctx->reserve_sz) != SQLITE_OK) return SQLITE_ERROR;
+ } else { /* CIPHER_DECRYPT */
+ memcpy(iv_out, iv_in, c_ctx->iv_sz); /* copy the iv from the input to output buffer */
+ }
+
+ if((c_ctx->flags & CIPHER_FLAG_HMAC) && (mode == CIPHER_DECRYPT) && !ctx->skip_read_hmac) {
+ if(sqlcipher_page_hmac(c_ctx, pgno, in, size + c_ctx->iv_sz, hmac_out) != SQLITE_OK) {
+ sqlcipher_memset(out, 0, page_sz);
+ CODEC_TRACE(("codec_cipher: hmac operations failed for pgno=%d\n", pgno));
+ return SQLITE_ERROR;
+ }
+
+ CODEC_TRACE(("codec_cipher: comparing hmac on in=%p out=%p hmac_sz=%d\n", hmac_in, hmac_out, c_ctx->hmac_sz));
+ if(sqlcipher_memcmp(hmac_in, hmac_out, c_ctx->hmac_sz) != 0) { /* the hmac check failed */
+ if(sqlcipher_ismemset(in, 0, page_sz) == 0) {
+ /* first check if the entire contents of the page is zeros. If so, this page
+ resulted from a short read (i.e. sqlite attempted to pull a page after the end of the file. these
+ short read failures must be ignored for autovaccum mode to work so wipe the output buffer
+ and return SQLITE_OK to skip the decryption step. */
+ CODEC_TRACE(("codec_cipher: zeroed page (short read) for pgno %d, encryption but returning SQLITE_OK\n", pgno));
+ sqlcipher_memset(out, 0, page_sz);
+ return SQLITE_OK;
+ } else {
+ /* if the page memory is not all zeros, it means the there was data and a hmac on the page.
+ since the check failed, the page was either tampered with or corrupted. wipe the output buffer,
+ and return SQLITE_ERROR to the caller */
+ CODEC_TRACE(("codec_cipher: hmac check failed for pgno=%d returning SQLITE_ERROR\n", pgno));
+ sqlcipher_memset(out, 0, page_sz);
+ return SQLITE_ERROR;
+ }
+ }
+ }
+
+ c_ctx->provider->cipher(c_ctx->provider_ctx, mode, c_ctx->key, c_ctx->key_sz, iv_out, in, size, out);
+
+ if((c_ctx->flags & CIPHER_FLAG_HMAC) && (mode == CIPHER_ENCRYPT)) {
+ sqlcipher_page_hmac(c_ctx, pgno, out_start, size + c_ctx->iv_sz, hmac_out);
+ }
+
+ CODEC_HEXDUMP("codec_cipher: output page data", out_start, page_sz);
+
+ return SQLITE_OK;
+}
+
+/**
+ * Derive an encryption key for a cipher contex key based on the raw password.
+ *
+ * If the raw key data is formated as x'hex' and there are exactly enough hex chars to fill
+ * the key (i.e 64 hex chars for a 256 bit key) then the key data will be used directly.
+
+ * Else, if the raw key data is formated as x'hex' and there are exactly enough hex chars to fill
+ * the key and the salt (i.e 92 hex chars for a 256 bit key and 16 byte salt) then it will be unpacked
+ * as the key followed by the salt.
+ *
+ * Otherwise, a key data will be derived using PBKDF2
+ *
+ * returns SQLITE_OK if initialization was successful
+ * returns SQLITE_ERROR if the key could't be derived (for instance if pass is NULL or pass_sz is 0)
+ */
+static int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
+ int rc;
+ CODEC_TRACE(("cipher_ctx_key_derive: entered c_ctx->pass=%s, c_ctx->pass_sz=%d \
+ ctx->kdf_salt=%p ctx->kdf_salt_sz=%d c_ctx->kdf_iter=%d \
+ ctx->hmac_kdf_salt=%p, c_ctx->fast_kdf_iter=%d c_ctx->key_sz=%d\n",
+ c_ctx->pass, c_ctx->pass_sz, ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter,
+ ctx->hmac_kdf_salt, c_ctx->fast_kdf_iter, c_ctx->key_sz));
+
+
+ if(c_ctx->pass && c_ctx->pass_sz) { // if pass is not null
+
+ if(ctx->need_kdf_salt) {
+ if(ctx->read_ctx->provider->random(ctx->read_ctx->provider_ctx, ctx->kdf_salt, FILE_HEADER_SZ) != SQLITE_OK) return SQLITE_ERROR;
+ ctx->need_kdf_salt = 0;
+ }
+ if (c_ctx->pass_sz == ((c_ctx->key_sz * 2) + 3) && sqlite3StrNICmp((const char *)c_ctx->pass ,"x'", 2) == 0) {
+ int n = c_ctx->pass_sz - 3; /* adjust for leading x' and tailing ' */
+ const unsigned char *z = c_ctx->pass + 2; /* adjust lead offset of x' */
+ CODEC_TRACE(("cipher_ctx_key_derive: using raw key from hex\n"));
+ cipher_hex2bin(z, n, c_ctx->key);
+ } else if (c_ctx->pass_sz == (((c_ctx->key_sz + ctx->kdf_salt_sz) * 2) + 3) && sqlite3StrNICmp((const char *)c_ctx->pass ,"x'", 2) == 0) {
+ const unsigned char *z = c_ctx->pass + 2; /* adjust lead offset of x' */
+ CODEC_TRACE(("cipher_ctx_key_derive: using raw key from hex\n"));
+ cipher_hex2bin(z, (c_ctx->key_sz * 2), c_ctx->key);
+ cipher_hex2bin(z + (c_ctx->key_sz * 2), (ctx->kdf_salt_sz * 2), ctx->kdf_salt);
+ } else {
+ CODEC_TRACE(("cipher_ctx_key_derive: deriving key using full PBKDF2 with %d iterations\n", c_ctx->kdf_iter));
+ c_ctx->provider->kdf(c_ctx->provider_ctx, c_ctx->pass, c_ctx->pass_sz,
+ ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter,
+ c_ctx->key_sz, c_ctx->key);
+ }
+
+ /* set the context "keyspec" containing the hex-formatted key and salt to be used when attaching databases */
+ if((rc = sqlcipher_cipher_ctx_set_keyspec(c_ctx, c_ctx->key, c_ctx->key_sz, ctx->kdf_salt, ctx->kdf_salt_sz)) != SQLITE_OK) return rc;
+
+ /* if this context is setup to use hmac checks, generate a seperate and different
+ key for HMAC. In this case, we use the output of the previous KDF as the input to
+ this KDF run. This ensures a distinct but predictable HMAC key. */
+ if(c_ctx->flags & CIPHER_FLAG_HMAC) {
+ int i;
+
+ /* start by copying the kdf key into the hmac salt slot
+ then XOR it with the fixed hmac salt defined at compile time
+ this ensures that the salt passed in to derive the hmac key, while
+ easy to derive and publically known, is not the same as the salt used
+ to generate the encryption key */
+ memcpy(ctx->hmac_kdf_salt, ctx->kdf_salt, ctx->kdf_salt_sz);
+ for(i = 0; i < ctx->kdf_salt_sz; i++) {
+ ctx->hmac_kdf_salt[i] ^= hmac_salt_mask;
+ }
+
+ CODEC_TRACE(("cipher_ctx_key_derive: deriving hmac key from encryption key using PBKDF2 with %d iterations\n",
+ c_ctx->fast_kdf_iter));
+
+
+ c_ctx->provider->kdf(c_ctx->provider_ctx, c_ctx->key, c_ctx->key_sz,
+ ctx->hmac_kdf_salt, ctx->kdf_salt_sz, c_ctx->fast_kdf_iter,
+ c_ctx->key_sz, c_ctx->hmac_key);
+ }
+
+ c_ctx->derive_key = 0;
+ return SQLITE_OK;
+ };
+ return SQLITE_ERROR;
+}
+
+int sqlcipher_codec_key_derive(codec_ctx *ctx) {
+ /* derive key on first use if necessary */
+ if(ctx->read_ctx->derive_key) {
+ if(sqlcipher_cipher_ctx_key_derive(ctx, ctx->read_ctx) != SQLITE_OK) return SQLITE_ERROR;
+ }
+
+ if(ctx->write_ctx->derive_key) {
+ if(sqlcipher_cipher_ctx_cmp(ctx->write_ctx, ctx->read_ctx) == 0) {
+ /* the relevant parameters are the same, just copy read key */
+ if(sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx) != SQLITE_OK) return SQLITE_ERROR;
+ } else {
+ if(sqlcipher_cipher_ctx_key_derive(ctx, ctx->write_ctx) != SQLITE_OK) return SQLITE_ERROR;
+ }
+ }
+
+ /* TODO: wipe and free passphrase after key derivation */
+ if(ctx->read_ctx->store_pass != 1) {
+ sqlcipher_cipher_ctx_set_pass(ctx->read_ctx, NULL, 0);
+ sqlcipher_cipher_ctx_set_pass(ctx->write_ctx, NULL, 0);
+ }
+
+ return SQLITE_OK;
+}
+
+int sqlcipher_codec_key_copy(codec_ctx *ctx, int source) {
+ if(source == CIPHER_READ_CTX) {
+ return sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx);
+ } else {
+ return sqlcipher_cipher_ctx_copy(ctx->read_ctx, ctx->write_ctx);
+ }
+}
+
+const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx) {
+ return ctx->read_ctx->provider->get_provider_name(ctx->read_ctx);
+}
+
+
+static int sqlcipher_check_connection(const char *filename, char *key, int key_sz, char *sql, int *user_version) {
+ int rc;
+ sqlite3 *db = NULL;
+ sqlite3_stmt *statement = NULL;
+ char *query_user_version = "PRAGMA user_version;";
+
+ rc = sqlite3_open(filename, &db);
+ if(rc != SQLITE_OK){
+ goto cleanup;
+ }
+ rc = sqlite3_key(db, key, key_sz);
+ if(rc != SQLITE_OK){
+ goto cleanup;
+ }
+ rc = sqlite3_exec(db, sql, NULL, NULL, NULL);
+ if(rc != SQLITE_OK){
+ goto cleanup;
+ }
+ rc = sqlite3_prepare(db, query_user_version, -1, &statement, NULL);
+ if(rc != SQLITE_OK){
+ goto cleanup;
+ }
+ rc = sqlite3_step(statement);
+ if(rc == SQLITE_ROW){
+ *user_version = sqlite3_column_int(statement, 0);
+ rc = SQLITE_OK;
+ }
+
+cleanup:
+ if(statement){
+ sqlite3_finalize(statement);
+ }
+ if(db){
+ sqlite3_close(db);
+ }
+ return rc;
+}
+
+int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
+ u32 meta;
+ int rc = 0;
+ int command_idx = 0;
+ int password_sz;
+ int saved_flags;
+ int saved_nChange;
+ int saved_nTotalChange;
+ void (*saved_xTrace)(void*,const char*);
+ Db *pDb = 0;
+ sqlite3 *db = ctx->pBt->db;
+ const char *db_filename = sqlite3_db_filename(db, "main");
+ char *migrated_db_filename = sqlite3_mprintf("%s-migrated", db_filename);
+ char *pragma_hmac_off = "PRAGMA cipher_use_hmac = OFF;";
+ char *pragma_4k_kdf_iter = "PRAGMA kdf_iter = 4000;";
+ char *pragma_1x_and_4k;
+ char *set_user_version;
+ char *key;
+ int key_sz;
+ int user_version = 0;
+ int upgrade_1x_format = 0;
+ int upgrade_4k_format = 0;
+ static const unsigned char aCopy[] = {
+ BTREE_SCHEMA_VERSION, 1, /* Add one to the old schema cookie */
+ BTREE_DEFAULT_CACHE_SIZE, 0, /* Preserve the default page cache size */
+ BTREE_TEXT_ENCODING, 0, /* Preserve the text encoding */
+ BTREE_USER_VERSION, 0, /* Preserve the user version */
+ BTREE_APPLICATION_ID, 0, /* Preserve the application id */
+ };
+
+
+ key_sz = ctx->read_ctx->pass_sz + 1;
+ key = sqlcipher_malloc(key_sz);
+ memset(key, 0, key_sz);
+ memcpy(key, ctx->read_ctx->pass, ctx->read_ctx->pass_sz);
+
+ if(db_filename){
+ const char* commands[5];
+ char *attach_command = sqlite3_mprintf("ATTACH DATABASE '%s-migrated' as migrate KEY '%q';",
+ db_filename, key);
+
+ int rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, "", &user_version);
+ if(rc == SQLITE_OK){
+ CODEC_TRACE(("No upgrade required - exiting\n"));
+ goto exit;
+ }
+
+ // Version 2 - check for 4k with hmac format
+ rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, pragma_4k_kdf_iter, &user_version);
+ if(rc == SQLITE_OK) {
+ CODEC_TRACE(("Version 2 format found\n"));
+ upgrade_4k_format = 1;
+ }
+
+ // Version 1 - check both no hmac and 4k together
+ pragma_1x_and_4k = sqlite3_mprintf("%s%s", pragma_hmac_off,
+ pragma_4k_kdf_iter);
+ rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, pragma_1x_and_4k, &user_version);
+ sqlite3_free(pragma_1x_and_4k);
+ if(rc == SQLITE_OK) {
+ CODEC_TRACE(("Version 1 format found\n"));
+ upgrade_1x_format = 1;
+ upgrade_4k_format = 1;
+ }
+
+ if(upgrade_1x_format == 0 && upgrade_4k_format == 0) {
+ CODEC_TRACE(("Upgrade format not determined\n"));
+ goto handle_error;
+ }
+
+ set_user_version = sqlite3_mprintf("PRAGMA migrate.user_version = %d;", user_version);
+ commands[0] = upgrade_4k_format == 1 ? pragma_4k_kdf_iter : "";
+ commands[1] = upgrade_1x_format == 1 ? pragma_hmac_off : "";
+ commands[2] = attach_command;
+ commands[3] = "SELECT sqlcipher_export('migrate');";
+ commands[4] = set_user_version;
+
+ for(command_idx = 0; command_idx < ArraySize(commands); command_idx++){
+ const char *command = commands[command_idx];
+ if(strcmp(command, "") == 0){
+ continue;
+ }
+ rc = sqlite3_exec(db, command, NULL, NULL, NULL);
+ if(rc != SQLITE_OK){
+ break;
+ }
+ }
+ sqlite3_free(attach_command);
+ sqlite3_free(set_user_version);
+ sqlcipher_free(key, key_sz);
+
+ if(rc == SQLITE_OK){
+ Btree *pDest;
+ Btree *pSrc;
+ int i = 0;
+
+ if( !db->autoCommit ){
+ CODEC_TRACE(("cannot migrate from within a transaction"));
+ goto handle_error;
+ }
+ if( db->nVdbeActive>1 ){
+ CODEC_TRACE(("cannot migrate - SQL statements in progress"));
+ goto handle_error;
+ }
+
+ /* Save the current value of the database flags so that it can be
+ ** restored before returning. Then set the writable-schema flag, and
+ ** disable CHECK and foreign key constraints. */
+ saved_flags = db->flags;
+ saved_nChange = db->nChange;
+ saved_nTotalChange = db->nTotalChange;
+ saved_xTrace = db->xTrace;
+ db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
+ db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
+ db->xTrace = 0;
+
+ pDest = db->aDb[0].pBt;
+ pDb = &(db->aDb[db->nDb-1]);
+ pSrc = pDb->pBt;
+
+ rc = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);
+ rc = sqlite3BtreeBeginTrans(pSrc, 2);
+ rc = sqlite3BtreeBeginTrans(pDest, 2);
+
+ assert( 1==sqlite3BtreeIsInTrans(pDest) );
+ assert( 1==sqlite3BtreeIsInTrans(pSrc) );
+
+ sqlite3CodecGetKey(db, db->nDb - 1, (void**)&key, &password_sz);
+ sqlite3CodecAttach(db, 0, key, password_sz);
+ sqlite3pager_get_codec(pDest->pBt->pPager, (void**)&ctx);
+
+ ctx->skip_read_hmac = 1;
+ for(i=0; i<ArraySize(aCopy); i+=2){
+ sqlite3BtreeGetMeta(pSrc, aCopy[i], &meta);
+ rc = sqlite3BtreeUpdateMeta(pDest, aCopy[i], meta+aCopy[i+1]);
+ if( NEVER(rc!=SQLITE_OK) ) goto handle_error;
+ }
+ rc = sqlite3BtreeCopyFile(pDest, pSrc);
+ ctx->skip_read_hmac = 0;
+ if( rc!=SQLITE_OK ) goto handle_error;
+ rc = sqlite3BtreeCommit(pDest);
+
+ db->flags = saved_flags;
+ db->nChange = saved_nChange;
+ db->nTotalChange = saved_nTotalChange;
+ db->xTrace = saved_xTrace;
+ db->autoCommit = 1;
+ if( pDb ){
+ sqlite3BtreeClose(pDb->pBt);
+ pDb->pBt = 0;
+ pDb->pSchema = 0;
+ }
+ sqlite3ResetAllSchemasOfConnection(db);
+ remove(migrated_db_filename);
+ sqlite3_free(migrated_db_filename);
+ } else {
+ CODEC_TRACE(("*** migration failure** \n\n"));
+ }
+
+ }
+ goto exit;
+
+ handle_error:
+ CODEC_TRACE(("An error occurred attempting to migrate the database\n"));
+ rc = SQLITE_ERROR;
+
+ exit:
+ return rc;
+}
+
+int sqlcipher_codec_add_random(codec_ctx *ctx, const char *zRight, int random_sz){
+ const char *suffix = &zRight[random_sz-1];
+ int n = random_sz - 3; /* adjust for leading x' and tailing ' */
+ if (n > 0 &&
+ sqlite3StrNICmp((const char *)zRight ,"x'", 2) == 0 &&
+ sqlite3StrNICmp(suffix, "'", 1) == 0 &&
+ n % 2 == 0) {
+ int rc = 0;
+ int buffer_sz = n / 2;
+ unsigned char *random;
+ const unsigned char *z = (const unsigned char *)zRight + 2; /* adjust lead offset of x' */
+ CODEC_TRACE(("sqlcipher_codec_add_random: using raw random blob from hex\n"));
+ random = sqlcipher_malloc(buffer_sz);
+ memset(random, 0, buffer_sz);
+ cipher_hex2bin(z, n, random);
+ rc = ctx->read_ctx->provider->add_random(ctx->read_ctx->provider_ctx, random, buffer_sz);
+ sqlcipher_free(random, buffer_sz);
+ return rc;
+ }
+ return SQLITE_ERROR;
+}
+
+int sqlcipher_cipher_profile(sqlite3 *db, const char *destination){
+ FILE *f;
+ if( strcmp(destination,"stdout")==0 ){
+ f = stdout;
+ }else if( strcmp(destination, "stderr")==0 ){
+ f = stderr;
+ }else if( strcmp(destination, "off")==0 ){
+ f = 0;
+ }else{
+ f = fopen(destination, "wb");
+ if( f==0 ){
+ return SQLITE_ERROR;
+ }
+ }
+ sqlite3_profile(db, sqlcipher_profile_callback, f);
+ return SQLITE_OK;
+}
+
+static void sqlcipher_profile_callback(void *file, const char *sql, sqlite3_uint64 run_time){
+ FILE *f = (FILE*)file;
+ double elapsed = run_time/1000000.0;
+ if( f ) fprintf(f, "Elapsed time:%.3f ms - %s\n", elapsed, sql);
+}
+
+int sqlcipher_codec_fips_status(codec_ctx *ctx) {
+ return ctx->read_ctx->provider->fips_status(ctx->read_ctx);
+}
+
+#endif
+/* END SQLCIPHER */
+
+/************** End of crypto_impl.c *****************************************/
+/************** Begin file crypto_libtomcrypt.c ******************************/
+/*
+** SQLCipher
+** http://sqlcipher.net
+**
+** Copyright (c) 2008 - 2013, ZETETIC LLC
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of the ZETETIC LLC nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*/
+/* BEGIN SQLCIPHER */
+#ifdef SQLITE_HAS_CODEC
+#ifdef SQLCIPHER_CRYPTO_LIBTOMCRYPT
+#include <tomcrypt.h>
+
+#define FORTUNA_MAX_SZ 32
+static prng_state prng;
+static unsigned int ltc_init = 0;
+static unsigned int ltc_ref_count = 0;
+static sqlite3_mutex* ltc_rand_mutex = NULL;
+
+static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
+ int rc = 0;
+ int data_to_read = length;
+ int block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
+ const unsigned char * data = (const unsigned char *)buffer;
+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
+ sqlite3_mutex_enter(ltc_rand_mutex);
+#endif
+ while(data_to_read > 0){
+ rc = fortuna_add_entropy(data, block_sz, &prng);
+ rc = rc != CRYPT_OK ? SQLITE_ERROR : SQLITE_OK;
+ if(rc != SQLITE_OK){
+ break;
+ }
+ data_to_read -= block_sz;
+ data += block_sz;
+ block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
+ }
+ fortuna_ready(&prng);
+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
+ sqlite3_mutex_leave(ltc_rand_mutex);
+#endif
+ return rc;
+}
+
+static int sqlcipher_ltc_activate(void *ctx) {
+ unsigned char random_buffer[FORTUNA_MAX_SZ];
+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
+ if(ltc_rand_mutex == NULL){
+ ltc_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+ }
+ sqlite3_mutex_enter(ltc_rand_mutex);
+#endif
+ sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
+ if(ltc_init == 0) {
+ if(register_prng(&fortuna_desc) != CRYPT_OK) return SQLITE_ERROR;
+ if(register_cipher(&rijndael_desc) != CRYPT_OK) return SQLITE_ERROR;
+ if(register_hash(&sha1_desc) != CRYPT_OK) return SQLITE_ERROR;
+ if(fortuna_start(&prng) != CRYPT_OK) {
+ return SQLITE_ERROR;
+ }
+ ltc_init = 1;
+ }
+ ltc_ref_count++;
+#ifndef SQLCIPHER_TEST
+ sqlite3_randomness(FORTUNA_MAX_SZ, random_buffer);
+#endif
+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
+ sqlite3_mutex_leave(ltc_rand_mutex);
+#endif
+ if(sqlcipher_ltc_add_random(ctx, random_buffer, FORTUNA_MAX_SZ) != SQLITE_OK) {
+ return SQLITE_ERROR;
+ }
+ sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
+ return SQLITE_OK;
+}
+
+static int sqlcipher_ltc_deactivate(void *ctx) {
+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
+ sqlite3_mutex_enter(ltc_rand_mutex);
+#endif
+ ltc_ref_count--;
+ if(ltc_ref_count == 0){
+ fortuna_done(&prng);
+ sqlcipher_memset((void *)&prng, 0, sizeof(prng));
+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
+ sqlite3_mutex_leave(ltc_rand_mutex);
+ sqlite3_mutex_free(ltc_rand_mutex);
+ ltc_rand_mutex = NULL;
+#endif
+ }
+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
+ else {
+ sqlite3_mutex_leave(ltc_rand_mutex);
+ }
+#endif
+ return SQLITE_OK;
+}
+
+static const char* sqlcipher_ltc_get_provider_name(void *ctx) {
+ return "libtomcrypt";
+}
+
+static int sqlcipher_ltc_random(void *ctx, void *buffer, int length) {
+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
+ sqlite3_mutex_enter(ltc_rand_mutex);
+#endif
+ fortuna_read(buffer, length, &prng);
+#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
+ sqlite3_mutex_leave(ltc_rand_mutex);
+#endif
+ return SQLITE_OK;
+}
+
+static int sqlcipher_ltc_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {
+ int rc, hash_idx;
+ hmac_state hmac;
+ unsigned long outlen = key_sz;
+
+ hash_idx = find_hash("sha1");
+ if((rc = hmac_init(&hmac, hash_idx, hmac_key, key_sz)) != CRYPT_OK) return SQLITE_ERROR;
+ if((rc = hmac_process(&hmac, in, in_sz)) != CRYPT_OK) return SQLITE_ERROR;
+ if((rc = hmac_process(&hmac, in2, in2_sz)) != CRYPT_OK) return SQLITE_ERROR;
+ if((rc = hmac_done(&hmac, out, &outlen)) != CRYPT_OK) return SQLITE_ERROR;
+ return SQLITE_OK;
+}
+
+static int sqlcipher_ltc_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key) {
+ int rc, hash_idx;
+ unsigned long outlen = key_sz;
+ unsigned long random_buffer_sz = sizeof(char) * 256;
+ unsigned char *random_buffer = sqlcipher_malloc(random_buffer_sz);
+ sqlcipher_memset(random_buffer, 0, random_buffer_sz);
+
+ hash_idx = find_hash("sha1");
+ if((rc = pkcs_5_alg2(pass, pass_sz, salt, salt_sz,
+ workfactor, hash_idx, key, &outlen)) != CRYPT_OK) {
+ return SQLITE_ERROR;
+ }
+ if((rc = pkcs_5_alg2(key, key_sz, salt, salt_sz,
+ 1, hash_idx, random_buffer, &random_buffer_sz)) != CRYPT_OK) {
+ return SQLITE_ERROR;
+ }
+ sqlcipher_ltc_add_random(ctx, random_buffer, random_buffer_sz);
+ sqlcipher_free(random_buffer, random_buffer_sz);
+ return SQLITE_OK;
+}
+
+static const char* sqlcipher_ltc_get_cipher(void *ctx) {
+ return "rijndael";
+}
+
+static int sqlcipher_ltc_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out) {
+ int rc, cipher_idx;
+ symmetric_CBC cbc;
+
+ if((cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx))) == -1) return SQLITE_ERROR;
+ if((rc = cbc_start(cipher_idx, iv, key, key_sz, 0, &cbc)) != CRYPT_OK) return SQLITE_ERROR;
+ rc = mode == 1 ? cbc_encrypt(in, out, in_sz, &cbc) : cbc_decrypt(in, out, in_sz, &cbc);
+ if(rc != CRYPT_OK) return SQLITE_ERROR;
+ cbc_done(&cbc);
+ return SQLITE_OK;
+}
+
+static int sqlcipher_ltc_set_cipher(void *ctx, const char *cipher_name) {
+ return SQLITE_OK;
+}
+
+static int sqlcipher_ltc_get_key_sz(void *ctx) {
+ int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
+ return cipher_descriptor[cipher_idx].max_key_length;
+}
+
+static int sqlcipher_ltc_get_iv_sz(void *ctx) {
+ int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
+ return cipher_descriptor[cipher_idx].block_length;
+}
+
+static int sqlcipher_ltc_get_block_sz(void *ctx) {
+ int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
+ return cipher_descriptor[cipher_idx].block_length;
+}
+
+static int sqlcipher_ltc_get_hmac_sz(void *ctx) {
+ int hash_idx = find_hash("sha1");
+ return hash_descriptor[hash_idx].hashsize;
+}
+
+static int sqlcipher_ltc_ctx_copy(void *target_ctx, void *source_ctx) {
+ return SQLITE_OK;
+}
+
+static int sqlcipher_ltc_ctx_cmp(void *c1, void *c2) {
+ return 1;
+}
+
+static int sqlcipher_ltc_ctx_init(void **ctx) {
+ sqlcipher_ltc_activate(NULL);
+ return SQLITE_OK;
+}
+
+static int sqlcipher_ltc_ctx_free(void **ctx) {
+ sqlcipher_ltc_deactivate(&ctx);
+ return SQLITE_OK;
+}
+
+static int sqlcipher_ltc_fips_status(void *ctx) {
+ return 0;
+}
+
+int sqlcipher_ltc_setup(sqlcipher_provider *p) {
+ p->activate = sqlcipher_ltc_activate;
+ p->deactivate = sqlcipher_ltc_deactivate;
+ p->get_provider_name = sqlcipher_ltc_get_provider_name;
+ p->random = sqlcipher_ltc_random;
+ p->hmac = sqlcipher_ltc_hmac;
+ p->kdf = sqlcipher_ltc_kdf;
+ p->cipher = sqlcipher_ltc_cipher;
+ p->set_cipher = sqlcipher_ltc_set_cipher;
+ p->get_cipher = sqlcipher_ltc_get_cipher;
+ p->get_key_sz = sqlcipher_ltc_get_key_sz;
+ p->get_iv_sz = sqlcipher_ltc_get_iv_sz;
+ p->get_block_sz = sqlcipher_ltc_get_block_sz;
+ p->get_hmac_sz = sqlcipher_ltc_get_hmac_sz;
+ p->ctx_copy = sqlcipher_ltc_ctx_copy;
+ p->ctx_cmp = sqlcipher_ltc_ctx_cmp;
+ p->ctx_init = sqlcipher_ltc_ctx_init;
+ p->ctx_free = sqlcipher_ltc_ctx_free;
+ p->add_random = sqlcipher_ltc_add_random;
+ p->fips_status = sqlcipher_ltc_fips_status;
+ return SQLITE_OK;
+}
+
+#endif
+#endif
+/* END SQLCIPHER */
+
+/************** End of crypto_libtomcrypt.c **********************************/
+/************** Begin file crypto_openssl.c **********************************/
+/*
+** SQLCipher
+** http://sqlcipher.net
+**
+** Copyright (c) 2008 - 2013, ZETETIC LLC
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of the ZETETIC LLC nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*/
+/* BEGIN SQLCIPHER */
+#ifdef SQLITE_HAS_CODEC
+#ifdef SQLCIPHER_CRYPTO_OPENSSL
+#include <openssl/rand.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+
+typedef struct {
+ EVP_CIPHER *evp_cipher;
+} openssl_ctx;
+
+static unsigned int openssl_external_init = 0;
+static unsigned int openssl_init_count = 0;
+static sqlite3_mutex* openssl_rand_mutex = NULL;
+
+static int sqlcipher_openssl_add_random(void *ctx, void *buffer, int length) {
+#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
+ sqlite3_mutex_enter(openssl_rand_mutex);
+#endif
+ RAND_add(buffer, length, 0);
+#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
+ sqlite3_mutex_leave(openssl_rand_mutex);
+#endif
+ return SQLITE_OK;
+}
+
+/* activate and initialize sqlcipher. Most importantly, this will automatically
+ intialize OpenSSL's EVP system if it hasn't already be externally. Note that
+ this function may be called multiple times as new codecs are intiialized.
+ Thus it performs some basic counting to ensure that only the last and final
+ sqlcipher_openssl_deactivate() will free the EVP structures.
+*/
+static int sqlcipher_openssl_activate(void *ctx) {
+ /* initialize openssl and increment the internal init counter
+ but only if it hasn't been initalized outside of SQLCipher by this program
+ e.g. on startup */
+ sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+
+ if(openssl_init_count == 0 && EVP_get_cipherbyname(CIPHER) != NULL) {
+ /* if openssl has not yet been initialized by this library, but
+ a call to get_cipherbyname works, then the openssl library
+ has been initialized externally already. */
+ openssl_external_init = 1;
+ }
+
+#ifdef SQLCIPHER_FIPS
+ if(!FIPS_mode()){
+ if(!FIPS_mode_set(1)){
+ ERR_load_crypto_strings();
+ ERR_print_errors_fp(stderr);
+ }
+ }
+#endif
+
+ if(openssl_init_count == 0 && openssl_external_init == 0) {
+ /* if the library was not externally initialized, then should be now */
+ OpenSSL_add_all_algorithms();
+ }
+
+#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
+ if(openssl_rand_mutex == NULL) {
+ /* allocate a mutex to guard against concurrent calls to RAND_bytes() */
+ openssl_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+ }
+#endif
+
+ openssl_init_count++;
+ sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+ return SQLITE_OK;
+}
+
+/* deactivate SQLCipher, most imporantly decremeting the activation count and
+ freeing the EVP structures on the final deactivation to ensure that
+ OpenSSL memory is cleaned up */
+static int sqlcipher_openssl_deactivate(void *ctx) {
+ sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+ openssl_init_count--;
+
+ if(openssl_init_count == 0) {
+ if(openssl_external_init == 0) {
+ /* if OpenSSL hasn't be initialized externally, and the counter reaches zero
+ after it's decremented, release EVP memory
+ Note: this code will only be reached if OpensSSL_add_all_algorithms()
+ is called by SQLCipher internally. This should prevent SQLCipher from
+ "cleaning up" openssl when it was initialized externally by the program */
+ EVP_cleanup();
+ }
+#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
+ sqlite3_mutex_free(openssl_rand_mutex);
+ openssl_rand_mutex = NULL;
+#endif
+ }
+ sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+ return SQLITE_OK;
+}
+
+static const char* sqlcipher_openssl_get_provider_name(void *ctx) {
+ return "openssl";
+}
+
+/* generate a defined number of random bytes */
+static int sqlcipher_openssl_random (void *ctx, void *buffer, int length) {
+ int rc = 0;
+ /* concurrent calls to RAND_bytes can cause a crash under some openssl versions when a
+ naive application doesn't use CRYPTO_set_locking_callback and
+ CRYPTO_THREADID_set_callback to ensure openssl thread safety.
+ This is simple workaround to prevent this common crash
+ but a more proper solution is that applications setup platform-appropriate
+ thread saftey in openssl externally */
+#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
+ sqlite3_mutex_enter(openssl_rand_mutex);
+#endif
+ rc = RAND_bytes((unsigned char *)buffer, length);
+#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
+ sqlite3_mutex_leave(openssl_rand_mutex);
+#endif
+ return (rc == 1) ? SQLITE_OK : SQLITE_ERROR;
+}
+
+static int sqlcipher_openssl_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {
+ HMAC_CTX hctx;
+ unsigned int outlen;
+ HMAC_CTX_init(&hctx);
+ HMAC_Init_ex(&hctx, hmac_key, key_sz, EVP_sha1(), NULL);
+ HMAC_Update(&hctx, in, in_sz);
+ HMAC_Update(&hctx, in2, in2_sz);
+ HMAC_Final(&hctx, out, &outlen);
+ HMAC_CTX_cleanup(&hctx);
+ return SQLITE_OK;
+}
+
+static int sqlcipher_openssl_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key) {
+ PKCS5_PBKDF2_HMAC_SHA1((const char *)pass, pass_sz, salt, salt_sz, workfactor, key_sz, key);
+ return SQLITE_OK;
+}
+
+static int sqlcipher_openssl_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out) {
+ EVP_CIPHER_CTX ectx;
+ int tmp_csz, csz;
+
+ EVP_CipherInit(&ectx, ((openssl_ctx *)ctx)->evp_cipher, NULL, NULL, mode);
+ EVP_CIPHER_CTX_set_padding(&ectx, 0); // no padding
+ EVP_CipherInit(&ectx, NULL, key, iv, mode);
+ EVP_CipherUpdate(&ectx, out, &tmp_csz, in, in_sz);
+ csz = tmp_csz;
+ out += tmp_csz;
+ EVP_CipherFinal(&ectx, out, &tmp_csz);
+ csz += tmp_csz;
+ EVP_CIPHER_CTX_cleanup(&ectx);
+ assert(in_sz == csz);
+ return SQLITE_OK;
+}
+
+static int sqlcipher_openssl_set_cipher(void *ctx, const char *cipher_name) {
+ openssl_ctx *o_ctx = (openssl_ctx *)ctx;
+ o_ctx->evp_cipher = (EVP_CIPHER *) EVP_get_cipherbyname(cipher_name);
+ return SQLITE_OK;
+}
+
+static const char* sqlcipher_openssl_get_cipher(void *ctx) {
+ return EVP_CIPHER_name(((openssl_ctx *)ctx)->evp_cipher);
+}
+
+static int sqlcipher_openssl_get_key_sz(void *ctx) {
+ return EVP_CIPHER_key_length(((openssl_ctx *)ctx)->evp_cipher);
+}
+
+static int sqlcipher_openssl_get_iv_sz(void *ctx) {
+ return EVP_CIPHER_iv_length(((openssl_ctx *)ctx)->evp_cipher);
+}
+
+static int sqlcipher_openssl_get_block_sz(void *ctx) {
+ return EVP_CIPHER_block_size(((openssl_ctx *)ctx)->evp_cipher);
+}
+
+static int sqlcipher_openssl_get_hmac_sz(void *ctx) {
+ return EVP_MD_size(EVP_sha1());
+}
+
+static int sqlcipher_openssl_ctx_copy(void *target_ctx, void *source_ctx) {
+ memcpy(target_ctx, source_ctx, sizeof(openssl_ctx));
+ return SQLITE_OK;
+}
+
+static int sqlcipher_openssl_ctx_cmp(void *c1, void *c2) {
+ return ((openssl_ctx *)c1)->evp_cipher == ((openssl_ctx *)c2)->evp_cipher;
+}
+
+static int sqlcipher_openssl_ctx_init(void **ctx) {
+ *ctx = sqlcipher_malloc(sizeof(openssl_ctx));
+ if(*ctx == NULL) return SQLITE_NOMEM;
+ sqlcipher_openssl_activate(*ctx);
+ return SQLITE_OK;
+}
+
+static int sqlcipher_openssl_ctx_free(void **ctx) {
+ sqlcipher_openssl_deactivate(*ctx);
+ sqlcipher_free(*ctx, sizeof(openssl_ctx));
+ return SQLITE_OK;
+}
+
+static int sqlcipher_openssl_fips_status(void *ctx) {
+#ifdef SQLCIPHER_FIPS
+ return FIPS_mode();
+#else
+ return 0;
+#endif
+}
+
+int sqlcipher_openssl_setup(sqlcipher_provider *p) {
+ p->activate = sqlcipher_openssl_activate;
+ p->deactivate = sqlcipher_openssl_deactivate;
+ p->get_provider_name = sqlcipher_openssl_get_provider_name;
+ p->random = sqlcipher_openssl_random;
+ p->hmac = sqlcipher_openssl_hmac;
+ p->kdf = sqlcipher_openssl_kdf;
+ p->cipher = sqlcipher_openssl_cipher;
+ p->set_cipher = sqlcipher_openssl_set_cipher;
+ p->get_cipher = sqlcipher_openssl_get_cipher;
+ p->get_key_sz = sqlcipher_openssl_get_key_sz;
+ p->get_iv_sz = sqlcipher_openssl_get_iv_sz;
+ p->get_block_sz = sqlcipher_openssl_get_block_sz;
+ p->get_hmac_sz = sqlcipher_openssl_get_hmac_sz;
+ p->ctx_copy = sqlcipher_openssl_ctx_copy;
+ p->ctx_cmp = sqlcipher_openssl_ctx_cmp;
+ p->ctx_init = sqlcipher_openssl_ctx_init;
+ p->ctx_free = sqlcipher_openssl_ctx_free;
+ p->add_random = sqlcipher_openssl_add_random;
+ p->fips_status = sqlcipher_openssl_fips_status;
+ return SQLITE_OK;
+}
+
+#endif
+#endif
+/* END SQLCIPHER */
+
+/************** End of crypto_openssl.c **************************************/
+/************** Begin file crypto_cc.c ***************************************/
+/*
+** SQLCipher
+** http://sqlcipher.net
+**
+** Copyright (c) 2008 - 2013, ZETETIC LLC
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of the ZETETIC LLC nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
+** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*/
+/* BEGIN SQLCIPHER */
+#ifdef SQLITE_HAS_CODEC
+#ifdef SQLCIPHER_CRYPTO_CC
+#include <CommonCrypto/CommonCrypto.h>
+#include <Security/SecRandom.h>
+
+static int sqlcipher_cc_add_random(void *ctx, void *buffer, int length) {
+ return SQLITE_OK;
+}
+
+/* generate a defined number of random bytes */
+static int sqlcipher_cc_random (void *ctx, void *buffer, int length) {
+ return (SecRandomCopyBytes(kSecRandomDefault, length, (uint8_t *)buffer) == 0) ? SQLITE_OK : SQLITE_ERROR;
+}
+
+static const char* sqlcipher_cc_get_provider_name(void *ctx) {
+ return "commoncrypto";
+}
+
+static int sqlcipher_cc_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {
+ CCHmacContext hmac_context;
+ CCHmacInit(&hmac_context, kCCHmacAlgSHA1, hmac_key, key_sz);
+ CCHmacUpdate(&hmac_context, in, in_sz);
+ CCHmacUpdate(&hmac_context, in2, in2_sz);
+ CCHmacFinal(&hmac_context, out);
+ return SQLITE_OK;
+}
+
+static int sqlcipher_cc_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key) {
+ CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pass, pass_sz, salt, salt_sz, kCCPRFHmacAlgSHA1, workfactor, key, key_sz);
+ return SQLITE_OK;
+}
+
+static int sqlcipher_cc_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out) {
+ CCCryptorRef cryptor;
+ size_t tmp_csz, csz;
+ CCOperation op = mode == CIPHER_ENCRYPT ? kCCEncrypt : kCCDecrypt;
+
+ CCCryptorCreate(op, kCCAlgorithmAES128, 0, key, kCCKeySizeAES256, iv, &cryptor);
+ CCCryptorUpdate(cryptor, in, in_sz, out, in_sz, &tmp_csz);
+ csz = tmp_csz;
+ out += tmp_csz;
+ CCCryptorFinal(cryptor, out, in_sz - csz, &tmp_csz);
+ csz += tmp_csz;
+ CCCryptorRelease(cryptor);
+ assert(size == csz);
+
+ return SQLITE_OK;
+}
+
+static int sqlcipher_cc_set_cipher(void *ctx, const char *cipher_name) {
+ return SQLITE_OK;
+}
+
+static const char* sqlcipher_cc_get_cipher(void *ctx) {
+ return "aes-256-cbc";
+}
+
+static int sqlcipher_cc_get_key_sz(void *ctx) {
+ return kCCKeySizeAES256;
+}
+
+static int sqlcipher_cc_get_iv_sz(void *ctx) {
+ return kCCBlockSizeAES128;
+}
+
+static int sqlcipher_cc_get_block_sz(void *ctx) {
+ return kCCBlockSizeAES128;
+}
+
+static int sqlcipher_cc_get_hmac_sz(void *ctx) {
+ return CC_SHA1_DIGEST_LENGTH;
+}
+
+static int sqlcipher_cc_ctx_copy(void *target_ctx, void *source_ctx) {
+ return SQLITE_OK;
+}
+
+static int sqlcipher_cc_ctx_cmp(void *c1, void *c2) {
+ return 1; /* always indicate contexts are the same */
+}
+
+static int sqlcipher_cc_ctx_init(void **ctx) {
+ return SQLITE_OK;
+}
+
+static int sqlcipher_cc_ctx_free(void **ctx) {
+ return SQLITE_OK;
+}
+
+static int sqlcipher_cc_fips_status(void *ctx) {
+ return 0;
+}
+
+int sqlcipher_cc_setup(sqlcipher_provider *p) {
+ p->random = sqlcipher_cc_random;
+ p->get_provider_name = sqlcipher_cc_get_provider_name;
+ p->hmac = sqlcipher_cc_hmac;
+ p->kdf = sqlcipher_cc_kdf;
+ p->cipher = sqlcipher_cc_cipher;
+ p->set_cipher = sqlcipher_cc_set_cipher;
+ p->get_cipher = sqlcipher_cc_get_cipher;
+ p->get_key_sz = sqlcipher_cc_get_key_sz;
+ p->get_iv_sz = sqlcipher_cc_get_iv_sz;
+ p->get_block_sz = sqlcipher_cc_get_block_sz;
+ p->get_hmac_sz = sqlcipher_cc_get_hmac_sz;
+ p->ctx_copy = sqlcipher_cc_ctx_copy;
+ p->ctx_cmp = sqlcipher_cc_ctx_cmp;
+ p->ctx_init = sqlcipher_cc_ctx_init;
+ p->ctx_free = sqlcipher_cc_ctx_free;
+ p->add_random = sqlcipher_cc_add_random;
+ p->fips_status = sqlcipher_cc_fips_status;
+ return SQLITE_OK;
+}
+
+#endif
+#endif
+/* END SQLCIPHER */
+
+/************** End of crypto_cc.c *******************************************/
/************** Begin file global.c ******************************************/
/*
** 2008 June 13
@@ -13834,16 +17254,16 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = {
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
- 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 6x */
- 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 7x */
+ 96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */
+ 112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
- 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, /* 9x */
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */
160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
- 224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */
- 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */
+ 224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */
+ 239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */
#endif
};
@@ -14440,7 +17860,7 @@ static const char * const azCompileOpt[] = {
** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
** is not required for a match.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){
+SQLITE_API int sqlite3_compileoption_used(const char *zOptName){
int i, n;
#if SQLITE_ENABLE_API_ARMOR
@@ -14468,7 +17888,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){
** Return the N-th compile-time option string. If N is out of range,
** return a NULL pointer.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N){
+SQLITE_API const char *sqlite3_compileoption_get(int N){
if( N>=0 && N<ArraySize(azCompileOpt) ){
return azCompileOpt[N];
}
@@ -14811,6 +18231,14 @@ struct ScanStatus {
**
** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
** is really a pointer to an instance of this structure.
+**
+** The Vdbe.inVtabMethod variable is set to non-zero for the duration of
+** any virtual table method invocations made by the vdbe program. It is
+** set to 2 for xDestroy method calls and 1 for all other methods. This
+** variable is used for two purposes: to allow xDestroy methods to execute
+** "DROP TABLE" statements and to prevent some nasty side effects of
+** malloc failure when SQLite is invoked recursively by a virtual table
+** method function.
*/
struct Vdbe {
sqlite3 *db; /* The database connection that owns this statement */
@@ -14834,13 +18262,11 @@ struct Vdbe {
u32 cacheCtr; /* VdbeCursor row cache generation counter */
int pc; /* The program counter */
int rc; /* Value to return */
-#ifdef SQLITE_DEBUG
- int rcApp; /* errcode set by sqlite3_result_error_code() */
-#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 */
bft explain:2; /* True if EXPLAIN present on SQL command */
+ bft inVtabMethod:2; /* See comments above */
bft changeCntOn:1; /* True to update the change-counter */
bft expired:1; /* True if the VM needs to be recompiled */
bft runOnlyOnce:1; /* Automatically expire on reset */
@@ -15000,32 +18426,10 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *);
*/
typedef struct sqlite3StatType sqlite3StatType;
static SQLITE_WSD struct sqlite3StatType {
-#if SQLITE_PTRSIZE>4
- sqlite3_int64 nowValue[10]; /* Current value */
- sqlite3_int64 mxValue[10]; /* Maximum value */
-#else
- u32 nowValue[10]; /* Current value */
- u32 mxValue[10]; /* Maximum value */
-#endif
+ int nowValue[10]; /* Current value */
+ int mxValue[10]; /* Maximum value */
} sqlite3Stat = { {0,}, {0,} };
-/*
-** Elements of sqlite3Stat[] are protected by either the memory allocator
-** mutex, or by the pcache1 mutex. The following array determines which.
-*/
-static const char statMutex[] = {
- 0, /* SQLITE_STATUS_MEMORY_USED */
- 1, /* SQLITE_STATUS_PAGECACHE_USED */
- 1, /* SQLITE_STATUS_PAGECACHE_OVERFLOW */
- 0, /* SQLITE_STATUS_SCRATCH_USED */
- 0, /* SQLITE_STATUS_SCRATCH_OVERFLOW */
- 0, /* SQLITE_STATUS_MALLOC_SIZE */
- 0, /* SQLITE_STATUS_PARSER_STACK */
- 1, /* SQLITE_STATUS_PAGECACHE_SIZE */
- 0, /* SQLITE_STATUS_SCRATCH_SIZE */
- 0, /* SQLITE_STATUS_MALLOC_COUNT */
-};
-
/* The "wsdStat" macro will resolve to the status information
** state vector. If writable static data is unsupported on the target,
@@ -15042,60 +18446,33 @@ static const char statMutex[] = {
#endif
/*
-** Return the current value of a status parameter. The caller must
-** be holding the appropriate mutex.
+** Return the current value of a status parameter.
*/
-SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int op){
+SQLITE_PRIVATE int sqlite3StatusValue(int op){
wsdStatInit;
assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
- assert( op>=0 && op<ArraySize(statMutex) );
- assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
- : sqlite3MallocMutex()) );
return wsdStat.nowValue[op];
}
/*
-** Add N to the value of a status record. The caller must hold the
-** appropriate mutex. (Locking is checked by assert()).
-**
-** The StatusUp() routine can accept positive or negative values for N.
-** The value of N is added to the current status value and the high-water
-** mark is adjusted if necessary.
-**
-** The StatusDown() routine lowers the current value by N. The highwater
-** mark is unchanged. N must be non-negative for StatusDown().
+** Add N to the value of a status record. It is assumed that the
+** caller holds appropriate locks.
*/
-SQLITE_PRIVATE void sqlite3StatusUp(int op, int N){
+SQLITE_PRIVATE void sqlite3StatusAdd(int op, int N){
wsdStatInit;
assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
- assert( op>=0 && op<ArraySize(statMutex) );
- assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
- : sqlite3MallocMutex()) );
wsdStat.nowValue[op] += N;
if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
wsdStat.mxValue[op] = wsdStat.nowValue[op];
}
}
-SQLITE_PRIVATE void sqlite3StatusDown(int op, int N){
- wsdStatInit;
- assert( N>=0 );
- assert( op>=0 && op<ArraySize(statMutex) );
- assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
- : sqlite3MallocMutex()) );
- assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
- wsdStat.nowValue[op] -= N;
-}
/*
-** Set the value of a status to X. The highwater mark is adjusted if
-** necessary. The caller must hold the appropriate mutex.
+** Set the value of a status to X.
*/
SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
wsdStatInit;
assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
- assert( op>=0 && op<ArraySize(statMutex) );
- assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
- : sqlite3MallocMutex()) );
wsdStat.nowValue[op] = X;
if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
wsdStat.mxValue[op] = wsdStat.nowValue[op];
@@ -15104,14 +18481,12 @@ SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
/*
** Query status information.
+**
+** This implementation assumes that reading or writing an aligned
+** 32-bit integer is an atomic operation. If that assumption is not true,
+** then this routine is not threadsafe.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_status64(
- int op,
- sqlite3_int64 *pCurrent,
- sqlite3_int64 *pHighwater,
- int resetFlag
-){
- sqlite3_mutex *pMutex;
+SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
wsdStatInit;
if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
return SQLITE_MISUSE_BKPT;
@@ -15119,35 +18494,18 @@ SQLITE_API int SQLITE_STDCALL sqlite3_status64(
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
#endif
- pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex();
- sqlite3_mutex_enter(pMutex);
*pCurrent = wsdStat.nowValue[op];
*pHighwater = wsdStat.mxValue[op];
if( resetFlag ){
wsdStat.mxValue[op] = wsdStat.nowValue[op];
}
- sqlite3_mutex_leave(pMutex);
- (void)pMutex; /* Prevent warning when SQLITE_THREADSAFE=0 */
return SQLITE_OK;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
- sqlite3_int64 iCur, iHwtr;
- int rc;
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
-#endif
- rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag);
- if( rc==0 ){
- *pCurrent = (int)iCur;
- *pHighwater = (int)iHwtr;
- }
- return rc;
-}
/*
** Query status information for a single database connection
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_status(
+SQLITE_API int sqlite3_db_status(
sqlite3 *db, /* The database connection whose status is desired */
int op, /* Status verb */
int *pCurrent, /* Write current value here */
@@ -16771,7 +20129,7 @@ static sqlite3_vfs * SQLITE_WSD vfsList = 0;
** Locate a VFS by name. If no name is given, simply return the
** first VFS on the list.
*/
-SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfs){
+SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
sqlite3_vfs *pVfs = 0;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex;
@@ -16817,7 +20175,7 @@ static void vfsUnlink(sqlite3_vfs *pVfs){
** VFS multiple times. The new VFS becomes the default if makeDflt is
** true.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
+SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
MUTEX_LOGIC(sqlite3_mutex *mutex;)
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
@@ -16845,7 +20203,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDf
/*
** Unregister a VFS so that it is no longer accessible.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
+SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
@@ -19181,7 +22539,7 @@ SQLITE_PRIVATE int sqlite3MutexEnd(void){
/*
** Retrieve a pointer to a static mutex or allocate a new dynamic one.
*/
-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int id){
+SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
#ifndef SQLITE_OMIT_AUTOINIT
if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0;
@@ -19200,7 +22558,7 @@ SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
/*
** Free a dynamic mutex.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex *p){
+SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
if( p ){
sqlite3GlobalConfig.mutex.xMutexFree(p);
}
@@ -19210,7 +22568,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex *p){
** Obtain the mutex p. If some other thread already has the mutex, block
** until it can be obtained.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex *p){
+SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
if( p ){
sqlite3GlobalConfig.mutex.xMutexEnter(p);
}
@@ -19220,7 +22578,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex *p){
** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex *p){
+SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
int rc = SQLITE_OK;
if( p ){
return sqlite3GlobalConfig.mutex.xMutexTry(p);
@@ -19234,7 +22592,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex *p){
** is not currently entered. If a NULL pointer is passed as an argument
** this function is a no-op.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex *p){
+SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
if( p ){
sqlite3GlobalConfig.mutex.xMutexLeave(p);
}
@@ -19245,10 +22603,10 @@ SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex *p){
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use inside assert() statements.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex *p){
+SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex *p){
+SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
}
#endif
@@ -19378,12 +22736,8 @@ static sqlite3_mutex *debugMutexAlloc(int id){
break;
}
default: {
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( id-2<0 || id-2>=ArraySize(aStatic) ){
- (void)SQLITE_MISUSE_BKPT;
- return 0;
- }
-#endif
+ assert( id-2 >= 0 );
+ assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
pNew = &aStatic[id-2];
pNew->id = id;
break;
@@ -19398,13 +22752,8 @@ static sqlite3_mutex *debugMutexAlloc(int id){
static void debugMutexFree(sqlite3_mutex *pX){
sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
assert( p->cnt==0 );
- if( p->id==SQLITE_MUTEX_RECURSIVE || p->id==SQLITE_MUTEX_FAST ){
- sqlite3_free(p);
- }else{
-#ifdef SQLITE_ENABLE_API_ARMOR
- (void)SQLITE_MISUSE_BKPT;
-#endif
- }
+ assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
+ sqlite3_free(p);
}
/*
@@ -19515,10 +22864,8 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
*/
struct sqlite3_mutex {
pthread_mutex_t mutex; /* Mutex controlling the lock */
-#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
- int id; /* Mutex type */
-#endif
#if SQLITE_MUTEX_NREF
+ int id; /* Mutex type */
volatile int nRef; /* Number of entrances */
volatile pthread_t owner; /* Thread that is within this mutex */
int trace; /* True to trace changes */
@@ -19635,12 +22982,18 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
pthread_mutex_init(&p->mutex, &recursiveAttr);
pthread_mutexattr_destroy(&recursiveAttr);
#endif
+#if SQLITE_MUTEX_NREF
+ p->id = iType;
+#endif
}
break;
}
case SQLITE_MUTEX_FAST: {
p = sqlite3MallocZero( sizeof(*p) );
if( p ){
+#if SQLITE_MUTEX_NREF
+ p->id = iType;
+#endif
pthread_mutex_init(&p->mutex, 0);
}
break;
@@ -19653,12 +23006,12 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
}
#endif
p = &staticMutexes[iType-2];
+#if SQLITE_MUTEX_NREF
+ p->id = iType;
+#endif
break;
}
}
-#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
- if( p ) p->id = iType;
-#endif
return p;
}
@@ -19670,18 +23023,9 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
*/
static void pthreadMutexFree(sqlite3_mutex *p){
assert( p->nRef==0 );
-#if SQLITE_ENABLE_API_ARMOR
- if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE )
-#endif
- {
- pthread_mutex_destroy(&p->mutex);
- sqlite3_free(p);
- }
-#ifdef SQLITE_ENABLE_API_ARMOR
- else{
- (void)SQLITE_MISUSE_BKPT;
- }
-#endif
+ assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
+ pthread_mutex_destroy(&p->mutex);
+ sqlite3_free(p);
}
/*
@@ -19893,6 +23237,16 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
#endif
+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+# ifndef SQLITE_DEBUG_OS_TRACE
+# define SQLITE_DEBUG_OS_TRACE 0
+# endif
+ int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
+# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X
+#else
+# define OSTRACE(X)
+#endif
+
/*
** Macros for performance tracing. Normally turned off. Only works
** on i486 hardware.
@@ -20085,7 +23439,7 @@ SQLITE_API int sqlite3_open_file_count = 0;
/*
** Include the primary Windows SDK header file.
*/
-#include "windows.h"
+/* #include "windows.h" */
#ifdef __CYGWIN__
# include <sys/cygwin.h>
@@ -20141,17 +23495,6 @@ SQLITE_API int sqlite3_open_file_count = 0;
# define SQLITE_WIN32_VOLATILE volatile
#endif
-/*
-** For some Windows sub-platforms, the _beginthreadex() / _endthreadex()
-** functions are not available (e.g. those not using MSVC, Cygwin, etc).
-*/
-#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
- SQLITE_THREADSAFE>0 && !defined(__CYGWIN__)
-# define SQLITE_OS_WIN_THREADS 1
-#else
-# define SQLITE_OS_WIN_THREADS 0
-#endif
-
#endif /* _OS_WIN_H_ */
/************** End of os_win.h **********************************************/
@@ -20234,8 +23577,8 @@ static int winMutex_isNt = -1; /* <0 means "need to query" */
*/
static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0;
-SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void); /* os_win.c */
-SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
+SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */
+SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
static int winMutexInit(void){
/* The first to increment to 1 does actual initialization */
@@ -20327,8 +23670,8 @@ static sqlite3_mutex *winMutexAlloc(int iType){
case SQLITE_MUTEX_RECURSIVE: {
p = sqlite3MallocZero( sizeof(*p) );
if( p ){
- p->id = iType;
#ifdef SQLITE_DEBUG
+ p->id = iType;
#ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC
p->trace = 1;
#endif
@@ -20348,9 +23691,12 @@ static sqlite3_mutex *winMutexAlloc(int iType){
return 0;
}
#endif
+ assert( iType-2 >= 0 );
+ assert( iType-2 < ArraySize(winMutex_staticMutexes) );
+ assert( winMutex_isInit==1 );
p = &winMutex_staticMutexes[iType-2];
- p->id = iType;
#ifdef SQLITE_DEBUG
+ p->id = iType;
#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
p->trace = 1;
#endif
@@ -20369,15 +23715,13 @@ static sqlite3_mutex *winMutexAlloc(int iType){
*/
static void winMutexFree(sqlite3_mutex *p){
assert( p );
+#ifdef SQLITE_DEBUG
assert( p->nRef==0 && p->owner==0 );
- if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){
- DeleteCriticalSection(&p->mutex);
- sqlite3_free(p);
- }else{
-#ifdef SQLITE_ENABLE_API_ARMOR
- (void)SQLITE_MISUSE_BKPT;
+ assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
#endif
- }
+ assert( winMutex_isInit==1 );
+ DeleteCriticalSection(&p->mutex);
+ sqlite3_free(p);
}
/*
@@ -20531,7 +23875,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
** held by SQLite. An example of non-essential memory is memory used to
** cache database pages that are not currently in use.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int n){
+SQLITE_API int sqlite3_release_memory(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
return sqlite3PcacheReleaseMemory(n);
#else
@@ -20587,13 +23931,6 @@ static SQLITE_WSD struct Mem0Global {
#define mem0 GLOBAL(struct Mem0Global, mem0)
/*
-** Return the memory allocator mutex. sqlite3_status() needs it.
-*/
-SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void){
- return mem0.mutex;
-}
-
-/*
** This routine runs when the memory allocator sees that the
** total memory allocation is about to exceed the soft heap
** limit.
@@ -20615,7 +23952,7 @@ static int sqlite3MemoryAlarm(
void *pArg,
sqlite3_int64 iThreshold
){
- sqlite3_int64 nUsed;
+ int nUsed;
sqlite3_mutex_enter(mem0.mutex);
mem0.alarmCallback = xCallback;
mem0.alarmArg = pArg;
@@ -20631,7 +23968,7 @@ static int sqlite3MemoryAlarm(
** Deprecated external interface. Internal/core SQLite code
** should call sqlite3MemoryAlarm.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_memory_alarm(
+SQLITE_API int sqlite3_memory_alarm(
void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
void *pArg,
sqlite3_int64 iThreshold
@@ -20644,7 +23981,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_memory_alarm(
** Set the soft heap-size limit for the library. Passing a zero or
** negative value indicates no limit.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 n){
+SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
sqlite3_int64 priorLimit;
sqlite3_int64 excess;
#ifndef SQLITE_OMIT_AUTOINIT
@@ -20664,7 +24001,7 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64
if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
return priorLimit;
}
-SQLITE_API void SQLITE_STDCALL sqlite3_soft_heap_limit(int n){
+SQLITE_API void sqlite3_soft_heap_limit(int n){
if( n<0 ) n = 0;
sqlite3_soft_heap_limit64(n);
}
@@ -20673,7 +24010,6 @@ SQLITE_API void SQLITE_STDCALL sqlite3_soft_heap_limit(int n){
** Initialize the memory allocation subsystem.
*/
SQLITE_PRIVATE int sqlite3MallocInit(void){
- int rc;
if( sqlite3GlobalConfig.m.xMalloc==0 ){
sqlite3MemSetDefault();
}
@@ -20709,9 +24045,7 @@ SQLITE_PRIVATE int sqlite3MallocInit(void){
sqlite3GlobalConfig.szPage = 0;
sqlite3GlobalConfig.nPage = 0;
}
- rc = sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);
- if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0));
- return rc;
+ return sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);
}
/*
@@ -20736,7 +24070,7 @@ SQLITE_PRIVATE void sqlite3MallocEnd(void){
/*
** Return the amount of memory currently checked out.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void){
+SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
int n, mx;
sqlite3_int64 res;
sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
@@ -20749,7 +24083,7 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void){
** checked out since either the beginning of this process
** or since the most recent reset.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag){
+SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
int n, mx;
sqlite3_int64 res;
sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
@@ -20787,7 +24121,7 @@ static int mallocWithAlarm(int n, void **pp){
nFull = sqlite3GlobalConfig.m.xRoundup(n);
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
if( mem0.alarmCallback!=0 ){
- sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
+ int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.alarmThreshold - nFull ){
mem0.nearlyFull = 1;
sqlite3MallocAlarm(nFull);
@@ -20804,8 +24138,8 @@ static int mallocWithAlarm(int n, void **pp){
#endif
if( p ){
nFull = sqlite3MallocSize(p);
- sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull);
- sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1);
+ sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
+ sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1);
}
*pp = p;
return nFull;
@@ -20840,13 +24174,13 @@ SQLITE_PRIVATE void *sqlite3Malloc(u64 n){
** First make sure the memory subsystem is initialized, then do the
** allocation.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int n){
+SQLITE_API void *sqlite3_malloc(int n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
return n<=0 ? 0 : sqlite3Malloc(n);
}
-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64 n){
+SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
@@ -20882,14 +24216,14 @@ SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
p = mem0.pScratchFree;
mem0.pScratchFree = mem0.pScratchFree->pNext;
mem0.nScratchFree--;
- sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1);
+ sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1);
sqlite3_mutex_leave(mem0.mutex);
}else{
sqlite3_mutex_leave(mem0.mutex);
p = sqlite3Malloc(n);
if( sqlite3GlobalConfig.bMemstat && p ){
sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusUp(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p));
+ sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p));
sqlite3_mutex_leave(mem0.mutex);
}
sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
@@ -20930,19 +24264,19 @@ SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
mem0.pScratchFree = pSlot;
mem0.nScratchFree++;
assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch );
- sqlite3StatusDown(SQLITE_STATUS_SCRATCH_USED, 1);
+ sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1);
sqlite3_mutex_leave(mem0.mutex);
}else{
/* Release memory back to the heap */
assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) );
- assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) );
+ assert( sqlite3MemdebugNoType(p, ~MEMTYPE_SCRATCH) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
if( sqlite3GlobalConfig.bMemstat ){
int iSize = sqlite3MallocSize(p);
sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize);
- sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize);
- sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
+ sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize);
+ sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize);
+ sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
sqlite3GlobalConfig.m.xFree(p);
sqlite3_mutex_leave(mem0.mutex);
}else{
@@ -20973,7 +24307,7 @@ SQLITE_PRIVATE int sqlite3MallocSize(void *p){
}
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
if( db==0 ){
- assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
+ assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
return sqlite3MallocSize(p);
}else{
@@ -20982,13 +24316,13 @@ SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
return db->lookaside.sz;
}else{
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
- assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+ assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
return sqlite3GlobalConfig.m.xSize(p);
}
}
}
-SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void *p){
- assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
+SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){
+ assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
}
@@ -20996,14 +24330,14 @@ SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void *p){
/*
** Free memory previously obtained from sqlite3Malloc().
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_free(void *p){
+SQLITE_API void sqlite3_free(void *p){
if( p==0 ) return; /* IMP: R-49053-54554 */
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
- assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
+ assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
if( sqlite3GlobalConfig.bMemstat ){
sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p));
- sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
+ sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
+ sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
sqlite3GlobalConfig.m.xFree(p);
sqlite3_mutex_leave(mem0.mutex);
}else{
@@ -21044,7 +24378,7 @@ SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
}
}
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
- assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+ assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
sqlite3_free(p);
@@ -21057,7 +24391,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
int nOld, nNew, nDiff;
void *pNew;
assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
- assert( sqlite3MemdebugNoType(pOld, (u8)~MEMTYPE_HEAP) );
+ assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
if( pOld==0 ){
return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */
}
@@ -21091,7 +24425,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
}
if( pNew ){
nNew = sqlite3MallocSize(pNew);
- sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
+ sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
}
sqlite3_mutex_leave(mem0.mutex);
}else{
@@ -21105,14 +24439,14 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
** The public interface to sqlite3Realloc. Make sure that the memory
** subsystem is initialized prior to invoking sqliteRealloc.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void *pOld, int n){
+SQLITE_API void *sqlite3_realloc(void *pOld, int n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
if( n<0 ) n = 0; /* IMP: R-26507-47431 */
return sqlite3Realloc(pOld, n);
}
-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
+SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
@@ -21224,7 +24558,7 @@ SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){
}
}else{
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
- assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+ assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
pNew = sqlite3_realloc64(p, n);
if( !pNew ){
@@ -21477,7 +24811,6 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
** Set the StrAccum object to an error mode.
*/
static void setStrAccumError(StrAccum *p, u8 eError){
- assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG );
p->accError = eError;
p->nAlloc = 0;
}
@@ -21552,6 +24885,13 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
char buf[etBUFSIZE]; /* Conversion buffer */
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( ap==0 ){
+ (void)SQLITE_MISUSE_BKPT;
+ sqlite3StrAccumReset(pAccum);
+ return;
+ }
+#endif
bufpt = 0;
if( bFlags ){
if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
@@ -21592,6 +24932,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
}
}while( !done && (c=(*++fmt))!=0 );
/* Get the field width */
+ width = 0;
if( c=='*' ){
if( bArgList ){
width = (int)getIntArg(pArgList);
@@ -21600,21 +24941,18 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
}
if( width<0 ){
flag_leftjustify = 1;
- width = width >= -2147483647 ? -width : 0;
+ width = -width;
}
c = *++fmt;
}else{
- unsigned wx = 0;
while( c>='0' && c<='9' ){
- wx = wx*10 + c - '0';
+ width = width*10 + c - '0';
c = *++fmt;
}
- testcase( wx>0x7fffffff );
- width = wx & 0x7fffffff;
}
-
/* Get the precision */
if( c=='.' ){
+ precision = 0;
c = *++fmt;
if( c=='*' ){
if( bArgList ){
@@ -21622,18 +24960,13 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
}else{
precision = va_arg(ap,int);
}
+ if( precision<0 ) precision = -precision;
c = *++fmt;
- if( precision<0 ){
- precision = precision >= -2147483647 ? -precision : -1;
- }
}else{
- unsigned px = 0;
while( c>='0' && c<='9' ){
- px = px*10 + c - '0';
+ precision = precision*10 + c - '0';
c = *++fmt;
}
- testcase( px>0x7fffffff );
- precision = px & 0x7fffffff;
}
}else{
precision = -1;
@@ -21797,8 +25130,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
else prefix = 0;
}
if( xtype==etGENERIC && precision>0 ) precision--;
- testcase( precision>0xfff );
- for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
+ for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
if( xtype==etFLOAT ) realvalue += rounder;
/* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
exp = 0;
@@ -21853,9 +25185,8 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
}else{
e2 = exp;
}
- if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
- bufpt = zExtra
- = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
+ if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
+ bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
if( bufpt==0 ){
setStrAccumError(pAccum, STRACCUM_NOMEM);
return;
@@ -22087,13 +25418,13 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
*/
static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
char *zNew;
- assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
+ assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */
if( p->accError ){
testcase(p->accError==STRACCUM_TOOBIG);
testcase(p->accError==STRACCUM_NOMEM);
return 0;
}
- if( p->mxAlloc==0 ){
+ if( !p->useMalloc ){
N = p->nAlloc - p->nChar - 1;
setStrAccumError(p, STRACCUM_TOOBIG);
return N;
@@ -22113,10 +25444,10 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
}else{
p->nAlloc = (int)szNew;
}
- if( p->db ){
+ if( p->useMalloc==1 ){
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
}else{
- zNew = sqlite3_realloc64(zOld, p->nAlloc);
+ zNew = sqlite3_realloc(zOld, p->nAlloc);
}
if( zNew ){
assert( p->zText!=0 || p->nChar==0 );
@@ -22136,10 +25467,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
** Append N copies of character c to the given string buffer.
*/
SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){
- testcase( p->nChar + (i64)N > 0x7fffffff );
- if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
- return;
- }
+ if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return;
while( (N--)>0 ) p->zText[p->nChar++] = c;
}
@@ -22164,7 +25492,7 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
** size of the memory allocation for StrAccum if necessary.
*/
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
- assert( z!=0 || N==0 );
+ assert( z!=0 );
assert( p->zText!=0 || p->nChar==0 || p->accError );
assert( N>=0 );
assert( p->accError==0 || p->nAlloc==0 );
@@ -22193,8 +25521,12 @@ SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
if( p->zText ){
p->zText[p->nChar] = 0;
- if( p->mxAlloc>0 && p->zText==p->zBase ){
- p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
+ if( p->useMalloc && p->zText==p->zBase ){
+ if( p->useMalloc==1 ){
+ p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
+ }else{
+ p->zText = sqlite3_malloc(p->nChar+1);
+ }
if( p->zText ){
memcpy(p->zText, p->zBase, p->nChar+1);
}else{
@@ -22210,31 +25542,25 @@ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
*/
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
if( p->zText!=p->zBase ){
- sqlite3DbFree(p->db, p->zText);
+ if( p->useMalloc==1 ){
+ sqlite3DbFree(p->db, p->zText);
+ }else{
+ sqlite3_free(p->zText);
+ }
}
p->zText = 0;
}
/*
-** Initialize a string accumulator.
-**
-** p: The accumulator to be initialized.
-** db: Pointer to a database connection. May be NULL. Lookaside
-** memory is used if not NULL. db->mallocFailed is set appropriately
-** when not NULL.
-** zBase: An initial buffer. May be NULL in which case the initial buffer
-** is malloced.
-** n: Size of zBase in bytes. If total space requirements never exceed
-** n then no memory allocations ever occur.
-** mx: Maximum number of bytes to accumulate. If mx==0 then no memory
-** allocations will ever occur.
+** Initialize a string accumulator
*/
-SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
+SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
p->zText = p->zBase = zBase;
- p->db = db;
+ p->db = 0;
p->nChar = 0;
p->nAlloc = n;
p->mxAlloc = mx;
+ p->useMalloc = 1;
p->accError = 0;
}
@@ -22247,8 +25573,9 @@ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list a
char zBase[SQLITE_PRINT_BUF_SIZE];
StrAccum acc;
assert( db!=0 );
- sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
+ sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
+ acc.db = db;
sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
if( acc.accError==STRACCUM_NOMEM ){
@@ -22292,7 +25619,7 @@ SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zForma
** Print into memory obtained from sqlite3_malloc(). Omit the internal
** %-conversion extensions.
*/
-SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap){
+SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
char *z;
char zBase[SQLITE_PRINT_BUF_SIZE];
StrAccum acc;
@@ -22306,7 +25633,8 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
- sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
+ sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
+ acc.useMalloc = 2;
sqlite3VXPrintf(&acc, 0, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
return z;
@@ -22316,7 +25644,7 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap
** Print into memory obtained from sqlite3_malloc()(). Omit the internal
** %-conversion extensions.
*/
-SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char *zFormat, ...){
+SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
va_list ap;
char *z;
#ifndef SQLITE_OMIT_AUTOINIT
@@ -22341,21 +25669,22 @@ SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char *zFormat, ...){
**
** sqlite3_vsnprintf() is the varargs version.
*/
-SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
+SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
StrAccum acc;
if( n<=0 ) return zBuf;
#ifdef SQLITE_ENABLE_API_ARMOR
if( zBuf==0 || zFormat==0 ) {
(void)SQLITE_MISUSE_BKPT;
- if( zBuf ) zBuf[0] = 0;
+ if( zBuf && n>0 ) zBuf[0] = 0;
return zBuf;
}
#endif
- sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
+ sqlite3StrAccumInit(&acc, zBuf, n, 0);
+ acc.useMalloc = 0;
sqlite3VXPrintf(&acc, 0, zFormat, ap);
return sqlite3StrAccumFinish(&acc);
}
-SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
+SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
char *z;
va_list ap;
va_start(ap,zFormat);
@@ -22377,7 +25706,8 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
StrAccum acc; /* String accumulator */
char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
- sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
+ sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
+ acc.useMalloc = 0;
sqlite3VXPrintf(&acc, 0, zFormat, ap);
sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
sqlite3StrAccumFinish(&acc));
@@ -22386,7 +25716,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
/*
** Format and write a message to the log if logging is enabled.
*/
-SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...){
+SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){
va_list ap; /* Vararg list */
if( sqlite3GlobalConfig.xLog ){
va_start(ap, zFormat);
@@ -22395,7 +25725,7 @@ SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...)
}
}
-#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
+#if defined(SQLITE_DEBUG)
/*
** A version of printf() that understands %lld. Used for debugging.
** The printf() built into some versions of windows does not understand %lld
@@ -22405,7 +25735,8 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
va_list ap;
StrAccum acc;
char zBuf[500];
- sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+ sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
+ acc.useMalloc = 0;
va_start(ap,zFormat);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
va_end(ap);
@@ -22432,7 +25763,7 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
** is not the last item in the tree. */
SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
if( p==0 ){
- p = sqlite3_malloc64( sizeof(*p) );
+ p = sqlite3_malloc( sizeof(*p) );
if( p==0 ) return 0;
memset(p, 0, sizeof(*p));
}else{
@@ -22455,7 +25786,8 @@ SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
int i;
StrAccum acc;
char zBuf[500];
- sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+ sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
+ acc.useMalloc = 0;
if( p ){
for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4);
@@ -22520,7 +25852,7 @@ static SQLITE_WSD struct sqlite3PrngType {
/*
** Return N random bytes.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *pBuf){
+SQLITE_API void sqlite3_randomness(int N, void *pBuf){
unsigned char t;
unsigned char *zBuf = pBuf;
@@ -22726,7 +26058,7 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
/********************************* Win32 Threads ****************************/
-#if SQLITE_OS_WIN_THREADS
+#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
#include <process.h>
@@ -22819,7 +26151,7 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
}
-#endif /* SQLITE_OS_WIN_THREADS */
+#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT */
/******************************** End Win32 Threads *************************/
@@ -23672,7 +27004,7 @@ SQLITE_PRIVATE int sqlite3Dequote(char *z){
** case-independent fashion, using the same definition of "case
** independence" that SQLite uses internally when comparing identifiers.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *zLeft, const char *zRight){
+SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
register unsigned char *a, *b;
if( zLeft==0 ){
return zRight ? -1 : 0;
@@ -23684,7 +27016,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *zLeft, const char *zRi
while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
return UpperToLower[*a] - UpperToLower[*b];
}
-SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
+SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
register unsigned char *a, *b;
if( zLeft==0 ){
return zRight ? -1 : 0;
@@ -24078,7 +27410,6 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){
}
}
#endif
- while( zNum[0]=='0' ) zNum++;
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
v = v*10 + c;
}
@@ -25216,25 +28547,23 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 136 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
/* 137 */ "IfPos" OpHelp("if r[P1]>0 goto P2"),
/* 138 */ "IfNeg" OpHelp("r[P1]+=P3, if r[P1]<0 goto P2"),
- /* 139 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]+=P3, goto P2"),
- /* 140 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
- /* 141 */ "JumpZeroIncr" OpHelp("if (r[P1]++)==0 ) goto P2"),
- /* 142 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
- /* 143 */ "IncrVacuum" OpHelp(""),
- /* 144 */ "Expire" OpHelp(""),
- /* 145 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
- /* 146 */ "VBegin" OpHelp(""),
- /* 147 */ "VCreate" OpHelp(""),
- /* 148 */ "VDestroy" OpHelp(""),
- /* 149 */ "VOpen" OpHelp(""),
- /* 150 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
- /* 151 */ "VNext" OpHelp(""),
- /* 152 */ "VRename" OpHelp(""),
- /* 153 */ "Pagecount" OpHelp(""),
- /* 154 */ "MaxPgcnt" OpHelp(""),
- /* 155 */ "Init" OpHelp("Start at P2"),
- /* 156 */ "Noop" OpHelp(""),
- /* 157 */ "Explain" OpHelp(""),
+ /* 139 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"),
+ /* 140 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
+ /* 141 */ "IncrVacuum" OpHelp(""),
+ /* 142 */ "Expire" OpHelp(""),
+ /* 143 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
+ /* 144 */ "VBegin" OpHelp(""),
+ /* 145 */ "VCreate" OpHelp(""),
+ /* 146 */ "VDestroy" OpHelp(""),
+ /* 147 */ "VOpen" OpHelp(""),
+ /* 148 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
+ /* 149 */ "VNext" OpHelp(""),
+ /* 150 */ "VRename" OpHelp(""),
+ /* 151 */ "Pagecount" OpHelp(""),
+ /* 152 */ "MaxPgcnt" OpHelp(""),
+ /* 153 */ "Init" OpHelp("Start at P2"),
+ /* 154 */ "Noop" OpHelp(""),
+ /* 155 */ "Explain" OpHelp(""),
};
return azName[i];
}
@@ -25315,6 +28644,18 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
#endif
/*
+** Define the OS_VXWORKS pre-processor macro to 1 if building on
+** vxworks, or 0 otherwise.
+*/
+#ifndef OS_VXWORKS
+# if defined(__RTP__) || defined(_WRS_KERNEL)
+# define OS_VXWORKS 1
+# else
+# define OS_VXWORKS 0
+# endif
+#endif
+
+/*
** standard include files.
*/
#include <sys/types.h>
@@ -25325,33 +28666,21 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
#include <sys/time.h>
#include <errno.h>
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
-# include <sys/mman.h>
+/* # include <sys/mman.h> */
#endif
-#if SQLITE_ENABLE_LOCKING_STYLE
+#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS
# include <sys/ioctl.h>
-# include <sys/file.h>
-# include <sys/param.h>
+# if OS_VXWORKS
+# include <semaphore.h>
+# include <limits.h>
+# else
+# include <sys/file.h>
+# include <sys/param.h>
+# endif
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
-#if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
- (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
-# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
- && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
-# define HAVE_GETHOSTUUID 1
-# else
-# warning "gethostuuid() is disabled."
-# endif
-#endif
-
-
-#if OS_VXWORKS
-/* # include <sys/ioctl.h> */
-# include <semaphore.h>
-# include <limits.h>
-#endif /* OS_VXWORKS */
-
-#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
+#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
# include <sys/mount.h>
#endif
@@ -25392,10 +28721,6 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
*/
#define MAX_PATHNAME 512
-/* Always cast the getpid() return type for compatibility with
-** kernel modules in VxWorks. */
-#define osGetpid(X) (pid_t)getpid()
-
/*
** Only set the lastErrno if the error code is a real error and not
** a normal expected return code of SQLITE_BUSY or SQLITE_OK
@@ -25484,7 +28809,7 @@ struct unixFile {
** method was called. If xOpen() is called from a different process id,
** indicating that a fork() has occurred, the PRNG will be reset.
*/
-static pid_t randomnessPid = 0;
+static int randomnessPid = 0;
/*
** Allowed values for the unixFile.ctrlFlags bitmask:
@@ -25501,8 +28826,7 @@ static pid_t randomnessPid = 0;
#define UNIXFILE_DELETE 0x20 /* Delete on close */
#define UNIXFILE_URI 0x40 /* Filename might have query parameters */
#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */
-#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings issued */
-#define UNIXFILE_BLOCK 0x0200 /* Next SHM lock might block */
+#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings have been issued */
/*
** Include code that is common to all os_*.c files
@@ -25540,6 +28864,16 @@ static pid_t randomnessPid = 0;
# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
#endif
+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+# ifndef SQLITE_DEBUG_OS_TRACE
+# define SQLITE_DEBUG_OS_TRACE 0
+# endif
+ int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
+# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X
+#else
+# define OSTRACE(X)
+#endif
+
/*
** Macros for performance tracing. Normally turned off. Only works
** on i486 hardware.
@@ -25831,7 +29165,7 @@ static struct unix_syscall {
{ "read", (sqlite3_syscall_ptr)read, 0 },
#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent)
-#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
+#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
{ "pread", (sqlite3_syscall_ptr)pread, 0 },
#else
{ "pread", (sqlite3_syscall_ptr)0, 0 },
@@ -25848,7 +29182,7 @@ static struct unix_syscall {
{ "write", (sqlite3_syscall_ptr)write, 0 },
#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)
-#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
+#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
{ "pwrite", (sqlite3_syscall_ptr)pwrite, 0 },
#else
{ "pwrite", (sqlite3_syscall_ptr)0, 0 },
@@ -26082,7 +29416,7 @@ static int unixMutexHeld(void) {
#endif
-#ifdef SQLITE_HAVE_OS_TRACE
+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
/*
** Helper function for printing out trace information from debugging
** binaries. This returns the string representation of the supplied
@@ -26163,9 +29497,9 @@ static int lockTrace(int fd, int op, struct flock *p){
/*
** Retry ftruncate() calls that fail due to EINTR
**
-** All calls to ftruncate() within this file should be made through
-** this wrapper. On the Android platform, bypassing the logic below
-** could lead to a corrupt database.
+** All calls to ftruncate() within this file should be made through this wrapper.
+** On the Android platform, bypassing the logic below could lead to a corrupt
+** database.
*/
static int robust_ftruncate(int h, sqlite3_int64 sz){
int rc;
@@ -26345,7 +29679,7 @@ static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){
assert( zAbsoluteName[0]=='/' );
n = (int)strlen(zAbsoluteName);
- pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) );
+ pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) );
if( pNew==0 ) return 0;
pNew->zCanonicalName = (char*)&pNew[1];
memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
@@ -26625,14 +29959,6 @@ static void robust_close(unixFile *pFile, int h, int lineno){
}
/*
-** Set the pFile->lastErrno. Do this in a subroutine as that provides
-** a convenient place to set a breakpoint.
-*/
-static void storeLastErrno(unixFile *pFile, int error){
- pFile->lastErrno = error;
-}
-
-/*
** Close all file descriptors accumuated in the unixInodeInfo->pUnused list.
*/
static void closePendingFds(unixFile *pFile){
@@ -26705,7 +30031,7 @@ static int findInodeInfo(
fd = pFile->h;
rc = osFstat(fd, &statbuf);
if( rc!=0 ){
- storeLastErrno(pFile, errno);
+ pFile->lastErrno = errno;
#ifdef EOVERFLOW
if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
#endif
@@ -26726,12 +30052,12 @@ static int findInodeInfo(
if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){
do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR );
if( rc!=1 ){
- storeLastErrno(pFile, errno);
+ pFile->lastErrno = errno;
return SQLITE_IOERR;
}
rc = osFstat(fd, &statbuf);
if( rc!=0 ){
- storeLastErrno(pFile, errno);
+ pFile->lastErrno = errno;
return SQLITE_IOERR;
}
}
@@ -26749,7 +30075,7 @@ static int findInodeInfo(
pInode = pInode->pNext;
}
if( pInode==0 ){
- pInode = sqlite3_malloc64( sizeof(*pInode) );
+ pInode = sqlite3_malloc( sizeof(*pInode) );
if( pInode==0 ){
return SQLITE_NOMEM;
}
@@ -26854,7 +30180,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
lock.l_type = F_WRLCK;
if( osFcntl(pFile->h, F_GETLK, &lock) ){
rc = SQLITE_IOERR_CHECKRESERVEDLOCK;
- storeLastErrno(pFile, errno);
+ pFile->lastErrno = errno;
} else if( lock.l_type!=F_UNLCK ){
reserved = 1;
}
@@ -26987,8 +30313,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
assert( pFile );
OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h,
azFileLock(eFileLock), azFileLock(pFile->eFileLock),
- azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared,
- osGetpid(0)));
+ azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , getpid()));
/* If there is already a lock of this type or more restrictive on the
** unixFile, do nothing. Don't use the end_lock: exit path, as
@@ -27055,7 +30380,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
tErrno = errno;
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
if( rc!=SQLITE_BUSY ){
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
}
goto end_lock;
}
@@ -27090,7 +30415,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
if( rc ){
if( rc!=SQLITE_BUSY ){
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
}
goto end_lock;
}else{
@@ -27123,7 +30448,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
tErrno = errno;
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
if( rc!=SQLITE_BUSY ){
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
}
}
}
@@ -27196,7 +30521,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
assert( pFile );
OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock,
pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
- osGetpid(0)));
+ getpid()));
assert( eFileLock<=SHARED_LOCK );
if( pFile->eFileLock<=eFileLock ){
@@ -27230,6 +30555,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
** 4: [RRRR.]
*/
if( eFileLock==SHARED_LOCK ){
+
#if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE
(void)handleNFSUnlock;
assert( handleNFSUnlock==0 );
@@ -27247,7 +30573,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
tErrno = errno;
rc = SQLITE_IOERR_UNLOCK;
if( IS_LOCK_ERROR(rc) ){
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
}
goto end_unlock;
}
@@ -27259,7 +30585,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
tErrno = errno;
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
if( IS_LOCK_ERROR(rc) ){
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
}
goto end_unlock;
}
@@ -27271,7 +30597,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
tErrno = errno;
rc = SQLITE_IOERR_UNLOCK;
if( IS_LOCK_ERROR(rc) ){
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
}
goto end_unlock;
}
@@ -27290,7 +30616,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
** SQLITE_BUSY would confuse the upper layer (in practice it causes
** an assert to fail). */
rc = SQLITE_IOERR_RDLOCK;
- storeLastErrno(pFile, errno);
+ pFile->lastErrno = errno;
goto end_unlock;
}
}
@@ -27303,7 +30629,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
pInode->eFileLock = SHARED_LOCK;
}else{
rc = SQLITE_IOERR_UNLOCK;
- storeLastErrno(pFile, errno);
+ pFile->lastErrno = errno;
goto end_unlock;
}
}
@@ -27321,7 +30647,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
pInode->eFileLock = NO_LOCK;
}else{
rc = SQLITE_IOERR_UNLOCK;
- storeLastErrno(pFile, errno);
+ pFile->lastErrno = errno;
pInode->eFileLock = NO_LOCK;
pFile->eFileLock = NO_LOCK;
}
@@ -27596,7 +30922,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) {
} else {
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
if( IS_LOCK_ERROR(rc) ){
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
}
}
return rc;
@@ -27623,7 +30949,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
assert( pFile );
OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
- pFile->eFileLock, osGetpid(0)));
+ pFile->eFileLock, getpid()));
assert( eFileLock<=SHARED_LOCK );
/* no-op if possible */
@@ -27650,7 +30976,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
rc = SQLITE_IOERR_UNLOCK;
}
if( IS_LOCK_ERROR(rc) ){
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
}
return rc;
}
@@ -27686,9 +31012,10 @@ static int dotlockClose(sqlite3_file *id) {
** still works when you do this, but concurrency is reduced since
** only a single process can be reading the database at a time.
**
-** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off
+** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if
+** compiling for VXWORKS.
*/
-#if SQLITE_ENABLE_LOCKING_STYLE
+#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
/*
** Retry flock() calls that fail with EINTR
@@ -27736,7 +31063,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
/* unlock failed with an error */
lrc = SQLITE_IOERR_UNLOCK;
if( IS_LOCK_ERROR(lrc) ){
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
rc = lrc;
}
}
@@ -27746,7 +31073,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
/* someone else might have it reserved */
lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
if( IS_LOCK_ERROR(lrc) ){
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
rc = lrc;
}
}
@@ -27812,7 +31139,7 @@ static int flockLock(sqlite3_file *id, int eFileLock) {
/* didn't get, must be busy */
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
if( IS_LOCK_ERROR(rc) ){
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
}
} else {
/* got it, set the type and return ok */
@@ -27841,7 +31168,7 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) {
assert( pFile );
OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock,
- pFile->eFileLock, osGetpid(0)));
+ pFile->eFileLock, getpid()));
assert( eFileLock<=SHARED_LOCK );
/* no-op if possible */
@@ -27902,7 +31229,7 @@ static int flockClose(sqlite3_file *id) {
** to a non-zero value otherwise *pResOut is set to zero. The return value
** is set to SQLITE_OK unless an I/O error occurs during lock checking.
*/
-static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) {
+static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
int rc = SQLITE_OK;
int reserved = 0;
unixFile *pFile = (unixFile*)id;
@@ -27924,7 +31251,7 @@ static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) {
int tErrno = errno;
if( EAGAIN != tErrno ){
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
} else {
/* someone else has the lock when we are in NO_LOCK */
reserved = (pFile->eFileLock < SHARED_LOCK);
@@ -27969,7 +31296,7 @@ static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) {
** This routine will only increase a lock. Use the sqlite3OsUnlock()
** routine to lower a locking level.
*/
-static int semXLock(sqlite3_file *id, int eFileLock) {
+static int semLock(sqlite3_file *id, int eFileLock) {
unixFile *pFile = (unixFile*)id;
sem_t *pSem = pFile->pInode->pSem;
int rc = SQLITE_OK;
@@ -28002,14 +31329,14 @@ static int semXLock(sqlite3_file *id, int eFileLock) {
** If the locking level of the file descriptor is already at or below
** the requested locking level, this routine is a no-op.
*/
-static int semXUnlock(sqlite3_file *id, int eFileLock) {
+static int semUnlock(sqlite3_file *id, int eFileLock) {
unixFile *pFile = (unixFile*)id;
sem_t *pSem = pFile->pInode->pSem;
assert( pFile );
assert( pSem );
OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock,
- pFile->eFileLock, osGetpid(0)));
+ pFile->eFileLock, getpid()));
assert( eFileLock<=SHARED_LOCK );
/* no-op if possible */
@@ -28028,7 +31355,7 @@ static int semXUnlock(sqlite3_file *id, int eFileLock) {
int rc, tErrno = errno;
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
if( IS_LOCK_ERROR(rc) ){
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
}
return rc;
}
@@ -28039,10 +31366,10 @@ static int semXUnlock(sqlite3_file *id, int eFileLock) {
/*
** Close a file.
*/
-static int semXClose(sqlite3_file *id) {
+static int semClose(sqlite3_file *id) {
if( id ){
unixFile *pFile = (unixFile*)id;
- semXUnlock(id, NO_LOCK);
+ semUnlock(id, NO_LOCK);
assert( pFile );
unixEnterMutex();
releaseInodeInfo(pFile);
@@ -28130,7 +31457,7 @@ static int afpSetLock(
setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK);
#endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */
if( IS_LOCK_ERROR(rc) ){
- storeLastErrno(pFile, tErrno);
+ pFile->lastErrno = tErrno;
}
return rc;
} else {
@@ -28223,7 +31550,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){
assert( pFile );
OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h,
azFileLock(eFileLock), azFileLock(pFile->eFileLock),
- azFileLock(pInode->eFileLock), pInode->nShared , osGetpid(0)));
+ azFileLock(pInode->eFileLock), pInode->nShared , getpid()));
/* If there is already a lock of this type or more restrictive on the
** unixFile, do nothing. Don't use the afp_end_lock: exit path, as
@@ -28313,7 +31640,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){
lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
if( IS_LOCK_ERROR(lrc1) ) {
- storeLastErrno(pFile, lrc1Errno);
+ pFile->lastErrno = lrc1Errno;
rc = lrc1;
goto afp_end_lock;
} else if( IS_LOCK_ERROR(lrc2) ){
@@ -28409,7 +31736,7 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
assert( pFile );
OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock,
pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
- osGetpid(0)));
+ getpid()));
assert( eFileLock<=SHARED_LOCK );
if( pFile->eFileLock<=eFileLock ){
@@ -28600,9 +31927,9 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
SimulateIOError( newOffset-- );
if( newOffset!=offset ){
if( newOffset == -1 ){
- storeLastErrno((unixFile*)id, errno);
+ ((unixFile*)id)->lastErrno = errno;
}else{
- storeLastErrno((unixFile*)id, 0);
+ ((unixFile*)id)->lastErrno = 0;
}
return -1;
}
@@ -28612,7 +31939,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
if( got<0 ){
if( errno==EINTR ){ got = 1; continue; }
prior = 0;
- storeLastErrno((unixFile*)id, errno);
+ ((unixFile*)id)->lastErrno = errno;
break;
}else if( got>0 ){
cnt -= got;
@@ -28677,7 +32004,7 @@ static int unixRead(
/* lastErrno set by seekAndRead */
return SQLITE_IOERR_READ;
}else{
- storeLastErrno(pFile, 0); /* not a system error */
+ pFile->lastErrno = 0; /* not a system error */
/* Unread parts of the buffer must be zero-filled */
memset(&((char*)pBuf)[got], 0, amt-got);
return SQLITE_IOERR_SHORT_READ;
@@ -28706,9 +32033,9 @@ static int seekAndWriteFd(
TIMER_START;
#if defined(USE_PREAD)
- do{ rc = (int)osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
+ do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
#elif defined(USE_PREAD64)
- do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
+ do{ rc = osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
#else
do{
i64 iSeek = lseek(fd, iOff, SEEK_SET);
@@ -28818,7 +32145,7 @@ static int unixWrite(
/* lastErrno set by seekAndWrite */
return SQLITE_IOERR_WRITE;
}else{
- storeLastErrno(pFile, 0); /* not a system error */
+ pFile->lastErrno = 0; /* not a system error */
return SQLITE_FULL;
}
}
@@ -29027,7 +32354,7 @@ static int unixSync(sqlite3_file *id, int flags){
rc = full_fsync(pFile->h, isFullsync, isDataOnly);
SimulateIOError( rc=1 );
if( rc ){
- storeLastErrno(pFile, errno);
+ pFile->lastErrno = errno;
return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
}
@@ -29071,7 +32398,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
rc = robust_ftruncate(pFile->h, nByte);
if( rc ){
- storeLastErrno(pFile, errno);
+ pFile->lastErrno = errno;
return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
}else{
#ifdef SQLITE_DEBUG
@@ -29111,7 +32438,7 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){
rc = osFstat(((unixFile*)id)->h, &buf);
SimulateIOError( rc=1 );
if( rc!=0 ){
- storeLastErrno((unixFile*)id, errno);
+ ((unixFile*)id)->lastErrno = errno;
return SQLITE_IOERR_FSTAT;
}
*pSize = buf.st_size;
@@ -29147,9 +32474,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
i64 nSize; /* Required file size */
struct stat buf; /* Used to hold return values of fstat() */
- if( osFstat(pFile->h, &buf) ){
- return SQLITE_IOERR_FSTAT;
- }
+ if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
if( nSize>(i64)buf.st_size ){
@@ -29196,7 +32521,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
int rc;
if( pFile->szChunk<=0 ){
if( robust_ftruncate(pFile->h, nByte) ){
- storeLastErrno(pFile, errno);
+ pFile->lastErrno = errno;
return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
}
}
@@ -29234,15 +32559,11 @@ static int unixGetTempname(int nBuf, char *zBuf);
static int unixFileControl(sqlite3_file *id, int op, void *pArg){
unixFile *pFile = (unixFile*)id;
switch( op ){
- case SQLITE_FCNTL_WAL_BLOCK: {
- /* pFile->ctrlFlags |= UNIXFILE_BLOCK; // Deferred feature */
- return SQLITE_OK;
- }
case SQLITE_FCNTL_LOCKSTATE: {
*(int*)pArg = pFile->eFileLock;
return SQLITE_OK;
}
- case SQLITE_FCNTL_LAST_ERRNO: {
+ case SQLITE_LAST_ERRNO: {
*(int*)pArg = pFile->lastErrno;
return SQLITE_OK;
}
@@ -29270,7 +32591,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
return SQLITE_OK;
}
case SQLITE_FCNTL_TEMPFILENAME: {
- char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname );
+ char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
if( zTFile ){
unixGetTempname(pFile->pVfs->mxPathname, zTFile);
*(char**)pArg = zTFile;
@@ -29311,8 +32632,8 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
#endif
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
- case SQLITE_FCNTL_SET_LOCKPROXYFILE:
- case SQLITE_FCNTL_GET_LOCKPROXYFILE: {
+ case SQLITE_SET_LOCKPROXYFILE:
+ case SQLITE_GET_LOCKPROXYFILE: {
return proxyFileControl(id,op,pArg);
}
#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
@@ -29452,9 +32773,7 @@ static int unixDeviceCharacteristics(sqlite3_file *id){
** Instead, it should be called via macro osGetpagesize().
*/
static int unixGetpagesize(void){
-#if OS_VXWORKS
- return 1024;
-#elif defined(_BSD_SOURCE)
+#if defined(_BSD_SOURCE)
return getpagesize();
#else
return (int)sysconf(_SC_PAGESIZE);
@@ -29547,17 +32866,15 @@ struct unixShm {
** otherwise.
*/
static int unixShmSystemLock(
- unixFile *pFile, /* Open connection to the WAL file */
+ unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */
int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */
int ofst, /* First byte of the locking range */
int n /* Number of bytes to lock */
){
- unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */
- struct flock f; /* The posix advisory locking structure */
- int rc = SQLITE_OK; /* Result code form fcntl() */
+ struct flock f; /* The posix advisory locking structure */
+ int rc = SQLITE_OK; /* Result code form fcntl() */
/* Access to the unixShmNode object is serialized by the caller */
- pShmNode = pFile->pInode->pShmNode;
assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 );
/* Shared locks never span more than one byte */
@@ -29567,7 +32884,6 @@ static int unixShmSystemLock(
assert( n>=1 && n<SQLITE_SHM_NLOCK );
if( pShmNode->h>=0 ){
- int lkType;
/* Initialize the locking parameters */
memset(&f, 0, sizeof(f));
f.l_type = lockType;
@@ -29575,10 +32891,8 @@ static int unixShmSystemLock(
f.l_start = ofst;
f.l_len = n;
- lkType = (pFile->ctrlFlags & UNIXFILE_BLOCK)!=0 ? F_SETLKW : F_SETLK;
- rc = osFcntl(pShmNode->h, lkType, &f);
+ rc = osFcntl(pShmNode->h, F_SETLK, &f);
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
- pFile->ctrlFlags &= ~UNIXFILE_BLOCK;
}
/* Update the global lock state and do debug tracing */
@@ -29711,7 +33025,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
int nShmFilename; /* Size of the SHM filename in bytes */
/* Allocate space for the new unixShm object. */
- p = sqlite3_malloc64( sizeof(*p) );
+ p = sqlite3_malloc( sizeof(*p) );
if( p==0 ) return SQLITE_NOMEM;
memset(p, 0, sizeof(*p));
assert( pDbFd->pShm==0 );
@@ -29724,9 +33038,6 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
pShmNode = pInode->pShmNode;
if( pShmNode==0 ){
struct stat sStat; /* fstat() info for database file */
-#ifndef SQLITE_SHM_DIRECTORY
- const char *zBasePath = pDbFd->zPath;
-#endif
/* Call fstat() to figure out the permissions on the database file. If
** a new *-shm file is created, an attempt will be made to create it
@@ -29740,9 +33051,9 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
#ifdef SQLITE_SHM_DIRECTORY
nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
#else
- nShmFilename = 6 + (int)strlen(zBasePath);
+ nShmFilename = 6 + (int)strlen(pDbFd->zPath);
#endif
- pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename );
+ pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
if( pShmNode==0 ){
rc = SQLITE_NOMEM;
goto shm_open_err;
@@ -29754,7 +33065,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
(u32)sStat.st_ino, (u32)sStat.st_dev);
#else
- sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath);
+ sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath);
sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
#endif
pShmNode->h = -1;
@@ -29788,13 +33099,13 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
** If not, truncate the file to zero length.
*/
rc = SQLITE_OK;
- if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
+ if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
if( robust_ftruncate(pShmNode->h, 0) ){
rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
}
}
if( rc==SQLITE_OK ){
- rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
+ rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1);
}
if( rc ) goto shm_open_err;
}
@@ -29952,7 +33263,7 @@ static int unixShmMap(
goto shmpage_out;
}
}else{
- pMem = sqlite3_malloc64(szRegion);
+ pMem = sqlite3_malloc(szRegion);
if( pMem==0 ){
rc = SQLITE_NOMEM;
goto shmpage_out;
@@ -30026,7 +33337,7 @@ static int unixShmLock(
/* Unlock the system-level locks */
if( (mask & allMask)==0 ){
- rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
+ rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n);
}else{
rc = SQLITE_OK;
}
@@ -30054,7 +33365,7 @@ static int unixShmLock(
/* Get shared locks at the system level, if necessary */
if( rc==SQLITE_OK ){
if( (allShared & mask)==0 ){
- rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
+ rc = unixShmSystemLock(pShmNode, F_RDLCK, ofst+UNIX_SHM_BASE, n);
}else{
rc = SQLITE_OK;
}
@@ -30079,7 +33390,7 @@ static int unixShmLock(
** also mark the local connection as being locked.
*/
if( rc==SQLITE_OK ){
- rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
+ rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n);
if( rc==SQLITE_OK ){
assert( (p->sharedMask & mask)==0 );
p->exclMask |= mask;
@@ -30088,7 +33399,7 @@ static int unixShmLock(
}
sqlite3_mutex_leave(pShmNode->mutex);
OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
- p->id, osGetpid(0), p->sharedMask, p->exclMask));
+ p->id, getpid(), p->sharedMask, p->exclMask));
return rc;
}
@@ -30147,9 +33458,7 @@ static int unixShmUnmap(
assert( pShmNode->nRef>0 );
pShmNode->nRef--;
if( pShmNode->nRef==0 ){
- if( deleteFlag && pShmNode->h>=0 ){
- osUnlink(pShmNode->zFilename);
- }
+ if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename);
unixShmPurge(pDbFd);
}
unixLeaveMutex();
@@ -30426,7 +33735,7 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
** * An I/O method finder function called FINDER that returns a pointer
** to the METHOD object in the previous bullet.
*/
-#define IOMETHODS(FINDER,METHOD,VERSION,CLOSE,LOCK,UNLOCK,CKLOCK,SHMMAP) \
+#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK, SHMMAP) \
static const sqlite3_io_methods METHOD = { \
VERSION, /* iVersion */ \
CLOSE, /* xClose */ \
@@ -30491,7 +33800,7 @@ IOMETHODS(
0 /* xShmMap method */
)
-#if SQLITE_ENABLE_LOCKING_STYLE
+#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
IOMETHODS(
flockIoFinder, /* Finder function name */
flockIoMethods, /* sqlite3_io_methods object name */
@@ -30509,10 +33818,10 @@ IOMETHODS(
semIoFinder, /* Finder function name */
semIoMethods, /* sqlite3_io_methods object name */
1, /* shared memory is disabled */
- semXClose, /* xClose method */
- semXLock, /* xLock method */
- semXUnlock, /* xUnlock method */
- semXCheckReservedLock, /* xCheckReservedLock method */
+ semClose, /* xClose method */
+ semLock, /* xLock method */
+ semUnlock, /* xUnlock method */
+ semCheckReservedLock, /* xCheckReservedLock method */
0 /* xShmMap method */
)
#endif
@@ -30636,13 +33945,15 @@ static const sqlite3_io_methods
#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
-#if OS_VXWORKS
-/*
-** This "finder" function for VxWorks checks to see if posix advisory
-** locking works. If it does, then that is what is used. If it does not
-** work, then fallback to named semaphore locking.
+#if OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE
+/*
+** This "finder" function attempts to determine the best locking strategy
+** for the database file "filePath". It then returns the sqlite3_io_methods
+** object that implements that strategy.
+**
+** This is for VXWorks only.
*/
-static const sqlite3_io_methods *vxworksIoFinderImpl(
+static const sqlite3_io_methods *autolockIoFinderImpl(
const char *filePath, /* name of the database file */
unixFile *pNew /* the open file object */
){
@@ -30668,9 +33979,9 @@ static const sqlite3_io_methods *vxworksIoFinderImpl(
}
}
static const sqlite3_io_methods
- *(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl;
+ *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
-#endif /* OS_VXWORKS */
+#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */
/*
** An abstract type for a pointer to an IO method finder function:
@@ -30789,7 +34100,7 @@ static int fillInUnixFile(
** the afpLockingContext.
*/
afpLockingContext *pCtx;
- pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) );
+ pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
if( pCtx==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -30819,7 +34130,7 @@ static int fillInUnixFile(
int nFilename;
assert( zFilename!=0 );
nFilename = (int)strlen(zFilename) + 6;
- zLockFile = (char *)sqlite3_malloc64(nFilename);
+ zLockFile = (char *)sqlite3_malloc(nFilename);
if( zLockFile==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -30852,7 +34163,7 @@ static int fillInUnixFile(
}
#endif
- storeLastErrno(pNew, 0);
+ pNew->lastErrno = 0;
#if OS_VXWORKS
if( rc!=SQLITE_OK ){
if( h>=0 ) robust_close(pNew, h, __LINE__);
@@ -31183,8 +34494,8 @@ static int unixOpen(
** the same instant might all reset the PRNG. But multiple resets
** are harmless.
*/
- if( randomnessPid!=osGetpid(0) ){
- randomnessPid = osGetpid(0);
+ if( randomnessPid!=getpid() ){
+ randomnessPid = getpid();
sqlite3_randomness(0,0);
}
@@ -31196,7 +34507,7 @@ static int unixOpen(
if( pUnused ){
fd = pUnused->fd;
}else{
- pUnused = sqlite3_malloc64(sizeof(*pUnused));
+ pUnused = sqlite3_malloc(sizeof(*pUnused));
if( !pUnused ){
return SQLITE_NOMEM;
}
@@ -31300,16 +34611,13 @@ static int unixOpen(
#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
if( fstatfs(fd, &fsInfo) == -1 ){
- storeLastErrno(p, errno);
+ ((unixFile*)pFile)->lastErrno = errno;
robust_close(p, fd, __LINE__);
return SQLITE_IOERR_ACCESS;
}
if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
}
- if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) {
- ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
- }
#endif
/* Set up appropriate ctrlFlags */
@@ -31332,6 +34640,19 @@ static int unixOpen(
if( envforce!=NULL ){
useProxy = atoi(envforce)>0;
}else{
+ if( statfs(zPath, &fsInfo) == -1 ){
+ /* In theory, the close(fd) call is sub-optimal. If the file opened
+ ** with fd is a database file, and there are other connections open
+ ** on that file that are currently holding advisory locks on it,
+ ** then the call to close() will cancel those locks. In practice,
+ ** we're assuming that statfs() doesn't fail very often. At least
+ ** not while other file descriptors opened by the same process on
+ ** the same file are working. */
+ p->lastErrno = errno;
+ robust_close(p, fd, __LINE__);
+ rc = SQLITE_IOERR_ACCESS;
+ goto open_finished;
+ }
useProxy = !(fsInfo.f_flags&MNT_LOCAL);
}
if( useProxy ){
@@ -31575,8 +34896,8 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
** tests repeatable.
*/
memset(zBuf, 0, nBuf);
- randomnessPid = osGetpid(0);
-#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
+ randomnessPid = getpid();
+#if !defined(SQLITE_TEST)
{
int fd, got;
fd = robust_open("/dev/urandom", O_RDONLY, 0);
@@ -31757,10 +35078,9 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
**
** C APIs
**
-** sqlite3_file_control(db, dbname, SQLITE_FCNTL_SET_LOCKPROXYFILE,
+** sqlite3_file_control(db, dbname, SQLITE_SET_LOCKPROXYFILE,
** <proxy_path> | ":auto:");
-** sqlite3_file_control(db, dbname, SQLITE_FCNTL_GET_LOCKPROXYFILE,
-** &<proxy_path>);
+** sqlite3_file_control(db, dbname, SQLITE_GET_LOCKPROXYFILE, &<proxy_path>);
**
**
** SQL pragmas
@@ -31853,7 +35173,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will
** force proxy locking to be used for every database file opened, and 0
** will force automatic proxy locking to be disabled for all database
-** files (explicitly calling the SQLITE_FCNTL_SET_LOCKPROXYFILE pragma or
+** files (explicitly calling the SQLITE_SET_LOCKPROXYFILE pragma or
** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING).
*/
@@ -31874,7 +35194,6 @@ struct proxyLockingContext {
char *lockProxyPath; /* Name of the proxy lock file */
char *dbPath; /* Name of the open file */
int conchHeld; /* 1 if the conch is held, -1 if lockless */
- int nFails; /* Number of conch taking failures */
void *oldLockingContext; /* Original lockingcontext to restore on close */
sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */
};
@@ -31896,7 +35215,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
{
if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){
OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n",
- lPath, errno, osGetpid(0)));
+ lPath, errno, getpid()));
return SQLITE_IOERR_LOCK;
}
len = strlcat(lPath, "sqliteplocks", maxLen);
@@ -31918,7 +35237,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
}
lPath[i+len]='\0';
strlcat(lPath, ":auto:", maxLen);
- OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, osGetpid(0)));
+ OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, getpid()));
return SQLITE_OK;
}
@@ -31945,7 +35264,7 @@ static int proxyCreateLockPath(const char *lockPath){
if( err!=EEXIST ) {
OSTRACE(("CREATELOCKPATH FAILED creating %s, "
"'%s' proxy lock path=%s pid=%d\n",
- buf, strerror(err), lockPath, osGetpid(0)));
+ buf, strerror(err), lockPath, getpid()));
return err;
}
}
@@ -31954,7 +35273,7 @@ static int proxyCreateLockPath(const char *lockPath){
}
buf[i] = lockPath[i];
}
- OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, osGetpid(0)));
+ OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, getpid()));
return 0;
}
@@ -31988,7 +35307,7 @@ static int proxyCreateUnixFile(
if( pUnused ){
fd = pUnused->fd;
}else{
- pUnused = sqlite3_malloc64(sizeof(*pUnused));
+ pUnused = sqlite3_malloc(sizeof(*pUnused));
if( !pUnused ){
return SQLITE_NOMEM;
}
@@ -32021,7 +35340,7 @@ static int proxyCreateUnixFile(
}
}
- pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew));
+ pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew));
if( pNew==NULL ){
rc = SQLITE_NOMEM;
goto end_create_proxy;
@@ -32054,10 +35373,8 @@ SQLITE_API int sqlite3_hostid_num = 0;
#define PROXY_HOSTIDLEN 16 /* conch file host id length */
-#ifdef HAVE_GETHOSTUUID
/* Not always defined in the headers as it ought to be */
extern int gethostuuid(uuid_t id, const struct timespec *wait);
-#endif
/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN
** bytes of writable memory.
@@ -32065,9 +35382,10 @@ extern int gethostuuid(uuid_t id, const struct timespec *wait);
static int proxyGetHostID(unsigned char *pHostID, int *pError){
assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
memset(pHostID, 0, PROXY_HOSTIDLEN);
-#ifdef HAVE_GETHOSTUUID
+#if defined(__MAX_OS_X_VERSION_MIN_REQUIRED)\
+ && __MAC_OS_X_VERSION_MIN_REQUIRED<1050
{
- struct timespec timeout = {1, 0}; /* 1 sec timeout */
+ static const struct timespec timeout = {1, 0}; /* 1 sec timeout */
if( gethostuuid(pHostID, &timeout) ){
int err = errno;
if( pError ){
@@ -32182,7 +35500,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
*/
struct stat buf;
if( osFstat(conchFile->h, &buf) ){
- storeLastErrno(pFile, errno);
+ pFile->lastErrno = errno;
return SQLITE_IOERR_LOCK;
}
@@ -32202,7 +35520,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
char tBuf[PROXY_MAXCONCHLEN];
int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0);
if( len<0 ){
- storeLastErrno(pFile, errno);
+ pFile->lastErrno = errno;
return SQLITE_IOERR_LOCK;
}
if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){
@@ -32222,7 +35540,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
if( 0==proxyBreakConchLock(pFile, myHostID) ){
rc = SQLITE_OK;
if( lockType==EXCLUSIVE_LOCK ){
- rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);
+ rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);
}
if( !rc ){
rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType);
@@ -32260,12 +35578,11 @@ static int proxyTakeConch(unixFile *pFile){
int forceNewLockPath = 0;
OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h,
- (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"),
- osGetpid(0)));
+ (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid()));
rc = proxyGetHostID(myHostID, &pError);
if( (rc&0xff)==SQLITE_IOERR ){
- storeLastErrno(pFile, pError);
+ pFile->lastErrno = pError;
goto end_takeconch;
}
rc = proxyConchLock(pFile, myHostID, SHARED_LOCK);
@@ -32276,7 +35593,7 @@ static int proxyTakeConch(unixFile *pFile){
readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN);
if( readLen<0 ){
/* I/O error: lastErrno set by seekAndRead */
- storeLastErrno(pFile, conchFile->lastErrno);
+ pFile->lastErrno = conchFile->lastErrno;
rc = SQLITE_IOERR_READ;
goto end_takeconch;
}else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) ||
@@ -32349,7 +35666,7 @@ static int proxyTakeConch(unixFile *pFile){
rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
}
}else{
- rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
+ rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK);
}
if( rc==SQLITE_OK ){
char writeBuffer[PROXY_MAXCONCHLEN];
@@ -32358,8 +35675,7 @@ static int proxyTakeConch(unixFile *pFile){
writeBuffer[0] = (char)PROXY_CONCHVERSION;
memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN);
if( pCtx->lockProxyPath!=NULL ){
- strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath,
- MAXPATHLEN);
+ strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAXPATHLEN);
}else{
strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN);
}
@@ -32471,7 +35787,7 @@ static int proxyReleaseConch(unixFile *pFile){
conchFile = pCtx->conchFile;
OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h,
(pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"),
- osGetpid(0)));
+ getpid()));
if( pCtx->conchHeld>0 ){
rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
}
@@ -32483,7 +35799,7 @@ static int proxyReleaseConch(unixFile *pFile){
/*
** Given the name of a database file, compute the name of its conch file.
-** Store the conch filename in memory obtained from sqlite3_malloc64().
+** Store the conch filename in memory obtained from sqlite3_malloc().
** Make *pConchPath point to the new name. Return SQLITE_OK on success
** or SQLITE_NOMEM if unable to obtain memory.
**
@@ -32499,7 +35815,7 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
/* Allocate space for the conch filename and initialize the name to
** the name of the original database file. */
- *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8);
+ *pConchPath = conchPath = (char *)sqlite3_malloc(len + 8);
if( conchPath==0 ){
return SQLITE_NOMEM;
}
@@ -32571,8 +35887,7 @@ static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){
/* afp style keeps a reference to the db path in the filePath field
** of the struct */
assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
- strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath,
- MAXPATHLEN);
+ strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, MAXPATHLEN);
} else
#endif
if( pFile->pMethod == &dotlockIoMethods ){
@@ -32613,9 +35928,9 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
}
OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h,
- (lockPath ? lockPath : ":auto:"), osGetpid(0)));
+ (lockPath ? lockPath : ":auto:"), getpid()));
- pCtx = sqlite3_malloc64( sizeof(*pCtx) );
+ pCtx = sqlite3_malloc( sizeof(*pCtx) );
if( pCtx==0 ){
return SQLITE_NOMEM;
}
@@ -32685,7 +36000,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
*/
static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
switch( op ){
- case SQLITE_FCNTL_GET_LOCKPROXYFILE: {
+ case SQLITE_GET_LOCKPROXYFILE: {
unixFile *pFile = (unixFile*)id;
if( pFile->pMethod == &proxyIoMethods ){
proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
@@ -32700,16 +36015,13 @@ static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
}
return SQLITE_OK;
}
- case SQLITE_FCNTL_SET_LOCKPROXYFILE: {
+ case SQLITE_SET_LOCKPROXYFILE: {
unixFile *pFile = (unixFile*)id;
int rc = SQLITE_OK;
int isProxyStyle = (pFile->pMethod == &proxyIoMethods);
if( pArg==NULL || (const char *)pArg==0 ){
if( isProxyStyle ){
- /* turn off proxy locking - not supported. If support is added for
- ** switching proxy locking mode off then it will need to fail if
- ** the journal mode is WAL mode.
- */
+ /* turn off proxy locking - not supported */
rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
}else{
/* turn off proxy locking - already off - NOOP */
@@ -32900,7 +36212,7 @@ static int proxyClose(sqlite3_file *id) {
** necessarily been initialized when this routine is called, and so they
** should not be used.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
+SQLITE_API int sqlite3_os_init(void){
/*
** The following macro defines an initializer for an sqlite3_vfs object.
** The name of the VFS is NAME. The pAppData is a pointer to a pointer
@@ -32954,10 +36266,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
** array cannot be const.
*/
static sqlite3_vfs aVfs[] = {
-#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
+#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__))
UNIXVFS("unix", autolockIoFinder ),
-#elif OS_VXWORKS
- UNIXVFS("unix", vxworksIoFinder ),
#else
UNIXVFS("unix", posixIoFinder ),
#endif
@@ -32967,12 +36277,12 @@ SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
#if OS_VXWORKS
UNIXVFS("unix-namedsem", semIoFinder ),
#endif
-#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS
- UNIXVFS("unix-posix", posixIoFinder ),
-#endif
#if SQLITE_ENABLE_LOCKING_STYLE
+ UNIXVFS("unix-posix", posixIoFinder ),
+#if !OS_VXWORKS
UNIXVFS("unix-flock", flockIoFinder ),
#endif
+#endif
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
UNIXVFS("unix-afp", afpIoFinder ),
UNIXVFS("unix-nfs", nfsIoFinder ),
@@ -32999,7 +36309,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
** to release dynamically allocated objects. But not on unix.
** This routine is a no-op for unix.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
+SQLITE_API int sqlite3_os_end(void){
return SQLITE_OK;
}
@@ -33059,6 +36369,16 @@ SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
#endif
+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+# ifndef SQLITE_DEBUG_OS_TRACE
+# define SQLITE_DEBUG_OS_TRACE 0
+# endif
+ int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
+# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X
+#else
+# define OSTRACE(X)
+#endif
+
/*
** Macros for performance tracing. Normally turned off. Only works
** on i486 hardware.
@@ -33402,10 +36722,8 @@ WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#endif /* SQLITE_OS_WINRT */
/*
-** These file mapping APIs are common to both Win32 and WinRT.
+** This file mapping API is common to both Win32 and WinRT.
*/
-
-WINBASEAPI BOOL WINAPI FlushViewOfFile(LPCVOID, SIZE_T);
WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
#endif /* SQLITE_WIN32_FILEMAPPING_API */
@@ -34273,32 +37591,6 @@ static struct win_syscall {
SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent)
#endif /* defined(InterlockedCompareExchange) */
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
- { "UuidCreate", (SYSCALL)UuidCreate, 0 },
-#else
- { "UuidCreate", (SYSCALL)0, 0 },
-#endif
-
-#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent)
-
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
- { "UuidCreateSequential", (SYSCALL)UuidCreateSequential, 0 },
-#else
- { "UuidCreateSequential", (SYSCALL)0, 0 },
-#endif
-
-#define osUuidCreateSequential \
- ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent)
-
-#if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0
- { "FlushViewOfFile", (SYSCALL)FlushViewOfFile, 0 },
-#else
- { "FlushViewOfFile", (SYSCALL)0, 0 },
-#endif
-
-#define osFlushViewOfFile \
- ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent)
-
}; /* End of the overrideable system calls */
/*
@@ -34392,7 +37684,7 @@ static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
** "pnLargest" argument, if non-zero, will be used to return the size of the
** largest committed free block in the heap, in bytes.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){
+SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){
int rc = SQLITE_OK;
UINT nLargest = 0;
HANDLE hHeap;
@@ -34432,7 +37724,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){
** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
** be returned and no changes will be made to the Win32 native heap.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){
+SQLITE_API int sqlite3_win32_reset_heap(){
int rc;
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
@@ -34477,7 +37769,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){
** (if available).
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const char *zBuf, int nBuf){
+SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
@@ -34517,7 +37809,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const char *zBuf, int n
static HANDLE sleepObj = NULL;
#endif
-SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds){
+SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
#if SQLITE_OS_WINRT
if ( sleepObj==NULL ){
sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
@@ -34566,7 +37858,7 @@ SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
** This function determines if the machine is running a version of Windows
** based on the NT kernel.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void){
+SQLITE_API int sqlite3_win32_is_nt(void){
#if SQLITE_OS_WINRT
/*
** NOTE: The WinRT sub-platform is always assumed to be based on the NT
@@ -34920,7 +38212,7 @@ static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
** Convert multibyte character string to UTF-8. Space to hold the
** returned string is obtained from sqlite3_malloc().
*/
-SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zFilename){
+SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
char *zFilenameUtf8;
LPWSTR zTmpWide;
@@ -34937,7 +38229,7 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zFilename
** Convert UTF-8 to multibyte character string. Space to hold the
** returned string is obtained from sqlite3_malloc().
*/
-SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zFilename){
+SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
char *zFilenameMbcs;
LPWSTR zTmpWide;
@@ -34957,7 +38249,7 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zFilename
** argument is the name of the directory to use. The return value will be
** SQLITE_OK if successful.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
+SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
char **ppDirectory = 0;
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
@@ -35182,11 +38474,11 @@ static int winRetryIoerr(int *pnRetry, DWORD *pError){
/*
** Log a I/O error retry episode.
*/
-static void winLogIoerr(int nRetry, int lineno){
+static void winLogIoerr(int nRetry){
if( nRetry ){
- sqlite3_log(SQLITE_NOTICE,
- "delayed %dms for lock/sharing conflict at line %d",
- winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno
+ sqlite3_log(SQLITE_IOERR,
+ "delayed %dms for lock/sharing conflict",
+ winIoerrRetryDelay*nRetry*(nRetry+1)/2
);
}
}
@@ -35666,8 +38958,7 @@ static int winClose(sqlite3_file *id){
assert( pFile->pShm==0 );
#endif
assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
- OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n",
- osGetCurrentProcessId(), pFile, pFile->h));
+ OSTRACE(("CLOSE file=%p\n", pFile->h));
#if SQLITE_MAX_MMAP_SIZE>0
winUnmapfile(pFile);
@@ -35696,8 +38987,7 @@ static int winClose(sqlite3_file *id){
pFile->h = NULL;
}
OpenCounter(-1);
- OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n",
- osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed"));
+ OSTRACE(("CLOSE file=%p, rc=%s\n", pFile->h, rc ? "ok" : "failed"));
return rc ? SQLITE_OK
: winLogError(SQLITE_IOERR_CLOSE, osGetLastError(),
"winClose", pFile->zPath);
@@ -35725,8 +39015,7 @@ static int winRead(
assert( amt>0 );
assert( offset>=0 );
SimulateIOError(return SQLITE_IOERR_READ);
- OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
- "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
+ OSTRACE(("READ file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n",
pFile->h, pBuf, amt, offset, pFile->locktype));
#if SQLITE_MAX_MMAP_SIZE>0
@@ -35735,8 +39024,7 @@ static int winRead(
if( offset<pFile->mmapSize ){
if( offset+amt <= pFile->mmapSize ){
memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
- OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
- osGetCurrentProcessId(), pFile, pFile->h));
+ OSTRACE(("READ-MMAP file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}else{
int nCopy = (int)(pFile->mmapSize - offset);
@@ -35750,8 +39038,7 @@ static int winRead(
#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
if( winSeekFile(pFile, offset) ){
- OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
- osGetCurrentProcessId(), pFile, pFile->h));
+ OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h));
return SQLITE_FULL;
}
while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
@@ -35765,22 +39052,19 @@ static int winRead(
DWORD lastErrno;
if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
pFile->lastErrno = lastErrno;
- OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n",
- osGetCurrentProcessId(), pFile, pFile->h));
+ OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h));
return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
"winRead", pFile->zPath);
}
- winLogIoerr(nRetry, __LINE__);
+ winLogIoerr(nRetry);
if( nRead<(DWORD)amt ){
/* Unread parts of the buffer must be zero-filled */
memset(&((char*)pBuf)[nRead], 0, amt-nRead);
- OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n",
- osGetCurrentProcessId(), pFile, pFile->h));
+ OSTRACE(("READ file=%p, rc=SQLITE_IOERR_SHORT_READ\n", pFile->h));
return SQLITE_IOERR_SHORT_READ;
}
- OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
- osGetCurrentProcessId(), pFile, pFile->h));
+ OSTRACE(("READ file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
@@ -35803,8 +39087,7 @@ static int winWrite(
SimulateIOError(return SQLITE_IOERR_WRITE);
SimulateDiskfullError(return SQLITE_FULL);
- OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
- "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
+ OSTRACE(("WRITE file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n",
pFile->h, pBuf, amt, offset, pFile->locktype));
#if SQLITE_MAX_MMAP_SIZE>0
@@ -35813,8 +39096,7 @@ static int winWrite(
if( offset<pFile->mmapSize ){
if( offset+amt <= pFile->mmapSize ){
memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
- OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
- osGetCurrentProcessId(), pFile, pFile->h));
+ OSTRACE(("WRITE-MMAP file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}else{
int nCopy = (int)(pFile->mmapSize - offset);
@@ -35877,20 +39159,17 @@ static int winWrite(
if( rc ){
if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
|| ( pFile->lastErrno==ERROR_DISK_FULL )){
- OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
- osGetCurrentProcessId(), pFile, pFile->h));
+ OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h));
return winLogError(SQLITE_FULL, pFile->lastErrno,
"winWrite1", pFile->zPath);
}
- OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n",
- osGetCurrentProcessId(), pFile, pFile->h));
+ OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h));
return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
"winWrite2", pFile->zPath);
}else{
- winLogIoerr(nRetry, __LINE__);
+ winLogIoerr(nRetry);
}
- OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
- osGetCurrentProcessId(), pFile, pFile->h));
+ OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
@@ -35904,8 +39183,8 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
assert( pFile );
SimulateIOError(return SQLITE_IOERR_TRUNCATE);
- OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n",
- osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype));
+ OSTRACE(("TRUNCATE file=%p, size=%lld, lock=%d\n",
+ pFile->h, nByte, pFile->locktype));
/* If the user has configured a chunk-size for this file, truncate the
** file so that it consists of an integer number of chunks (i.e. the
@@ -35937,8 +39216,7 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
}
#endif
- OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n",
- osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc)));
+ OSTRACE(("TRUNCATE file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
return rc;
}
@@ -35962,7 +39240,7 @@ static int winSync(sqlite3_file *id, int flags){
BOOL rc;
#endif
#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
- defined(SQLITE_HAVE_OS_TRACE)
+ (defined(SQLITE_TEST) && defined(SQLITE_DEBUG))
/*
** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or
** OSTRACE() macros.
@@ -35983,9 +39261,8 @@ static int winSync(sqlite3_file *id, int flags){
*/
SimulateDiskfullError( return SQLITE_FULL );
- OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n",
- osGetCurrentProcessId(), pFile, pFile->h, flags,
- pFile->locktype));
+ OSTRACE(("SYNC file=%p, flags=%x, lock=%d\n",
+ pFile->h, flags, pFile->locktype));
#ifndef SQLITE_TEST
UNUSED_PARAMETER(flags);
@@ -36000,38 +39277,19 @@ static int winSync(sqlite3_file *id, int flags){
** no-op
*/
#ifdef SQLITE_NO_SYNC
- OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
- osGetCurrentProcessId(), pFile, pFile->h));
+ OSTRACE(("SYNC-NOP file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
#else
-#if SQLITE_MAX_MMAP_SIZE>0
- if( pFile->pMapRegion ){
- if( osFlushViewOfFile(pFile->pMapRegion, 0) ){
- OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
- "rc=SQLITE_OK\n", osGetCurrentProcessId(),
- pFile, pFile->pMapRegion));
- }else{
- pFile->lastErrno = osGetLastError();
- OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
- "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(),
- pFile, pFile->pMapRegion));
- return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
- "winSync1", pFile->zPath);
- }
- }
-#endif
rc = osFlushFileBuffers(pFile->h);
SimulateIOError( rc=FALSE );
if( rc ){
- OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
- osGetCurrentProcessId(), pFile, pFile->h));
+ OSTRACE(("SYNC file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}else{
pFile->lastErrno = osGetLastError();
- OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n",
- osGetCurrentProcessId(), pFile, pFile->h));
+ OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h));
return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
- "winSync2", pFile->zPath);
+ "winSync", pFile->zPath);
}
#endif
}
@@ -36639,7 +39897,7 @@ struct winShmNode {
int nRef; /* Number of winShm objects pointing to this */
winShm *pFirst; /* All winShm objects pointing to this */
winShmNode *pNext; /* Next in list of all winShmNode objects */
-#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
+#ifdef SQLITE_DEBUG
u8 nextShmId; /* Next available winShm.id value */
#endif
};
@@ -36670,7 +39928,7 @@ struct winShm {
u8 hasMutex; /* True if holding the winShmNode mutex */
u16 sharedMask; /* Mask of shared locks held */
u16 exclMask; /* Mask of exclusive locks held */
-#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
+#ifdef SQLITE_DEBUG
u8 id; /* Id of this connection with its winShmNode */
#endif
};
@@ -36861,7 +40119,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
/* Make the new connection a child of the winShmNode */
p->pShmNode = pShmNode;
-#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
+#ifdef SQLITE_DEBUG
p->id = pShmNode->nextShmId++;
#endif
pShmNode->nRef++;
@@ -37081,16 +40339,16 @@ static int winShmMap(
void volatile **pp /* OUT: Mapped memory */
){
winFile *pDbFd = (winFile*)fd;
- winShm *pShm = pDbFd->pShm;
+ winShm *p = pDbFd->pShm;
winShmNode *pShmNode;
int rc = SQLITE_OK;
- if( !pShm ){
+ if( !p ){
rc = winOpenSharedMemory(pDbFd);
if( rc!=SQLITE_OK ) return rc;
- pShm = pDbFd->pShm;
+ p = pDbFd->pShm;
}
- pShmNode = pShm->pShmNode;
+ pShmNode = p->pShmNode;
sqlite3_mutex_enter(pShmNode->mutex);
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
@@ -37130,7 +40388,7 @@ static int winShmMap(
}
/* Map the requested memory region into this processes address space. */
- apNew = (struct ShmRegion *)sqlite3_realloc64(
+ apNew = (struct ShmRegion *)sqlite3_realloc(
pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
);
if( !apNew ){
@@ -38002,7 +41260,7 @@ static int winOpen(
}
}
#endif
- winLogIoerr(cnt, __LINE__);
+ winLogIoerr(cnt);
OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name,
dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
@@ -38186,7 +41444,7 @@ static int winDelete(
if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
}else{
- winLogIoerr(cnt, __LINE__);
+ winLogIoerr(cnt);
}
sqlite3_free(zConverted);
OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
@@ -38236,7 +41494,7 @@ static int winAccess(
attr = sAttrData.dwFileAttributes;
}
}else{
- winLogIoerr(cnt, __LINE__);
+ winLogIoerr(cnt);
if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
sqlite3_free(zConverted);
return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
@@ -38577,7 +41835,7 @@ static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
int n = 0;
UNUSED_PARAMETER(pVfs);
-#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
+#if defined(SQLITE_TEST)
n = nBuf;
memset(zBuf, 0, nBuf);
#else
@@ -38611,23 +41869,7 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
memcpy(&zBuf[n], &i, sizeof(i));
n += sizeof(i);
}
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
- if( sizeof(UUID)<=nBuf-n ){
- UUID id;
- memset(&id, 0, sizeof(UUID));
- osUuidCreate(&id);
- memcpy(zBuf, &id, sizeof(UUID));
- n += sizeof(UUID);
- }
- if( sizeof(UUID)<=nBuf-n ){
- UUID id;
- memset(&id, 0, sizeof(UUID));
- osUuidCreateSequential(&id);
- memcpy(zBuf, &id, sizeof(UUID));
- n += sizeof(UUID);
- }
#endif
-#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
return n;
}
@@ -38751,7 +41993,7 @@ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
/*
** Initialize and deinitialize the operating system interface.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
+SQLITE_API int sqlite3_os_init(void){
static sqlite3_vfs winVfs = {
3, /* iVersion */
sizeof(winFile), /* szOsFile */
@@ -38805,7 +42047,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==80 );
+ assert( ArraySize(aSyscall)==77 );
/* get memory map allocation granularity */
memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
@@ -38826,7 +42068,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
return SQLITE_OK;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
+SQLITE_API int sqlite3_os_end(void){
#if SQLITE_OS_WINRT
if( sleepObj!=NULL ){
osCloseHandle(sleepObj);
@@ -39182,7 +42424,7 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
** bits to act as the reference */
pBitvec = sqlite3BitvecCreate( sz );
pV = sqlite3MallocZero( (sz+7)/8 + 1 );
- pTmpSpace = sqlite3_malloc64(BITVEC_SZ);
+ pTmpSpace = sqlite3_malloc(BITVEC_SZ);
if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end;
/* NULL pBitvec tests */
@@ -39364,20 +42606,12 @@ static void pcacheUnpin(PgHdr *p){
}
/*
-** Compute the number of pages of cache requested. p->szCache is the
-** cache size requested by the "PRAGMA cache_size" statement.
-**
-**
+** Compute the number of pages of cache requested.
*/
static int numberOfCachePages(PCache *p){
if( p->szCache>=0 ){
- /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
- ** suggested cache size is set to N. */
return p->szCache;
}else{
- /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
- ** the number of cache pages is adjusted to use approximately abs(N*1024)
- ** bytes of memory. */
return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
}
}
@@ -40117,6 +43351,7 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
static void *pcache1Alloc(int nByte){
void *p = 0;
assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
+ sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
if( nByte<=pcache1.szSlot ){
sqlite3_mutex_enter(pcache1.mutex);
p = (PgHdr1 *)pcache1.pFree;
@@ -40125,8 +43360,7 @@ static void *pcache1Alloc(int nByte){
pcache1.nFreeSlot--;
pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
assert( pcache1.nFreeSlot>=0 );
- sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
- sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1);
+ sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
}
sqlite3_mutex_leave(pcache1.mutex);
}
@@ -40139,8 +43373,7 @@ static void *pcache1Alloc(int nByte){
if( p ){
int sz = sqlite3MallocSize(p);
sqlite3_mutex_enter(pcache1.mutex);
- sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
- sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
+ sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
sqlite3_mutex_leave(pcache1.mutex);
}
#endif
@@ -40158,7 +43391,7 @@ static int pcache1Free(void *p){
if( p>=pcache1.pStart && p<pcache1.pEnd ){
PgFreeslot *pSlot;
sqlite3_mutex_enter(pcache1.mutex);
- sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1);
+ sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
pSlot = (PgFreeslot*)p;
pSlot->pNext = pcache1.pFree;
pcache1.pFree = pSlot;
@@ -40172,7 +43405,7 @@ static int pcache1Free(void *p){
nFreed = sqlite3MallocSize(p);
#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
sqlite3_mutex_enter(pcache1.mutex);
- sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
+ sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
sqlite3_mutex_leave(pcache1.mutex);
#endif
sqlite3_free(p);
@@ -40909,14 +44142,6 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){
*/
SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); }
-/*
-** Return the global mutex used by this PCACHE implementation. The
-** sqlite3_status() routine needs access to this mutex.
-*/
-SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void){
- return pcache1.mutex;
-}
-
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** This function is called to free superfluous dynamically allocated memory
@@ -44671,7 +47896,9 @@ static int pagerWalFrames(
){
int rc; /* Return code */
int nList; /* Number of pages in pList */
+#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
PgHdr *p; /* For looping over pages */
+#endif
assert( pPager->pWal );
assert( pList );
@@ -44688,6 +47915,7 @@ static int pagerWalFrames(
** any pages with page numbers greater than nTruncate into the WAL file.
** They will never be read by any client. So remove them from the pDirty
** list here. */
+ PgHdr *p;
PgHdr **ppNext = &pList;
nList = 0;
for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
@@ -44707,6 +47935,7 @@ static int pagerWalFrames(
pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags
);
if( rc==SQLITE_OK && pPager->pBackup ){
+ PgHdr *p;
for(p=pList; p; p=p->pDirty){
sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
}
@@ -48637,8 +51866,6 @@ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
}
assert( state==pPager->eState );
}
- }else if( eMode==PAGER_JOURNALMODE_OFF ){
- sqlite3OsClose(pPager->jfd);
}
}
@@ -48896,6 +52123,38 @@ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
#endif /* SQLITE_OMIT_DISKIO */
+/* BEGIN SQLCIPHER */
+#ifdef SQLITE_HAS_CODEC
+SQLITE_PRIVATE void sqlite3pager_get_codec(Pager *pPager, void **ctx) {
+ *ctx = pPager->pCodec;
+}
+
+SQLITE_PRIVATE int sqlite3pager_is_mj_pgno(Pager *pPager, Pgno pgno) {
+ return (PAGER_MJ_PGNO(pPager) == pgno) ? 1 : 0;
+}
+
+SQLITE_PRIVATE sqlite3_file *sqlite3Pager_get_fd(Pager *pPager) {
+ return (isOpen(pPager->fd)) ? pPager->fd : NULL;
+}
+
+SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetCodec(
+ Pager *pPager,
+ void *(*xCodec)(void*,void*,Pgno,int),
+ void (*xCodecSizeChng)(void*,int,int),
+ void (*xCodecFree)(void*),
+ void *pCodec
+){
+ sqlite3PagerSetCodec(pPager, xCodec, xCodecSizeChng, xCodecFree, pCodec);
+}
+
+SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetError( Pager *pPager, int error) {
+ pPager->errCode = error;
+}
+
+#endif
+/* END SQLCIPHER */
+
+
/************** End of pager.c ***********************************************/
/************** Begin file wal.c *********************************************/
/*
@@ -49421,7 +52680,7 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
if( pWal->nWiData<=iPage ){
int nByte = sizeof(u32*)*(iPage+1);
volatile u32 **apNew;
- apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
+ apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte);
if( !apNew ){
*ppPage = 0;
return SQLITE_NOMEM;
@@ -49687,10 +52946,9 @@ static void walUnlockShared(Wal *pWal, int lockIdx){
SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
}
-static int walLockExclusive(Wal *pWal, int lockIdx, int n, int fBlock){
+static int walLockExclusive(Wal *pWal, int lockIdx, int n){
int rc;
if( pWal->exclusiveMode ) return SQLITE_OK;
- if( fBlock ) sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_WAL_BLOCK, 0);
rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
@@ -49976,7 +53234,7 @@ static int walIndexRecover(Wal *pWal){
assert( pWal->writeLock );
iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
nLock = SQLITE_SHM_NLOCK - iLock;
- rc = walLockExclusive(pWal, iLock, nLock, 0);
+ rc = walLockExclusive(pWal, iLock, nLock);
if( rc ){
return rc;
}
@@ -50046,7 +53304,7 @@ static int walIndexRecover(Wal *pWal){
/* Malloc a buffer to read frames into. */
szFrame = szPage + WAL_FRAME_HDRSIZE;
- aFrame = (u8 *)sqlite3_malloc64(szFrame);
+ aFrame = (u8 *)sqlite3_malloc(szFrame);
if( !aFrame ){
rc = SQLITE_NOMEM;
goto recovery_error;
@@ -50439,7 +53697,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
nByte = sizeof(WalIterator)
+ (nSegment-1)*sizeof(struct WalSegment)
+ iLast*sizeof(ht_slot);
- p = (WalIterator *)sqlite3_malloc64(nByte);
+ p = (WalIterator *)sqlite3_malloc(nByte);
if( !p ){
return SQLITE_NOMEM;
}
@@ -50449,7 +53707,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
/* Allocate temporary space used by the merge-sort routine. This block
** of memory will be freed before this function returns.
*/
- aTmp = (ht_slot *)sqlite3_malloc64(
+ aTmp = (ht_slot *)sqlite3_malloc(
sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
);
if( !aTmp ){
@@ -50510,7 +53768,7 @@ static int walBusyLock(
){
int rc;
do {
- rc = walLockExclusive(pWal, lockIdx, n, 0);
+ rc = walLockExclusive(pWal, lockIdx, n);
}while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
return rc;
}
@@ -50629,14 +53887,6 @@ static int walCheckpoint(
mxSafeFrame = pWal->hdr.mxFrame;
mxPage = pWal->hdr.nPage;
for(i=1; i<WAL_NREADER; 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. */
u32 y = pInfo->aReadMark[i];
if( mxSafeFrame>y ){
assert( y<=pWal->hdr.mxFrame );
@@ -50951,7 +54201,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
walUnlockShared(pWal, WAL_WRITE_LOCK);
rc = SQLITE_READONLY_RECOVERY;
}
- }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 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);
@@ -51157,7 +54407,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
&& (mxReadMark<pWal->hdr.mxFrame || mxI==0)
){
for(i=1; i<WAL_NREADER; i++){
- rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1, 0);
+ rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
if( rc==SQLITE_OK ){
mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame;
mxI = i;
@@ -51413,7 +54663,7 @@ SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
/* Only one writer allowed at a time. Get the write lock. Return
** SQLITE_BUSY if unable.
*/
- rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 0);
+ rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
if( rc ){
return rc;
}
@@ -51558,7 +54808,7 @@ static int walRestartLog(Wal *pWal){
if( pInfo->nBackfill>0 ){
u32 salt1;
sqlite3_randomness(4, &salt1);
- rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1, 0);
+ rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
if( rc==SQLITE_OK ){
/* If all readers are using WAL_READ_LOCK(0) (in other words if no
** readers are currently using the WAL), then the transactions
@@ -51883,7 +55133,7 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint(
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
** "checkpoint" lock on the database file. */
- rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1, 0);
+ rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
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
@@ -52075,692 +55325,6 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
** big and we want to break it down some. This packaged seemed like
** a good breakout.
*/
-/************** Include btreeInt.h in the middle of btmutex.c ****************/
-/************** Begin file btreeInt.h ****************************************/
-/*
-** 2004 April 6
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file implements an external (disk-based) database using BTrees.
-** For a detailed discussion of BTrees, refer to
-**
-** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
-** "Sorting And Searching", pages 473-480. Addison-Wesley
-** Publishing Company, Reading, Massachusetts.
-**
-** The basic idea is that each page of the file contains N database
-** entries and N+1 pointers to subpages.
-**
-** ----------------------------------------------------------------
-** | Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) |
-** ----------------------------------------------------------------
-**
-** All of the keys on the page that Ptr(0) points to have values less
-** than Key(0). All of the keys on page Ptr(1) and its subpages have
-** values greater than Key(0) and less than Key(1). All of the keys
-** on Ptr(N) and its subpages have values greater than Key(N-1). And
-** so forth.
-**
-** Finding a particular key requires reading O(log(M)) pages from the
-** disk where M is the number of entries in the tree.
-**
-** In this implementation, a single file can hold one or more separate
-** BTrees. Each BTree is identified by the index of its root page. The
-** key and data for any entry are combined to form the "payload". A
-** fixed amount of payload can be carried directly on the database
-** page. If the payload is larger than the preset amount then surplus
-** bytes are stored on overflow pages. The payload for an entry
-** and the preceding pointer are combined to form a "Cell". Each
-** page has a small header which contains the Ptr(N) pointer and other
-** information such as the size of key and data.
-**
-** FORMAT DETAILS
-**
-** The file is divided into pages. The first page is called page 1,
-** the second is page 2, and so forth. A page number of zero indicates
-** "no such page". The page size can be any power of 2 between 512 and 65536.
-** Each page can be either a btree page, a freelist page, an overflow
-** page, or a pointer-map page.
-**
-** The first page is always a btree page. The first 100 bytes of the first
-** page contain a special header (the "file header") that describes the file.
-** The format of the file header is as follows:
-**
-** OFFSET SIZE DESCRIPTION
-** 0 16 Header string: "SQLite format 3\000"
-** 16 2 Page size in bytes. (1 means 65536)
-** 18 1 File format write version
-** 19 1 File format read version
-** 20 1 Bytes of unused space at the end of each page
-** 21 1 Max embedded payload fraction (must be 64)
-** 22 1 Min embedded payload fraction (must be 32)
-** 23 1 Min leaf payload fraction (must be 32)
-** 24 4 File change counter
-** 28 4 Reserved for future use
-** 32 4 First freelist page
-** 36 4 Number of freelist pages in the file
-** 40 60 15 4-byte meta values passed to higher layers
-**
-** 40 4 Schema cookie
-** 44 4 File format of schema layer
-** 48 4 Size of page cache
-** 52 4 Largest root-page (auto/incr_vacuum)
-** 56 4 1=UTF-8 2=UTF16le 3=UTF16be
-** 60 4 User version
-** 64 4 Incremental vacuum mode
-** 68 4 Application-ID
-** 72 20 unused
-** 92 4 The version-valid-for number
-** 96 4 SQLITE_VERSION_NUMBER
-**
-** All of the integer values are big-endian (most significant byte first).
-**
-** The file change counter is incremented when the database is changed
-** This counter allows other processes to know when the file has changed
-** and thus when they need to flush their cache.
-**
-** The max embedded payload fraction is the amount of the total usable
-** space in a page that can be consumed by a single cell for standard
-** B-tree (non-LEAFDATA) tables. A value of 255 means 100%. The default
-** is to limit the maximum cell size so that at least 4 cells will fit
-** on one page. Thus the default max embedded payload fraction is 64.
-**
-** If the payload for a cell is larger than the max payload, then extra
-** payload is spilled to overflow pages. Once an overflow page is allocated,
-** as many bytes as possible are moved into the overflow pages without letting
-** the cell size drop below the min embedded payload fraction.
-**
-** The min leaf payload fraction is like the min embedded payload fraction
-** except that it applies to leaf nodes in a LEAFDATA tree. The maximum
-** payload fraction for a LEAFDATA tree is always 100% (or 255) and it
-** not specified in the header.
-**
-** Each btree pages is divided into three sections: The header, the
-** cell pointer array, and the cell content area. Page 1 also has a 100-byte
-** file header that occurs before the page header.
-**
-** |----------------|
-** | file header | 100 bytes. Page 1 only.
-** |----------------|
-** | page header | 8 bytes for leaves. 12 bytes for interior nodes
-** |----------------|
-** | cell pointer | | 2 bytes per cell. Sorted order.
-** | array | | Grows downward
-** | | v
-** |----------------|
-** | unallocated |
-** | space |
-** |----------------| ^ Grows upwards
-** | cell content | | Arbitrary order interspersed with freeblocks.
-** | area | | and free space fragments.
-** |----------------|
-**
-** The page headers looks like this:
-**
-** OFFSET SIZE DESCRIPTION
-** 0 1 Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf
-** 1 2 byte offset to the first freeblock
-** 3 2 number of cells on this page
-** 5 2 first byte of the cell content area
-** 7 1 number of fragmented free bytes
-** 8 4 Right child (the Ptr(N) value). Omitted on leaves.
-**
-** The flags define the format of this btree page. The leaf flag means that
-** this page has no children. The zerodata flag means that this page carries
-** only keys and no data. The intkey flag means that the key is an integer
-** which is stored in the key size entry of the cell header rather than in
-** the payload area.
-**
-** The cell pointer array begins on the first byte after the page header.
-** The cell pointer array contains zero or more 2-byte numbers which are
-** offsets from the beginning of the page to the cell content in the cell
-** content area. The cell pointers occur in sorted order. The system strives
-** to keep free space after the last cell pointer so that new cells can
-** be easily added without having to defragment the page.
-**
-** Cell content is stored at the very end of the page and grows toward the
-** beginning of the page.
-**
-** Unused space within the cell content area is collected into a linked list of
-** freeblocks. Each freeblock is at least 4 bytes in size. The byte offset
-** to the first freeblock is given in the header. Freeblocks occur in
-** increasing order. Because a freeblock must be at least 4 bytes in size,
-** any group of 3 or fewer unused bytes in the cell content area cannot
-** exist on the freeblock chain. A group of 3 or fewer free bytes is called
-** a fragment. The total number of bytes in all fragments is recorded.
-** in the page header at offset 7.
-**
-** SIZE DESCRIPTION
-** 2 Byte offset of the next freeblock
-** 2 Bytes in this freeblock
-**
-** Cells are of variable length. Cells are stored in the cell content area at
-** the end of the page. Pointers to the cells are in the cell pointer array
-** that immediately follows the page header. Cells is not necessarily
-** contiguous or in order, but cell pointers are contiguous and in order.
-**
-** Cell content makes use of variable length integers. A variable
-** length integer is 1 to 9 bytes where the lower 7 bits of each
-** byte are used. The integer consists of all bytes that have bit 8 set and
-** the first byte with bit 8 clear. The most significant byte of the integer
-** appears first. A variable-length integer may not be more than 9 bytes long.
-** As a special case, all 8 bytes of the 9th byte are used as data. This
-** allows a 64-bit integer to be encoded in 9 bytes.
-**
-** 0x00 becomes 0x00000000
-** 0x7f becomes 0x0000007f
-** 0x81 0x00 becomes 0x00000080
-** 0x82 0x00 becomes 0x00000100
-** 0x80 0x7f becomes 0x0000007f
-** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678
-** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081
-**
-** Variable length integers are used for rowids and to hold the number of
-** bytes of key and data in a btree cell.
-**
-** The content of a cell looks like this:
-**
-** SIZE DESCRIPTION
-** 4 Page number of the left child. Omitted if leaf flag is set.
-** var Number of bytes of data. Omitted if the zerodata flag is set.
-** var Number of bytes of key. Or the key itself if intkey flag is set.
-** * Payload
-** 4 First page of the overflow chain. Omitted if no overflow
-**
-** Overflow pages form a linked list. Each page except the last is completely
-** filled with data (pagesize - 4 bytes). The last page can have as little
-** as 1 byte of data.
-**
-** SIZE DESCRIPTION
-** 4 Page number of next overflow page
-** * Data
-**
-** Freelist pages come in two subtypes: trunk pages and leaf pages. The
-** file header points to the first in a linked list of trunk page. Each trunk
-** page points to multiple leaf pages. The content of a leaf page is
-** unspecified. A trunk page looks like this:
-**
-** SIZE DESCRIPTION
-** 4 Page number of next trunk page
-** 4 Number of leaf pointers on this page
-** * zero or more pages numbers of leaves
-*/
-
-
-/* The following value is the maximum cell size assuming a maximum page
-** size give above.
-*/
-#define MX_CELL_SIZE(pBt) ((int)(pBt->pageSize-8))
-
-/* The maximum number of cells on a single page of the database. This
-** assumes a minimum cell size of 6 bytes (4 bytes for the cell itself
-** plus 2 bytes for the index to the cell in the page header). Such
-** small cells will be rare, but they are possible.
-*/
-#define MX_CELL(pBt) ((pBt->pageSize-8)/6)
-
-/* Forward declarations */
-typedef struct MemPage MemPage;
-typedef struct BtLock BtLock;
-
-/*
-** This is a magic string that appears at the beginning of every
-** SQLite database in order to identify the file as a real database.
-**
-** You can change this value at compile-time by specifying a
-** -DSQLITE_FILE_HEADER="..." on the compiler command-line. The
-** header must be exactly 16 bytes including the zero-terminator so
-** the string itself should be 15 characters long. If you change
-** the header, then your custom library will not be able to read
-** databases generated by the standard tools and the standard tools
-** will not be able to read databases created by your custom library.
-*/
-#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */
-# define SQLITE_FILE_HEADER "SQLite format 3"
-#endif
-
-/*
-** Page type flags. An ORed combination of these flags appear as the
-** first byte of on-disk image of every BTree page.
-*/
-#define PTF_INTKEY 0x01
-#define PTF_ZERODATA 0x02
-#define PTF_LEAFDATA 0x04
-#define PTF_LEAF 0x08
-
-/*
-** As each page of the file is loaded into memory, an instance of the following
-** structure is appended and initialized to zero. This structure stores
-** information about the page that is decoded from the raw file page.
-**
-** The pParent field points back to the parent page. This allows us to
-** walk up the BTree from any leaf to the root. Care must be taken to
-** unref() the parent page pointer when this page is no longer referenced.
-** The pageDestructor() routine handles that chore.
-**
-** Access to all fields of this structure is controlled by the mutex
-** stored in MemPage.pBt->mutex.
-*/
-struct MemPage {
- u8 isInit; /* True if previously initialized. MUST BE FIRST! */
- u8 nOverflow; /* Number of overflow cell bodies in aCell[] */
- u8 intKey; /* True if table b-trees. False for index b-trees */
- u8 intKeyLeaf; /* True if the leaf of an intKey table */
- u8 noPayload; /* True if internal intKey page (thus w/o data) */
- u8 leaf; /* True if a leaf page */
- u8 hdrOffset; /* 100 for page 1. 0 otherwise */
- u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */
- u8 max1bytePayload; /* min(maxLocal,127) */
- u8 bBusy; /* Prevent endless loops on corrupt database files */
- u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
- u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */
- u16 cellOffset; /* Index in aData of first cell pointer */
- u16 nFree; /* Number of free bytes on the page */
- u16 nCell; /* Number of cells on this page, local and ovfl */
- u16 maskPage; /* Mask for page offset */
- u16 aiOvfl[5]; /* Insert the i-th overflow cell before the aiOvfl-th
- ** non-overflow cell */
- u8 *apOvfl[5]; /* Pointers to the body of overflow cells */
- BtShared *pBt; /* Pointer to BtShared that this page is part of */
- u8 *aData; /* Pointer to disk image of the page data */
- u8 *aDataEnd; /* One byte past the end of usable data */
- u8 *aCellIdx; /* The cell index area */
- DbPage *pDbPage; /* Pager page handle */
- Pgno pgno; /* Page number for this page */
-};
-
-/*
-** The in-memory image of a disk page has the auxiliary information appended
-** to the end. EXTRA_SIZE is the number of bytes of space needed to hold
-** that extra information.
-*/
-#define EXTRA_SIZE sizeof(MemPage)
-
-/*
-** A linked list of the following structures is stored at BtShared.pLock.
-** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor
-** is opened on the table with root page BtShared.iTable. Locks are removed
-** from this list when a transaction is committed or rolled back, or when
-** a btree handle is closed.
-*/
-struct BtLock {
- Btree *pBtree; /* Btree handle holding this lock */
- Pgno iTable; /* Root page of table */
- u8 eLock; /* READ_LOCK or WRITE_LOCK */
- BtLock *pNext; /* Next in BtShared.pLock list */
-};
-
-/* Candidate values for BtLock.eLock */
-#define READ_LOCK 1
-#define WRITE_LOCK 2
-
-/* A Btree handle
-**
-** A database connection contains a pointer to an instance of
-** this object for every database file that it has open. This structure
-** is opaque to the database connection. The database connection cannot
-** see the internals of this structure and only deals with pointers to
-** this structure.
-**
-** For some database files, the same underlying database cache might be
-** shared between multiple connections. In that case, each connection
-** has it own instance of this object. But each instance of this object
-** points to the same BtShared object. The database cache and the
-** schema associated with the database file are all contained within
-** the BtShared object.
-**
-** All fields in this structure are accessed under sqlite3.mutex.
-** The pBt pointer itself may not be changed while there exists cursors
-** in the referenced BtShared that point back to this Btree since those
-** cursors have to go through this Btree to find their BtShared and
-** they often do so without holding sqlite3.mutex.
-*/
-struct Btree {
- sqlite3 *db; /* The database connection holding this btree */
- BtShared *pBt; /* Sharable content of this btree */
- u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
- u8 sharable; /* True if we can share pBt with another db */
- u8 locked; /* True if db currently has pBt locked */
- int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
- int nBackup; /* Number of backup operations reading this btree */
- u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */
- Btree *pNext; /* List of other sharable Btrees from the same db */
- Btree *pPrev; /* Back pointer of the same list */
-#ifndef SQLITE_OMIT_SHARED_CACHE
- BtLock lock; /* Object used to lock page 1 */
-#endif
-};
-
-/*
-** Btree.inTrans may take one of the following values.
-**
-** If the shared-data extension is enabled, there may be multiple users
-** of the Btree structure. At most one of these may open a write transaction,
-** but any number may have active read transactions.
-*/
-#define TRANS_NONE 0
-#define TRANS_READ 1
-#define TRANS_WRITE 2
-
-/*
-** An instance of this object represents a single database file.
-**
-** A single database file can be in use at the same time by two
-** or more database connections. When two or more connections are
-** sharing the same database file, each connection has it own
-** private Btree object for the file and each of those Btrees points
-** to this one BtShared object. BtShared.nRef is the number of
-** connections currently sharing this database file.
-**
-** Fields in this structure are accessed under the BtShared.mutex
-** mutex, except for nRef and pNext which are accessed under the
-** global SQLITE_MUTEX_STATIC_MASTER mutex. The pPager field
-** may not be modified once it is initially set as long as nRef>0.
-** The pSchema field may be set once under BtShared.mutex and
-** thereafter is unchanged as long as nRef>0.
-**
-** isPending:
-**
-** If a BtShared client fails to obtain a write-lock on a database
-** table (because there exists one or more read-locks on the table),
-** the shared-cache enters 'pending-lock' state and isPending is
-** set to true.
-**
-** The shared-cache leaves the 'pending lock' state when either of
-** the following occur:
-**
-** 1) The current writer (BtShared.pWriter) concludes its transaction, OR
-** 2) The number of locks held by other connections drops to zero.
-**
-** while in the 'pending-lock' state, no connection may start a new
-** transaction.
-**
-** This feature is included to help prevent writer-starvation.
-*/
-struct BtShared {
- Pager *pPager; /* The page cache */
- sqlite3 *db; /* Database connection currently using this Btree */
- BtCursor *pCursor; /* A list of all open cursors */
- MemPage *pPage1; /* First page of the database */
- u8 openFlags; /* Flags to sqlite3BtreeOpen() */
-#ifndef SQLITE_OMIT_AUTOVACUUM
- u8 autoVacuum; /* True if auto-vacuum is enabled */
- u8 incrVacuum; /* True if incr-vacuum is enabled */
- 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 */
-#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 */
- u32 pageSize; /* Total number of bytes on a page */
- u32 usableSize; /* Number of usable bytes on each page */
- int nTransaction; /* Number of open transactions (read + write) */
- u32 nPage; /* Number of pages in the database */
- void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */
- void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */
- sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */
- Bitvec *pHasContent; /* Set of pages moved to free-list this transaction */
-#ifndef SQLITE_OMIT_SHARED_CACHE
- int nRef; /* Number of references to this structure */
- BtShared *pNext; /* Next on a list of sharable BtShared structs */
- BtLock *pLock; /* List of locks held on this shared-btree struct */
- Btree *pWriter; /* Btree with currently open write transaction */
-#endif
- u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */
-};
-
-/*
-** Allowed values for BtShared.btsFlags
-*/
-#define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */
-#define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */
-#define BTS_SECURE_DELETE 0x0004 /* PRAGMA secure_delete is enabled */
-#define BTS_INITIALLY_EMPTY 0x0008 /* Database was empty at trans start */
-#define BTS_NO_WAL 0x0010 /* Do not open write-ahead-log files */
-#define BTS_EXCLUSIVE 0x0020 /* pWriter has an exclusive lock */
-#define BTS_PENDING 0x0040 /* Waiting for read-locks to clear */
-
-/*
-** An instance of the following structure is used to hold information
-** about a cell. The parseCellPtr() function fills in this structure
-** based on information extract from the raw disk page.
-*/
-typedef struct CellInfo CellInfo;
-struct CellInfo {
- i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */
- u8 *pPayload; /* Pointer to the start of payload */
- u32 nPayload; /* Bytes of payload */
- u16 nLocal; /* Amount of payload held locally, not on overflow */
- u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */
- u16 nSize; /* Size of the cell content on the main b-tree page */
-};
-
-/*
-** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than
-** this will be declared corrupt. This value is calculated based on a
-** maximum database size of 2^31 pages a minimum fanout of 2 for a
-** root-node and 3 for all other internal nodes.
-**
-** If a tree that appears to be taller than this is encountered, it is
-** assumed that the database is corrupt.
-*/
-#define BTCURSOR_MAX_DEPTH 20
-
-/*
-** A cursor is a pointer to a particular entry within a particular
-** b-tree within a database file.
-**
-** The entry is identified by its MemPage and the index in
-** MemPage.aCell[] of the entry.
-**
-** A single database file can be shared by two more database connections,
-** but cursors cannot be shared. Each cursor is associated with a
-** particular database connection identified BtCursor.pBtree.db.
-**
-** Fields in this structure are accessed under the BtShared.mutex
-** found at self->pBt->mutex.
-**
-** skipNext meaning:
-** eState==SKIPNEXT && skipNext>0: Next sqlite3BtreeNext() is no-op.
-** eState==SKIPNEXT && skipNext<0: Next sqlite3BtreePrevious() is no-op.
-** eState==FAULT: Cursor fault with skipNext as error code.
-*/
-struct BtCursor {
- Btree *pBtree; /* The Btree to which this cursor belongs */
- BtShared *pBt; /* The BtShared this cursor points to */
- BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */
- struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
- Pgno *aOverflow; /* Cache of overflow page locations */
- CellInfo info; /* A parse of the cell we are pointing at */
- i64 nKey; /* Size of pKey, or last integer key */
- void *pKey; /* Saved key that was cursor last known position */
- Pgno pgnoRoot; /* The root page of this tree */
- int nOvflAlloc; /* Allocated size of aOverflow[] array */
- int skipNext; /* Prev() is noop if negative. Next() is noop if positive.
- ** Error code if eState==CURSOR_FAULT */
- u8 curFlags; /* zero or more BTCF_* flags defined below */
- u8 eState; /* One of the CURSOR_XXX constants (see below) */
- u8 hints; /* As configured by CursorSetHints() */
- i16 iPage; /* Index of current page in apPage */
- u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
- MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
-};
-
-/*
-** Legal values for BtCursor.curFlags
-*/
-#define BTCF_WriteFlag 0x01 /* True if a write cursor */
-#define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */
-#define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */
-#define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */
-#define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */
-
-/*
-** Potential values for BtCursor.eState.
-**
-** CURSOR_INVALID:
-** Cursor does not point to a valid entry. This can happen (for example)
-** because the table is empty or because BtreeCursorFirst() has not been
-** called.
-**
-** CURSOR_VALID:
-** Cursor points to a valid entry. getPayload() etc. may be called.
-**
-** CURSOR_SKIPNEXT:
-** Cursor is valid except that the Cursor.skipNext field is non-zero
-** indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious()
-** operation should be a no-op.
-**
-** CURSOR_REQUIRESEEK:
-** The table that this cursor was opened on still exists, but has been
-** modified since the cursor was last used. The cursor position is saved
-** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in
-** this state, restoreCursorPosition() can be called to attempt to
-** seek the cursor to the saved position.
-**
-** CURSOR_FAULT:
-** An unrecoverable error (an I/O error or a malloc failure) has occurred
-** on a different connection that shares the BtShared cache with this
-** cursor. The error has left the cache in an inconsistent state.
-** Do nothing else with this cursor. Any attempt to use the cursor
-** should return the error code stored in BtCursor.skipNext
-*/
-#define CURSOR_INVALID 0
-#define CURSOR_VALID 1
-#define CURSOR_SKIPNEXT 2
-#define CURSOR_REQUIRESEEK 3
-#define CURSOR_FAULT 4
-
-/*
-** The database page the PENDING_BYTE occupies. This page is never used.
-*/
-# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
-
-/*
-** These macros define the location of the pointer-map entry for a
-** database page. The first argument to each is the number of usable
-** bytes on each page of the database (often 1024). The second is the
-** page number to look up in the pointer map.
-**
-** PTRMAP_PAGENO returns the database page number of the pointer-map
-** page that stores the required pointer. PTRMAP_PTROFFSET returns
-** the offset of the requested map entry.
-**
-** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page,
-** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be
-** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
-** this test.
-*/
-#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno)
-#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1))
-#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))
-
-/*
-** The pointer map is a lookup table that identifies the parent page for
-** each child page in the database file. The parent page is the page that
-** contains a pointer to the child. Every page in the database contains
-** 0 or 1 parent pages. (In this context 'database page' refers
-** to any page that is not part of the pointer map itself.) Each pointer map
-** entry consists of a single byte 'type' and a 4 byte parent page number.
-** The PTRMAP_XXX identifiers below are the valid types.
-**
-** The purpose of the pointer map is to facility moving pages from one
-** position in the file to another as part of autovacuum. When a page
-** is moved, the pointer in its parent must be updated to point to the
-** new location. The pointer map is used to locate the parent page quickly.
-**
-** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not
-** used in this case.
-**
-** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number
-** is not used in this case.
-**
-** PTRMAP_OVERFLOW1: The database page is the first page in a list of
-** overflow pages. The page number identifies the page that
-** contains the cell with a pointer to this overflow page.
-**
-** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of
-** overflow pages. The page-number identifies the previous
-** page in the overflow page list.
-**
-** PTRMAP_BTREE: The database page is a non-root btree page. The page number
-** identifies the parent page in the btree.
-*/
-#define PTRMAP_ROOTPAGE 1
-#define PTRMAP_FREEPAGE 2
-#define PTRMAP_OVERFLOW1 3
-#define PTRMAP_OVERFLOW2 4
-#define PTRMAP_BTREE 5
-
-/* A bunch of assert() statements to check the transaction state variables
-** of handle p (type Btree*) are internally consistent.
-*/
-#define btreeIntegrity(p) \
- assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \
- assert( p->pBt->inTransaction>=p->inTrans );
-
-
-/*
-** The ISAUTOVACUUM macro is used within balance_nonroot() to determine
-** if the database supports auto-vacuum or not. Because it is used
-** within an expression that is an argument to another macro
-** (sqliteMallocRaw), it is not possible to use conditional compilation.
-** So, this macro is defined instead.
-*/
-#ifndef SQLITE_OMIT_AUTOVACUUM
-#define ISAUTOVACUUM (pBt->autoVacuum)
-#else
-#define ISAUTOVACUUM 0
-#endif
-
-
-/*
-** This structure is passed around through all the sanity checking routines
-** in order to keep track of some global state information.
-**
-** The aRef[] array is allocated so that there is 1 bit for each page in
-** the database. As the integrity-check proceeds, for each page used in
-** the database the corresponding bit is set. This allows integrity-check to
-** detect pages that are used twice and orphaned pages (both of which
-** indicate corruption).
-*/
-typedef struct IntegrityCk IntegrityCk;
-struct IntegrityCk {
- BtShared *pBt; /* The tree being checked out */
- Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */
- u8 *aPgRef; /* 1 bit per page in the db (see above) */
- Pgno nPage; /* Number of pages in the database */
- int mxErr; /* Stop accumulating errors when this reaches zero */
- int nErr; /* Number of messages written to zErrMsg so far */
- int mallocFailed; /* A memory allocation error has occurred */
- const char *zPfx; /* Error message prefix */
- int v1, v2; /* Values for up to two %d fields in zPfx */
- StrAccum errMsg; /* Accumulate the error message text here */
-};
-
-/*
-** Routines to read or write a two- and four-byte big-endian integer values.
-*/
-#define get2byte(x) ((x)[0]<<8 | (x)[1])
-#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v))
-#define get4byte sqlite3Get4byte
-#define put4byte sqlite3Put4byte
-
-/************** End of btreeInt.h ********************************************/
-/************** Continuing where we left off in btmutex.c ********************/
#ifndef SQLITE_OMIT_SHARED_CACHE
#if SQLITE_THREADSAFE
@@ -52886,7 +55450,6 @@ static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){
** Exit the recursive mutex on a Btree.
*/
SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){
- assert( sqlite3_mutex_held(p->db->mutex) );
if( p->sharable ){
assert( p->wantToLock>0 );
p->wantToLock--;
@@ -53134,7 +55697,7 @@ static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
** The shared cache setting effects only future calls to
** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int enable){
+SQLITE_API int sqlite3_enable_shared_cache(int enable){
sqlite3GlobalConfig.sharedCacheEnabled = enable;
return SQLITE_OK;
}
@@ -53223,12 +55786,6 @@ static int hasSharedCacheTableLock(
for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
Index *pIdx = (Index *)sqliteHashData(p);
if( pIdx->tnum==(int)iRoot ){
- if( iTab ){
- /* Two or more indexes share the same root page. There must
- ** be imposter tables. So just return true. The assert is not
- ** useful in that case. */
- return 1;
- }
iTab = pIdx->pTable->tnum;
}
}
@@ -53648,15 +56205,10 @@ static void btreeReleaseAllCursorPages(BtCursor *pCur){
static int saveCursorPosition(BtCursor *pCur){
int rc;
- assert( CURSOR_VALID==pCur->eState || CURSOR_SKIPNEXT==pCur->eState );
+ assert( CURSOR_VALID==pCur->eState );
assert( 0==pCur->pKey );
assert( cursorHoldsMutex(pCur) );
- if( pCur->eState==CURSOR_SKIPNEXT ){
- pCur->eState = CURSOR_VALID;
- }else{
- pCur->skipNext = 0;
- }
rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
assert( rc==SQLITE_OK ); /* KeySize() cannot fail */
@@ -53727,7 +56279,7 @@ static int SQLITE_NOINLINE saveCursorsOnList(
){
do{
if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
- if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
+ if( p->eState==CURSOR_VALID ){
int rc = saveCursorPosition(p);
if( SQLITE_OK!=rc ){
return rc;
@@ -53799,19 +56351,17 @@ static int btreeMoveto(
*/
static int btreeRestoreCursorPosition(BtCursor *pCur){
int rc;
- int skipNext;
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState>=CURSOR_REQUIRESEEK );
if( pCur->eState==CURSOR_FAULT ){
return pCur->skipNext;
}
pCur->eState = CURSOR_INVALID;
- rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext);
+ rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skipNext);
if( rc==SQLITE_OK ){
sqlite3_free(pCur->pKey);
pCur->pKey = 0;
assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
- pCur->skipNext |= skipNext;
if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
pCur->eState = CURSOR_SKIPNEXT;
}
@@ -53863,10 +56413,9 @@ SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow)
*pDifferentRow = 1;
return rc;
}
- if( pCur->eState!=CURSOR_VALID ){
+ if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){
*pDifferentRow = 1;
}else{
- assert( pCur->skipNext==0 );
*pDifferentRow = 0;
}
return SQLITE_OK;
@@ -55007,18 +57556,16 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
*/
if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){
if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
- int nFilename = sqlite3Strlen30(zFilename)+1;
int nFullPathname = pVfs->mxPathname+1;
- char *zFullPathname = sqlite3Malloc(MAX(nFullPathname,nFilename));
+ char *zFullPathname = sqlite3Malloc(nFullPathname);
MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
-
p->sharable = 1;
if( !zFullPathname ){
sqlite3_free(p);
return SQLITE_NOMEM;
}
if( isMemdb ){
- memcpy(zFullPathname, zFilename, nFilename);
+ memcpy(zFullPathname, zFilename, sqlite3Strlen30(zFilename)+1);
}else{
rc = sqlite3OsFullPathname(pVfs, zFilename,
nFullPathname, zFullPathname);
@@ -55075,8 +57622,8 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
** the right size. This is to guard against size changes that result
** when compiling on a different architecture.
*/
- assert( sizeof(i64)==8 );
- assert( sizeof(u64)==8 );
+ assert( sizeof(i64)==8 || sizeof(i64)==4 );
+ assert( sizeof(u64)==8 || sizeof(u64)==4 );
assert( sizeof(u32)==4 );
assert( sizeof(u16)==2 );
assert( sizeof(Pgno)==4 );
@@ -55463,9 +58010,6 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve,
BtShared *pBt = p->pBt;
assert( nReserve>=-1 && nReserve<=255 );
sqlite3BtreeEnter(p);
-#if SQLITE_HAS_CODEC
- if( nReserve>pBt->optimalReserve ) pBt->optimalReserve = (u8)nReserve;
-#endif
if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
sqlite3BtreeLeave(p);
return SQLITE_READONLY;
@@ -55477,7 +58021,7 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve,
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
((pageSize-1)&pageSize)==0 ){
assert( (pageSize & 7)==0 );
- assert( !pBt->pCursor );
+ assert( !pBt->pPage1 && !pBt->pCursor );
pBt->pageSize = (u32)pageSize;
freeTempSpace(pBt);
}
@@ -55495,6 +58039,7 @@ SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){
return p->pBt->pageSize;
}
+#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
/*
** This function is similar to sqlite3BtreeGetReserve(), except that it
** may only be called if it is guaranteed that the b-tree mutex is already
@@ -55507,33 +58052,25 @@ SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){
** database handle that owns *p, causing undefined behavior.
*/
SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){
- int n;
assert( sqlite3_mutex_held(p->pBt->mutex) );
- n = p->pBt->pageSize - p->pBt->usableSize;
- return n;
+ return p->pBt->pageSize - p->pBt->usableSize;
}
+#endif /* SQLITE_HAS_CODEC || SQLITE_DEBUG */
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
/*
** Return the number of bytes of space at the end of every page that
** are intentually left unused. This is the "reserved" space that is
** sometimes used by extensions.
-**
-** 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 sqlite3BtreeGetOptimalReserve(Btree *p){
+SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree *p){
int n;
sqlite3BtreeEnter(p);
- n = sqlite3BtreeGetReserveNoMutex(p);
-#ifdef SQLITE_HAS_CODEC
- if( n<p->pBt->optimalReserve ) n = p->pBt->optimalReserve;
-#endif
+ n = p->pBt->pageSize - p->pBt->usableSize;
sqlite3BtreeLeave(p);
return n;
}
-
/*
** Set the maximum page count for a database if mxPage is positive.
** No changes are made if mxPage is 0 or negative.
@@ -55564,6 +58101,7 @@ SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){
sqlite3BtreeLeave(p);
return b;
}
+#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */
/*
** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
@@ -56683,7 +59221,7 @@ SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int wr
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
int i;
if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){
- if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
+ if( p->eState==CURSOR_VALID ){
rc = saveCursorPosition(p);
if( rc!=SQLITE_OK ){
(void)sqlite3BtreeTripAllCursors(pBtree, rc, 0);
@@ -57089,8 +59627,6 @@ SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
- assert( pCur->iPage>=0 );
- assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 );
getCellInfo(pCur);
*pSize = pCur->info.nPayload;
@@ -57499,18 +60035,13 @@ static const void *fetchPayload(
BtCursor *pCur, /* Cursor pointing to entry to read from */
u32 *pAmt /* Write the number of available bytes here */
){
- u32 amt;
assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
assert( pCur->eState==CURSOR_VALID );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorHoldsMutex(pCur) );
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
assert( pCur->info.nSize>0 );
- assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
- assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
- amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload);
- if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal;
- *pAmt = amt;
+ *pAmt = pCur->info.nLocal;
return (void*)pCur->info.pPayload;
}
@@ -57574,7 +60105,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
return SQLITE_OK;
}
-#if SQLITE_DEBUG
+#if 0
/*
** Page pParent is an internal (non-leaf) tree page. This function
** asserts that page number iChild is the left-child if the iIdx'th
@@ -57583,8 +60114,6 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
** the page.
*/
static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){
- if( CORRUPT_DB ) return; /* The conditions tested below might not be true
- ** in a corrupt database */
assert( iIdx<=pParent->nCell );
if( iIdx==pParent->nCell ){
assert( get4byte(&pParent->aData[pParent->hdrOffset+8])==iChild );
@@ -57609,11 +60138,19 @@ static void moveToParent(BtCursor *pCur){
assert( pCur->eState==CURSOR_VALID );
assert( pCur->iPage>0 );
assert( pCur->apPage[pCur->iPage] );
+
+ /* UPDATE: It is actually possible for the condition tested by the assert
+ ** below to be untrue if the database file is corrupt. This can occur if
+ ** one cursor has modified page pParent while a reference to it is held
+ ** by a second cursor. Which can only happen if a single page is linked
+ ** into more than one b-tree structure in a corrupt database. */
+#if 0
assertParentIndex(
pCur->apPage[pCur->iPage-1],
pCur->aiIdx[pCur->iPage-1],
pCur->apPage[pCur->iPage]->pgno
);
+#endif
testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
releasePage(pCur->apPage[pCur->iPage]);
@@ -59788,6 +62325,7 @@ static int balance_nonroot(
}else if( iParentIdx==i ){
nxDiv = i-2+bBulk;
}else{
+ assert( bBulk==0 );
nxDiv = iParentIdx-1;
}
i = 2-bBulk;
@@ -60538,8 +63076,7 @@ static int balance(BtCursor *pCur){
** pSpace buffer passed to the latter call to balance_nonroot().
*/
u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize);
- rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1,
- pCur->hints&BTREE_BULKLOAD);
+ rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, pCur->hints);
if( pFree ){
/* If pFree is not NULL, it points to the pSpace buffer used
** by a previous call to balance_nonroot(). Its contents are
@@ -60560,7 +63097,6 @@ static int balance(BtCursor *pCur){
/* The next iteration of the do-loop balances the parent page. */
releasePage(pPage);
pCur->iPage--;
- assert( pCur->iPage>=0 );
}
}while( rc==SQLITE_OK );
@@ -61037,13 +63573,9 @@ static int clearDatabasePage(
if( pgno>btreePagecount(pBt) ){
return SQLITE_CORRUPT_BKPT;
}
+
rc = getAndInitPage(pBt, pgno, &pPage, 0);
if( rc ) return rc;
- if( pPage->bBusy ){
- rc = SQLITE_CORRUPT_BKPT;
- goto cleardatabasepage_out;
- }
- pPage->bBusy = 1;
hdr = pPage->hdrOffset;
for(i=0; i<pPage->nCell; i++){
pCell = findCell(pPage, i);
@@ -61068,7 +63600,6 @@ static int clearDatabasePage(
}
cleardatabasepage_out:
- pPage->bBusy = 0;
releasePage(pPage);
return rc;
}
@@ -61576,57 +64107,6 @@ static void checkList(
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
-/*
-** An implementation of a min-heap.
-**
-** aHeap[0] is the number of elements on the heap. aHeap[1] is the
-** root element. The daughter nodes of aHeap[N] are aHeap[N*2]
-** and aHeap[N*2+1].
-**
-** The heap property is this: Every node is less than or equal to both
-** of its daughter nodes. A consequence of the heap property is that the
-** root node aHeap[1] is always the minimum value currently in the heap.
-**
-** The btreeHeapInsert() routine inserts an unsigned 32-bit number onto
-** the heap, preserving the heap property. The btreeHeapPull() routine
-** removes the root element from the heap (the minimum value in the heap)
-** and then moves other nodes around as necessary to preserve the heap
-** property.
-**
-** This heap is used for cell overlap and coverage testing. Each u32
-** entry represents the span of a cell or freeblock on a btree page.
-** The upper 16 bits are the index of the first byte of a range and the
-** lower 16 bits are the index of the last byte of that range.
-*/
-static void btreeHeapInsert(u32 *aHeap, u32 x){
- u32 j, i = ++aHeap[0];
- aHeap[i] = x;
- while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){
- x = aHeap[j];
- aHeap[j] = aHeap[i];
- aHeap[i] = x;
- i = j;
- }
-}
-static int btreeHeapPull(u32 *aHeap, u32 *pOut){
- u32 j, i, x;
- if( (x = aHeap[0])==0 ) return 0;
- *pOut = aHeap[1];
- aHeap[1] = aHeap[x];
- aHeap[x] = 0xffffffff;
- aHeap[0]--;
- i = 1;
- while( (j = i*2)<=aHeap[0] ){
- if( aHeap[j]>aHeap[j+1] ) j++;
- if( aHeap[i]<aHeap[j] ) break;
- x = aHeap[i];
- aHeap[i] = aHeap[j];
- aHeap[j] = x;
- i = j;
- }
- return 1;
-}
-
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** Do various sanity checks on a single page of a tree. Return
@@ -61659,8 +64139,7 @@ static int checkTreePage(
u8 *data;
BtShared *pBt;
int usableSize;
- u32 *heap = 0;
- u32 x, prev = 0;
+ char *hit = 0;
i64 nMinKey = 0;
i64 nMaxKey = 0;
const char *saved_zPfx = pCheck->zPfx;
@@ -61805,15 +64284,15 @@ static int checkTreePage(
*/
data = pPage->aData;
hdr = pPage->hdrOffset;
- heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
+ hit = sqlite3PageMalloc( pBt->pageSize );
pCheck->zPfx = 0;
- if( heap==0 ){
+ if( hit==0 ){
pCheck->mallocFailed = 1;
}else{
int contentOffset = get2byteNotZero(&data[hdr+5]);
assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */
- heap[0] = 0;
- btreeHeapInsert(heap, contentOffset-1);
+ memset(hit+contentOffset, 0, usableSize-contentOffset);
+ memset(hit, 1, contentOffset);
/* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
** number of cells on the page. */
nCell = get2byte(&data[hdr+3]);
@@ -61825,6 +64304,7 @@ static int checkTreePage(
for(i=0; i<nCell; i++){
int pc = get2byte(&data[cellStart+i*2]);
u32 size = 65536;
+ int j;
if( pc<=usableSize-4 ){
size = cellSizePtr(pPage, &data[pc]);
}
@@ -61833,7 +64313,7 @@ static int checkTreePage(
checkAppendMsg(pCheck,
"Corruption detected in cell %d on page %d",i,iPage);
}else{
- btreeHeapInsert(heap, (pc<<16)|(pc+size-1));
+ for(j=pc+size-1; j>=pc; j--) hit[j]++;
}
}
/* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header
@@ -61845,7 +64325,7 @@ static int checkTreePage(
assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */
size = get2byte(&data[i+2]);
assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */
- btreeHeapInsert(heap, (i<<16)|(i+size-1));
+ for(j=i+size-1; j>=i; j--) hit[j]++;
/* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
** big-endian integer which is the offset in the b-tree page of the next
** freeblock in the chain, or zero if the freeblock is the last on the
@@ -61857,33 +64337,27 @@ static int checkTreePage(
assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */
i = j;
}
- cnt = 0;
- assert( heap[0]>0 );
- assert( (heap[1]>>16)==0 );
- btreeHeapPull(heap,&prev);
- while( btreeHeapPull(heap,&x) ){
- if( (prev&0xffff)+1>(x>>16) ){
+ for(i=cnt=0; i<usableSize; i++){
+ if( hit[i]==0 ){
+ cnt++;
+ }else if( hit[i]>1 ){
checkAppendMsg(pCheck,
- "Multiple uses for byte %u of page %d", x>>16, iPage);
+ "Multiple uses for byte %d of page %d", i, iPage);
break;
- }else{
- cnt += (x>>16) - (prev&0xffff) - 1;
- prev = x;
}
}
- cnt += usableSize - (prev&0xffff) - 1;
/* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments
** is stored in the fifth field of the b-tree page header.
** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the
** number of fragmented free bytes within the cell content area.
*/
- if( heap[0]==0 && cnt!=data[hdr+7] ){
+ if( cnt!=data[hdr+7] ){
checkAppendMsg(pCheck,
"Fragmentation of %d bytes reported as %d on page %d",
cnt, data[hdr+7], iPage);
}
}
- sqlite3PageFree(heap);
+ sqlite3PageFree(hit);
releasePage(pPage);
end_of_check:
@@ -61947,7 +64421,8 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
}
i = PENDING_BYTE_PAGE(pBt);
if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
- sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
+ sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
+ sCheck.errMsg.useMalloc = 2;
/* Check the integrity of the freelist
*/
@@ -62264,23 +64739,14 @@ SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
}
/*
-** set the mask of hint flags for cursor pCsr.
+** set the mask of hint flags for cursor pCsr. Currently the only valid
+** values are 0 and BTREE_BULKLOAD.
*/
SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
- assert( mask==BTREE_BULKLOAD || mask==BTREE_SEEK_EQ || mask==0 );
+ assert( mask==BTREE_BULKLOAD || mask==0 );
pCsr->hints = mask;
}
-#ifdef SQLITE_DEBUG
-/*
-** Return true if the cursor has a hint specified. This routine is
-** only used from within assert() statements
-*/
-SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){
- return (pCsr->hints & mask)!=0;
-}
-#endif
-
/*
** Return true if the given Btree is read-only.
*/
@@ -62439,7 +64905,7 @@ static int checkReadTransaction(sqlite3 *db, Btree *p){
** If an error occurs, NULL is returned and an error code and error message
** stored in database handle pDestDb.
*/
-SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
+SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3* pDestDb, /* Database to write to */
const char *zDestDb, /* Name of database within pDestDb */
sqlite3* pSrcDb, /* Database connection to read from */
@@ -62542,7 +65008,7 @@ static int backupOnePage(
** 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);
+ int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
#endif
int rc = SQLITE_OK;
i64 iOff;
@@ -62647,7 +65113,7 @@ static void attachBackupObject(sqlite3_backup *p){
/*
** Copy nPage pages from the source b-tree to the destination.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage){
+SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
int rc;
int destMode; /* Destination journal mode */
int pgszSrc = 0; /* Source page size */
@@ -62892,7 +65358,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage){
/*
** Release all resources associated with an sqlite3_backup* handle.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p){
+SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
sqlite3_backup **pp; /* Ptr to head of pagers backup list */
sqlite3 *pSrcDb; /* Source database connection */
int rc; /* Value to return */
@@ -62944,7 +65410,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p){
** Return the number of pages still to be backed up as of the most recent
** call to sqlite3_backup_step().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p){
+SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ){
(void)SQLITE_MISUSE_BKPT;
@@ -62958,7 +65424,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p){
** Return the total number of pages in the source database as of the most
** recent call to sqlite3_backup_step().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p){
+SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ){
(void)SQLITE_MISUSE_BKPT;
@@ -63283,11 +65749,10 @@ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
pMem->flags |= MEM_Term;
- }
- pMem->flags &= ~MEM_Ephem;
#ifdef SQLITE_DEBUG
- pMem->pScopyFrom = 0;
+ pMem->pScopyFrom = 0;
#endif
+ }
return SQLITE_OK;
}
@@ -64174,7 +66639,7 @@ struct ValueNewStat4Ctx {
** Otherwise, if the second argument is non-zero, then this function is
** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not
** already been allocated, allocate the UnpackedRecord structure that
-** that function will return to its caller here. Then return a pointer to
+** that function will return to its caller here. Then return a pointer
** an sqlite3_value within the UnpackedRecord.a[] array.
*/
static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
@@ -64219,113 +66684,6 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
}
/*
-** The expression object indicated by the second argument is guaranteed
-** to be a scalar SQL function. If
-**
-** * all function arguments are SQL literals,
-** * the SQLITE_FUNC_CONSTANT function flag is set, and
-** * the SQLITE_FUNC_NEEDCOLL function flag is not set,
-**
-** then this routine attempts to invoke the SQL function. Assuming no
-** error occurs, output parameter (*ppVal) is set to point to a value
-** object containing the result before returning SQLITE_OK.
-**
-** Affinity aff is applied to the result of the function before returning.
-** If the result is a text value, the sqlite3_value object uses encoding
-** enc.
-**
-** If the conditions above are not met, this function returns SQLITE_OK
-** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to
-** NULL and an SQLite error code returned.
-*/
-#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
-static int valueFromFunction(
- sqlite3 *db, /* The database connection */
- Expr *p, /* The expression to evaluate */
- u8 enc, /* Encoding to use */
- u8 aff, /* Affinity to use */
- sqlite3_value **ppVal, /* Write the new value here */
- struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */
-){
- sqlite3_context ctx; /* Context object for function invocation */
- sqlite3_value **apVal = 0; /* Function arguments */
- int nVal = 0; /* Size of apVal[] array */
- FuncDef *pFunc = 0; /* Function definition */
- sqlite3_value *pVal = 0; /* New value */
- int rc = SQLITE_OK; /* Return code */
- int nName; /* Size of function name in bytes */
- ExprList *pList = 0; /* Function arguments */
- int i; /* Iterator variable */
-
- assert( pCtx!=0 );
- assert( (p->flags & EP_TokenOnly)==0 );
- pList = p->x.pList;
- if( pList ) nVal = pList->nExpr;
- nName = sqlite3Strlen30(p->u.zToken);
- pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0);
- assert( pFunc );
- if( (pFunc->funcFlags & SQLITE_FUNC_CONSTANT)==0
- || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
- ){
- return SQLITE_OK;
- }
-
- if( pList ){
- apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
- if( apVal==0 ){
- rc = SQLITE_NOMEM;
- goto value_from_function_out;
- }
- for(i=0; i<nVal; i++){
- rc = sqlite3ValueFromExpr(db, pList->a[i].pExpr, enc, aff, &apVal[i]);
- if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out;
- }
- }
-
- pVal = valueNew(db, pCtx);
- if( pVal==0 ){
- rc = SQLITE_NOMEM;
- goto value_from_function_out;
- }
-
- assert( pCtx->pParse->rc==SQLITE_OK );
- memset(&ctx, 0, sizeof(ctx));
- ctx.pOut = pVal;
- ctx.pFunc = pFunc;
- pFunc->xFunc(&ctx, nVal, apVal);
- if( ctx.isError ){
- rc = ctx.isError;
- sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal));
- }else{
- sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8);
- assert( rc==SQLITE_OK );
- rc = sqlite3VdbeChangeEncoding(pVal, enc);
- if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){
- rc = SQLITE_TOOBIG;
- pCtx->pParse->nErr++;
- }
- }
- pCtx->pParse->rc = rc;
-
- value_from_function_out:
- if( rc!=SQLITE_OK ){
- pVal = 0;
- }
- if( apVal ){
- for(i=0; i<nVal; i++){
- sqlite3ValueFree(apVal[i]);
- }
- sqlite3DbFree(db, apVal);
- }
-
- *ppVal = pVal;
- return rc;
-}
-#else
-# define valueFromFunction(a,b,c,d,e,f) SQLITE_OK
-#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
-
-/*
** Extract a value from the supplied expression in the manner described
** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object
** using valueNew().
@@ -64357,12 +66715,6 @@ static int valueFromExpr(
while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft;
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
- /* Compressed expressions only appear when parsing the DEFAULT clause
- ** on a table column definition, and hence only when pCtx==0. This
- ** check ensures that an EP_TokenOnly expression is never passed down
- ** into valueFromFunction(). */
- assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 );
-
if( op==TK_CAST ){
u8 aff = sqlite3AffinityType(pExpr->u.zToken,0);
rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
@@ -64439,12 +66791,6 @@ static int valueFromExpr(
}
#endif
-#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
- else if( op==TK_FUNCTION && pCtx!=0 ){
- rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
- }
-#endif
-
*ppVal = pVal;
return rc;
@@ -64731,7 +67077,7 @@ SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
Mem *aMem = pRec->aMem;
sqlite3 *db = aMem[0].db;
for(i=0; i<nCol; i++){
- sqlite3VdbeMemRelease(&aMem[i]);
+ if( aMem[i].szMalloc ) sqlite3DbFree(db, aMem[i].zMalloc);
}
sqlite3KeyInfoUnref(pRec->pKeyInfo);
sqlite3DbFree(db, pRec);
@@ -64834,7 +67180,7 @@ SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepa
/*
** Return the SQL associated with a prepared statement
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt){
+SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe *)pStmt;
return (p && p->isPrepareV2) ? p->zSql : 0;
}
@@ -65897,7 +68243,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
#ifndef SQLITE_OMIT_VIRTUALTABLE
case P4_VTAB: {
sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
- sqlite3_snprintf(nTemp, zTemp, "vtab:%p", pVtab);
+ sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
break;
}
#endif
@@ -66561,37 +68907,20 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
else if( pCx->pVtabCursor ){
sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
- assert( pVtabCursor->pVtab->nRef>0 );
- pVtabCursor->pVtab->nRef--;
+ p->inVtabMethod = 1;
pModule->xClose(pVtabCursor);
+ p->inVtabMethod = 0;
}
#endif
}
/*
-** Close all cursors in the current frame.
-*/
-static void closeCursorsInFrame(Vdbe *p){
- if( p->apCsr ){
- int i;
- for(i=0; i<p->nCursor; i++){
- VdbeCursor *pC = p->apCsr[i];
- if( pC ){
- sqlite3VdbeFreeCursor(p, pC);
- p->apCsr[i] = 0;
- }
- }
- }
-}
-
-/*
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
** is used, for example, when a trigger sub-program is halted to restore
** control to the main program.
*/
SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
Vdbe *v = pFrame->v;
- closeCursorsInFrame(v);
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
v->anExec = pFrame->anExec;
#endif
@@ -66626,7 +68955,17 @@ static void closeAllCursors(Vdbe *p){
p->nFrame = 0;
}
assert( p->nFrame==0 );
- closeCursorsInFrame(p);
+
+ if( p->apCsr ){
+ int i;
+ for(i=0; i<p->nCursor; i++){
+ VdbeCursor *pC = p->apCsr[i];
+ if( pC ){
+ sqlite3VdbeFreeCursor(p, pC);
+ p->apCsr[i] = 0;
+ }
+ }
+ }
if( p->aMem ){
releaseMemArray(&p->aMem[1], p->nMem);
}
@@ -66929,7 +69268,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
** doing this the directory is synced again before any individual
** transaction files are deleted.
*/
- rc = sqlite3OsDelete(pVfs, zMaster, needSync);
+ rc = sqlite3OsDelete(pVfs, zMaster, 1);
sqlite3DbFree(db, zMaster);
zMaster = 0;
if( rc ){
@@ -68159,8 +70498,7 @@ static void vdbeAssertFieldCountWithinLimits(
if( CORRUPT_DB ) return;
idx = getVarint32(aKey, szHdr);
- assert( nKey>=0 );
- assert( szHdr<=(u32)nKey );
+ assert( szHdr<=nKey );
while( idx<szHdr ){
idx += getVarint32(aKey+idx, notUsed);
nField++;
@@ -68371,7 +70709,7 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the
** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db).
*/
-SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
+static int vdbeRecordCompareWithSkip(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2, /* Right key */
int bSkip /* If true, skip the first field */
@@ -68557,7 +70895,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2 /* Right key */
){
- return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
+ return vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
}
@@ -68645,7 +70983,7 @@ static int vdbeRecordCompareInt(
}else if( pPKey2->nField>1 ){
/* The first fields of the two keys are equal. Compare the trailing
** fields. */
- res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
+ res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
}else{
/* The first fields of the two keys are equal and there are no trailing
** fields. Return pPKey2->default_rc in this case. */
@@ -68693,7 +71031,7 @@ static int vdbeRecordCompareString(
res = nStr - pPKey2->aMem[0].n;
if( res==0 ){
if( pPKey2->nField>1 ){
- res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
+ res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
}else{
res = pPKey2->default_rc;
}
@@ -68997,7 +71335,7 @@ SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){
** collating sequences are registered or if an authorizer function is
** added or changed.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
return p==0 || p->expired;
}
@@ -69034,7 +71372,7 @@ static int vdbeSafetyNotNull(Vdbe *p){
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
/* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL
@@ -69060,7 +71398,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt){
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
rc = SQLITE_OK;
@@ -69079,7 +71417,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt){
/*
** Set all the parameters in the compiled SQL statement to NULL.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
int i;
int rc = SQLITE_OK;
Vdbe *p = (Vdbe*)pStmt;
@@ -69103,7 +71441,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt *pStmt){
** The following routines extract information from a Mem or sqlite3_value
** structure.
*/
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value *pVal){
+SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){
Mem *p = (Mem*)pVal;
if( p->flags & (MEM_Blob|MEM_Str) ){
sqlite3VdbeMemExpandBlob(p);
@@ -69113,40 +71451,36 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value *pVal){
return sqlite3_value_text(pVal);
}
}
-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value *pVal){
+SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){
return sqlite3ValueBytes(pVal, SQLITE_UTF8);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value *pVal){
+SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){
return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
}
-SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value *pVal){
+SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){
return sqlite3VdbeRealValue((Mem*)pVal);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value *pVal){
+SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){
return (int)sqlite3VdbeIntValue((Mem*)pVal);
}
-SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value *pVal){
+SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
return sqlite3VdbeIntValue((Mem*)pVal);
}
-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value *pVal){
+SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value* pVal){
+SQLITE_API const void *sqlite3_value_text16(sqlite3_value* pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
}
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value *pVal){
+SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16BE);
}
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value *pVal){
+SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16LE);
}
#endif /* SQLITE_OMIT_UTF16 */
-/* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five
-** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
-** point number string BLOB NULL
-*/
-SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value* pVal){
+SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
static const u8 aType[] = {
SQLITE_BLOB, /* 0x00 */
SQLITE_NULL, /* 0x01 */
@@ -69222,7 +71556,7 @@ static int invokeValueDestructor(
if( pCtx ) sqlite3_result_error_toobig(pCtx);
return SQLITE_TOOBIG;
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(
+SQLITE_API void sqlite3_result_blob(
sqlite3_context *pCtx,
const void *z,
int n,
@@ -69232,7 +71566,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, 0, xDel);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(
+SQLITE_API void sqlite3_result_blob64(
sqlite3_context *pCtx,
const void *z,
sqlite3_uint64 n,
@@ -69246,37 +71580,37 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(
setResultStrOrError(pCtx, z, (int)n, 0, xDel);
}
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context *pCtx, double rVal){
+SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetDouble(pCtx->pOut, rVal);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
+SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
+SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
-SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context *pCtx, int iVal){
+SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
+SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetInt64(pCtx->pOut, iVal);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context *pCtx){
+SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text(
+SQLITE_API void sqlite3_result_text(
sqlite3_context *pCtx,
const char *z,
int n,
@@ -69285,7 +71619,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_text(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(
+SQLITE_API void sqlite3_result_text64(
sqlite3_context *pCtx,
const char *z,
sqlite3_uint64 n,
@@ -69302,7 +71636,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(
}
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(
+SQLITE_API void sqlite3_result_text16(
sqlite3_context *pCtx,
const void *z,
int n,
@@ -69311,7 +71645,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(
+SQLITE_API void sqlite3_result_text16be(
sqlite3_context *pCtx,
const void *z,
int n,
@@ -69320,7 +71654,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(
+SQLITE_API void sqlite3_result_text16le(
sqlite3_context *pCtx,
const void *z,
int n,
@@ -69330,20 +71664,17 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(
setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
}
#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
+SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemCopy(pCtx->pOut, pValue);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
+SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
+SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
pCtx->isError = errCode;
pCtx->fErrorOrAux = 1;
-#ifdef SQLITE_DEBUG
- if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
-#endif
if( pCtx->pOut->flags & MEM_Null ){
sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1,
SQLITE_UTF8, SQLITE_STATIC);
@@ -69351,7 +71682,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context *pCtx,
}
/* Force an SQLITE_TOOBIG error. */
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context *pCtx){
+SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_TOOBIG;
pCtx->fErrorOrAux = 1;
@@ -69360,7 +71691,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context *pCtx
}
/* An SQLITE_NOMEM error. */
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context *pCtx){
+SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
pCtx->isError = SQLITE_NOMEM;
@@ -69424,7 +71755,7 @@ static int sqlite3Step(Vdbe *p){
** or SQLITE_BUSY error.
*/
#ifdef SQLITE_OMIT_AUTORESET
- if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){
+ if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){
sqlite3_reset((sqlite3_stmt*)p);
}else{
return SQLITE_MISUSE_BKPT;
@@ -69470,9 +71801,6 @@ static int sqlite3Step(Vdbe *p){
if( p->bIsReader ) db->nVdbeRead++;
p->pc = 0;
}
-#ifdef SQLITE_DEBUG
- p->rcApp = SQLITE_OK;
-#endif
#ifndef SQLITE_OMIT_EXPLAIN
if( p->explain ){
rc = sqlite3VdbeList(p);
@@ -69517,7 +71845,7 @@ end_of_step:
assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR
|| rc==SQLITE_BUSY || rc==SQLITE_MISUSE
);
- assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp );
+ assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE );
if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
/* If this statement was prepared using sqlite3_prepare_v2(), and an
** error has occurred, then return the error code in p->rc to the
@@ -69533,7 +71861,7 @@ end_of_step:
** sqlite3Step() to do most of the work. If a schema error occurs,
** call sqlite3Reprepare() and try again.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
int rc = SQLITE_OK; /* Result from sqlite3Step() */
int rc2 = SQLITE_OK; /* Result from sqlite3Reprepare() */
Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */
@@ -69584,7 +71912,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt *pStmt){
** Extract the user data from a sqlite3_context structure and return a
** pointer to it.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context *p){
+SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
assert( p && p->pFunc );
return p->pFunc->pUserData;
}
@@ -69599,32 +71927,22 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context *p){
** sqlite3_create_function16() routines that originally registered the
** application defined function.
*/
-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context *p){
+SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
assert( p && p->pFunc );
return p->pOut->db;
}
/*
-** Return the current time for a statement. If the current time
-** is requested more than once within the same run of a single prepared
-** statement, the exact same time is returned for each invocation regardless
-** of the amount of time that elapses between invocations. In other words,
-** the time returned is always the time of the first call.
+** Return the current time for a statement
*/
SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
+ Vdbe *v = p->pVdbe;
int rc;
-#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
- sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime;
- assert( p->pVdbe!=0 );
-#else
- sqlite3_int64 iTime = 0;
- sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime;
-#endif
- if( *piTime==0 ){
- rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime);
- if( rc ) *piTime = 0;
+ if( v->iCurrentTime==0 ){
+ rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, &v->iCurrentTime);
+ if( rc ) v->iCurrentTime = 0;
}
- return *piTime;
+ return v->iCurrentTime;
}
/*
@@ -69675,7 +71993,7 @@ static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){
** context is allocated on the first call. Subsequent calls return the
** same context that was returned on prior calls.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context *p, int nByte){
+SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
assert( p && p->pFunc && p->pFunc->xStep );
assert( sqlite3_mutex_held(p->pOut->db->mutex) );
testcase( nByte<0 );
@@ -69690,15 +72008,10 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context *p, in
** Return the auxiliary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
+SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
AuxData *pAuxData;
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
-#if SQLITE_ENABLE_STAT3_OR_STAT4
- if( pCtx->pVdbe==0 ) return 0;
-#else
- assert( pCtx->pVdbe!=0 );
-#endif
for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
}
@@ -69711,7 +72024,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context *pCtx, int i
** argument to the user-function defined by pCtx. Any previous value is
** deleted by calling the delete function specified when it was set.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(
+SQLITE_API void sqlite3_set_auxdata(
sqlite3_context *pCtx,
int iArg,
void *pAux,
@@ -69722,11 +72035,6 @@ SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
if( iArg<0 ) goto failed;
-#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
- if( pVdbe==0 ) goto failed;
-#else
- assert( pVdbe!=0 );
-#endif
for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
@@ -69766,7 +72074,7 @@ failed:
** implementations should keep their own counts within their aggregate
** context.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context *p){
+SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){
assert( p && p->pMem && p->pFunc && p->pFunc->xStep );
return p->pMem->n;
}
@@ -69775,7 +72083,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context *p){
/*
** Return the number of columns in the result set for the statement pStmt.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
return pVm ? pVm->nResColumn : 0;
}
@@ -69784,7 +72092,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt){
** Return the number of values available from the current row of the
** currently executing statement pStmt.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
if( pVm==0 || pVm->pResultSet==0 ) return 0;
return pVm->nResColumn;
@@ -69886,7 +72194,7 @@ static void columnMallocFailure(sqlite3_stmt *pStmt)
** The following routines are used to access elements of the current row
** in the result set.
*/
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
+SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
const void *val;
val = sqlite3_value_blob( columnMem(pStmt,i) );
/* Even though there is no encoding conversion, value_blob() might
@@ -69896,37 +72204,37 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt *pStmt, i
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
int val = sqlite3_value_bytes( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
int val = sqlite3_value_bytes16( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt *pStmt, int i){
+SQLITE_API double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
double val = sqlite3_value_double( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
int val = sqlite3_value_int( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
+SQLITE_API sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt *pStmt, int i){
+SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt *pStmt, int i){
+SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
Mem *pOut = columnMem(pStmt, i);
if( pOut->flags&MEM_Static ){
pOut->flags &= ~MEM_Static;
@@ -69936,13 +72244,13 @@ SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt *pStm
return (sqlite3_value *)pOut;
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
+SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
const void *val = sqlite3_value_text16( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
int iType = sqlite3_value_type( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return iType;
@@ -70006,12 +72314,12 @@ static const void *columnName(
** Return the name of the Nth column of the result set returned by SQL
** statement pStmt.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME);
}
@@ -70031,12 +72339,12 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt *pStmt,
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE);
}
@@ -70049,12 +72357,12 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt *pS
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unambiguous reference to a database column.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE);
}
@@ -70065,12 +72373,12 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stm
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unambiguous reference to a database column.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE);
}
@@ -70081,12 +72389,12 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt *
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unambiguous reference to a database column.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN);
}
@@ -70187,7 +72495,7 @@ static int bindText(
/*
** Bind a blob value to an SQL statement variable.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(
+SQLITE_API int sqlite3_bind_blob(
sqlite3_stmt *pStmt,
int i,
const void *zData,
@@ -70196,7 +72504,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(
){
return bindText(pStmt, i, zData, nData, xDel, 0);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(
+SQLITE_API int sqlite3_bind_blob64(
sqlite3_stmt *pStmt,
int i,
const void *zData,
@@ -70210,7 +72518,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(
return bindText(pStmt, i, zData, (int)nData, xDel, 0);
}
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
+SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
@@ -70220,10 +72528,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt *pStmt, int i, do
}
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
+SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
return sqlite3_bind_int64(p, i, (i64)iValue);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
+SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
@@ -70233,7 +72541,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sql
}
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
int rc;
Vdbe *p = (Vdbe*)pStmt;
rc = vdbeUnbind(p, i);
@@ -70242,7 +72550,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
}
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(
+SQLITE_API int sqlite3_bind_text(
sqlite3_stmt *pStmt,
int i,
const char *zData,
@@ -70251,7 +72559,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(
){
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(
+SQLITE_API int sqlite3_bind_text64(
sqlite3_stmt *pStmt,
int i,
const char *zData,
@@ -70268,7 +72576,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(
}
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(
+SQLITE_API int sqlite3_bind_text16(
sqlite3_stmt *pStmt,
int i,
const void *zData,
@@ -70278,7 +72586,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
}
#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
+SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
int rc;
switch( sqlite3_value_type((sqlite3_value*)pValue) ){
case SQLITE_INTEGER: {
@@ -70309,7 +72617,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt *pStmt, int i, con
}
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
+SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
@@ -70324,7 +72632,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i,
** Return the number of wildcards that can be potentially bound to.
** This routine is added to support DBD::SQLite.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
return p ? p->nVar : 0;
}
@@ -70335,7 +72643,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
**
** The result is always UTF-8.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
+SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
Vdbe *p = (Vdbe*)pStmt;
if( p==0 || i<1 || i>p->nzVar ){
return 0;
@@ -70363,7 +72671,7 @@ SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nNa
}
return 0;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
+SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName));
}
@@ -70397,7 +72705,7 @@ SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt
** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise
** SQLITE_OK is returned.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
+SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
Vdbe *pFrom = (Vdbe*)pFromStmt;
Vdbe *pTo = (Vdbe*)pToStmt;
if( pFrom->nVar!=pTo->nVar ){
@@ -70419,7 +72727,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt,
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt *pStmt){
+SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->db : 0;
}
@@ -70427,14 +72735,14 @@ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt *pStmt){
** Return true if the prepared statement is guaranteed to not modify the
** database.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
}
/*
** Return true if the prepared statement is in need of being reset.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
Vdbe *v = (Vdbe*)pStmt;
return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN;
}
@@ -70445,7 +72753,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt *pStmt){
** prepared statement for the database connection. Return NULL if there
** are no more.
*/
-SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
+SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
sqlite3_stmt *pNext;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(pDb) ){
@@ -70466,7 +72774,7 @@ SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_
/*
** Return the value of a status counter for a prepared statement
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
+SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
Vdbe *pVdbe = (Vdbe*)pStmt;
u32 v;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -70484,7 +72792,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, i
/*
** Return status data for a single loop within query pStmt.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
+SQLITE_API int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement being queried */
int idx, /* Index of loop to report on */
int iScanStatusOp, /* Which metric to return */
@@ -70543,7 +72851,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
/*
** Zero all counters associated with the sqlite3_stmt_scanstatus() data.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
+SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
memset(p->anExec, 0, p->nOp * sizeof(i64));
}
@@ -70635,8 +72943,9 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
char zBase[100]; /* Initial working space */
db = p->db;
- sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase),
+ sqlite3StrAccumInit(&out, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
+ out.db = db;
if( db->nVdbeExec>1 ){
while( *zRawSql ){
const char *zStart = zRawSql;
@@ -70645,8 +72954,6 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
assert( (zRawSql - zStart) > 0 );
sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
}
- }else if( p->nVar==0 ){
- sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql));
}else{
while( zRawSql[0] ){
n = findNextHostParameter(zRawSql, &nToken);
@@ -70663,12 +72970,10 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
idx = nextIndex;
}
}else{
- assert( zRawSql[0]==':' || zRawSql[0]=='$' ||
- zRawSql[0]=='@' || zRawSql[0]=='#' );
+ assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' );
testcase( zRawSql[0]==':' );
testcase( zRawSql[0]=='$' );
testcase( zRawSql[0]=='@' );
- testcase( zRawSql[0]=='#' );
idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
assert( idx>0 );
}
@@ -71045,7 +73350,7 @@ static void applyAffinity(
** is appropriate. But only do the conversion if it is possible without
** loss of information and return the revised type of the argument.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value *pVal){
+SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){
int eType = sqlite3_value_type(pVal);
if( eType==SQLITE_TEXT ){
Mem *pMem = (Mem*)pVal;
@@ -71343,21 +73648,6 @@ static int checkSavepointCount(sqlite3 *db){
}
#endif
-/*
-** Return the register of pOp->p2 after first preparing it to be
-** overwritten with an integer value.
-*/
-static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
- Mem *pOut;
- assert( pOp->p2>0 );
- assert( pOp->p2<=(p->nMem-p->nCursor) );
- pOut = &p->aMem[pOp->p2];
- memAboutToChange(p, pOut);
- if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
- pOut->flags = MEM_Int;
- return pOut;
-}
-
/*
** Execute as much of a VDBE program as we can.
@@ -71366,11 +73656,9 @@ static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
SQLITE_PRIVATE int sqlite3VdbeExec(
Vdbe *p /* The VDBE */
){
+ int pc=0; /* The program counter */
Op *aOp = p->aOp; /* Copy of p->aOp */
- Op *pOp = aOp; /* Current operation */
-#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
- Op *pOrigOp; /* Value of pOp at the top of the loop */
-#endif
+ Op *pOp; /* Current operation */
int rc = SQLITE_OK; /* Value to return */
sqlite3 *db = p->db; /* The database */
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
@@ -71446,22 +73734,23 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
}
sqlite3EndBenignMalloc();
#endif
- for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){
- assert( pOp>=aOp && pOp<&aOp[p->nOp]);
+ for(pc=p->pc; rc==SQLITE_OK; pc++){
+ assert( pc>=0 && pc<p->nOp );
if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
start = sqlite3Hwtime();
#endif
nVmStep++;
+ pOp = &aOp[pc];
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
- if( p->anExec ) p->anExec[(int)(pOp-aOp)]++;
+ if( p->anExec ) p->anExec[pc]++;
#endif
/* Only allow tracing if SQLITE_DEBUG is defined.
*/
#ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){
- sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp);
+ sqlite3VdbePrintOp(stdout, pc, pOp);
}
#endif
@@ -71478,9 +73767,23 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
}
#endif
+ /* On any opcode with the "out2-prerelease" tag, free any
+ ** external allocations out of mem[p2] and set mem[p2] to be
+ ** an undefined integer. Opcodes will either fill in the integer
+ ** value or convert mem[p2] to a different type.
+ */
+ assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
+ if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
+ assert( pOp->p2>0 );
+ assert( pOp->p2<=(p->nMem-p->nCursor) );
+ pOut = &aMem[pOp->p2];
+ memAboutToChange(p, pOut);
+ if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
+ pOut->flags = MEM_Int;
+ }
+
/* Sanity checking on other operands */
#ifdef SQLITE_DEBUG
- assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
if( (pOp->opflags & OPFLG_IN1)!=0 ){
assert( pOp->p1>0 );
assert( pOp->p1<=(p->nMem-p->nCursor) );
@@ -71513,9 +73816,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
memAboutToChange(p, &aMem[pOp->p3]);
}
#endif
-#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
- pOrigOp = pOp;
-#endif
switch( pOp->opcode ){
@@ -71539,7 +73839,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
**
** Other keywords in the comment that follows each case are used to
** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[].
-** Keywords include: in1, in2, in3, out2, out3. See
+** Keywords include: in1, in2, in3, out2_prerelease, out2, out3. See
** the mkopcodeh.awk script for additional information.
**
** Documentation about VDBE opcodes is generated by scanning this file
@@ -71567,8 +73867,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: { /* jump */
-jump_to_p2_and_check_for_interrupt:
- pOp = &aOp[pOp->p2 - 1];
+ pc = pOp->p2 - 1;
/* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
@@ -71613,13 +73912,9 @@ case OP_Gosub: { /* jump */
assert( VdbeMemDynamic(pIn1)==0 );
memAboutToChange(p, pIn1);
pIn1->flags = MEM_Int;
- pIn1->u.i = (int)(pOp-aOp);
+ pIn1->u.i = pc;
REGISTER_TRACE(pOp->p1, pIn1);
-
- /* Most jump operations do a goto to this spot in order to update
- ** the pOp pointer. */
-jump_to_p2:
- pOp = &aOp[pOp->p2 - 1];
+ pc = pOp->p2 - 1;
break;
}
@@ -71631,7 +73926,7 @@ jump_to_p2:
case OP_Return: { /* in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags==MEM_Int );
- pOp = &aOp[pIn1->u.i];
+ pc = (int)pIn1->u.i;
pIn1->flags = MEM_Undefined;
break;
}
@@ -71655,7 +73950,7 @@ case OP_InitCoroutine: { /* jump */
assert( !VdbeMemDynamic(pOut) );
pOut->u.i = pOp->p3 - 1;
pOut->flags = MEM_Int;
- if( pOp->p2 ) goto jump_to_p2;
+ if( pOp->p2 ) pc = pOp->p2 - 1;
break;
}
@@ -71675,7 +73970,7 @@ case OP_EndCoroutine: { /* in1 */
pCaller = &aOp[pIn1->u.i];
assert( pCaller->opcode==OP_Yield );
assert( pCaller->p2>=0 && pCaller->p2<p->nOp );
- pOp = &aOp[pCaller->p2 - 1];
+ pc = pCaller->p2 - 1;
pIn1->flags = MEM_Undefined;
break;
}
@@ -71699,9 +73994,9 @@ case OP_Yield: { /* in1, jump */
assert( VdbeMemDynamic(pIn1)==0 );
pIn1->flags = MEM_Int;
pcDest = (int)pIn1->u.i;
- pIn1->u.i = (int)(pOp - aOp);
+ pIn1->u.i = pc;
REGISTER_TRACE(pOp->p1, pIn1);
- pOp = &aOp[pcDest];
+ pc = pcDest;
break;
}
@@ -71752,34 +74047,30 @@ case OP_HaltIfNull: { /* in3 */
case OP_Halt: {
const char *zType;
const char *zLogFmt;
- VdbeFrame *pFrame;
- int pcx;
- pcx = (int)(pOp - aOp);
if( pOp->p1==SQLITE_OK && p->pFrame ){
/* Halt the sub-program. Return control to the parent frame. */
- pFrame = p->pFrame;
+ VdbeFrame *pFrame = p->pFrame;
p->pFrame = pFrame->pParent;
p->nFrame--;
sqlite3VdbeSetChanges(db, p->nChange);
- pcx = sqlite3VdbeFrameRestore(pFrame);
+ pc = sqlite3VdbeFrameRestore(pFrame);
lastRowid = db->lastRowid;
if( pOp->p2==OE_Ignore ){
- /* Instruction pcx is the OP_Program that invoked the sub-program
+ /* Instruction pc is the OP_Program that invoked the sub-program
** currently being halted. If the p2 instruction of this OP_Halt
** instruction is set to OE_Ignore, then the sub-program is throwing
** an IGNORE exception. In this case jump to the address specified
** as the p2 of the calling OP_Program. */
- pcx = p->aOp[pcx].p2-1;
+ pc = p->aOp[pc].p2-1;
}
aOp = p->aOp;
aMem = p->aMem;
- pOp = &aOp[pcx];
break;
}
p->rc = pOp->p1;
p->errorAction = (u8)pOp->p2;
- p->pc = pcx;
+ p->pc = pc;
if( p->rc ){
if( pOp->p5 ){
static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
@@ -71803,7 +74094,7 @@ case OP_Halt: {
}else{
sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType);
}
- sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
+ sqlite3_log(pOp->p1, zLogFmt, pc, p->zSql, p->zErrMsg);
}
rc = sqlite3VdbeHalt(p);
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
@@ -71822,8 +74113,7 @@ case OP_Halt: {
**
** The 32-bit integer value P1 is written into register P2.
*/
-case OP_Integer: { /* out2 */
- pOut = out2Prerelease(p, pOp);
+case OP_Integer: { /* out2-prerelease */
pOut->u.i = pOp->p1;
break;
}
@@ -71834,8 +74124,7 @@ case OP_Integer: { /* out2 */
** P4 is a pointer to a 64-bit integer value.
** Write that value into register P2.
*/
-case OP_Int64: { /* out2 */
- pOut = out2Prerelease(p, pOp);
+case OP_Int64: { /* out2-prerelease */
assert( pOp->p4.pI64!=0 );
pOut->u.i = *pOp->p4.pI64;
break;
@@ -71848,8 +74137,7 @@ case OP_Int64: { /* out2 */
** P4 is a pointer to a 64-bit floating point value.
** Write that value into register P2.
*/
-case OP_Real: { /* same as TK_FLOAT, out2 */
- pOut = out2Prerelease(p, pOp);
+case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
pOut->flags = MEM_Real;
assert( !sqlite3IsNaN(*pOp->p4.pReal) );
pOut->u.r = *pOp->p4.pReal;
@@ -71861,13 +74149,12 @@ case OP_Real: { /* same as TK_FLOAT, out2 */
** Synopsis: r[P2]='P4'
**
** P4 points to a nul terminated UTF-8 string. This opcode is transformed
-** into a String opcode before it is executed for the first time. During
+** into a String before it is executed for the first time. During
** this transformation, the length of string P4 is computed and stored
** as the P1 parameter.
*/
-case OP_String8: { /* same as TK_STRING, out2 */
+case OP_String8: { /* same as TK_STRING, out2-prerelease */
assert( pOp->p4.z!=0 );
- pOut = out2Prerelease(p, pOp);
pOp->opcode = OP_String;
pOp->p1 = sqlite3Strlen30(pOp->p4.z);
@@ -71894,31 +74181,18 @@ case OP_String8: { /* same as TK_STRING, out2 */
/* Fall through to the next case, OP_String */
}
-/* Opcode: String P1 P2 P3 P4 P5
+/* Opcode: String P1 P2 * P4 *
** Synopsis: r[P2]='P4' (len=P1)
**
** The string value P4 of length P1 (bytes) is stored in register P2.
-**
-** If P5!=0 and the content of register P3 is greater than zero, then
-** the datatype of the register P2 is converted to BLOB. The content is
-** the same sequence of bytes, it is merely interpreted as a BLOB instead
-** of a string, as if it had been CAST.
*/
-case OP_String: { /* out2 */
+case OP_String: { /* out2-prerelease */
assert( pOp->p4.z!=0 );
- pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
pOut->z = pOp->p4.z;
pOut->n = pOp->p1;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
- if( pOp->p5 ){
- assert( pOp->p3>0 );
- assert( pOp->p3<=(p->nMem-p->nCursor) );
- pIn3 = &aMem[pOp->p3];
- assert( pIn3->flags & MEM_Int );
- if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term;
- }
break;
}
@@ -71934,10 +74208,9 @@ case OP_String: { /* out2 */
** NULL values will not compare equal even if SQLITE_NULLEQ is set on
** OP_Ne or OP_Eq.
*/
-case OP_Null: { /* out2 */
+case OP_Null: { /* out2-prerelease */
int cnt;
u16 nullFlag;
- pOut = out2Prerelease(p, pOp);
cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=(p->nMem-p->nCursor) );
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
@@ -71972,9 +74245,8 @@ case OP_SoftNull: {
** P4 points to a blob of data P1 bytes long. Store this
** blob in register P2.
*/
-case OP_Blob: { /* out2 */
+case OP_Blob: { /* out2-prerelease */
assert( pOp->p1 <= SQLITE_MAX_LENGTH );
- pOut = out2Prerelease(p, pOp);
sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
@@ -71989,7 +74261,7 @@ case OP_Blob: { /* out2 */
** If the parameter is named, then its name appears in P4.
** The P4 value is used by sqlite3_bind_parameter_name().
*/
-case OP_Variable: { /* out2 */
+case OP_Variable: { /* out2-prerelease */
Mem *pVar; /* Value being transferred */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
@@ -71998,7 +74270,6 @@ case OP_Variable: { /* out2 */
if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
}
- pOut = out2Prerelease(p, pOp);
sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
break;
@@ -72033,11 +74304,10 @@ case OP_Move: {
memAboutToChange(p, pOut);
sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
- if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<pOut ){
- pOut->pScopyFrom += pOp->p2 - p1;
+ if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){
+ pOut->pScopyFrom += p1 - pOp->p2;
}
#endif
- Deephemeralize(pOut);
REGISTER_TRACE(p2++, pOut);
pIn1++;
pOut++;
@@ -72176,7 +74446,7 @@ case OP_ResultRow: {
/* Return SQLITE_ROW
*/
- p->pc = (int)(pOp - aOp) + 1;
+ p->pc = pc + 1;
rc = SQLITE_ROW;
goto vdbe_return;
}
@@ -72369,7 +74639,7 @@ arithmetic_result_is_null:
**
** The interface used by the implementation of the aforementioned functions
** to retrieve the collation sequence set by this opcode is not available
-** publicly. Only built-in functions have access to this feature.
+** publicly, only to user functions defined in func.c.
*/
case OP_CollSeq: {
assert( pOp->p4type==P4_COLLSEQ );
@@ -72422,7 +74692,7 @@ case OP_Function: {
assert( pOp->p4type==P4_FUNCDEF );
ctx.pFunc = pOp->p4.pFunc;
- ctx.iOp = (int)(pOp - aOp);
+ ctx.iOp = pc;
ctx.pVdbe = p;
MemSetTypeFlag(ctx.pOut, MEM_Null);
ctx.fErrorOrAux = 0;
@@ -72436,7 +74706,7 @@ case OP_Function: {
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
rc = ctx.isError;
}
- sqlite3VdbeDeleteAuxData(p, (int)(pOp - aOp), pOp->p1);
+ sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
}
/* Copy the result of the function into register P3 */
@@ -72565,7 +74835,8 @@ case OP_MustBeInt: { /* jump, in1 */
rc = SQLITE_MISMATCH;
goto abort_due_to_error;
}else{
- goto jump_to_p2;
+ pc = pOp->p2 - 1;
+ break;
}
}
}
@@ -72751,7 +75022,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
}else{
VdbeBranchTaken(2,3);
if( pOp->p5 & SQLITE_JUMPIFNULL ){
- goto jump_to_p2;
+ pc = pOp->p2-1;
}
}
break;
@@ -72771,15 +75042,11 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
testcase( pIn1->flags & MEM_Int );
testcase( pIn1->flags & MEM_Real );
sqlite3VdbeMemStringify(pIn1, encoding, 1);
- testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
- flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
}
if( (pIn3->flags & MEM_Str)==0 && (pIn3->flags & (MEM_Int|MEM_Real))!=0 ){
testcase( pIn3->flags & MEM_Int );
testcase( pIn3->flags & MEM_Real );
sqlite3VdbeMemStringify(pIn3, encoding, 1);
- testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) );
- flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
}
}
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
@@ -72803,12 +75070,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
default: res = res>=0; break;
}
- /* Undo any changes made by applyAffinity() to the input registers. */
- assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
- pIn1->flags = flags1;
- assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
- pIn3->flags = flags3;
-
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
@@ -72818,9 +75079,12 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
}else{
VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
if( res ){
- goto jump_to_p2;
+ pc = pOp->p2-1;
}
}
+ /* Undo any changes made by applyAffinity() to the input registers. */
+ pIn1->flags = flags1;
+ pIn3->flags = flags3;
break;
}
@@ -72915,11 +75179,11 @@ case OP_Compare: {
*/
case OP_Jump: { /* jump */
if( iCompare<0 ){
- VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1];
+ pc = pOp->p1 - 1; VdbeBranchTaken(0,3);
}else if( iCompare==0 ){
- VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1];
+ pc = pOp->p2 - 1; VdbeBranchTaken(1,3);
}else{
- VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1];
+ pc = pOp->p3 - 1; VdbeBranchTaken(2,3);
}
break;
}
@@ -73029,7 +75293,7 @@ case OP_Once: { /* jump */
assert( pOp->p1<p->nOnceFlag );
VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
if( p->aOnceFlag[pOp->p1] ){
- goto jump_to_p2;
+ pc = pOp->p2-1;
}else{
p->aOnceFlag[pOp->p1] = 1;
}
@@ -73064,7 +75328,7 @@ case OP_IfNot: { /* jump, in1 */
}
VdbeBranchTaken(c!=0, 2);
if( c ){
- goto jump_to_p2;
+ pc = pOp->p2-1;
}
break;
}
@@ -73078,7 +75342,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
pIn1 = &aMem[pOp->p1];
VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2);
if( (pIn1->flags & MEM_Null)!=0 ){
- goto jump_to_p2;
+ pc = pOp->p2 - 1;
}
break;
}
@@ -73092,7 +75356,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
pIn1 = &aMem[pOp->p1];
VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2);
if( (pIn1->flags & MEM_Null)==0 ){
- goto jump_to_p2;
+ pc = pOp->p2 - 1;
}
break;
}
@@ -73306,7 +75570,7 @@ case OP_Column: {
}
}
- /* If after trying to extract new entries from the header, nHdrParsed is
+ /* If after trying to extra new entries from the header, nHdrParsed is
** still not up to p2, that means that the record has fewer than p2
** columns. So the result will be either the default value or a NULL.
*/
@@ -73430,7 +75694,7 @@ case OP_MakeRecord: {
u64 nData; /* Number of bytes of data space */
int nHdr; /* Number of bytes of header space */
i64 nByte; /* Data space required for this record */
- i64 nZero; /* Number of zero bytes at the end of the record */
+ int nZero; /* Number of zero bytes at the end of the record */
int nVarint; /* Number of bytes in a varint */
u32 serial_type; /* Type field */
Mem *pData0; /* First field to be combined into the record */
@@ -73522,7 +75786,7 @@ case OP_MakeRecord: {
if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
}
nByte = nHdr+nData;
- if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
@@ -73573,7 +75837,7 @@ case OP_MakeRecord: {
** opened by cursor P1 in register P2
*/
#ifndef SQLITE_OMIT_BTREECOUNT
-case OP_Count: { /* out2 */
+case OP_Count: { /* out2-prerelease */
i64 nEntry;
BtCursor *pCrsr;
@@ -73581,7 +75845,6 @@ case OP_Count: { /* out2 */
assert( pCrsr );
nEntry = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3BtreeCount(pCrsr, &nEntry);
- pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
break;
}
@@ -73695,7 +75958,7 @@ case OP_Savepoint: {
}
db->autoCommit = 1;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pc = (int)(pOp - aOp);
+ p->pc = pc;
db->autoCommit = 0;
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
@@ -73754,7 +76017,7 @@ case OP_Savepoint: {
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
}
- if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){
+ if( !isTransaction ){
rc = sqlite3VtabSavepoint(db, p1, iSavepoint);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
@@ -73814,7 +76077,7 @@ case OP_AutoCommit: {
}else{
db->autoCommit = (u8)desiredAutoCommit;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pc = (int)(pOp - aOp);
+ p->pc = pc;
db->autoCommit = (u8)(1-desiredAutoCommit);
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
@@ -73891,7 +76154,7 @@ case OP_Transaction: {
if( pBt ){
rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
if( rc==SQLITE_BUSY ){
- p->pc = (int)(pOp - aOp);
+ p->pc = pc;
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
@@ -73921,12 +76184,7 @@ case OP_Transaction: {
p->nStmtDefImmCons = db->nDeferredImmCons;
}
- /* Gather the schema version number for checking:
- ** IMPLEMENTATION-OF: R-32195-19465 The schema version is used by SQLite
- ** each time a query is executed to ensure that the internal cache of the
- ** schema used when compiling the SQL query matches the schema of the
- ** database against which the compiled query is actually executed.
- */
+ /* Gather the schema version number for checking */
sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
iGen = db->aDb[pOp->p1].pSchema->iGeneration;
}else{
@@ -73970,7 +76228,7 @@ case OP_Transaction: {
** must be started or there must be an open cursor) before
** executing this instruction.
*/
-case OP_ReadCookie: { /* out2 */
+case OP_ReadCookie: { /* out2-prerelease */
int iMeta;
int iDb;
int iCookie;
@@ -73984,7 +76242,6 @@ case OP_ReadCookie: { /* out2 */
assert( DbMaskTest(p->btreeMask, iDb) );
sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
- pOut = out2Prerelease(p, pOp);
pOut->u.i = iMeta;
break;
}
@@ -74095,29 +76352,31 @@ case OP_SetCookie: { /* in3 */
** See also OpenRead.
*/
case OP_ReopenIdx: {
- int nField;
- KeyInfo *pKeyInfo;
- int p2;
- int iDb;
- int wrFlag;
- Btree *pX;
VdbeCursor *pCur;
- Db *pDb;
- assert( pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ );
+ assert( pOp->p5==0 );
assert( pOp->p4type==P4_KEYINFO );
pCur = p->apCsr[pOp->p1];
if( pCur && pCur->pgnoRoot==(u32)pOp->p2 ){
assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */
- goto open_cursor_set_hints;
+ break;
}
/* If the cursor is not currently open or is open on a different
** index, then fall through into OP_OpenRead to force a reopen */
+}
case OP_OpenRead:
-case OP_OpenWrite:
+case OP_OpenWrite: {
+ int nField;
+ KeyInfo *pKeyInfo;
+ int p2;
+ int iDb;
+ int wrFlag;
+ Btree *pX;
+ VdbeCursor *pCur;
+ Db *pDb;
- assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR|OPFLAG_SEEKEQ))==pOp->p5 );
- assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ );
+ assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
+ assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
assert( p->bIsReader );
assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx
|| p->readOnly==0 );
@@ -74180,17 +76439,14 @@ case OP_OpenWrite:
pCur->pgnoRoot = p2;
rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
pCur->pKeyInfo = pKeyInfo;
+ assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
+ sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
+
/* Set the VdbeCursor.isTable variable. Previous versions of
** SQLite used to check if the root-page flags were sane at this point
** and report database corruption if they were not, but this check has
** since moved into the btree layer. */
pCur->isTable = pOp->p4type!=P4_KEYINFO;
-
-open_cursor_set_hints:
- assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
- assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ );
- sqlite3BtreeCursorHints(pCur->pCursor,
- (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
break;
}
@@ -74306,7 +76562,7 @@ case OP_SequenceTest: {
pC = p->apCsr[pOp->p1];
assert( pC->pSorter );
if( (pC->seqCount++)==0 ){
- goto jump_to_p2;
+ pc = pOp->p2 - 1;
}
break;
}
@@ -74451,22 +76707,6 @@ case OP_SeekGT: { /* jump, in3 */
#ifdef SQLITE_DEBUG
pC->seekOp = pOp->opcode;
#endif
-
- /* 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.
- */
-#ifdef SQLITE_DEBUG
- if( sqlite3BtreeCursorHasHint(pC->pCursor, BTREE_SEEK_EQ) ){
- assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
- assert( pOp[1].opcode==OP_IdxLT || 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 );
- }
-#endif
-
if( pC->isTable ){
/* The input value in P3 might be of any type: integer, real, string,
** blob, or NULL. But it needs to be an integer before we can do
@@ -74483,7 +76723,7 @@ case OP_SeekGT: { /* jump, in3 */
if( (pIn3->flags & MEM_Real)==0 ){
/* If the P3 value cannot be converted into any kind of a number,
** then the seek is not possible, so jump to P2 */
- VdbeBranchTaken(1,2); goto jump_to_p2;
+ pc = pOp->p2 - 1; VdbeBranchTaken(1,2);
break;
}
@@ -74574,7 +76814,7 @@ case OP_SeekGT: { /* jump, in3 */
assert( pOp->p2>0 );
VdbeBranchTaken(res!=0,2);
if( res ){
- goto jump_to_p2;
+ pc = pOp->p2 - 1;
}
break;
}
@@ -74668,7 +76908,6 @@ case OP_NoConflict: /* jump, in3 */
case OP_NotFound: /* jump, in3 */
case OP_Found: { /* jump, in3 */
int alreadyExists;
- int takeJump;
int ii;
VdbeCursor *pC;
int res;
@@ -74691,7 +76930,7 @@ case OP_Found: { /* jump, in3 */
pIn3 = &aMem[pOp->p3];
assert( pC->pCursor!=0 );
assert( pC->isTable==0 );
- pFree = 0;
+ pFree = 0; /* Not needed. Only used to suppress a compiler warning. */
if( pOp->p4.i>0 ){
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p4.i;
@@ -74714,20 +76953,21 @@ case OP_Found: { /* jump, in3 */
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
}
pIdxKey->default_rc = 0;
- takeJump = 0;
if( pOp->opcode==OP_NoConflict ){
/* For the OP_NoConflict opcode, take the jump if any of the
** input fields are NULL, since any key with a NULL will not
** conflict */
for(ii=0; ii<pIdxKey->nField; ii++){
if( pIdxKey->aMem[ii].flags & MEM_Null ){
- takeJump = 1;
+ pc = pOp->p2 - 1; VdbeBranchTaken(1,2);
break;
}
}
}
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res);
- sqlite3DbFree(db, pFree);
+ if( pOp->p4.i==0 ){
+ sqlite3DbFree(db, pFree);
+ }
if( rc!=SQLITE_OK ){
break;
}
@@ -74738,10 +76978,10 @@ case OP_Found: { /* jump, in3 */
pC->cacheStatus = CACHE_STALE;
if( pOp->opcode==OP_Found ){
VdbeBranchTaken(alreadyExists!=0,2);
- if( alreadyExists ) goto jump_to_p2;
+ if( alreadyExists ) pc = pOp->p2 - 1;
}else{
- VdbeBranchTaken(takeJump||alreadyExists==0,2);
- if( takeJump || !alreadyExists ) goto jump_to_p2;
+ VdbeBranchTaken(alreadyExists==0,2);
+ if( !alreadyExists ) pc = pOp->p2 - 1;
}
break;
}
@@ -74790,8 +77030,10 @@ case OP_NotExists: { /* jump, in3 */
pC->cacheStatus = CACHE_STALE;
pC->deferredMoveto = 0;
VdbeBranchTaken(res!=0,2);
+ if( res!=0 ){
+ pc = pOp->p2 - 1;
+ }
pC->seekResult = res;
- if( res!=0 ) goto jump_to_p2;
break;
}
@@ -74803,10 +77045,9 @@ case OP_NotExists: { /* jump, in3 */
** The sequence number on the cursor is incremented after this
** instruction.
*/
-case OP_Sequence: { /* out2 */
+case OP_Sequence: { /* out2-prerelease */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( p->apCsr[pOp->p1]!=0 );
- pOut = out2Prerelease(p, pOp);
pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
break;
}
@@ -74827,7 +77068,7 @@ case OP_Sequence: { /* out2 */
** generated record number. This P3 mechanism is used to help implement the
** AUTOINCREMENT feature.
*/
-case OP_NewRowid: { /* out2 */
+case OP_NewRowid: { /* out2-prerelease */
i64 v; /* The new rowid */
VdbeCursor *pC; /* Cursor of table to get the new rowid */
int res; /* Result of an sqlite3BtreeLast() */
@@ -74837,7 +77078,6 @@ case OP_NewRowid: { /* out2 */
v = 0;
res = 0;
- pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
@@ -75151,7 +77391,9 @@ case OP_SorterCompare: {
res = 0;
rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
VdbeBranchTaken(res!=0,2);
- if( res ) goto jump_to_p2;
+ if( res ){
+ pc = pOp->p2-1;
+ }
break;
};
@@ -75280,13 +77522,12 @@ case OP_RowData: {
** be a separate OP_VRowid opcode for use with virtual tables, but this
** one opcode now works for both table types.
*/
-case OP_Rowid: { /* out2 */
+case OP_Rowid: { /* out2-prerelease */
VdbeCursor *pC;
i64 v;
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
- pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
@@ -75339,7 +77580,7 @@ case OP_NullRow: {
break;
}
-/* Opcode: Last P1 P2 P3 * *
+/* Opcode: Last P1 P2 * * *
**
** The next use of the Rowid or Column or Prev instruction for P1
** will refer to the last entry in the database table or index.
@@ -75366,13 +77607,12 @@ case OP_Last: { /* jump */
pC->nullRow = (u8)res;
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
- pC->seekResult = pOp->p3;
#ifdef SQLITE_DEBUG
pC->seekOp = OP_Last;
#endif
if( pOp->p2>0 ){
VdbeBranchTaken(res!=0,2);
- if( res ) goto jump_to_p2;
+ if( res ) pc = pOp->p2 - 1;
}
break;
}
@@ -75436,7 +77676,9 @@ case OP_Rewind: { /* jump */
pC->nullRow = (u8)res;
assert( pOp->p2>0 && pOp->p2<p->nOp );
VdbeBranchTaken(res!=0,2);
- if( res ) goto jump_to_p2;
+ if( res ){
+ pc = pOp->p2 - 1;
+ }
break;
}
@@ -75547,11 +77789,11 @@ next_tail:
VdbeBranchTaken(res==0,2);
if( res==0 ){
pC->nullRow = 0;
+ pc = pOp->p2 - 1;
p->aCounter[pOp->p5]++;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
- goto jump_to_p2_and_check_for_interrupt;
}else{
pC->nullRow = 1;
}
@@ -75659,12 +77901,11 @@ case OP_IdxDelete: {
**
** See also: Rowid, MakeRecord.
*/
-case OP_IdxRowid: { /* out2 */
+case OP_IdxRowid: { /* out2-prerelease */
BtCursor *pCrsr;
VdbeCursor *pC;
i64 rowid;
- pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
@@ -75777,7 +78018,9 @@ case OP_IdxGE: { /* jump */
res++;
}
VdbeBranchTaken(res>0,2);
- if( res>0 ) goto jump_to_p2;
+ if( res>0 ){
+ pc = pOp->p2 - 1 ;
+ }
break;
}
@@ -75801,18 +78044,32 @@ case OP_IdxGE: { /* jump */
**
** See also: Clear
*/
-case OP_Destroy: { /* out2 */
+case OP_Destroy: { /* out2-prerelease */
int iMoved;
+ int iCnt;
+ Vdbe *pVdbe;
int iDb;
assert( p->readOnly==0 );
- pOut = out2Prerelease(p, pOp);
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ iCnt = 0;
+ for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){
+ if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->bIsReader
+ && pVdbe->inVtabMethod<2 && pVdbe->pc>=0
+ ){
+ iCnt++;
+ }
+ }
+#else
+ iCnt = db->nVdbeRead;
+#endif
pOut->flags = MEM_Null;
- if( db->nVdbeRead > db->nVDestroy+1 ){
+ if( iCnt>1 ){
rc = SQLITE_LOCKED;
p->errorAction = OE_Abort;
}else{
iDb = pOp->p3;
+ assert( iCnt==1 );
assert( DbMaskTest(p->btreeMask, iDb) );
iMoved = 0; /* Not needed. Only to silence a warning. */
rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
@@ -75915,13 +78172,12 @@ case OP_ResetSorter: {
**
** See documentation on OP_CreateTable for additional information.
*/
-case OP_CreateIndex: /* out2 */
-case OP_CreateTable: { /* out2 */
+case OP_CreateIndex: /* out2-prerelease */
+case OP_CreateTable: { /* out2-prerelease */
int pgno;
int flags;
Db *pDb;
- pOut = out2Prerelease(p, pOp);
pgno = 0;
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) );
@@ -76147,12 +78403,12 @@ case OP_RowSetRead: { /* jump, in1, out3 */
){
/* The boolean index is empty */
sqlite3VdbeMemSetNull(pIn1);
+ pc = pOp->p2 - 1;
VdbeBranchTaken(1,2);
- goto jump_to_p2_and_check_for_interrupt;
}else{
/* A value was pulled from the index */
- VdbeBranchTaken(0,2);
sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
+ VdbeBranchTaken(0,2);
}
goto check_for_interrupt;
}
@@ -76203,7 +78459,10 @@ case OP_RowSetTest: { /* jump, in1, in3 */
if( iSet ){
exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
VdbeBranchTaken(exists!=0,2);
- if( exists ) goto jump_to_p2;
+ if( exists ){
+ pc = pOp->p2 - 1;
+ break;
+ }
}
if( iSet>=0 ){
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
@@ -76292,7 +78551,7 @@ case OP_Program: { /* jump */
pFrame->v = p;
pFrame->nChildMem = nMem;
pFrame->nChildCsr = pProgram->nCsr;
- pFrame->pc = (int)(pOp - aOp);
+ pFrame->pc = pc;
pFrame->aMem = p->aMem;
pFrame->nMem = p->nMem;
pFrame->apCsr = p->apCsr;
@@ -76315,7 +78574,7 @@ case OP_Program: { /* jump */
pFrame = pRt->u.pFrame;
assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
assert( pProgram->nCsr==pFrame->nChildCsr );
- assert( (int)(pOp - aOp)==pFrame->pc );
+ assert( pc==pFrame->pc );
}
p->nFrame++;
@@ -76336,7 +78595,7 @@ case OP_Program: { /* jump */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
p->anExec = 0;
#endif
- pOp = &aOp[-1];
+ pc = -1;
memset(p->aOnceFlag, 0, p->nOnceFlag);
break;
@@ -76354,10 +78613,9 @@ case OP_Program: { /* jump */
** the value of the P1 argument to the value of the P1 argument to the
** calling OP_Program instruction.
*/
-case OP_Param: { /* out2 */
+case OP_Param: { /* out2-prerelease */
VdbeFrame *pFrame;
Mem *pIn;
- pOut = out2Prerelease(p, pOp);
pFrame = p->pFrame;
pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1];
sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem);
@@ -76401,10 +78659,10 @@ case OP_FkCounter: {
case OP_FkIfZero: { /* jump */
if( pOp->p1 ){
VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2);
- if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
+ if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
}else{
VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2);
- if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
+ if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
}
break;
}
@@ -76444,18 +78702,18 @@ case OP_MemMax: { /* in2 */
/* Opcode: IfPos P1 P2 * * *
** Synopsis: if r[P1]>0 goto P2
**
-** Register P1 must contain an integer.
-** If the value of register P1 is 1 or greater, jump to P2 and
-** add the literal value P3 to register P1.
+** If the value of register P1 is 1 or greater, jump to P2.
**
-** If the initial value of register P1 is less than 1, then the
-** value is unchanged and control passes through to the next instruction.
+** It is illegal to use this instruction on a register that does
+** not contain an integer. An assertion fault will result if you try.
*/
case OP_IfPos: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
VdbeBranchTaken( pIn1->u.i>0, 2);
- if( pIn1->u.i>0 ) goto jump_to_p2;
+ if( pIn1->u.i>0 ){
+ pc = pOp->p2 - 1;
+ }
break;
}
@@ -76470,56 +78728,26 @@ case OP_IfNeg: { /* jump, in1 */
assert( pIn1->flags&MEM_Int );
pIn1->u.i += pOp->p3;
VdbeBranchTaken(pIn1->u.i<0, 2);
- if( pIn1->u.i<0 ) goto jump_to_p2;
- break;
-}
-
-/* Opcode: IfNotZero P1 P2 P3 * *
-** Synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2
-**
-** Register P1 must contain an integer. If the content of register P1 is
-** initially nonzero, then add P3 to P1 and jump to P2. If register P1 is
-** initially zero, leave it unchanged and fall through.
-*/
-case OP_IfNotZero: { /* jump, in1 */
- pIn1 = &aMem[pOp->p1];
- assert( pIn1->flags&MEM_Int );
- VdbeBranchTaken(pIn1->u.i<0, 2);
- if( pIn1->u.i ){
- pIn1->u.i += pOp->p3;
- goto jump_to_p2;
+ if( pIn1->u.i<0 ){
+ pc = pOp->p2 - 1;
}
break;
}
-/* Opcode: DecrJumpZero P1 P2 * * *
-** Synopsis: if (--r[P1])==0 goto P2
-**
-** Register P1 must hold an integer. Decrement the value in register P1
-** then jump to P2 if the new value is exactly zero.
-*/
-case OP_DecrJumpZero: { /* jump, in1 */
- pIn1 = &aMem[pOp->p1];
- assert( pIn1->flags&MEM_Int );
- pIn1->u.i--;
- VdbeBranchTaken(pIn1->u.i==0, 2);
- if( pIn1->u.i==0 ) goto jump_to_p2;
- break;
-}
-
-
-/* Opcode: JumpZeroIncr P1 P2 * * *
-** Synopsis: if (r[P1]++)==0 ) goto P2
+/* Opcode: IfZero P1 P2 P3 * *
+** Synopsis: r[P1]+=P3, if r[P1]==0 goto P2
**
-** The register P1 must contain an integer. If register P1 is initially
-** zero, then jump to P2. Increment register P1 regardless of whether or
-** not the jump is taken.
+** The register P1 must contain an integer. Add literal P3 to the
+** value in register P1. If the result is exactly 0, jump to P2.
*/
-case OP_JumpZeroIncr: { /* jump, in1 */
+case OP_IfZero: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
+ pIn1->u.i += pOp->p3;
VdbeBranchTaken(pIn1->u.i==0, 2);
- if( (pIn1->u.i++)==0 ) goto jump_to_p2;
+ if( pIn1->u.i==0 ){
+ pc = pOp->p2 - 1;
+ }
break;
}
@@ -76561,7 +78789,7 @@ case OP_AggStep: {
ctx.pOut = &t;
ctx.isError = 0;
ctx.pVdbe = p;
- ctx.iOp = (int)(pOp - aOp);
+ ctx.iOp = pc;
ctx.skipFlag = 0;
(ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
if( ctx.isError ){
@@ -76656,7 +78884,7 @@ case OP_Checkpoint: {
**
** Write a string containing the final journal-mode to register P2.
*/
-case OP_JournalMode: { /* out2 */
+case OP_JournalMode: { /* out2-prerelease */
Btree *pBt; /* Btree to change journal mode of */
Pager *pPager; /* Pager associated with pBt */
int eNew; /* New journal mode */
@@ -76665,7 +78893,6 @@ case OP_JournalMode: { /* out2 */
const char *zFilename; /* Name of database file for pPager */
#endif
- pOut = out2Prerelease(p, pOp);
eNew = pOp->p3;
assert( eNew==PAGER_JOURNALMODE_DELETE
|| eNew==PAGER_JOURNALMODE_TRUNCATE
@@ -76741,6 +78968,7 @@ case OP_JournalMode: { /* out2 */
}
eNew = sqlite3PagerSetJournalMode(pPager, eNew);
+ pOut = &aMem[pOp->p2];
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
pOut->z = (char *)sqlite3JournalModename(eNew);
pOut->n = sqlite3Strlen30(pOut->z);
@@ -76781,8 +79009,8 @@ case OP_IncrVacuum: { /* jump */
rc = sqlite3BtreeIncrVacuum(pBt);
VdbeBranchTaken(rc==SQLITE_DONE,2);
if( rc==SQLITE_DONE ){
+ pc = pOp->p2 - 1;
rc = SQLITE_OK;
- goto jump_to_p2;
}
break;
}
@@ -76860,29 +79088,13 @@ case OP_VBegin: {
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VCreate P1 P2 * * *
+/* Opcode: VCreate P1 * * P4 *
**
-** P2 is a register that holds the name of a virtual table in database
-** P1. Call the xCreate method for that table.
+** P4 is the name of a virtual table in database P1. Call the xCreate method
+** for that table.
*/
case OP_VCreate: {
- Mem sMem; /* For storing the record being decoded */
- const char *zTab; /* Name of the virtual table */
-
- memset(&sMem, 0, sizeof(sMem));
- sMem.db = db;
- /* Because P2 is always a static string, it is impossible for the
- ** sqlite3VdbeMemCopy() to fail */
- assert( (aMem[pOp->p2].flags & MEM_Str)!=0 );
- assert( (aMem[pOp->p2].flags & MEM_Static)!=0 );
- rc = sqlite3VdbeMemCopy(&sMem, &aMem[pOp->p2]);
- assert( rc==SQLITE_OK );
- zTab = (const char*)sqlite3_value_text(&sMem);
- assert( zTab || db->mallocFailed );
- if( zTab ){
- rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg);
- }
- sqlite3VdbeMemRelease(&sMem);
+ rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p4.z, &p->zErrMsg);
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -76894,9 +79106,9 @@ case OP_VCreate: {
** of that table.
*/
case OP_VDestroy: {
- db->nVDestroy++;
+ p->inVtabMethod = 2;
rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
- db->nVDestroy--;
+ p->inVtabMethod = 0;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -76912,17 +79124,14 @@ case OP_VOpen: {
VdbeCursor *pCur;
sqlite3_vtab_cursor *pVtabCursor;
sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
+ sqlite3_module *pModule;
assert( p->bIsReader );
pCur = 0;
pVtabCursor = 0;
pVtab = pOp->p4.pVtab->pVtab;
- if( pVtab==0 || NEVER(pVtab->pModule==0) ){
- rc = SQLITE_LOCKED;
- break;
- }
- pModule = pVtab->pModule;
+ pModule = (sqlite3_module *)pVtab->pModule;
+ assert(pVtab && pModule);
rc = pModule->xOpen(pVtab, &pVtabCursor);
sqlite3VtabImportErrmsg(p, pVtab);
if( SQLITE_OK==rc ){
@@ -76933,11 +79142,9 @@ case OP_VOpen: {
pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
if( pCur ){
pCur->pVtabCursor = pVtabCursor;
- pVtab->nRef++;
}else{
- assert( db->mallocFailed );
+ db->mallocFailed = 1;
pModule->xClose(pVtabCursor);
- goto no_mem;
}
}
break;
@@ -76993,19 +79200,27 @@ case OP_VFilter: { /* jump */
iQuery = (int)pQuery->u.i;
/* Invoke the xFilter method */
- res = 0;
- apArg = p->apArg;
- for(i = 0; i<nArg; i++){
- apArg[i] = &pArgc[i+1];
- }
- rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
- sqlite3VtabImportErrmsg(p, pVtab);
- if( rc==SQLITE_OK ){
- res = pModule->xEof(pVtabCursor);
+ {
+ res = 0;
+ apArg = p->apArg;
+ for(i = 0; i<nArg; i++){
+ apArg[i] = &pArgc[i+1];
+ }
+
+ p->inVtabMethod = 1;
+ rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
+ p->inVtabMethod = 0;
+ sqlite3VtabImportErrmsg(p, pVtab);
+ if( rc==SQLITE_OK ){
+ res = pModule->xEof(pVtabCursor);
+ }
+ VdbeBranchTaken(res!=0,2);
+ if( res ){
+ pc = pOp->p2 - 1;
+ }
}
pCur->nullRow = 0;
- VdbeBranchTaken(res!=0,2);
- if( res ) goto jump_to_p2;
+
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -77084,7 +79299,9 @@ case OP_VNext: { /* jump */
** data is available) and the error code returned when xColumn or
** some other method is next invoked on the save virtual table cursor.
*/
+ p->inVtabMethod = 1;
rc = pModule->xNext(pCur->pVtabCursor);
+ p->inVtabMethod = 0;
sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK ){
res = pModule->xEof(pCur->pVtabCursor);
@@ -77092,7 +79309,7 @@ case OP_VNext: { /* jump */
VdbeBranchTaken(!res,2);
if( !res ){
/* If there is data, jump to P2 */
- goto jump_to_p2_and_check_for_interrupt;
+ pc = pOp->p2 - 1;
}
goto check_for_interrupt;
}
@@ -77159,7 +79376,7 @@ case OP_VRename: {
*/
case OP_VUpdate: {
sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
+ sqlite3_module *pModule;
int nArg;
int i;
sqlite_int64 rowid;
@@ -77171,11 +79388,7 @@ case OP_VUpdate: {
);
assert( p->readOnly==0 );
pVtab = pOp->p4.pVtab->pVtab;
- if( pVtab==0 || NEVER(pVtab->pModule==0) ){
- rc = SQLITE_LOCKED;
- break;
- }
- pModule = pVtab->pModule;
+ pModule = (sqlite3_module *)pVtab->pModule;
nArg = pOp->p2;
assert( pOp->p4type==P4_VTAB );
if( ALWAYS(pModule->xUpdate) ){
@@ -77215,8 +79428,7 @@ case OP_VUpdate: {
**
** Write the current number of pages in database P1 to memory cell P2.
*/
-case OP_Pagecount: { /* out2 */
- pOut = out2Prerelease(p, pOp);
+case OP_Pagecount: { /* out2-prerelease */
pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt);
break;
}
@@ -77232,11 +79444,10 @@ case OP_Pagecount: { /* out2 */
**
** Store the maximum page count after the change in register P2.
*/
-case OP_MaxPgcnt: { /* out2 */
+case OP_MaxPgcnt: { /* out2-prerelease */
unsigned int newMax;
Btree *pBt;
- pOut = out2Prerelease(p, pOp);
pBt = db->aDb[pOp->p1].pBt;
newMax = 0;
if( pOp->p3 ){
@@ -77265,6 +79476,9 @@ case OP_Init: { /* jump */
char *zTrace;
char *z;
+ if( pOp->p2 ){
+ pc = pOp->p2 - 1;
+ }
#ifndef SQLITE_OMIT_TRACE
if( db->xTrace
&& !p->doingRerun
@@ -77292,7 +79506,6 @@ case OP_Init: { /* jump */
}
#endif /* SQLITE_DEBUG */
#endif /* SQLITE_OMIT_TRACE */
- if( pOp->p2 ) goto jump_to_p2;
break;
}
@@ -77324,8 +79537,8 @@ default: { /* This is really OP_Noop and OP_Explain */
#ifdef VDBE_PROFILE
{
u64 endTime = sqlite3Hwtime();
- if( endTime>start ) pOrigOp->cycles += endTime - start;
- pOrigOp->cnt++;
+ if( endTime>start ) pOp->cycles += endTime - start;
+ pOp->cnt++;
}
#endif
@@ -77335,16 +79548,16 @@ default: { /* This is really OP_Noop and OP_Explain */
** the evaluator loop. So we can leave it out when NDEBUG is defined.
*/
#ifndef NDEBUG
- assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] );
+ assert( pc>=-1 && pc<p->nOp );
#ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){
if( rc!=0 ) printf("rc=%d\n",rc);
- if( pOrigOp->opflags & (OPFLG_OUT2) ){
- registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
+ if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){
+ registerTrace(pOp->p2, &aMem[pOp->p2]);
}
- if( pOrigOp->opflags & OPFLG_OUT3 ){
- registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
+ if( pOp->opflags & OPFLG_OUT3 ){
+ registerTrace(pOp->p3, &aMem[pOp->p3]);
}
}
#endif /* SQLITE_DEBUG */
@@ -77359,7 +79572,7 @@ vdbe_error_halt:
p->rc = rc;
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
- (int)(pOp - aOp), p->zSql, p->zErrMsg);
+ pc, p->zSql, p->zErrMsg);
sqlite3VdbeHalt(p);
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
rc = SQLITE_ERROR;
@@ -77522,7 +79735,7 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
/*
** Open a blob handle.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
+SQLITE_API int sqlite3_blob_open(
sqlite3* db, /* The database connection */
const char *zDb, /* The attached database containing the blob */
const char *zTable, /* The table containing the blob */
@@ -77572,17 +79785,12 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
Incrblob *pBlob = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
- if( ppBlob==0 ){
- return SQLITE_MISUSE_BKPT;
- }
-#endif
- *ppBlob = 0;
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !sqlite3SafetyCheckOk(db) || zTable==0 ){
+ if( !sqlite3SafetyCheckOk(db) || ppBlob==0 || zTable==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
flags = !!flags; /* flags = (flags ? 1 : 0); */
+ *ppBlob = 0;
sqlite3_mutex_enter(db->mutex);
@@ -77759,7 +79967,7 @@ blob_open_out:
** Close a blob handle that was previously created using
** sqlite3_blob_open().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *pBlob){
+SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
int rc;
sqlite3 *db;
@@ -77796,7 +80004,7 @@ static int blobReadWrite(
sqlite3_mutex_enter(db->mutex);
v = (Vdbe*)p->pStmt;
- if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){
+ if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
/* Request is out of range. Return a transient error. */
rc = SQLITE_ERROR;
}else if( v==0 ){
@@ -77828,14 +80036,14 @@ static int blobReadWrite(
/*
** Read data from a blob handle.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
+SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData);
}
/*
** Write data to a blob handle.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
+SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
}
@@ -77845,7 +80053,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *pBlob, const void
** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
** so no mutex is required for access.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *pBlob){
+SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
return (p && p->pStmt) ? p->nByte : 0;
}
@@ -77860,7 +80068,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *pBlob){
** subsequent calls to sqlite3_blob_xxx() functions (except blob_close())
** immediately return SQLITE_ABORT.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
+SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
int rc;
Incrblob *p = (Incrblob *)pBlob;
sqlite3 *db;
@@ -78185,7 +80393,6 @@ struct MergeEngine {
** after the thread has finished are not dire. So we don't worry about
** memory barriers and such here.
*/
-typedef int (*SorterCompare)(SortSubtask*,int*,const void*,int,const void*,int);
struct SortSubtask {
SQLiteThread *pThread; /* Background thread, if any */
int bDone; /* Set if thread is finished but not joined */
@@ -78193,12 +80400,10 @@ struct SortSubtask {
UnpackedRecord *pUnpacked; /* Space to unpack a record */
SorterList list; /* List for thread to write to a PMA */
int nPMA; /* Number of PMAs currently in file */
- SorterCompare xCompare; /* Compare function to use */
SorterFile file; /* Temp file for level-0 PMAs */
SorterFile file2; /* Space for other PMAs */
};
-
/*
** Main sorter structure. A single instance of this is allocated for each
** sorter cursor created by the VDBE.
@@ -78225,13 +80430,9 @@ struct VdbeSorter {
u8 bUseThreads; /* True to use background threads */
u8 iPrev; /* Previous thread used to flush PMA */
u8 nTask; /* Size of aTask[] array */
- u8 typeMask;
SortSubtask aTask[1]; /* One or more subtasks */
};
-#define SORTER_TYPE_INTEGER 0x01
-#define SORTER_TYPE_TEXT 0x02
-
/*
** An instance of the following object is used to read records out of a
** PMA, in sorted order. The next key to be read is cached in nKey/aKey.
@@ -78643,163 +80844,33 @@ static int vdbePmaReaderInit(
return rc;
}
-/*
-** A version of vdbeSorterCompare() that assumes that it has already been
-** determined that the first field of key1 is equal to the first field of
-** key2.
-*/
-static int vdbeSorterCompareTail(
- SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
- int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
- const void *pKey1, int nKey1, /* Left side of comparison */
- const void *pKey2, int nKey2 /* Right side of comparison */
-){
- UnpackedRecord *r2 = pTask->pUnpacked;
- if( *pbKey2Cached==0 ){
- sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
- *pbKey2Cached = 1;
- }
- return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1);
-}
/*
** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2,
** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences
** used by the comparison. Return the result of the comparison.
**
-** If IN/OUT parameter *pbKey2Cached is true when this function is called,
-** it is assumed that (pTask->pUnpacked) contains the unpacked version
-** of key2. If it is false, (pTask->pUnpacked) is populated with the unpacked
-** version of key2 and *pbKey2Cached set to true before returning.
+** Before returning, object (pTask->pUnpacked) is populated with the
+** unpacked version of key2. Or, if pKey2 is passed a NULL pointer, then it
+** is assumed that the (pTask->pUnpacked) structure already contains the
+** unpacked key to use as key2.
**
** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set
** to SQLITE_NOMEM.
*/
static int vdbeSorterCompare(
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
- int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
UnpackedRecord *r2 = pTask->pUnpacked;
- if( !*pbKey2Cached ){
+ if( pKey2 ){
sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
- *pbKey2Cached = 1;
}
return sqlite3VdbeRecordCompare(nKey1, pKey1, r2);
}
/*
-** A specially optimized version of vdbeSorterCompare() that assumes that
-** the first field of each key is a TEXT value and that the collation
-** sequence to compare them with is BINARY.
-*/
-static int vdbeSorterCompareText(
- SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
- int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
- const void *pKey1, int nKey1, /* Left side of comparison */
- const void *pKey2, int nKey2 /* Right side of comparison */
-){
- const u8 * const p1 = (const u8 * const)pKey1;
- const u8 * const p2 = (const u8 * const)pKey2;
- const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */
- const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */
-
- int n1;
- int n2;
- int res;
-
- getVarint32(&p1[1], n1); n1 = (n1 - 13) / 2;
- getVarint32(&p2[1], n2); n2 = (n2 - 13) / 2;
- res = memcmp(v1, v2, MIN(n1, n2));
- if( res==0 ){
- res = n1 - n2;
- }
-
- if( res==0 ){
- if( pTask->pSorter->pKeyInfo->nField>1 ){
- res = vdbeSorterCompareTail(
- pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
- );
- }
- }else{
- if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
- res = res * -1;
- }
- }
-
- return res;
-}
-
-/*
-** A specially optimized version of vdbeSorterCompare() that assumes that
-** the first field of each key is an INTEGER value.
-*/
-static int vdbeSorterCompareInt(
- SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
- int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
- const void *pKey1, int nKey1, /* Left side of comparison */
- const void *pKey2, int nKey2 /* Right side of comparison */
-){
- const u8 * const p1 = (const u8 * const)pKey1;
- const u8 * const p2 = (const u8 * const)pKey2;
- const int s1 = p1[1]; /* Left hand serial type */
- const int s2 = p2[1]; /* Right hand serial type */
- const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */
- const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */
- int res; /* Return value */
-
- assert( (s1>0 && s1<7) || s1==8 || s1==9 );
- assert( (s2>0 && s2<7) || s2==8 || s2==9 );
-
- if( s1>7 && s2>7 ){
- res = s1 - s2;
- }else{
- if( s1==s2 ){
- if( (*v1 ^ *v2) & 0x80 ){
- /* The two values have different signs */
- res = (*v1 & 0x80) ? -1 : +1;
- }else{
- /* The two values have the same sign. Compare using memcmp(). */
- static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 };
- int i;
- res = 0;
- for(i=0; i<aLen[s1]; i++){
- if( (res = v1[i] - v2[i]) ) break;
- }
- }
- }else{
- if( s2>7 ){
- res = +1;
- }else if( s1>7 ){
- res = -1;
- }else{
- res = s1 - s2;
- }
- assert( res!=0 );
-
- if( res>0 ){
- if( *v1 & 0x80 ) res = -1;
- }else{
- if( *v2 & 0x80 ) res = +1;
- }
- }
- }
-
- if( res==0 ){
- if( pTask->pSorter->pKeyInfo->nField>1 ){
- res = vdbeSorterCompareTail(
- pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
- );
- }
- }else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
- res = res * -1;
- }
-
- return res;
-}
-
-/*
** Initialize the temporary index cursor just opened as a sorter cursor.
**
** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField)
@@ -78866,13 +80937,9 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
pKeyInfo->db = 0;
- if( nField && nWorker==0 ){
- pKeyInfo->nXField += (pKeyInfo->nField - nField);
- pKeyInfo->nField = nField;
- }
+ if( nField && nWorker==0 ) pKeyInfo->nField = nField;
pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
pSorter->nTask = nWorker + 1;
- pSorter->iPrev = nWorker-1;
pSorter->bUseThreads = (pSorter->nTask>1);
pSorter->db = db;
for(i=0; i<pSorter->nTask; i++){
@@ -78898,12 +80965,6 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
}
}
-
- if( (pKeyInfo->nField+pKeyInfo->nXField)<13
- && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
- ){
- pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
- }
}
return rc;
@@ -78928,24 +80989,30 @@ static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){
*/
static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){
sqlite3DbFree(db, pTask->pUnpacked);
+ pTask->pUnpacked = 0;
#if SQLITE_MAX_WORKER_THREADS>0
/* pTask->list.aMemory can only be non-zero if it was handed memory
** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */
if( pTask->list.aMemory ){
sqlite3_free(pTask->list.aMemory);
+ pTask->list.aMemory = 0;
}else
#endif
{
assert( pTask->list.aMemory==0 );
vdbeSorterRecordFree(0, pTask->list.pList);
}
+ pTask->list.pList = 0;
if( pTask->file.pFd ){
sqlite3OsCloseFree(pTask->file.pFd);
+ pTask->file.pFd = 0;
+ pTask->file.iEof = 0;
}
if( pTask->file2.pFd ){
sqlite3OsCloseFree(pTask->file2.pFd);
+ pTask->file2.pFd = 0;
+ pTask->file2.iEof = 0;
}
- memset(pTask, 0, sizeof(SortSubtask));
}
#ifdef SQLITE_DEBUG_SORTER_THREADS
@@ -79125,7 +81192,6 @@ SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){
for(i=0; i<pSorter->nTask; i++){
SortSubtask *pTask = &pSorter->aTask[i];
vdbeSortSubtaskCleanup(db, pTask);
- pTask->pSorter = pSorter;
}
if( pSorter->list.aMemory==0 ){
vdbeSorterRecordFree(0, pSorter->list.pList);
@@ -79187,7 +81253,6 @@ static int vdbeSorterOpenTempFile(
sqlite3_file **ppFd
){
int rc;
- if( sqlite3FaultSim(202) ) return SQLITE_IOERR_ACCESS;
rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd,
SQLITE_OPEN_TEMP_JOURNAL |
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
@@ -79235,23 +81300,22 @@ static void vdbeSorterMerge(
){
SorterRecord *pFinal = 0;
SorterRecord **pp = &pFinal;
- int bCached = 0;
+ void *pVal2 = p2 ? SRVAL(p2) : 0;
while( p1 && p2 ){
int res;
- res = pTask->xCompare(
- pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal
- );
-
+ res = vdbeSorterCompare(pTask, SRVAL(p1), p1->nVal, pVal2, p2->nVal);
if( res<=0 ){
*pp = p1;
pp = &p1->u.pNext;
p1 = p1->u.pNext;
+ pVal2 = 0;
}else{
*pp = p2;
- pp = &p2->u.pNext;
+ pp = &p2->u.pNext;
p2 = p2->u.pNext;
- bCached = 0;
+ if( p2==0 ) break;
+ pVal2 = SRVAL(p2);
}
}
*pp = p1 ? p1 : p2;
@@ -79259,19 +81323,6 @@ static void vdbeSorterMerge(
}
/*
-** Return the SorterCompare function to compare values collected by the
-** sorter object passed as the only argument.
-*/
-static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){
- if( p->typeMask==SORTER_TYPE_INTEGER ){
- return vdbeSorterCompareInt;
- }else if( p->typeMask==SORTER_TYPE_TEXT ){
- return vdbeSorterCompareText;
- }
- return vdbeSorterCompare;
-}
-
-/*
** Sort the linked list of records headed at pTask->pList. Return
** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if
** an error occurs.
@@ -79285,14 +81336,12 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
rc = vdbeSortAllocUnpacked(pTask);
if( rc!=SQLITE_OK ) return rc;
- p = pList->pList;
- pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter);
-
aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
if( !aSlot ){
return SQLITE_NOMEM;
}
+ p = pList->pList;
while( p ){
SorterRecord *pNext;
if( pList->aMemory ){
@@ -79506,12 +81555,13 @@ static int vdbeMergeEngineStep(
int i; /* Index of aTree[] to recalculate */
PmaReader *pReadr1; /* First PmaReader to compare */
PmaReader *pReadr2; /* Second PmaReader to compare */
- int bCached = 0;
+ u8 *pKey2; /* To pReadr2->aKey, or 0 if record cached */
/* Find the first two PmaReaders to compare. The one that was just
** advanced (iPrev) and the one next to it in the array. */
pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)];
pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)];
+ pKey2 = pReadr2->aKey;
for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){
/* Compare pReadr1 and pReadr2. Store the result in variable iRes. */
@@ -79521,8 +81571,8 @@ static int vdbeMergeEngineStep(
}else if( pReadr2->pFd==0 ){
iRes = -1;
}else{
- iRes = pTask->xCompare(pTask, &bCached,
- pReadr1->aKey, pReadr1->nKey, pReadr2->aKey, pReadr2->nKey
+ iRes = vdbeSorterCompare(pTask,
+ pReadr1->aKey, pReadr1->nKey, pKey2, pReadr2->nKey
);
}
@@ -79544,9 +81594,9 @@ static int vdbeMergeEngineStep(
if( iRes<0 || (iRes==0 && pReadr1<pReadr2) ){
pMerger->aTree[i] = (int)(pReadr1 - pMerger->aReadr);
pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
- bCached = 0;
+ pKey2 = pReadr2->aKey;
}else{
- if( pReadr1->pFd ) bCached = 0;
+ if( pReadr1->pFd ) pKey2 = 0;
pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr);
pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
}
@@ -79653,16 +81703,6 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
int bFlush; /* True to flush contents of memory to PMA */
int nReq; /* Bytes of memory required */
int nPMA; /* Bytes of PMA space required */
- int t; /* serial type of first record field */
-
- 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{
- pSorter->typeMask = 0;
- }
assert( pSorter );
@@ -79928,12 +81968,10 @@ static void vdbeMergeEngineCompare(
}else if( p2->pFd==0 ){
iRes = i1;
}else{
- SortSubtask *pTask = pMerger->pTask;
- int bCached = 0;
int res;
- assert( pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */
- res = pTask->xCompare(
- pTask, &bCached, p1->aKey, p1->nKey, p2->aKey, p2->nKey
+ assert( pMerger->pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */
+ res = vdbeSorterCompare(
+ pMerger->pTask, p1->aKey, p1->nKey, p2->aKey, p2->nKey
);
if( res<=0 ){
iRes = i1;
@@ -79957,12 +81995,11 @@ static void vdbeMergeEngineCompare(
#define INCRINIT_TASK 1
#define INCRINIT_ROOT 2
-/*
-** Forward reference required as the vdbeIncrMergeInit() and
-** vdbePmaReaderIncrInit() routines are called mutually recursively when
-** building a merge tree.
+/* Forward reference.
+** The vdbeIncrMergeInit() and vdbePmaReaderIncrMergeInit() routines call each
+** other (when building a merge tree).
*/
-static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode);
+static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode);
/*
** Initialize the MergeEngine object passed as the second argument. Once this
@@ -80009,7 +82046,7 @@ static int vdbeMergeEngineInit(
** better advantage of multi-processor hardware. */
rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]);
}else{
- rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
+ rc = vdbePmaReaderIncrMergeInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
}
if( rc!=SQLITE_OK ) return rc;
}
@@ -80021,15 +82058,17 @@ static int vdbeMergeEngineInit(
}
/*
-** The PmaReader passed as the first argument is guaranteed to be an
-** incremental-reader (pReadr->pIncr!=0). This function serves to open
-** and/or initialize the temp file related fields of the IncrMerge
+** Initialize the IncrMerge field of a PmaReader.
+**
+** If the PmaReader passed as the first argument is not an incremental-reader
+** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it serves
+** to open and/or initialize the temp file related fields of the IncrMerge
** object at (pReadr->pIncr).
**
** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders
-** in the sub-tree headed by pReadr are also initialized. Data is then
-** loaded into the buffers belonging to pReadr and it is set to point to
-** the first key in its range.
+** in the sub-tree headed by pReadr are also initialized. Data is then loaded
+** into the buffers belonging to pReadr and it is set to
+** point to the first key in its range.
**
** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed
** to be a multi-threaded PmaReader and this function is being called in a
@@ -80056,62 +82095,59 @@ static int vdbeMergeEngineInit(
static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){
int rc = SQLITE_OK;
IncrMerger *pIncr = pReadr->pIncr;
- SortSubtask *pTask = pIncr->pTask;
- sqlite3 *db = pTask->pSorter->db;
/* eMode is always INCRINIT_NORMAL in single-threaded mode */
assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
- rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode);
+ if( pIncr ){
+ SortSubtask *pTask = pIncr->pTask;
+ sqlite3 *db = pTask->pSorter->db;
- /* Set up the required files for pIncr. A multi-theaded IncrMerge object
- ** requires two temp files to itself, whereas a single-threaded object
- ** only requires a region of pTask->file2. */
- if( rc==SQLITE_OK ){
- int mxSz = pIncr->mxSz;
+ rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode);
+
+ /* Set up the required files for pIncr. A multi-theaded IncrMerge object
+ ** requires two temp files to itself, whereas a single-threaded object
+ ** only requires a region of pTask->file2. */
+ if( rc==SQLITE_OK ){
+ int mxSz = pIncr->mxSz;
#if SQLITE_MAX_WORKER_THREADS>0
- if( pIncr->bUseThread ){
- rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd);
- if( rc==SQLITE_OK ){
- rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd);
- }
- }else
+ if( pIncr->bUseThread ){
+ rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd);
+ if( rc==SQLITE_OK ){
+ rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd);
+ }
+ }else
#endif
- /*if( !pIncr->bUseThread )*/{
- if( pTask->file2.pFd==0 ){
- assert( pTask->file2.iEof>0 );
- rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd);
- pTask->file2.iEof = 0;
- }
- if( rc==SQLITE_OK ){
- pIncr->aFile[1].pFd = pTask->file2.pFd;
- pIncr->iStartOff = pTask->file2.iEof;
- pTask->file2.iEof += mxSz;
+ /*if( !pIncr->bUseThread )*/{
+ if( pTask->file2.pFd==0 ){
+ assert( pTask->file2.iEof>0 );
+ rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd);
+ pTask->file2.iEof = 0;
+ }
+ if( rc==SQLITE_OK ){
+ pIncr->aFile[1].pFd = pTask->file2.pFd;
+ pIncr->iStartOff = pTask->file2.iEof;
+ pTask->file2.iEof += mxSz;
+ }
}
}
- }
#if SQLITE_MAX_WORKER_THREADS>0
- if( rc==SQLITE_OK && pIncr->bUseThread ){
- /* Use the current thread to populate aFile[1], even though this
- ** PmaReader is multi-threaded. If this is an INCRINIT_TASK object,
- ** then this function is already running in background thread
- ** pIncr->pTask->thread.
- **
- ** If this is the INCRINIT_ROOT object, then it is running in the
- ** main VDBE thread. But that is Ok, as that thread cannot return
- ** control to the VDBE or proceed with anything useful until the
- ** first results are ready from this merger object anyway.
- */
- assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK );
- rc = vdbeIncrPopulate(pIncr);
- }
+ if( rc==SQLITE_OK && pIncr->bUseThread ){
+ /* Use the current thread to populate aFile[1], even though this
+ ** PmaReader is multi-threaded. The reason being that this function
+ ** is already running in background thread pIncr->pTask->thread. */
+ assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK );
+ rc = vdbeIncrPopulate(pIncr);
+ }
#endif
- if( rc==SQLITE_OK && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) ){
- rc = vdbePmaReaderNext(pReadr);
+ if( rc==SQLITE_OK
+ && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK)
+ ){
+ rc = vdbePmaReaderNext(pReadr);
+ }
}
-
return rc;
}
@@ -80120,7 +82156,7 @@ static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){
** The main routine for vdbePmaReaderIncrMergeInit() operations run in
** background threads.
*/
-static void *vdbePmaReaderBgIncrInit(void *pCtx){
+static void *vdbePmaReaderBgInit(void *pCtx){
PmaReader *pReader = (PmaReader*)pCtx;
void *pRet = SQLITE_INT_TO_PTR(
vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK)
@@ -80128,36 +82164,20 @@ static void *vdbePmaReaderBgIncrInit(void *pCtx){
pReader->pIncr->pTask->bDone = 1;
return pRet;
}
-#endif
/*
-** If the PmaReader passed as the first argument is not an incremental-reader
-** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes
-** the vdbePmaReaderIncrMergeInit() function with the parameters passed to
-** this routine to initialize the incremental merge.
-**
-** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1),
-** then a background thread is launched to call vdbePmaReaderIncrMergeInit().
-** Or, if the IncrMerger is single threaded, the same function is called
-** using the current thread.
+** Use a background thread to invoke vdbePmaReaderIncrMergeInit(INCRINIT_TASK)
+** on the PmaReader object passed as the first argument.
+**
+** This call will initialize the various fields of the pReadr->pIncr
+** structure and, if it is a multi-threaded IncrMerger, launch a
+** background thread to populate aFile[1].
*/
-static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode){
- IncrMerger *pIncr = pReadr->pIncr; /* Incremental merger */
- int rc = SQLITE_OK; /* Return code */
- if( pIncr ){
-#if SQLITE_MAX_WORKER_THREADS>0
- assert( pIncr->bUseThread==0 || eMode==INCRINIT_TASK );
- if( pIncr->bUseThread ){
- void *pCtx = (void*)pReadr;
- rc = vdbeSorterCreateThread(pIncr->pTask, vdbePmaReaderBgIncrInit, pCtx);
- }else
-#endif
- {
- rc = vdbePmaReaderIncrMergeInit(pReadr, eMode);
- }
- }
- return rc;
+static int vdbePmaReaderBgIncrInit(PmaReader *pReadr){
+ void *pCtx = (void*)pReadr;
+ return vdbeSorterCreateThread(pReadr->pIncr->pTask, vdbePmaReaderBgInit, pCtx);
}
+#endif
/*
** Allocate a new MergeEngine object to merge the contents of nPMA level-0
@@ -80369,11 +82389,6 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
MergeEngine *pMain = 0;
#if SQLITE_MAX_WORKER_THREADS
sqlite3 *db = pTask0->pSorter->db;
- int i;
- SorterCompare xCompare = vdbeSorterGetCompare(pSorter);
- for(i=0; i<pSorter->nTask; i++){
- pSorter->aTask[i].xCompare = xCompare;
- }
#endif
rc = vdbeSorterMergeTreeBuild(pSorter, &pMain);
@@ -80402,21 +82417,15 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
}
}
for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){
- /* Check that:
- **
- ** a) The incremental merge object is configured to use the
- ** right task, and
- ** b) If it is using task (nTask-1), it is configured to run
- ** in single-threaded mode. This is important, as the
- ** root merge (INCRINIT_ROOT) will be using the same task
- ** object.
- */
PmaReader *p = &pMain->aReadr[iTask];
- assert( p->pIncr==0 || (
- (p->pIncr->pTask==&pSorter->aTask[iTask]) /* a */
- && (iTask!=pSorter->nTask-1 || p->pIncr->bUseThread==0) /* b */
- ));
- rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK);
+ assert( p->pIncr==0 || p->pIncr->pTask==&pSorter->aTask[iTask] );
+ if( p->pIncr ){
+ if( iTask==pSorter->nTask-1 ){
+ rc = vdbePmaReaderIncrMergeInit(p, INCRINIT_TASK);
+ }else{
+ rc = vdbePmaReaderBgIncrInit(p);
+ }
+ }
}
}
pMain = 0;
@@ -81371,7 +83380,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
**
** The nSubquery parameter specifies how many levels of subquery the
-** alias is removed from the original expression. The usual value is
+** alias is removed from the original expression. The usually value is
** zero but it might be more if the alias is contained within a subquery
** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION
** structures must be increased by the nSubquery amount.
@@ -81391,6 +83400,7 @@ static void resolveAlias(
assert( iCol>=0 && iCol<pEList->nExpr );
pOrig = pEList->a[iCol].pExpr;
assert( pOrig!=0 );
+ assert( pOrig->flags & EP_Resolved );
db = pParse->db;
pDup = sqlite3ExprDup(db, pOrig, 0);
if( pDup==0 ) return;
@@ -81538,10 +83548,9 @@ static int lookupName(
testcase( pNC->ncFlags & NC_PartIdx );
testcase( pNC->ncFlags & NC_IsCheck );
if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){
- /* Silently ignore database qualifiers inside CHECK constraints and
- ** partial indices. Do not raise errors because that might break
- ** legacy and because it does not hurt anything to just ignore the
- ** database name. */
+ /* Silently ignore database qualifiers inside CHECK constraints and partial
+ ** indices. Do not raise errors because that might break legacy and
+ ** because it does not hurt anything to just ignore the database name. */
zDb = 0;
}else{
for(i=0; i<db->nDb; i++){
@@ -81612,8 +83621,7 @@ static int lookupName(
if( pMatch ){
pExpr->iTable = pMatch->iCursor;
pExpr->pTab = pMatch->pTab;
- /* RIGHT JOIN not (yet) supported */
- assert( (pMatch->jointype & JT_RIGHT)==0 );
+ assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */
if( (pMatch->jointype & JT_LEFT)!=0 ){
ExprSetProperty(pExpr, EP_CanBeNull);
}
@@ -81934,8 +83942,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pExpr->affinity = SQLITE_AFF_INTEGER;
break;
}
-#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
- && !defined(SQLITE_OMIT_SUBQUERY) */
+#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
/* A lone identifier is the name of a column.
*/
@@ -82000,20 +84007,19 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
if( n==2 ){
pExpr->iTable = exprProbability(pList->a[1].pExpr);
if( pExpr->iTable<0 ){
- sqlite3ErrorMsg(pParse,
- "second argument to likelihood() must be a "
- "constant between 0.0 and 1.0");
+ sqlite3ErrorMsg(pParse, "second argument to likelihood() must be a "
+ "constant between 0.0 and 1.0");
pNC->nErr++;
}
}else{
- /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is
- ** equivalent to likelihood(X, 0.0625).
- ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is
- ** short-hand for likelihood(X,0.0625).
- ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand
- ** for likelihood(X,0.9375).
- ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent
- ** to likelihood(X,0.9375). */
+ /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to
+ ** likelihood(X, 0.0625).
+ ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for
+ ** likelihood(X,0.0625).
+ ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand for
+ ** likelihood(X,0.9375).
+ ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent to
+ ** likelihood(X,0.9375). */
/* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */
pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120;
}
@@ -82030,9 +84036,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
return WRC_Prune;
}
#endif
- if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ){
- ExprSetProperty(pExpr,EP_ConstFunc);
- }
+ if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant);
}
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
@@ -82284,11 +84288,9 @@ static int resolveCompoundOrderBy(
if( pItem->pExpr==pE ){
pItem->pExpr = pNew;
}else{
- Expr *pParent = pItem->pExpr;
- assert( pParent->op==TK_COLLATE );
- while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft;
- assert( pParent->pLeft==pE );
- pParent->pLeft = pNew;
+ assert( pItem->pExpr->op==TK_COLLATE );
+ assert( pItem->pExpr->pLeft==pE );
+ pItem->pExpr->pLeft = pNew;
}
sqlite3ExprDelete(db, pE);
pItem->u.x.iOrderByCol = (u16)iCol;
@@ -82345,8 +84347,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
return 1;
}
- resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,
- zType,0);
+ resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, zType,0);
}
}
return 0;
@@ -82479,20 +84480,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
sqlite3ResolveExprNames(&sNC, p->pOffset) ){
return WRC_Abort;
}
-
- /* If the SF_Converted flags is set, then this Select object was
- ** was created by the convertCompoundSelectToSubquery() function.
- ** In this case the ORDER BY clause (p->pOrderBy) should be resolved
- ** as if it were part of the sub-query, not the parent. This block
- ** moves the pOrderBy down to the sub-query. It will be moved back
- ** after the names have been resolved. */
- if( p->selFlags & SF_Converted ){
- Select *pSub = p->pSrc->a[0].pSelect;
- assert( p->pSrc->nSrc==1 && p->pOrderBy );
- assert( pSub->pPrior && pSub->pOrderBy==0 );
- pSub->pOrderBy = p->pOrderBy;
- p->pOrderBy = 0;
- }
/* Recursively resolve names in all subqueries
*/
@@ -82575,30 +84562,12 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
sNC.pNext = 0;
sNC.ncFlags |= NC_AllowAgg;
- /* If this is a converted compound query, move the ORDER BY clause from
- ** the sub-query back to the parent query. At this point each term
- ** within the ORDER BY clause has been transformed to an integer value.
- ** These integers will be replaced by copies of the corresponding result
- ** set expressions by the call to resolveOrderGroupBy() below. */
- if( p->selFlags & SF_Converted ){
- Select *pSub = p->pSrc->a[0].pSelect;
- p->pOrderBy = pSub->pOrderBy;
- pSub->pOrderBy = 0;
- }
-
/* Process the ORDER BY clause for singleton SELECT statements.
** The ORDER BY clause for compounds SELECT statements is handled
** below, after all of the result-sets for all of the elements of
** the compound have been resolved.
- **
- ** If there is an ORDER BY clause on a term of a compound-select other
- ** than the right-most term, then that is a syntax error. But the error
- ** is not detected until much later, and so we need to go ahead and
- ** resolve those symbols on the incorrect ORDER BY for consistency.
*/
- if( isCompound<=nCompound /* Defer right-most ORDER BY of a compound */
- && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER")
- ){
+ if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){
return WRC_Abort;
}
if( db->mallocFailed ){
@@ -82868,11 +84837,10 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(
Parse *pParse, /* Parsing context */
Expr *pExpr, /* Add the "COLLATE" clause to this expression */
- const Token *pCollName, /* Name of collating sequence */
- int dequote /* True to dequote pCollName */
+ const Token *pCollName /* Name of collating sequence */
){
if( pCollName->n>0 ){
- Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
+ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
if( pNew ){
pNew->pLeft = pExpr;
pNew->flags |= EP_Collate|EP_Skip;
@@ -82886,7 +84854,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, con
assert( zC!=0 );
s.z = zC;
s.n = sqlite3Strlen30(s.z);
- return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
+ return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
}
/*
@@ -82932,9 +84900,9 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
break;
}
- if( (op==TK_AGG_COLUMN || op==TK_COLUMN
+ if( p->pTab!=0
+ && (op==TK_AGG_COLUMN || op==TK_COLUMN
|| op==TK_REGISTER || op==TK_TRIGGER)
- && p->pTab!=0
){
/* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
** a TK_COLUMN but was previously evaluated and cached in a register */
@@ -82946,25 +84914,10 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
break;
}
if( p->flags & EP_Collate ){
- if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
+ if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
p = p->pLeft;
}else{
- Expr *pNext = p->pRight;
- /* The Expr.x union is never used at the same time as Expr.pRight */
- assert( p->x.pList==0 || p->pRight==0 );
- /* p->flags holds EP_Collate and p->pLeft->flags does not. And
- ** p->x.pSelect cannot. So if p->x.pLeft exists, it must hold at
- ** least one EP_Collate. Thus the following two ALWAYS. */
- if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){
- int i;
- for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
- if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
- pNext = p->x.pList->a[i].pExpr;
- break;
- }
- }
- }
- p = pNext;
+ p = p->pRight;
}
}else{
break;
@@ -83170,9 +85123,6 @@ static void heightOfSelect(Select *p, int *pnHeight){
** Expr.pSelect member has a height of 1. Any other expression
** has a height equal to the maximum height of any other
** referenced Expr plus one.
-**
-** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
-** if appropriate.
*/
static void exprSetHeight(Expr *p){
int nHeight = 0;
@@ -83180,9 +85130,8 @@ static void exprSetHeight(Expr *p){
heightOfExpr(p->pRight, &nHeight);
if( ExprHasProperty(p, EP_xIsSelect) ){
heightOfSelect(p->x.pSelect, &nHeight);
- }else if( p->x.pList ){
+ }else{
heightOfExprList(p->x.pList, &nHeight);
- p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
}
p->nHeight = nHeight + 1;
}
@@ -83191,12 +85140,8 @@ static void exprSetHeight(Expr *p){
** Set the Expr.nHeight variable using the exprSetHeight() function. If
** the height is greater than the maximum allowed expression depth,
** leave an error in pParse.
-**
-** Also propagate all EP_Propagate flags from the Expr.x.pList into
-** Expr.flags.
*/
-SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
- if( pParse->nErr ) return;
+SQLITE_PRIVATE void sqlite3ExprSetHeight(Parse *pParse, Expr *p){
exprSetHeight(p);
sqlite3ExprCheckHeight(pParse, p->nHeight);
}
@@ -83210,17 +85155,8 @@ SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){
heightOfSelect(p, &nHeight);
return nHeight;
}
-#else /* ABOVE: Height enforcement enabled. BELOW: Height enforcement off */
-/*
-** Propagate all EP_Propagate flags from the Expr.x.pList into
-** Expr.flags.
-*/
-SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
- if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
- p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
- }
-}
-#define exprSetHeight(y)
+#else
+ #define exprSetHeight(y)
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
/*
@@ -83322,11 +85258,11 @@ SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(
}else{
if( pRight ){
pRoot->pRight = pRight;
- pRoot->flags |= EP_Propagate & pRight->flags;
+ pRoot->flags |= EP_Collate & pRight->flags;
}
if( pLeft ){
pRoot->pLeft = pLeft;
- pRoot->flags |= EP_Propagate & pLeft->flags;
+ pRoot->flags |= EP_Collate & pLeft->flags;
}
exprSetHeight(pRoot);
}
@@ -83426,7 +85362,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *
}
pNew->x.pList = pList;
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
- sqlite3ExprSetHeightAndFlags(pParse, pNew);
+ sqlite3ExprSetHeight(pParse, pNew);
return pNew;
}
@@ -84042,22 +85978,6 @@ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
}
/*
-** Return the bitwise-OR of all Expr.flags fields in the given
-** ExprList.
-*/
-SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){
- int i;
- u32 m = 0;
- if( pList ){
- for(i=0; i<pList->nExpr; i++){
- Expr *pExpr = pList->a[i].pExpr;
- if( ALWAYS(pExpr) ) m |= pExpr->flags;
- }
- }
- return m;
-}
-
-/*
** These routines are Walker callbacks used to check expressions to
** see if they are "constant" for some definition of constant. The
** Walker.eCode value determines the type of "constant" we are looking
@@ -84097,7 +86017,7 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
** and either pWalker->eCode==4 or 5 or the function has the
** SQLITE_FUNC_CONST flag. */
case TK_FUNCTION:
- if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){
+ if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_Constant) ){
return WRC_Continue;
}else{
pWalker->eCode = 0;
@@ -84491,7 +86411,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int
** ephemeral table.
*/
p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
- if( pParse->nErr==0 && isCandidateForInOpt(p) ){
+ if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
sqlite3 *db = pParse->db; /* Database connection */
Table *pTab; /* Table <table>. */
Expr *pExpr; /* Expression <column> */
@@ -84816,7 +86736,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
&sqlite3IntTokens[1]);
pSel->iLimit = 0;
- pSel->selFlags &= ~SF_MultiValue;
if( sqlite3Select(pParse, pSel, &dest) ){
return 0;
}
@@ -85105,8 +87024,7 @@ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int
int idxLru;
struct yColCache *p;
- /* Unless an error has occurred, register numbers are always positive. */
- assert( iReg>0 || pParse->nErr || pParse->db->mallocFailed );
+ assert( iReg>0 ); /* Register numbers are always positive */
assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */
/* The SQLITE_ColumnCache flag disables the column cache. This is used
@@ -86182,7 +88100,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
break;
}
case TK_ID: {
- sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
+ sqlite3TreeViewLine(pView,"ID %Q", pExpr->u.zToken);
break;
}
#ifndef SQLITE_OMIT_CAST
@@ -86817,7 +88735,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
- if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){
+ if( ALWAYS((combinedFlags & EP_Reduced)==0) ){
if( pA->iColumn!=pB->iColumn ) return 2;
if( pA->iTable!=pB->iTable
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
@@ -87349,7 +89267,6 @@ static void renameParentFunc(
n = sqlite3GetToken(z, &token);
}while( token==TK_SPACE );
- if( token==TK_ILLEGAL ) break;
zParent = sqlite3DbStrNDup(db, (const char *)z, n);
if( zParent==0 ) break;
sqlite3Dequote(zParent);
@@ -87914,10 +89831,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
*/
if( pDflt ){
sqlite3_value *pVal = 0;
- int rc;
- rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal);
- assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
- if( rc!=SQLITE_OK ){
+ if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
db->mallocFailed = 1;
return;
}
@@ -89576,17 +91490,14 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
z = argv[2];
if( pIndex ){
- tRowcnt *aiRowEst = 0;
int nCol = pIndex->nKeyCol+1;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
- /* Index.aiRowEst may already be set here if there are duplicate
- ** sqlite_stat1 entries for this index. In that case just clobber
- ** the old data with the new instead of allocating a new array. */
- if( pIndex->aiRowEst==0 ){
- pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
- if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1;
- }
- aiRowEst = pIndex->aiRowEst;
+ tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(
+ sizeof(tRowcnt) * nCol
+ );
+ if( aiRowEst==0 ) pInfo->db->mallocFailed = 1;
+#else
+ tRowcnt * const aiRowEst = 0;
#endif
pIndex->bUnordered = 0;
decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
@@ -90142,7 +92053,7 @@ static void attachFunc(
case SQLITE_NULL:
/* No key specified. Use the key from the main database */
sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
- if( nKey>0 || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
+ if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){
rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
}
break;
@@ -90249,7 +92160,7 @@ static void detachFunc(
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
- sqlite3CollapseDatabaseArray(db);
+ sqlite3ResetAllSchemasOfConnection(db);
return;
detach_error:
@@ -90283,6 +92194,7 @@ static void codeAttach(
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
){
+ pParse->nErr++;
goto attach_end;
}
@@ -90604,7 +92516,7 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep(
** Setting the auth function to NULL disables this hook. The default
** setting of the auth function is NULL.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
+SQLITE_API int sqlite3_set_authorizer(
sqlite3 *db,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pArg
@@ -90941,11 +92853,9 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
assert( pParse->pToplevel==0 );
db = pParse->db;
+ if( db->mallocFailed ) return;
if( pParse->nested ) return;
- if( db->mallocFailed || pParse->nErr ){
- if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR;
- return;
- }
+ if( pParse->nErr ) return;
/* Begin by generating some termination code at the end of the
** vdbe program
@@ -91027,7 +92937,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
/* Get the VDBE program ready for execution
*/
- if( v && pParse->nErr==0 && !db->mallocFailed ){
+ if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){
assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */
/* A minimum of one cursor is required if autoincrement is used
* See ticket [a696379c1f08866] */
@@ -91109,6 +93019,10 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const cha
Table *p = 0;
int i;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || zName==0 ) return 0;
+#endif
+
/* All mutexes are required for schema access. Make sure we hold them. */
assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
#if SQLITE_USER_AUTHENTICATION
@@ -91562,12 +93476,14 @@ SQLITE_PRIVATE int sqlite3TwoPartName(
if( ALWAYS(pName2!=0) && pName2->n>0 ){
if( db->init.busy ) {
sqlite3ErrorMsg(pParse, "corrupt database");
+ pParse->nErr++;
return -1;
}
*pUnqual = pName2;
iDb = sqlite3FindDb(db, pName1);
if( iDb<0 ){
sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
+ pParse->nErr++;
return -1;
}
}else{
@@ -91726,7 +93642,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
if( !noErr ){
sqlite3ErrorMsg(pParse, "table %T already exists", pName);
}else{
- assert( !db->init.busy || CORRUPT_DB );
+ assert( !db->init.busy );
sqlite3CodeVerifySchema(pParse, iDb);
}
goto begin_table_error;
@@ -92015,8 +93931,7 @@ SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){
p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return;
pCol = &p->aCol[p->nCol-1];
- assert( pCol->zType==0 || CORRUPT_DB );
- sqlite3DbFree(pParse->db, pCol->zType);
+ assert( pCol->zType==0 );
pCol->zType = sqlite3NameFromToken(pParse->db, pType);
pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst);
}
@@ -92527,14 +94442,11 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
assert( pPk!=0 );
nPk = pPk->nKeyCol;
- /* Make sure every column of the PRIMARY KEY is NOT NULL. (Except,
- ** do not enforce this for imposter tables.) */
- if( !db->init.imposterTable ){
- for(i=0; i<nPk; i++){
- pTab->aCol[pPk->aiColumn[i]].notNull = 1;
- }
- pPk->uniqNotNull = 1;
+ /* Make sure every column of the PRIMARY KEY is NOT NULL */
+ for(i=0; i<nPk; i++){
+ pTab->aCol[pPk->aiColumn[i]].notNull = 1;
}
+ pPk->uniqNotNull = 1;
/* The root page of the PRIMARY KEY is the table root page */
pPk->tnum = pTab->tnum;
@@ -93250,7 +95162,6 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView,
}
assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
- if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
if( noErr ) db->suppressErr++;
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
if( noErr ) db->suppressErr--;
@@ -93564,8 +95475,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
addr2 = sqlite3VdbeCurrentAddr(v);
}
sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
- sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1);
- sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
+ sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord);
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
@@ -93658,7 +95568,8 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
char *zExtra = 0; /* Extra space after the Index object */
Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
- if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){
+ assert( pParse->nErr==0 ); /* Never called with prior errors */
+ if( db->mallocFailed || IN_DECLARE_VTAB ){
goto exit_create_index;
}
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
@@ -93984,7 +95895,6 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
pIdx->onError = pIndex->onError;
}
}
- pRet = pIdx;
goto exit_create_index;
}
}
@@ -94577,6 +96487,7 @@ SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pI
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){
if( p ){
int i;
+ assert( p->a || p->nSrc==0 );
for(i=p->nSrc-1; i>0; i--){
p->a[i].jointype = p->a[i-1].jointype;
}
@@ -94823,7 +96734,8 @@ SQLITE_PRIVATE void sqlite3UniqueConstraint(
StrAccum errMsg;
Table *pTab = pIdx->pTable;
- sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
+ sqlite3StrAccumInit(&errMsg, 0, 0, 200);
+ errMsg.db = pParse->db;
for(j=0; j<pIdx->nKeyCol; j++){
char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
@@ -95769,7 +97681,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
pInClause->x.pSelect = pSelect;
pInClause->flags |= EP_xIsSelect;
- sqlite3ExprSetHeightAndFlags(pParse, pInClause);
+ sqlite3ExprSetHeight(pParse, pInClause);
return pInClause;
/* something went wrong. clean up anything allocated. */
@@ -96442,9 +98354,7 @@ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
** Return the collating function associated with a function.
*/
static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
- VdbeOp *pOp;
- assert( context->pVdbe!=0 );
- pOp = &context->pVdbe->aOp[context->iOp-1];
+ VdbeOp *pOp = &context->pVdbe->aOp[context->iOp-1];
assert( pOp->opcode==OP_CollSeq );
assert( pOp->p4type==P4_COLLSEQ );
return pOp->p4.pColl;
@@ -96652,13 +98562,13 @@ static void printfFunc(
StrAccum str;
const char *zFormat;
int n;
- sqlite3 *db = sqlite3_context_db_handle(context);
if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
x.nArg = argc-1;
x.nUsed = 0;
x.apArg = argv+1;
- sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
+ sqlite3StrAccumInit(&str, 0, 0, SQLITE_MAX_LENGTH);
+ str.db = sqlite3_context_db_handle(context);
sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
n = str.nChar;
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
@@ -96713,14 +98623,6 @@ static void substrFunc(
}
}
}
-#ifdef SQLITE_SUBSTR_COMPATIBILITY
- /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as
- ** as substr(X,1,N) - it returns the first N characters of X. This
- ** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8]
- ** from 2009-02-02 for compatibility of applications that exploited the
- ** old buggy behavior. */
- if( p1==0 ) p1 = 1; /* <rdar://problem/6778339> */
-#endif
if( argc==3 ){
p2 = sqlite3_value_int(argv[2]);
if( p2<0 ){
@@ -96808,7 +98710,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
#endif
/*
-** Allocate nByte bytes of space using sqlite3Malloc(). If the
+** Allocate nByte bytes of space using sqlite3_malloc(). If the
** allocation fails, call sqlite3_result_error_nomem() to notify
** the database handle that malloc() has failed and return NULL.
** If nByte is larger than the maximum string or blob length, then
@@ -97182,7 +99084,7 @@ static int patternCompare(
/*
** The sqlite3_strglob() interface.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlobPattern, const char *zString){
+SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){
return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0;
}
@@ -97477,7 +99379,7 @@ static void charFunc(
){
unsigned char *z, *zOut;
int i;
- zOut = z = sqlite3_malloc64( argc*4+1 );
+ zOut = z = sqlite3_malloc( argc*4+1 );
if( z==0 ){
sqlite3_result_error_nomem(context);
return;
@@ -97625,7 +99527,7 @@ static void replaceFunc(
return;
}
zOld = zOut;
- zOut = sqlite3_realloc64(zOut, (int)nOut);
+ zOut = sqlite3_realloc(zOut, (int)nOut);
if( zOut==0 ){
sqlite3_result_error_nomem(context);
sqlite3_free(zOld);
@@ -97987,7 +99889,8 @@ static void groupConcatStep(
if( pAccum ){
sqlite3 *db = sqlite3_context_db_handle(context);
- int firstTerm = pAccum->mxAlloc==0;
+ int firstTerm = pAccum->useMalloc==0;
+ pAccum->useMalloc = 2;
pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
if( !firstTerm ){
if( argc==2 ){
@@ -98026,10 +99929,24 @@ static void groupConcatFinalize(sqlite3_context *context){
*/
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
int rc = sqlite3_overload_function(db, "MATCH", 2);
+/* BEGIN SQLCIPHER */
+#ifdef SQLITE_HAS_CODEC
+#ifndef OMIT_EXPORT
+ extern void sqlcipher_exportFunc(sqlite3_context *, int, sqlite3_value **);
+#endif
+#endif
+/* END SQLCIPHER */
assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
if( rc==SQLITE_NOMEM ){
db->mallocFailed = 1;
}
+/* BEGIN SQLCIPHER */
+#ifdef SQLITE_HAS_CODEC
+#ifndef OMIT_EXPORT
+ sqlite3CreateFunc(db, "sqlcipher_export", 1, SQLITE_TEXT, 0, sqlcipher_exportFunc, 0, 0, 0);
+#endif
+#endif
+/* END SQLCIPHER */
}
/*
@@ -98071,11 +99988,6 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive)
** then set aWc[0] through aWc[2] to the wildcard characters and
** return TRUE. If the function is not a LIKE-style function then
** return FALSE.
-**
-** *pIsNocase is set to true if uppercase and lowercase are equivalent for
-** the function (default for LIKE). If the function makes the distinction
-** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to
-** false.
*/
SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
FuncDef *pDef;
@@ -99407,8 +101319,7 @@ static Trigger *fkActionTrigger(
iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iFromCol>=0 );
- assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
- tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName;
+ tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid";
tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
tToCol.n = sqlite3Strlen30(tToCol.z);
@@ -99420,10 +101331,10 @@ static Trigger *fkActionTrigger(
** parent table are used for the comparison. */
pEq = sqlite3PExpr(pParse, TK_EQ,
sqlite3PExpr(pParse, TK_DOT,
- sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
+ sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
+ sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
, 0),
- sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
+ sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol)
, 0);
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
@@ -99435,12 +101346,12 @@ static Trigger *fkActionTrigger(
if( pChanges ){
pEq = sqlite3PExpr(pParse, TK_IS,
sqlite3PExpr(pParse, TK_DOT,
- sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
+ sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
+ sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
0),
sqlite3PExpr(pParse, TK_DOT,
- sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
+ sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
+ sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
0),
0);
pWhen = sqlite3ExprAnd(db, pWhen, pEq);
@@ -99450,8 +101361,8 @@ static Trigger *fkActionTrigger(
Expr *pNew;
if( action==OE_Cascade ){
pNew = sqlite3PExpr(pParse, TK_DOT,
- sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
+ sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
+ sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
, 0);
}else if( action==OE_SetDflt ){
Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
@@ -99498,12 +101409,13 @@ static Trigger *fkActionTrigger(
pTrigger = (Trigger *)sqlite3DbMallocZero(db,
sizeof(Trigger) + /* struct Trigger */
sizeof(TriggerStep) + /* Single step in trigger program */
- nFrom + 1 /* Space for pStep->zTarget */
+ nFrom + 1 /* Space for pStep->target.z */
);
if( pTrigger ){
pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
- pStep->zTarget = (char *)&pStep[1];
- memcpy((char *)pStep->zTarget, zFrom, nFrom);
+ pStep->target.z = (char *)&pStep[1];
+ pStep->target.n = nFrom;
+ memcpy((char *)pStep->target.z, zFrom, nFrom);
pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
@@ -99968,23 +101880,20 @@ static int xferOptimization(
/*
** This routine is called to handle SQL of the following forms:
**
-** insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),...
+** insert into TABLE (IDLIST) values(EXPRLIST)
** insert into TABLE (IDLIST) select
-** insert into TABLE (IDLIST) default values
**
** The IDLIST following the table name is always optional. If omitted,
-** then a list of all (non-hidden) columns for the table is substituted.
-** The IDLIST appears in the pColumn parameter. pColumn is NULL if IDLIST
-** is omitted.
+** then a list of all columns for the table is substituted. The IDLIST
+** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted.
**
-** For the pSelect parameter holds the values to be inserted for the
-** first two forms shown above. A VALUES clause is really just short-hand
-** for a SELECT statement that omits the FROM clause and everything else
-** that follows. If the pSelect parameter is NULL, that means that the
-** DEFAULT VALUES form of the INSERT statement is intended.
+** The pList parameter holds EXPRLIST in the first form of the INSERT
+** statement above, and pSelect is NULL. For the second form, pList is
+** NULL and pSelect is a pointer to the select statement used to generate
+** data for the insert.
**
** The code generated follows one of four templates. For a simple
-** insert with data coming from a single-row VALUES clause, the code executes
+** insert with data coming from a VALUES clause, the code executes
** once straight down through. Pseudo-code follows (we call this
** the "1st template"):
**
@@ -100091,7 +102000,7 @@ SQLITE_PRIVATE void sqlite3Insert(
u8 useTempTable = 0; /* Store SELECT results in intermediate table */
u8 appendFlag = 0; /* True if the insert is likely to be an append */
u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
- u8 bIdListInOrder; /* True if IDLIST is in table order */
+ u8 bIdListInOrder = 1; /* True if IDLIST is in table order */
ExprList *pList = 0; /* List of VALUES() to be inserted */
/* Register allocations */
@@ -100116,8 +102025,8 @@ SQLITE_PRIVATE void sqlite3Insert(
}
/* If the Select object is really just a simple VALUES() list with a
- ** single row (the common case) then keep that one row of values
- ** and discard the other (unused) parts of the pSelect object
+ ** single row values (the common case) then keep that one row of values
+ ** and go ahead and discard the Select object
*/
if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){
pList = pSelect->pEList;
@@ -100225,7 +102134,6 @@ SQLITE_PRIVATE void sqlite3Insert(
** is appears in the original table. (The index of the INTEGER
** PRIMARY KEY in the original table is pTab->iPKey.)
*/
- bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0;
if( pColumn ){
for(i=0; i<pColumn->nId; i++){
pColumn->a[i].idx = -1;
@@ -100261,8 +102169,7 @@ SQLITE_PRIVATE void sqlite3Insert(
** co-routine is the common header to the 3rd and 4th templates.
*/
if( pSelect ){
- /* Data is coming from a SELECT or from a multi-row VALUES clause.
- ** Generate a co-routine to run the SELECT. */
+ /* Data is coming from a SELECT. Generate a co-routine to run the SELECT */
int regYield; /* Register holding co-routine entry-point */
int addrTop; /* Top of the co-routine */
int rc; /* Result code */
@@ -100275,7 +102182,8 @@ SQLITE_PRIVATE void sqlite3Insert(
dest.nSdst = pTab->nCol;
rc = sqlite3Select(pParse, pSelect, &dest);
regFromSelect = dest.iSdst;
- if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
+ assert( pParse->nErr==0 || rc );
+ if( rc || db->mallocFailed ) goto insert_cleanup;
sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
assert( pSelect->pEList );
@@ -100323,8 +102231,8 @@ SQLITE_PRIVATE void sqlite3Insert(
sqlite3ReleaseTempReg(pParse, regTempRowid);
}
}else{
- /* This is the case if the data for the INSERT is coming from a
- ** single-row VALUES clause
+ /* This is the case if the data for the INSERT is coming from a VALUES
+ ** clause
*/
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
@@ -101395,7 +103303,6 @@ static int xferOptimization(
int onError, /* How to handle constraint errors */
int iDbDest /* The database of pDest */
){
- sqlite3 *db = pParse->db;
ExprList *pEList; /* The result set of the SELECT */
Table *pSrc; /* The table in the FROM clause of SELECT */
Index *pSrcIdx, *pDestIdx; /* Source and destination indices */
@@ -101543,11 +103450,11 @@ static int xferOptimization(
** the extra complication to make this rule less restrictive is probably
** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
*/
- if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
+ if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
return 0;
}
#endif
- if( (db->flags & SQLITE_CountRows)!=0 ){
+ if( (pParse->db->flags & SQLITE_CountRows)!=0 ){
return 0; /* xfer opt does not play well with PRAGMA count_changes */
}
@@ -101558,7 +103465,7 @@ static int xferOptimization(
#ifdef SQLITE_TEST
sqlite3_xferopt_count++;
#endif
- iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema);
+ iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema);
v = sqlite3GetVdbe(pParse);
sqlite3CodeVerifySchema(pParse, iDbSrc);
iSrc = pParse->nTab++;
@@ -101568,18 +103475,14 @@ static int xferOptimization(
regRowid = sqlite3GetTempReg(pParse);
sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
assert( HasRowid(pDest) || destHasUniqueIdx );
- if( (db->flags & SQLITE_Vacuum)==0 && (
- (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
+ if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
|| destHasUniqueIdx /* (2) */
|| (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */
- )){
+ ){
/* In some circumstances, we are able to run the xfer optimization
- ** only if the destination table is initially empty. Unless the
- ** SQLITE_Vacuum flag is set, this block generates code to make
- ** that determination. If SQLITE_Vacuum is set, then the destination
- ** table is always empty.
- **
- ** Conditions under which the destination must be empty:
+ ** only if the destination table is initially empty. This code makes
+ ** that determination. Conditions under which the destination must
+ ** be empty:
**
** (1) There is no INTEGER PRIMARY KEY but there are indices.
** (If the destination is not initially empty, the rowid fields
@@ -101622,7 +103525,6 @@ static int xferOptimization(
sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
}
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
- u8 useSeekResult = 0;
for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
}
@@ -101636,33 +103538,7 @@ static int xferOptimization(
VdbeComment((v, "%s", pDestIdx->zName));
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
- if( db->flags & SQLITE_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
- ** order. In this case, instead of seeking within the b-tree as part
- ** of every OP_IdxInsert opcode, an OP_Last is added before the
- ** OP_IdxInsert to seek to the point within the b-tree where each key
- ** should be inserted. This is faster.
- **
- ** If any of the indexed columns use a collation sequence other than
- ** BINARY, this optimization is disabled. This is because the user
- ** might change the definition of a collation sequence and then run
- ** a VACUUM command. In that case keys may not be written in strictly
- ** sorted order. */
- for(i=0; i<pSrcIdx->nColumn; i++){
- char *zColl = pSrcIdx->azColl[i];
- assert( zColl!=0 );
- if( sqlite3_stricmp("BINARY", zColl) ) break;
- }
- if( i==pSrcIdx->nColumn ){
- useSeekResult = OPFLAG_USESEEKRESULT;
- sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
- }
- }
sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
- sqlite3VdbeChangeP5(v, useSeekResult);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
@@ -101712,7 +103588,7 @@ static int xferOptimization(
** argument to xCallback(). If xCallback=NULL then no callback
** is invoked, even for queries.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_exec(
+SQLITE_API int sqlite3_exec(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
sqlite3_callback xCallback, /* Invoke this callback routine */
@@ -102781,7 +104657,7 @@ static int sqlite3LoadExtension(
const char *zEntry;
char *zAltEntry = 0;
void **aHandle;
- u64 nMsg = 300 + sqlite3Strlen30(zFile);
+ int nMsg = 300 + sqlite3Strlen30(zFile);
int ii;
/* Shared library endings to try if zFile cannot be loaded as written */
@@ -102824,7 +104700,7 @@ static int sqlite3LoadExtension(
#endif
if( handle==0 ){
if( pzErrMsg ){
- *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
+ *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
if( zErrmsg ){
sqlite3_snprintf(nMsg, zErrmsg,
"unable to open shared library [%s]", zFile);
@@ -102850,7 +104726,7 @@ static int sqlite3LoadExtension(
if( xInit==0 && zProc==0 ){
int iFile, iEntry, c;
int ncFile = sqlite3Strlen30(zFile);
- zAltEntry = sqlite3_malloc64(ncFile+30);
+ zAltEntry = sqlite3_malloc(ncFile+30);
if( zAltEntry==0 ){
sqlite3OsDlClose(pVfs, handle);
return SQLITE_NOMEM;
@@ -102872,7 +104748,7 @@ static int sqlite3LoadExtension(
if( xInit==0 ){
if( pzErrMsg ){
nMsg += sqlite3Strlen30(zEntry);
- *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
+ *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
if( zErrmsg ){
sqlite3_snprintf(nMsg, zErrmsg,
"no entry point [%s] in shared library [%s]", zEntry, zFile);
@@ -102907,7 +104783,7 @@ static int sqlite3LoadExtension(
db->aExtension[db->nExtension++] = handle;
return SQLITE_OK;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
+SQLITE_API int sqlite3_load_extension(
sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
@@ -102938,7 +104814,7 @@ SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){
** Enable or disable extension loading. Extension loading is disabled by
** default so as not to open security holes in older applications.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff){
+SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
sqlite3_mutex_enter(db->mutex);
if( onoff ){
db->flags |= SQLITE_LoadExtension;
@@ -102971,7 +104847,7 @@ static const sqlite3_api_routines sqlite3Apis = { 0 };
*/
typedef struct sqlite3AutoExtList sqlite3AutoExtList;
static SQLITE_WSD struct sqlite3AutoExtList {
- u32 nExt; /* Number of entries in aExt[] */
+ int nExt; /* Number of entries in aExt[] */
void (**aExt)(void); /* Pointers to the extension init functions */
} sqlite3Autoext = { 0, 0 };
@@ -102995,7 +104871,7 @@ static SQLITE_WSD struct sqlite3AutoExtList {
** Register a statically linked extension that is automatically
** loaded by every new database connection.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xInit)(void)){
+SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
@@ -103004,7 +104880,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xInit)(void)){
}else
#endif
{
- u32 i;
+ int i;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
@@ -103014,9 +104890,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xInit)(void)){
if( wsdAutoext.aExt[i]==xInit ) break;
}
if( i==wsdAutoext.nExt ){
- u64 nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
+ int nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
void (**aNew)(void);
- aNew = sqlite3_realloc64(wsdAutoext.aExt, nByte);
+ aNew = sqlite3_realloc(wsdAutoext.aExt, nByte);
if( aNew==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -103040,7 +104916,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xInit)(void)){
** Return 1 if xInit was found on the list and removed. Return 0 if xInit
** was not on the list.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xInit)(void)){
+SQLITE_API int sqlite3_cancel_auto_extension(void (*xInit)(void)){
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
@@ -103048,7 +104924,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xInit)(void))
int n = 0;
wsdAutoextInit;
sqlite3_mutex_enter(mutex);
- for(i=(int)wsdAutoext.nExt-1; i>=0; i--){
+ for(i=wsdAutoext.nExt-1; i>=0; i--){
if( wsdAutoext.aExt[i]==xInit ){
wsdAutoext.nExt--;
wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
@@ -103063,7 +104939,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xInit)(void))
/*
** Reset the automatic extension loading mechanism.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void){
+SQLITE_API void sqlite3_reset_auto_extension(void){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize()==SQLITE_OK )
#endif
@@ -103086,7 +104962,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void){
** If anything goes wrong, set an error in the database connection.
*/
SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
- u32 i;
+ int i;
int go = 1;
int rc;
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
@@ -103145,18 +105021,11 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
#endif
/***************************************************************************
-** The "pragma.h" include file is an automatically generated file that
-** that includes the PragType_XXXX macro definitions and the aPragmaName[]
-** object. This ensures that the aPragmaName[] table is arranged in
-** lexicographical order to facility a binary search of the pragma name.
-** Do not edit pragma.h directly. Edit and rerun the script in at
-** ../tool/mkpragmatab.tcl. */
-/************** Include pragma.h in the middle of pragma.c *******************/
-/************** Begin file pragma.h ******************************************/
-/* DO NOT EDIT!
-** This file is automatically generated by the script at
-** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
-** that script and rerun it.
+** The next block of code, including the PragTyp_XXXX macro definitions and
+** the aPragmaName[] object is composed of generated code. DO NOT EDIT.
+**
+** To add new pragmas, edit the code in ../tool/mkpragmatab.tcl and rerun
+** that script. Then copy/paste the output in place of the following:
*/
#define PragTyp_HEADER_VALUE 0
#define PragTyp_AUTO_VACUUM 1
@@ -103391,10 +105260,6 @@ static const struct sPragmaNames {
/* ePragTyp: */ PragTyp_INDEX_LIST,
/* ePragFlag: */ PragFlag_NeedSchema,
/* iArg: */ 0 },
- { /* zName: */ "index_xinfo",
- /* ePragTyp: */ PragTyp_INDEX_INFO,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 1 },
#endif
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
{ /* zName: */ "integrity_check",
@@ -103611,10 +105476,9 @@ static const struct sPragmaNames {
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
#endif
};
-/* Number of pragmas: 59 on by default, 72 total. */
-
-/************** End of pragma.h **********************************************/
-/************** Continuing where we left off in pragma.c *********************/
+/* Number of pragmas: 58 on by default, 71 total. */
+/* End of the automatically generated pragma table.
+***************************************************************************/
/*
** Interpret the given string as a safety level. Return 0 for OFF,
@@ -103750,15 +105614,15 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
*/
static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
Vdbe *v = sqlite3GetVdbe(pParse);
- int nMem = ++pParse->nMem;
+ int mem = ++pParse->nMem;
i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value));
if( pI64 ){
memcpy(pI64, &value, sizeof(value));
}
- sqlite3VdbeAddOp4(v, OP_Int64, 0, nMem, 0, (char*)pI64, P4_INT64);
+ sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
}
@@ -103867,7 +105731,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3 *db = pParse->db; /* The database connection */
Db *pDb; /* The specific database being pragmaed */
Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */
- const struct sPragmaNames *pPragma;
+/* BEGIN SQLCIPHER */
+#ifdef SQLITE_HAS_CODEC
+ extern int sqlcipher_codec_pragma(sqlite3*, int, Parse *, const char *, const char *);
+#endif
+/* END SQLCIPHER */
+
if( v==0 ) return;
sqlite3VdbeRunOnlyOnce(v);
@@ -103903,17 +105772,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
/* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS
** connection. If it returns SQLITE_OK, then assume that the VFS
** handled the pragma and generate a no-op prepared statement.
- **
- ** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed,
- ** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file
- ** object corresponding to the database file to which the pragma
- ** statement refers.
- **
- ** IMPLEMENTATION-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA
- ** file control is an array of pointers to strings (char**) in which the
- ** second element of the array is the name of the pragma and the third
- ** element is the argument to the pragma or NULL if the pragma has no
- ** argument.
*/
aFcntl[0] = 0;
aFcntl[1] = zLeft;
@@ -103923,11 +105781,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
if( rc==SQLITE_OK ){
if( aFcntl[0] ){
- int nMem = ++pParse->nMem;
- sqlite3VdbeAddOp4(v, OP_String8, 0, nMem, 0, aFcntl[0], 0);
+ int mem = ++pParse->nMem;
+ sqlite3VdbeAddOp4(v, OP_String8, 0, mem, 0, aFcntl[0], 0);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
sqlite3_free(aFcntl[0]);
}
goto pragma_out;
@@ -103939,9 +105797,19 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
pParse->nErr++;
pParse->rc = rc;
+
goto pragma_out;
}
+/* BEGIN SQLCIPHER */
+#ifdef SQLITE_HAS_CODEC
+ if(sqlcipher_codec_pragma(db, iDb, pParse, zLeft, zRight)) {
+ /* sqlcipher_codec_pragma executes internal */
+ goto pragma_out;
+ }
+#endif
+/* END SQLCIPHER */
+
/* Locate the pragma in the lookup table */
lwr = 0;
upr = ArraySize(aPragmaNames)-1;
@@ -103956,15 +105824,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
if( lwr>upr ) goto pragma_out;
- pPragma = &aPragmaNames[mid];
/* Make sure the database schema is loaded if the pragma requires that */
- if( (pPragma->mPragFlag & PragFlag_NeedSchema)!=0 ){
+ if( (aPragmaNames[mid].mPragFlag & PragFlag_NeedSchema)!=0 ){
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
}
/* Jump to the appropriate pragma handler */
- switch( pPragma->ePragTyp ){
+ switch( aPragmaNames[mid].ePragTyp ){
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
/*
@@ -104532,9 +106399,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3ErrorMsg(pParse,
"Safety level may not be changed inside a transaction");
}else{
- int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
- if( iLevel==0 ) iLevel = 1;
- pDb->safety_level = iLevel;
+ pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
setAllPagerFlags(db);
}
}
@@ -104545,9 +106410,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
case PragTyp_FLAG: {
if( zRight==0 ){
- returnSingleInt(pParse, pPragma->zName, (db->flags & pPragma->iArg)!=0 );
+ returnSingleInt(pParse, aPragmaNames[mid].zName,
+ (db->flags & aPragmaNames[mid].iArg)!=0 );
}else{
- int mask = pPragma->iArg; /* Mask of bits to set or clear. */
+ int mask = aPragmaNames[mid].iArg; /* Mask of bits to set or clear. */
if( db->autoCommit==0 ){
/* Foreign key support may not be enabled or disabled while not
** in auto-commit mode. */
@@ -104629,7 +106495,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
}else if( pPk==0 ){
k = 1;
}else{
- for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
+ for(k=1; ALWAYS(k<=pTab->nCol) && pPk->aiColumn[k-1]!=i; k++){}
}
sqlite3VdbeAddOp2(v, OP_Integer, k, 6);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
@@ -104676,42 +106542,20 @@ SQLITE_PRIVATE void sqlite3Pragma(
pIdx = sqlite3FindIndex(db, zRight, zDb);
if( pIdx ){
int i;
- int mx;
- if( pPragma->iArg ){
- /* PRAGMA index_xinfo (newer version with more rows and columns) */
- mx = pIdx->nColumn;
- pParse->nMem = 6;
- }else{
- /* PRAGMA index_info (legacy version) */
- mx = pIdx->nKeyCol;
- pParse->nMem = 3;
- }
pTab = pIdx->pTable;
- sqlite3VdbeSetNumCols(v, pParse->nMem);
+ sqlite3VdbeSetNumCols(v, 3);
+ pParse->nMem = 3;
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
- if( pPragma->iArg ){
- sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "desc", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "coll", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "key", SQLITE_STATIC);
- }
- for(i=0; i<mx; i++){
+ for(i=0; i<pIdx->nKeyCol; i++){
i16 cnum = pIdx->aiColumn[i];
sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2);
- if( cnum<0 ){
- sqlite3VdbeAddOp2(v, OP_Null, 0, 3);
- }else{
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
- }
- if( pPragma->iArg ){
- sqlite3VdbeAddOp2(v, OP_Integer, pIdx->aSortOrder[i], 4);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, pIdx->azColl[i], 0);
- sqlite3VdbeAddOp2(v, OP_Integer, i<pIdx->nKeyCol, 6);
- }
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem);
+ assert( pTab->nCol>cnum );
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
}
}
}
@@ -104724,22 +106568,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
v = sqlite3GetVdbe(pParse);
- sqlite3VdbeSetNumCols(v, 5);
- pParse->nMem = 5;
+ sqlite3VdbeSetNumCols(v, 3);
+ pParse->nMem = 3;
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "origin", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "partial", SQLITE_STATIC);
for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
- const char *azOrigin[] = { "c", "u", "pk" };
sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
sqlite3VdbeAddOp2(v, OP_Integer, IsUniqueIndex(pIdx), 3);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, azOrigin[pIdx->idxType], 0);
- sqlite3VdbeAddOp2(v, OP_Integer, pIdx->pPartIdxWhere!=0, 5);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
}
}
}
@@ -105309,9 +107148,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
** applications for any purpose.
*/
case PragTyp_HEADER_VALUE: {
- int iCookie = pPragma->iArg; /* Which cookie to read or write */
+ int iCookie = aPragmaNames[mid].iArg; /* Which cookie to read or write */
sqlite3VdbeUsesBtree(v, iDb);
- if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){
+ if( zRight && (aPragmaNames[mid].mPragFlag & PragFlag_ReadOnly)==0 ){
/* Write the specified cookie value */
static const VdbeOpList setCookie[] = {
{ OP_Transaction, 0, 1, 0}, /* 0 */
@@ -105413,9 +107252,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
/*
** PRAGMA shrink_memory
**
- ** IMPLEMENTATION-OF: R-23445-46109 This pragma causes the database
- ** connection on which it is invoked to free up as much memory as it
- ** can, by calling sqlite3_db_release_memory().
+ ** This pragma attempts to free as much memory as possible from the
+ ** current database connection.
*/
case PragTyp_SHRINK_MEMORY: {
sqlite3_db_release_memory(db);
@@ -105432,7 +107270,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** disables the timeout.
*/
/*case PragTyp_BUSY_TIMEOUT*/ default: {
- assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT );
+ assert( aPragmaNames[mid].ePragTyp==PragTyp_BUSY_TIMEOUT );
if( zRight ){
sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
}
@@ -105444,12 +107282,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
** PRAGMA soft_heap_limit
** PRAGMA soft_heap_limit = N
**
- ** IMPLEMENTATION-OF: R-26343-45930 This pragma invokes the
- ** sqlite3_soft_heap_limit64() interface with the argument N, if N is
- ** specified and is a non-negative integer.
- ** IMPLEMENTATION-OF: R-64451-07163 The soft_heap_limit pragma always
- ** returns the same integer that would be returned by the
- ** sqlite3_soft_heap_limit64(-1) C-language function.
+ ** Call sqlite3_soft_heap_limit64(N). Return the result. If N is omitted,
+ ** use -1.
*/
case PragTyp_SOFT_HEAP_LIMIT: {
sqlite3_int64 N;
@@ -105635,7 +107469,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
if( argv[1]==0 ){
corruptSchema(pData, argv[0], 0);
- }else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){
+ }else if( argv[2] && argv[2][0] ){
/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
** But because db->init.busy is set to 1, no VDBE code is generated
** or executed. All the parser does is build the internal data
@@ -105666,8 +107500,8 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
}
}
sqlite3_finalize(pStmt);
- }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){
- corruptSchema(pData, argv[0], 0);
+ }else if( argv[0]==0 ){
+ corruptSchema(pData, 0, 0);
}else{
/* If the SQL column is blank it means this is an index that
** was created to be the PRIMARY KEY or to fulfill a UNIQUE
@@ -106345,7 +108179,7 @@ SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){
** and the statement is automatically recompiled if an schema change
** occurs.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
+SQLITE_API int sqlite3_prepare(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -106357,7 +108191,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
+SQLITE_API int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -106433,7 +108267,7 @@ static int sqlite3Prepare16(
** and the statement is automatically recompiled if an schema change
** occurs.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
+SQLITE_API int sqlite3_prepare16(
sqlite3 *db, /* Database handle. */
const void *zSql, /* UTF-16 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -106445,7 +108279,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
+SQLITE_API int sqlite3_prepare16_v2(
sqlite3 *db, /* Database handle. */
const void *zSql, /* UTF-16 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -106574,6 +108408,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
Select standin;
sqlite3 *db = pParse->db;
pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
+ assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */
if( pNew==0 ){
assert( db->mallocFailed );
pNew = &standin;
@@ -106593,7 +108428,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
pNew->op = TK_SELECT;
pNew->pLimit = pLimit;
pNew->pOffset = pOffset;
- assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
+ assert( pOffset==0 || pLimit!=0 );
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
if( db->mallocFailed ) {
@@ -107025,17 +108860,20 @@ static void pushOntoSorter(
}
sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord);
if( pSelect->iLimit ){
- int addr;
+ int addr1, addr2;
int iLimit;
if( pSelect->iOffset ){
iLimit = pSelect->iOffset+1;
}else{
iLimit = pSelect->iLimit;
}
- addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, -1); VdbeCoverage(v);
+ addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1);
+ addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
+ sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor);
sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor);
- sqlite3VdbeJumpHere(v, addr);
+ sqlite3VdbeJumpHere(v, addr2);
}
}
@@ -107432,7 +109270,7 @@ static void selectInnerLoop(
** the output for us.
*/
if( pSort==0 && p->iLimit ){
- sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v);
}
}
@@ -107843,7 +109681,7 @@ static const char *columnTypeImpl(
** of the SELECT statement. Return the declaration type and origin
** data for the result-set column of the sub-select.
*/
- if( iCol>=0 && iCol<pS->pEList->nExpr ){
+ if( iCol>=0 && ALWAYS(iCol<pS->pEList->nExpr) ){
/* If iCol is less than zero, then the expression requests the
** rowid of the sub-select or view. This expression is legal (see
** test case misc2.2.2) - it always evaluates to NULL.
@@ -108163,14 +110001,12 @@ static void selectAddColumnTypeAndCollation(
a = pSelect->pEList->a;
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
p = a[i].pExpr;
- if( pCol->zType==0 ){
- pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
- }
+ pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
szAll += pCol->szEst;
pCol->affinity = sqlite3ExprAffinity(p);
if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
pColl = sqlite3ExprCollSeq(pParse, p);
- if( pColl && pCol->zColl==0 ){
+ if( pColl ){
pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
}
}
@@ -108287,7 +110123,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
sqlite3ExprCode(pParse, p->pLimit, iLimit);
sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v);
VdbeComment((v, "LIMIT counter"));
- sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); VdbeCoverage(v);
}
if( p->pOffset ){
p->iOffset = iOffset = ++pParse->nMem;
@@ -108506,7 +110342,7 @@ static void generateWithRecursiveQuery(
selectInnerLoop(pParse, p, p->pEList, iCurrent,
0, 0, pDest, addrCont, addrBreak);
if( regLimit ){
- sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak);
+ sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1);
VdbeCoverage(v);
}
sqlite3VdbeResolveLabel(v, addrCont);
@@ -108572,7 +110408,8 @@ static int multiSelectValues(
int nExpr = p->pEList->nExpr;
int nRow = 1;
int rc = 0;
- assert( p->selFlags & SF_MultiValue );
+ assert( p->pNext==0 );
+ assert( p->selFlags & SF_AllValues );
do{
assert( p->selFlags & SF_Values );
assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
@@ -108681,7 +110518,7 @@ static int multiSelect(
/* Special handling for a compound-select that originates as a VALUES clause.
*/
- if( p->selFlags & SF_MultiValue ){
+ if( p->selFlags & SF_AllValues ){
rc = multiSelectValues(pParse, p, &dest);
goto multi_select_end;
}
@@ -108730,7 +110567,7 @@ static int multiSelect(
p->iLimit = pPrior->iLimit;
p->iOffset = pPrior->iOffset;
if( p->iLimit ){
- addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
+ addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); VdbeCoverage(v);
VdbeComment((v, "Jump ahead if LIMIT reached"));
}
explainSetInteger(iSub2, pParse->iNextSelectId);
@@ -109066,7 +110903,7 @@ static int generateOutputSubroutine(
*/
case SRT_Set: {
int r1;
- assert( pIn->nSdst==1 || pParse->nErr>0 );
+ assert( pIn->nSdst==1 );
pDest->affSdst =
sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
r1 = sqlite3GetTempReg(pParse);
@@ -109092,7 +110929,7 @@ static int generateOutputSubroutine(
** of the scan loop.
*/
case SRT_Mem: {
- assert( pIn->nSdst==1 || pParse->nErr>0 ); testcase( pIn->nSdst!=1 );
+ assert( pIn->nSdst==1 );
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
/* The LIMIT clause will jump out of the loop for us */
break;
@@ -109107,7 +110944,7 @@ static int generateOutputSubroutine(
pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
pDest->nSdst = pIn->nSdst;
}
- sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst);
+ sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst);
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
break;
}
@@ -109131,7 +110968,7 @@ static int generateOutputSubroutine(
/* Jump to the end of the loop if the LIMIT is reached.
*/
if( p->iLimit ){
- sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v);
}
/* Generate the subroutine return
@@ -109323,10 +111160,8 @@ static int multiSelectOrderBy(
if( aPermute ){
struct ExprList_item *pItem;
for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
- assert( pItem->u.x.iOrderByCol>0 );
- /* assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ) is also true
- ** but only for well-formed SELECT statements. */
- testcase( pItem->u.x.iOrderByCol > p->pEList->nExpr );
+ assert( pItem->u.x.iOrderByCol>0
+ && pItem->u.x.iOrderByCol<=p->pEList->nExpr );
aPermute[i] = pItem->u.x.iOrderByCol - 1;
}
pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
@@ -109536,7 +111371,7 @@ static int multiSelectOrderBy(
/*** TBD: Insert subroutine calls to close cursors on incomplete
**** subqueries ****/
explainComposite(pParse, p->op, iSub1, iSub2, 0);
- return pParse->nErr!=0;
+ return SQLITE_OK;
}
#endif
@@ -109656,10 +111491,7 @@ static void substSelect(
**
** (1) The subquery and the outer query do not both use aggregates.
**
-** (2) The subquery is not an aggregate or (2a) the outer query is not a join
-** and (2b) the outer query does not use subqueries other than the one
-** FROM-clause subquery that is a candidate for flattening. (2b is
-** due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
+** (2) The subquery is not an aggregate or the outer query is not a join.
**
** (3) The subquery is not the right operand of a left outer join
** (Originally ticket #306. Strengthened by ticket #3300)
@@ -109796,17 +111628,8 @@ static int flattenSubquery(
iParent = pSubitem->iCursor;
pSub = pSubitem->pSelect;
assert( pSub!=0 );
- if( subqueryIsAgg ){
- if( isAgg ) return 0; /* Restriction (1) */
- if( pSrc->nSrc>1 ) return 0; /* Restriction (2a) */
- if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery))
- || (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0
- || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0
- ){
- return 0; /* Restriction (2b) */
- }
- }
-
+ if( isAgg && subqueryIsAgg ) return 0; /* Restriction (1) */
+ if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; /* Restriction (2) */
pSubSrc = pSub->pSrc;
assert( pSubSrc );
/* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
@@ -110348,10 +112171,7 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
pNew->pOrderBy = 0;
p->pPrior = 0;
p->pNext = 0;
- p->pWith = 0;
p->selFlags &= ~SF_Compound;
- assert( (p->selFlags & SF_Converted)==0 );
- p->selFlags |= SF_Converted;
assert( pNew->pPrior!=0 );
pNew->pPrior->pNext = pNew;
pNew->pLimit = 0;
@@ -110503,7 +112323,7 @@ static int withExpand(
for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
pEList = pLeft->pEList;
if( pCte->pCols ){
- if( pEList && pEList->nExpr!=pCte->pCols->nExpr ){
+ if( pEList->nExpr!=pCte->pCols->nExpr ){
sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns",
pCte->zName, pEList->nExpr, pCte->pCols->nExpr
);
@@ -110630,7 +112450,7 @@ static int selectExpander(Walker *pWalker, Select *p){
/* A sub-query in the FROM clause of a SELECT */
assert( pSel!=0 );
assert( pFrom->pTab==0 );
- if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
+ sqlite3WalkSelect(pWalker, pSel);
pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
if( pTab==0 ) return WRC_Abort;
pTab->nRef = 1;
@@ -110887,7 +112707,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
sqlite3WalkSelect(&w, pSelect);
}
w.xSelectCallback = selectExpander;
- if( (pSelect->selFlags & SF_MultiValue)==0 ){
+ if( (pSelect->selFlags & SF_AllValues)==0 ){
w.xSelectCallback2 = selectPopWith;
}
sqlite3WalkSelect(&w, pSelect);
@@ -111073,8 +112893,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
}
if( pF->iDistinct>=0 ){
addrNext = sqlite3VdbeMakeLabel(v);
- testcase( nArg==0 ); /* Error condition */
- testcase( nArg>1 ); /* Also an error */
+ assert( nArg==1 );
codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
}
if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
@@ -111230,13 +113049,6 @@ SQLITE_PRIVATE int sqlite3Select(
}
isAgg = (p->selFlags & SF_Aggregate)!=0;
assert( pEList!=0 );
-#if SELECTTRACE_ENABLED
- if( sqlite3SelectTrace & 0x100 ){
- SELECTTRACE(0x100,pParse,p, ("after name resolution:\n"));
- sqlite3TreeViewSelect(0, p, 0);
- }
-#endif
-
/* Begin generating code.
*/
@@ -111949,9 +113761,10 @@ SQLITE_PRIVATE int sqlite3Select(
*/
sqlite3VdbeResolveLabel(v, iEnd);
- /* The SELECT has been coded. If there is an error in the Parse structure,
- ** set the return code to 1. Otherwise 0. */
- rc = (pParse->nErr>0);
+ /* The SELECT was successfully coded. Set the return code to 0
+ ** to indicate no errors.
+ */
+ rc = 0;
/* Control jumps to here if an error is encountered above, or upon
** successful coding of the SELECT.
@@ -111981,9 +113794,9 @@ select_end:
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
int n = 0;
pView = sqlite3TreeViewPush(pView, moreToFollow);
- sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p)",
+ sqlite3TreeViewLine(pView, "SELECT%s%s",
((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
- ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p
+ ((p->selFlags & SF_Aggregate) ? " agg_flag" : "")
);
if( p->pSrc && p->pSrc->nSrc ) n++;
if( p->pWhere ) n++;
@@ -112002,7 +113815,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
struct SrcList_item *pItem = &p->pSrc->a[i];
StrAccum x;
char zLine[100];
- sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
+ sqlite3StrAccumInit(&x, zLine, sizeof(zLine), 0);
sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
if( pItem->zDatabase ){
sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
@@ -112161,7 +113974,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
z = 0;
}else{
int n = sqlite3Strlen30(argv[i])+1;
- z = sqlite3_malloc64( n );
+ z = sqlite3_malloc( n );
if( z==0 ) goto malloc_failed;
memcpy(z, argv[i], n);
}
@@ -112186,7 +113999,7 @@ malloc_failed:
** Instead, the entire table should be passed to sqlite3_free_table() when
** the calling procedure is finished using it.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
+SQLITE_API int sqlite3_get_table(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
char ***pazResult, /* Write the result table here */
@@ -112210,7 +114023,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
res.nData = 1;
res.nAlloc = 20;
res.rc = SQLITE_OK;
- res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc );
+ res.azResult = sqlite3_malloc(sizeof(char*)*res.nAlloc );
if( res.azResult==0 ){
db->errCode = SQLITE_NOMEM;
return SQLITE_NOMEM;
@@ -112238,7 +114051,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
}
if( res.nAlloc>res.nData ){
char **azNew;
- azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData );
+ azNew = sqlite3_realloc( res.azResult, sizeof(char*)*res.nData );
if( azNew==0 ){
sqlite3_free_table(&res.azResult[1]);
db->errCode = SQLITE_NOMEM;
@@ -112255,7 +114068,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
/*
** This routine frees the space the sqlite3_get_table() malloced.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_free_table(
+SQLITE_API void sqlite3_free_table(
char **azResult /* Result returned from sqlite3_get_table() */
){
if( azResult ){
@@ -112466,6 +114279,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
/* Do not create a trigger on a system table */
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
+ pParse->nErr++;
goto trigger_cleanup;
}
@@ -112645,12 +114459,12 @@ static TriggerStep *triggerStepAllocate(
){
TriggerStep *pTriggerStep;
- pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
+ pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
if( pTriggerStep ){
char *z = (char*)&pTriggerStep[1];
memcpy(z, pName->z, pName->n);
- sqlite3Dequote(z);
- pTriggerStep->zTarget = z;
+ pTriggerStep->target.z = z;
+ pTriggerStep->target.n = pName->n;
pTriggerStep->op = op;
}
return pTriggerStep;
@@ -112933,7 +114747,7 @@ SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
}
/*
-** Convert the pStep->zTarget string into a SrcList and return a pointer
+** Convert the pStep->target token into a SrcList and return a pointer
** to that SrcList.
**
** This routine adds a specific database name, if needed, to the target when
@@ -112946,17 +114760,17 @@ static SrcList *targetSrcList(
Parse *pParse, /* The parsing context */
TriggerStep *pStep /* The trigger containing the target token */
){
- sqlite3 *db = pParse->db;
int iDb; /* Index of the database to use */
SrcList *pSrc; /* SrcList to be returned */
- pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
+ pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
if( pSrc ){
assert( pSrc->nSrc>0 );
- pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
- iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
+ assert( pSrc->a!=0 );
+ iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
if( iDb==0 || iDb>=2 ){
- assert( iDb<db->nDb );
+ sqlite3 *db = pParse->db;
+ assert( iDb<pParse->db->nDb );
pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
}
}
@@ -113068,7 +114882,6 @@ static void transferParseError(Parse *pTo, Parse *pFrom){
if( pTo->nErr==0 ){
pTo->zErrMsg = pFrom->zErrMsg;
pTo->nErr = pFrom->nErr;
- pTo->rc = pFrom->rc;
}else{
sqlite3DbFree(pFrom->db, pFrom->zErrMsg);
}
@@ -114353,7 +116166,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
** cause problems for the call to BtreeSetPageSize() below. */
sqlite3BtreeCommit(pTemp);
- nRes = sqlite3BtreeGetOptimalReserve(pMain);
+ nRes = sqlite3BtreeGetReserve(pMain);
/* A VACUUM cannot change the pagesize of an encrypted database. */
#ifdef SQLITE_HAS_CODEC
@@ -114419,8 +116232,6 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
** the contents to the temporary database.
*/
- assert( (db->flags & SQLITE_Vacuum)==0 );
- db->flags |= SQLITE_Vacuum;
rc = execExecSql(db, pzErrMsg,
"SELECT 'INSERT INTO vacuum_db.' || quote(name) "
"|| ' SELECT * FROM main.' || quote(name) || ';'"
@@ -114428,8 +116239,6 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
"WHERE type = 'table' AND name!='sqlite_sequence' "
" AND coalesce(rootpage,1)>0"
);
- assert( (db->flags & SQLITE_Vacuum)!=0 );
- db->flags &= ~SQLITE_Vacuum;
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Copy over the sequence table
@@ -114568,8 +116377,6 @@ end_of_vacuum:
struct VtabCtx {
VTable *pVTable; /* The virtual table being constructed */
Table *pTab; /* The Table object to which the virtual table belongs */
- VtabCtx *pPrior; /* Parent context (if any) */
- int bDeclared; /* True after sqlite3_declare_vtab() is called */
};
/*
@@ -114621,7 +116428,7 @@ static int createModule(
/*
** External API function used to create a new virtual-table module.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
+SQLITE_API int sqlite3_create_module(
sqlite3 *db, /* Database in which module is registered */
const char *zName, /* Name assigned to this module */
const sqlite3_module *pModule, /* The definition of the module */
@@ -114636,7 +116443,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
/*
** External API function used to create a new virtual-table module.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2(
+SQLITE_API int sqlite3_create_module_v2(
sqlite3 *db, /* Database in which module is registered */
const char *zName, /* Name assigned to this module */
const sqlite3_module *pModule, /* The definition of the module */
@@ -114935,7 +116742,6 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
char *zStmt;
char *zWhere;
int iDb;
- int iReg;
Vdbe *v;
/* Compute the complete text of the CREATE VIRTUAL TABLE statement */
@@ -114970,10 +116776,8 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName);
sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
-
- iReg = ++pParse->nMem;
- sqlite3VdbeAddOp4(v, OP_String8, 0, iReg, 0, pTab->zName, 0);
- sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
+ sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0,
+ pTab->zName, sqlite3Strlen30(pTab->zName) + 1);
}
/* If we are rereading the sqlite_master table create the in-memory
@@ -115016,7 +116820,7 @@ SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){
pArg->z = p->z;
pArg->n = p->n;
}else{
- assert(pArg->z <= p->z);
+ assert(pArg->z < p->z);
pArg->n = (int)(&p->z[p->n] - pArg->z);
}
}
@@ -115033,27 +116837,15 @@ static int vtabCallConstructor(
int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
char **pzErr
){
- VtabCtx sCtx;
+ VtabCtx sCtx, *pPriorCtx;
VTable *pVTable;
int rc;
const char *const*azArg = (const char *const*)pTab->azModuleArg;
int nArg = pTab->nModuleArg;
char *zErr = 0;
- char *zModuleName;
+ char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
int iDb;
- VtabCtx *pCtx;
-
- /* Check that the virtual-table is not already being initialized */
- for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){
- if( pCtx->pTab==pTab ){
- *pzErr = sqlite3MPrintf(db,
- "vtable constructor called recursively: %s", pTab->zName
- );
- return SQLITE_LOCKED;
- }
- }
- zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
if( !zModuleName ){
return SQLITE_NOMEM;
}
@@ -115074,13 +116866,11 @@ static int vtabCallConstructor(
assert( xConstruct );
sCtx.pTab = pTab;
sCtx.pVTable = pVTable;
- sCtx.pPrior = db->pVtabCtx;
- sCtx.bDeclared = 0;
+ pPriorCtx = db->pVtabCtx;
db->pVtabCtx = &sCtx;
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
- db->pVtabCtx = sCtx.pPrior;
+ db->pVtabCtx = pPriorCtx;
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
- assert( sCtx.pTab==pTab );
if( SQLITE_OK!=rc ){
if( zErr==0 ){
@@ -115096,14 +116886,13 @@ static int vtabCallConstructor(
memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
pVTable->pVtab->pModule = pMod->pModule;
pVTable->nRef = 1;
- if( sCtx.bDeclared==0 ){
+ if( sCtx.pTab ){
const char *zFormat = "vtable constructor did not declare schema: %s";
*pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
sqlite3VtabUnlock(pVTable);
rc = SQLITE_ERROR;
}else{
int iCol;
- u8 oooHidden = 0;
/* If everything went according to plan, link the new VTable structure
** into the linked list headed by pTab->pVTable. Then loop through the
** columns of the table to see if any of them contain the token "hidden".
@@ -115116,10 +116905,7 @@ static int vtabCallConstructor(
char *zType = pTab->aCol[iCol].zType;
int nType;
int i = 0;
- if( !zType ){
- pTab->tabFlags |= oooHidden;
- continue;
- }
+ if( !zType ) continue;
nType = sqlite3Strlen30(zType);
if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
for(i=0; i<nType; i++){
@@ -115142,9 +116928,6 @@ static int vtabCallConstructor(
zType[i-1] = '\0';
}
pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
- oooHidden = TF_OOOHidden;
- }else{
- pTab->tabFlags |= oooHidden;
}
}
}
@@ -115272,26 +117055,22 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
** valid to call this function from within the xCreate() or xConnect() of a
** virtual table module.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
- VtabCtx *pCtx;
+SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
Parse *pParse;
+
int rc = SQLITE_OK;
Table *pTab;
char *zErr = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
- if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){
- return SQLITE_MISUSE_BKPT;
- }
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
- pCtx = db->pVtabCtx;
- if( !pCtx || pCtx->bDeclared ){
+ if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
sqlite3Error(db, SQLITE_MISUSE);
sqlite3_mutex_leave(db->mutex);
return SQLITE_MISUSE_BKPT;
}
- pTab = pCtx->pTab;
assert( (pTab->tabFlags & TF_Virtual)!=0 );
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
@@ -115314,7 +117093,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3 *db, const char *zCre
pParse->pNewTable->nCol = 0;
pParse->pNewTable->aCol = 0;
}
- pCtx->bDeclared = 1;
+ db->pVtabCtx->pTab = 0;
}else{
sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
@@ -115349,15 +117128,11 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){
- VTable *p;
- for(p=pTab->pVTable; p; p=p->pNext){
- assert( p->pVtab );
- if( p->pVtab->nRef>0 ){
- return SQLITE_LOCKED;
- }
- }
- p = vtabDisconnectAll(db, pTab);
+ VTable *p = vtabDisconnectAll(db, pTab);
+
+ assert( rc==SQLITE_OK );
rc = p->pMod->pModule->xDestroy(p->pVtab);
+
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
if( rc==SQLITE_OK ){
assert( pTab->pVTable==p && p->pNext==0 );
@@ -115508,7 +117283,7 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
int rc = SQLITE_OK;
assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN );
- assert( iSavepoint>=-1 );
+ assert( iSavepoint>=0 );
if( db->aVTrans ){
int i;
for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
@@ -115626,7 +117401,7 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
if( pTab==pToplevel->apVtabLock[i] ) return;
}
n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
- apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n);
+ apVtabLock = sqlite3_realloc(pToplevel->apVtabLock, n);
if( apVtabLock ){
pToplevel->apVtabLock = apVtabLock;
pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
@@ -115642,7 +117417,7 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
** The results of this routine are undefined unless it is called from
** within an xUpdate method.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *db){
+SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){
static const unsigned char aMap[] = {
SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE
};
@@ -115660,7 +117435,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *db){
** the SQLite core with additional information about the behavior
** of the virtual table being implemented.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3 *db, int op, ...){
+SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
va_list ap;
int rc = SQLITE_OK;
@@ -115786,8 +117561,6 @@ struct WhereLevel {
int addrCont; /* Jump here to continue with the next loop cycle */
int addrFirst; /* First instruction of interior of the loop */
int addrBody; /* Beginning of the body of this loop */
- int iLikeRepCntr; /* LIKE range processing counter register */
- int addrLikeRep; /* LIKE range processing address */
u8 iFrom; /* Which entry in the FROM clause */
u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
int p1, p2; /* Operands of the opcode used to ends the loop */
@@ -115972,7 +117745,7 @@ struct WhereTerm {
} u;
LogEst truthProb; /* Probability of truth for this expression */
u16 eOperator; /* A WO_xx value describing <op> */
- u16 wtFlags; /* TERM_xxx bit flags. See below */
+ u8 wtFlags; /* TERM_xxx bit flags. See below */
u8 nChild; /* Number of children that must disable us */
WhereClause *pWC; /* The clause this term is part of */
Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */
@@ -115994,9 +117767,6 @@ struct WhereTerm {
#else
# define TERM_VNULL 0x00 /* Disabled if not using stat3 */
#endif
-#define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */
-#define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */
-#define TERM_LIKE 0x400 /* The original LIKE operator */
/*
** An instance of the WhereScan object is used as an iterator for locating
@@ -116372,7 +118142,7 @@ static void whereClauseClear(WhereClause *pWC){
** calling this routine. Such pointers may be reinitialized by referencing
** the pWC->a[] array.
*/
-static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
+static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
WhereTerm *pTerm;
int idx;
testcase( wtFlags & TERM_VIRTUAL );
@@ -116425,14 +118195,13 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
** all terms of the WHERE clause.
*/
static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
- Expr *pE2 = sqlite3ExprSkipCollate(pExpr);
pWC->op = op;
- if( pE2==0 ) return;
- if( pE2->op!=op ){
+ if( pExpr==0 ) return;
+ if( pExpr->op!=op ){
whereClauseInsert(pWC, pExpr, 0);
}else{
- whereSplit(pWC, pE2->pLeft, op);
- whereSplit(pWC, pE2->pRight, op);
+ whereSplit(pWC, pExpr->pLeft, op);
+ whereSplit(pWC, pExpr->pRight, op);
}
}
@@ -116798,11 +118567,7 @@ static void exprAnalyzeAll(
** so and false if not.
**
** In order for the operator to be optimizible, the RHS must be a string
-** literal that does not begin with a wildcard. The LHS must be a column
-** that may only be NULL, a string, or a BLOB, never a number. (This means
-** that virtual tables cannot participate in the LIKE optimization.) If the
-** collating sequence for the column on the LHS must be appropriate for
-** the operator.
+** literal that does not begin with a wildcard.
*/
static int isLikeOrGlob(
Parse *pParse, /* Parsing and code generating context */
@@ -116831,7 +118596,7 @@ static int isLikeOrGlob(
pLeft = pList->a[1].pExpr;
if( pLeft->op!=TK_COLUMN
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
- || IsVirtual(pLeft->pTab) /* Value might be numeric */
+ || IsVirtual(pLeft->pTab)
){
/* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
** be the name of an indexed column with TEXT affinity. */
@@ -116941,79 +118706,6 @@ static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){
pWC->a[iParent].nChild++;
}
-/*
-** Return the N-th AND-connected subterm of pTerm. Or if pTerm is not
-** a conjunction, then return just pTerm when N==0. If N is exceeds
-** the number of available subterms, return NULL.
-*/
-static WhereTerm *whereNthSubterm(WhereTerm *pTerm, int N){
- if( pTerm->eOperator!=WO_AND ){
- return N==0 ? pTerm : 0;
- }
- if( N<pTerm->u.pAndInfo->wc.nTerm ){
- return &pTerm->u.pAndInfo->wc.a[N];
- }
- return 0;
-}
-
-/*
-** Subterms pOne and pTwo are contained within WHERE clause pWC. The
-** two subterms are in disjunction - they are OR-ed together.
-**
-** If these two terms are both of the form: "A op B" with the same
-** A and B values but different operators and if the operators are
-** compatible (if one is = and the other is <, for example) then
-** add a new virtual AND term to pWC that is the combination of the
-** two.
-**
-** Some examples:
-**
-** x<y OR x=y --> x<=y
-** x=y OR x=y --> x=y
-** x<=y OR x<y --> x<=y
-**
-** The following is NOT generated:
-**
-** x<y OR x>y --> x!=y
-*/
-static void whereCombineDisjuncts(
- SrcList *pSrc, /* the FROM clause */
- WhereClause *pWC, /* The complete WHERE clause */
- WhereTerm *pOne, /* First disjunct */
- WhereTerm *pTwo /* Second disjunct */
-){
- u16 eOp = pOne->eOperator | pTwo->eOperator;
- sqlite3 *db; /* Database connection (for malloc) */
- Expr *pNew; /* New virtual expression */
- int op; /* Operator for the combined expression */
- int idxNew; /* Index in pWC of the next virtual term */
-
- if( (pOne->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return;
- if( (pTwo->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return;
- if( (eOp & (WO_EQ|WO_LT|WO_LE))!=eOp
- && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return;
- assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 );
- assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 );
- if( sqlite3ExprCompare(pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return;
- if( sqlite3ExprCompare(pOne->pExpr->pRight, pTwo->pExpr->pRight, -1) )return;
- /* If we reach this point, it means the two subterms can be combined */
- if( (eOp & (eOp-1))!=0 ){
- if( eOp & (WO_LT|WO_LE) ){
- eOp = WO_LE;
- }else{
- assert( eOp & (WO_GT|WO_GE) );
- eOp = WO_GE;
- }
- }
- db = pWC->pWInfo->pParse->db;
- pNew = sqlite3ExprDup(db, pOne->pExpr, 0);
- if( pNew==0 ) return;
- for(op=TK_EQ; eOp!=(WO_EQ<<(op-TK_EQ)); op++){ assert( op<TK_GE ); }
- pNew->op = op;
- idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
- exprAnalyze(pSrc, pWC, idxNew);
-}
-
#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
/*
** Analyze a term that consists of two or more OR-connected
@@ -117038,7 +118730,6 @@ static void whereCombineDisjuncts(
** (C) t1.x=t2.y OR (t1.x=t2.z AND t1.y=15)
** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*')
** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6)
-** (F) x>A OR (x=A AND y>=B)
**
** CASE 1:
**
@@ -117055,16 +118746,6 @@ static void whereCombineDisjuncts(
**
** CASE 2:
**
-** If there are exactly two disjuncts one side has x>A and the other side
-** has x=A (for the same x and A) then add a new virtual conjunct term to the
-** WHERE clause of the form "x>=A". Example:
-**
-** x>A OR (x=A AND y>B) adds: x>=A
-**
-** The added conjunct can sometimes be helpful in query planning.
-**
-** CASE 3:
-**
** If all subterms are indexable by a single table T, then set
**
** WhereTerm.eOperator = WO_OR
@@ -117191,26 +118872,12 @@ static void exprAnalyzeOrTerm(
}
/*
- ** Record the set of tables that satisfy case 3. The set might be
+ ** Record the set of tables that satisfy case 2. The set might be
** empty.
*/
pOrInfo->indexable = indexable;
pTerm->eOperator = indexable==0 ? 0 : WO_OR;
- /* For a two-way OR, attempt to implementation case 2.
- */
- if( indexable && pOrWc->nTerm==2 ){
- int iOne = 0;
- WhereTerm *pOne;
- while( (pOne = whereNthSubterm(&pOrWc->a[0],iOne++))!=0 ){
- int iTwo = 0;
- WhereTerm *pTwo;
- while( (pTwo = whereNthSubterm(&pOrWc->a[1],iTwo++))!=0 ){
- whereCombineDisjuncts(pSrc, pWC, pOne, pTwo);
- }
- }
- }
-
/*
** chngToIN holds a set of tables that *might* satisfy case 1. But
** we have to do some additional checking to see if case 1 really
@@ -117340,7 +119007,7 @@ static void exprAnalyzeOrTerm(
}else{
sqlite3ExprListDelete(db, pList);
}
- pTerm->eOperator = WO_NOOP; /* case 1 trumps case 3 */
+ pTerm->eOperator = WO_NOOP; /* case 1 trumps case 2 */
}
}
}
@@ -117378,7 +119045,7 @@ static void exprAnalyze(
Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */
Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */
int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */
- int noCase = 0; /* uppercase equivalent to lowercase */
+ int noCase = 0; /* LIKE/GLOB distinguishes case */
int op; /* Top-level operator. pExpr->op */
Parse *pParse = pWInfo->pParse; /* Parsing context */
sqlite3 *db = pParse->db; /* Database connection */
@@ -117516,15 +119183,12 @@ static void exprAnalyze(
/* Add constraints to reduce the search space on a LIKE or GLOB
** operator.
**
- ** A like pattern of the form "x LIKE 'aBc%'" is changed into constraints
+ ** A like pattern of the form "x LIKE 'abc%'" is changed into constraints
**
- ** x>='ABC' AND x<'abd' AND x LIKE 'aBc%'
+ ** x>='abc' AND x<'abd' AND x LIKE 'abc%'
**
** The last character of the prefix "abc" is incremented to form the
- ** termination condition "abd". If case is not significant (the default
- ** for LIKE) then the lower-bound is made all uppercase and the upper-
- ** bound is made all lowercase so that the bounds also work when comparing
- ** BLOBs.
+ ** termination condition "abd".
*/
if( pWC->op==TK_AND
&& isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase)
@@ -117535,26 +119199,10 @@ static void exprAnalyze(
Expr *pNewExpr2;
int idxNew1;
int idxNew2;
- const char *zCollSeqName; /* Name of collating sequence */
- const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC;
+ Token sCollSeqName; /* Name of collating sequence */
pLeft = pExpr->x.pList->a[1].pExpr;
pStr2 = sqlite3ExprDup(db, pStr1, 0);
-
- /* Convert the lower bound to upper-case and the upper bound to
- ** lower-case (upper-case is less than lower-case in ASCII) so that
- ** the range constraints also work for BLOBs
- */
- if( noCase && !pParse->db->mallocFailed ){
- int i;
- char c;
- pTerm->wtFlags |= TERM_LIKE;
- for(i=0; (c = pStr1->u.zToken[i])!=0; i++){
- pStr1->u.zToken[i] = sqlite3Toupper(c);
- pStr2->u.zToken[i] = sqlite3Tolower(c);
- }
- }
-
if( !db->mallocFailed ){
u8 c, *pC; /* Last character before the first wildcard */
pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1];
@@ -117571,21 +119219,22 @@ static void exprAnalyze(
}
*pC = c + 1;
}
- zCollSeqName = noCase ? "NOCASE" : "BINARY";
+ sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
+ sCollSeqName.n = 6;
pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
- pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
- sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
+ pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
+ sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
pStr1, 0);
transferJoinMarkings(pNewExpr1, pExpr);
- idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags);
+ idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew1==0 );
exprAnalyze(pSrc, pWC, idxNew1);
pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
- sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName),
+ sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
pStr2, 0);
transferJoinMarkings(pNewExpr2, pExpr);
- idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags);
+ idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew2==0 );
exprAnalyze(pSrc, pWC, idxNew2);
pTerm = &pWC->a[idxTerm];
@@ -117703,7 +119352,7 @@ static int findIndexCol(
&& p->iTable==iBase
){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
- if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){
+ if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
return i;
}
}
@@ -117903,16 +119552,12 @@ static void constructAutomaticIndex(
pLoop = pLevel->pWLoop;
idxCols = 0;
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
- Expr *pExpr = pTerm->pExpr;
- assert( !ExprHasProperty(pExpr, EP_FromJoin) /* prereq always non-zero */
- || pExpr->iRightJoinTable!=pSrc->iCursor /* for the right-hand */
- || pLoop->prereq!=0 ); /* table of a LEFT JOIN */
if( pLoop->prereq==0
&& (pTerm->wtFlags & TERM_VIRTUAL)==0
- && !ExprHasProperty(pExpr, EP_FromJoin)
- && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
+ && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+ && sqlite3ExprIsTableConstant(pTerm->pExpr, pSrc->iCursor) ){
pPartial = sqlite3ExprAnd(pParse->db, pPartial,
- sqlite3ExprDup(pParse->db, pExpr, 0));
+ sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
}
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
int iCol = pTerm->u.leftColumn;
@@ -117977,7 +119622,7 @@ static void constructAutomaticIndex(
idxCols |= cMask;
pIdx->aiColumn[n] = pTerm->u.leftColumn;
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
- pIdx->azColl[n] = pColl ? pColl->zName : "BINARY";
+ pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : "BINARY";
n++;
}
}
@@ -118199,14 +119844,11 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
** Estimate the location of a particular key among all keys in an
** index. Store the results in aStat as follows:
**
-** aStat[0] Est. number of rows less than pRec
-** aStat[1] Est. number of rows equal to pRec
+** aStat[0] Est. number of rows less than pVal
+** aStat[1] Est. number of rows equal to pVal
**
** Return the index of the sample that is the smallest sample that
-** is greater than or equal to pRec. Note that this index is not an index
-** into the aSample[] array - it is an index into a virtual set of samples
-** based on the contents of aSample[] and the number of fields in record
-** pRec.
+** is greater than or equal to pRec.
*/
static int whereKeyStats(
Parse *pParse, /* Database connection */
@@ -118217,158 +119859,67 @@ static int whereKeyStats(
){
IndexSample *aSample = pIdx->aSample;
int iCol; /* Index of required stats in anEq[] etc. */
- int i; /* Index of first sample >= pRec */
- int iSample; /* Smallest sample larger than or equal to pRec */
int iMin = 0; /* Smallest sample not yet tested */
+ int i = pIdx->nSample; /* Smallest sample larger than or equal to pRec */
int iTest; /* Next sample to test */
int res; /* Result of comparison operation */
- int nField; /* Number of fields in pRec */
- tRowcnt iLower = 0; /* anLt[] + anEq[] of largest sample pRec is > */
#ifndef SQLITE_DEBUG
UNUSED_PARAMETER( pParse );
#endif
assert( pRec!=0 );
+ iCol = pRec->nField - 1;
assert( pIdx->nSample>0 );
- assert( pRec->nField>0 && pRec->nField<=pIdx->nSampleCol );
-
- /* Do a binary search to find the first sample greater than or equal
- ** to pRec. If pRec contains a single field, the set of samples to search
- ** is simply the aSample[] array. If the samples in aSample[] contain more
- ** than one fields, all fields following the first are ignored.
- **
- ** If pRec contains N fields, where N is more than one, then as well as the
- ** samples in aSample[] (truncated to N fields), the search also has to
- ** consider prefixes of those samples. For example, if the set of samples
- ** in aSample is:
- **
- ** aSample[0] = (a, 5)
- ** aSample[1] = (a, 10)
- ** aSample[2] = (b, 5)
- ** aSample[3] = (c, 100)
- ** aSample[4] = (c, 105)
- **
- ** Then the search space should ideally be the samples above and the
- ** unique prefixes [a], [b] and [c]. But since that is hard to organize,
- ** the code actually searches this set:
- **
- ** 0: (a)
- ** 1: (a, 5)
- ** 2: (a, 10)
- ** 3: (a, 10)
- ** 4: (b)
- ** 5: (b, 5)
- ** 6: (c)
- ** 7: (c, 100)
- ** 8: (c, 105)
- ** 9: (c, 105)
- **
- ** For each sample in the aSample[] array, N samples are present in the
- ** effective sample array. In the above, samples 0 and 1 are based on
- ** sample aSample[0]. Samples 2 and 3 on aSample[1] etc.
- **
- ** Often, sample i of each block of N effective samples has (i+1) fields.
- ** Except, each sample may be extended to ensure that it is greater than or
- ** equal to the previous sample in the array. For example, in the above,
- ** sample 2 is the first sample of a block of N samples, so at first it
- ** appears that it should be 1 field in size. However, that would make it
- ** smaller than sample 1, so the binary search would not work. As a result,
- ** it is extended to two fields. The duplicates that this creates do not
- ** cause any problems.
- */
- nField = pRec->nField;
- iCol = 0;
- iSample = pIdx->nSample * nField;
+ assert( pRec->nField>0 && iCol<pIdx->nSampleCol );
do{
- int iSamp; /* Index in aSample[] of test sample */
- int n; /* Number of fields in test sample */
-
- iTest = (iMin+iSample)/2;
- iSamp = iTest / nField;
- if( iSamp>0 ){
- /* The proposed effective sample is a prefix of sample aSample[iSamp].
- ** Specifically, the shortest prefix of at least (1 + iTest%nField)
- ** fields that is greater than the previous effective sample. */
- for(n=(iTest % nField) + 1; n<nField; n++){
- if( aSample[iSamp-1].anLt[n-1]!=aSample[iSamp].anLt[n-1] ) break;
- }
- }else{
- n = iTest + 1;
- }
-
- pRec->nField = n;
- res = sqlite3VdbeRecordCompare(aSample[iSamp].n, aSample[iSamp].p, pRec);
+ iTest = (iMin+i)/2;
+ res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec);
if( res<0 ){
- iLower = aSample[iSamp].anLt[n-1] + aSample[iSamp].anEq[n-1];
- iMin = iTest+1;
- }else if( res==0 && n<nField ){
- iLower = aSample[iSamp].anLt[n-1];
iMin = iTest+1;
- res = -1;
}else{
- iSample = iTest;
- iCol = n-1;
+ i = iTest;
}
- }while( res && iMin<iSample );
- i = iSample / nField;
+ }while( res && iMin<i );
#ifdef SQLITE_DEBUG
/* The following assert statements check that the binary search code
** above found the right answer. This block serves no purpose other
** than to invoke the asserts. */
- if( pParse->db->mallocFailed==0 ){
- if( res==0 ){
- /* If (res==0) is true, then pRec must be equal to sample i. */
- assert( i<pIdx->nSample );
- assert( iCol==nField-1 );
- pRec->nField = nField;
- assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)
- || pParse->db->mallocFailed
- );
- }else{
- /* Unless i==pIdx->nSample, indicating that pRec is larger than
- ** all samples in the aSample[] array, pRec must be smaller than the
- ** (iCol+1) field prefix of sample i. */
- assert( i<=pIdx->nSample && i>=0 );
- pRec->nField = iCol+1;
- assert( i==pIdx->nSample
- || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0
- || pParse->db->mallocFailed );
-
- /* if i==0 and iCol==0, then record pRec is smaller than all samples
- ** in the aSample[] array. Otherwise, if (iCol>0) then pRec must
- ** be greater than or equal to the (iCol) field prefix of sample i.
- ** If (i>0), then pRec must also be greater than sample (i-1). */
- if( iCol>0 ){
- pRec->nField = iCol;
- assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0
- || pParse->db->mallocFailed );
- }
- if( i>0 ){
- pRec->nField = nField;
- assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0
- || pParse->db->mallocFailed );
- }
- }
+ if( res==0 ){
+ /* If (res==0) is true, then sample $i must be equal to pRec */
+ assert( i<pIdx->nSample );
+ assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)
+ || pParse->db->mallocFailed );
+ }else{
+ /* Otherwise, pRec must be smaller than sample $i and larger than
+ ** sample ($i-1). */
+ assert( i==pIdx->nSample
+ || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0
+ || pParse->db->mallocFailed );
+ assert( i==0
+ || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0
+ || pParse->db->mallocFailed );
}
#endif /* ifdef SQLITE_DEBUG */
+ /* At this point, aSample[i] is the first sample that is greater than
+ ** or equal to pVal. Or if i==pIdx->nSample, then all samples are less
+ ** than pVal. If aSample[i]==pVal, then res==0.
+ */
if( res==0 ){
- /* Record pRec is equal to sample i */
- assert( iCol==nField-1 );
aStat[0] = aSample[i].anLt[iCol];
aStat[1] = aSample[i].anEq[iCol];
}else{
- /* At this point, the (iCol+1) field prefix of aSample[i] is the first
- ** sample that is greater than pRec. Or, if i==pIdx->nSample then pRec
- ** is larger than all samples in the array. */
- tRowcnt iUpper, iGap;
- if( i>=pIdx->nSample ){
- iUpper = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]);
+ tRowcnt iLower, iUpper, iGap;
+ if( i==0 ){
+ iLower = 0;
+ iUpper = aSample[0].anLt[iCol];
}else{
- iUpper = aSample[i].anLt[iCol];
+ i64 nRow0 = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]);
+ iUpper = i>=pIdx->nSample ? nRow0 : aSample[i].anLt[iCol];
+ iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol];
}
-
+ aStat[1] = pIdx->aAvgEq[iCol];
if( iLower>=iUpper ){
iGap = 0;
}else{
@@ -118380,11 +119931,7 @@ static int whereKeyStats(
iGap = iGap/3;
}
aStat[0] = iLower + iGap;
- aStat[1] = pIdx->aAvgEq[iCol];
}
-
- /* Restore the pRec->nField value before returning. */
- pRec->nField = nField;
return i;
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
@@ -118858,43 +120405,20 @@ static int whereInScanEst(
** but joins might run a little slower. The trick is to disable as much
** as we can without disabling too much. If we disabled in (1), we'd get
** the wrong answer. See ticket #813.
-**
-** If all the children of a term are disabled, then that term is also
-** automatically disabled. In this way, terms get disabled if derived
-** virtual terms are tested first. For example:
-**
-** x GLOB 'abc*' AND x>='abc' AND x<'acd'
-** \___________/ \______/ \_____/
-** parent child1 child2
-**
-** Only the parent term was in the original WHERE clause. The child1
-** and child2 terms were added by the LIKE optimization. If both of
-** the virtual child terms are valid, then testing of the parent can be
-** skipped.
-**
-** Usually the parent term is marked as TERM_CODED. But if the parent
-** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead.
-** The TERM_LIKECOND marking indicates that the term should be coded inside
-** a conditional such that is only evaluated on the second pass of a
-** LIKE-optimization loop, when scanning BLOBs instead of strings.
*/
static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
- int nLoop = 0;
- while( pTerm
+ if( pTerm
&& (pTerm->wtFlags & TERM_CODED)==0
&& (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
&& (pLevel->notReady & pTerm->prereqAll)==0
){
- if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){
- pTerm->wtFlags |= TERM_LIKECOND;
- }else{
- pTerm->wtFlags |= TERM_CODED;
+ pTerm->wtFlags |= TERM_CODED;
+ if( pTerm->iParent>=0 ){
+ WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent];
+ if( (--pOther->nChild)==0 ){
+ disableTerm(pLevel, pOther);
+ }
}
- if( pTerm->iParent<0 ) break;
- pTerm = &pTerm->pWC->a[pTerm->iParent];
- pTerm->nChild--;
- if( pTerm->nChild!=0 ) break;
- nLoop++;
}
}
@@ -119273,7 +120797,8 @@ static int explainOneScan(
|| ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
|| (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
- sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
+ sqlite3StrAccumInit(&str, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
+ str.db = db;
sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
if( pItem->pSelect ){
sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
@@ -119377,34 +120902,7 @@ static void addScanStatus(
# define addScanStatus(a, b, c, d) ((void)d)
#endif
-/*
-** If the most recently coded instruction is a constant range contraint
-** that originated from the LIKE optimization, then change the P3 to be
-** pLoop->iLikeRepCntr and set P5.
-**
-** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range
-** expression: "x>='ABC' AND x<'abd'". But this requires that the range
-** scan loop run twice, once for strings and a second time for BLOBs.
-** The OP_String opcodes on the second pass convert the upper and lower
-** bound string contants to blobs. This routine makes the necessary changes
-** to the OP_String opcodes for that to happen.
-*/
-static void whereLikeOptimizationStringFixup(
- Vdbe *v, /* prepared statement under construction */
- WhereLevel *pLevel, /* The loop that contains the LIKE operator */
- WhereTerm *pTerm /* The upper or lower bound just coded */
-){
- if( pTerm->wtFlags & TERM_LIKEOPT ){
- VdbeOp *pOp;
- assert( pLevel->iLikeRepCntr>0 );
- pOp = sqlite3VdbeGetOp(v, -1);
- assert( pOp!=0 );
- assert( pOp->opcode==OP_String8
- || pTerm->pWC->pWInfo->pParse->db->mallocFailed );
- pOp->p3 = pLevel->iLikeRepCntr;
- pOp->p5 = 1;
- }
-}
+
/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
@@ -119734,25 +121232,10 @@ static Bitmask codeOneLoopStart(
if( pLoop->wsFlags & WHERE_BTM_LIMIT ){
pRangeStart = pLoop->aLTerm[j++];
nExtraReg = 1;
- /* Like optimization range constraints always occur in pairs */
- assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 ||
- (pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 );
}
if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
pRangeEnd = pLoop->aLTerm[j++];
nExtraReg = 1;
- if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){
- assert( pRangeStart!=0 ); /* LIKE opt constraints */
- assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */
- pLevel->iLikeRepCntr = ++pParse->nMem;
- testcase( bRev );
- testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC );
- sqlite3VdbeAddOp2(v, OP_Integer,
- bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC),
- pLevel->iLikeRepCntr);
- VdbeComment((v, "LIKE loop counter"));
- pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v);
- }
if( pRangeStart==0
&& (j = pIdx->aiColumn[nEq])>=0
&& pIdx->pTable->aCol[j].notNull==0
@@ -119795,7 +121278,6 @@ static Bitmask codeOneLoopStart(
if( pRangeStart ){
Expr *pRight = pRangeStart->pExpr->pRight;
sqlite3ExprCode(pParse, pRight, regBase+nEq);
- whereLikeOptimizationStringFixup(v, pLevel, pRangeStart);
if( (pRangeStart->wtFlags & TERM_VNULL)==0
&& sqlite3ExprCanBeNull(pRight)
){
@@ -119841,7 +121323,6 @@ static Bitmask codeOneLoopStart(
Expr *pRight = pRangeEnd->pExpr->pRight;
sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
sqlite3ExprCode(pParse, pRight, regBase+nEq);
- whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
if( (pRangeEnd->wtFlags & TERM_VNULL)==0
&& sqlite3ExprCanBeNull(pRight)
){
@@ -120069,8 +121550,7 @@ static Bitmask codeOneLoopStart(
*/
wctrlFlags = WHERE_OMIT_OPEN_CLOSE
| WHERE_FORCE_TABLE
- | WHERE_ONETABLE_ONLY
- | WHERE_NO_AUTOINDEX;
+ | WHERE_ONETABLE_ONLY;
for(ii=0; ii<pOrWc->nTerm; ii++){
WhereTerm *pOrTerm = &pOrWc->a[ii];
if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
@@ -120232,7 +121712,6 @@ static Bitmask codeOneLoopStart(
*/
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
Expr *pE;
- int skipLikeAddr = 0;
testcase( pTerm->wtFlags & TERM_VIRTUAL );
testcase( pTerm->wtFlags & TERM_CODED );
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
@@ -120247,13 +121726,7 @@ static Bitmask codeOneLoopStart(
if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
continue;
}
- if( pTerm->wtFlags & TERM_LIKECOND ){
- assert( pLevel->iLikeRepCntr>0 );
- skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfNot, pLevel->iLikeRepCntr);
- VdbeCoverage(v);
- }
sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
- if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
pTerm->wtFlags |= TERM_CODED;
}
@@ -120472,13 +121945,6 @@ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
*/
static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
if( ALWAYS(pWInfo) ){
- int i;
- for(i=0; i<pWInfo->nLevel; i++){
- WhereLevel *pLevel = &pWInfo->a[i];
- if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
- sqlite3DbFree(db, pLevel->u.in.aInLoop);
- }
- }
whereClauseClear(&pWInfo->sWC);
while( pWInfo->pLoops ){
WhereLoop *p = pWInfo->pLoops;
@@ -120925,10 +122391,6 @@ static int whereLoopAddBtreeIndex(
}
if( pTerm->prereqRight & pNew->maskSelf ) continue;
- /* Do not allow the upper bound of a LIKE optimization range constraint
- ** to mix with a lower range bound from some other source */
- if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
-
pNew->wsFlags = saved_wsFlags;
pNew->u.btree.nEq = saved_nEq;
pNew->nLTerm = saved_nLTerm;
@@ -120958,7 +122420,7 @@ static int whereLoopAddBtreeIndex(
}else if( eOp & (WO_EQ) ){
pNew->wsFlags |= WHERE_COLUMN_EQ;
if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){
- if( iCol>=0 && pProbe->uniqNotNull==0 ){
+ if( iCol>=0 && !IsUniqueIndex(pProbe) ){
pNew->wsFlags |= WHERE_UNQ_WANTED;
}else{
pNew->wsFlags |= WHERE_ONEROW;
@@ -120972,17 +122434,6 @@ static int whereLoopAddBtreeIndex(
pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
pBtm = pTerm;
pTop = 0;
- if( pTerm->wtFlags & TERM_LIKEOPT ){
- /* Range contraints that come from the LIKE optimization are
- ** always used in pairs. */
- pTop = &pTerm[1];
- assert( (pTop-(pTerm->pWC->a))<pTerm->pWC->nTerm );
- assert( pTop->wtFlags & TERM_LIKEOPT );
- assert( pTop->eOperator==WO_LT );
- if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
- pNew->aLTerm[pNew->nLTerm++] = pTop;
- pNew->wsFlags |= WHERE_TOP_LIMIT;
- }
}else{
assert( eOp & (WO_LT|WO_LE) );
testcase( eOp & WO_LT );
@@ -121184,9 +122635,8 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
int i;
WhereTerm *pTerm;
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
- Expr *pExpr = pTerm->pExpr;
- if( sqlite3ExprImpliesExpr(pExpr, pWhere, iTab)
- && (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
+ if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab)
+ && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
){
return 1;
}
@@ -121293,7 +122743,6 @@ static int whereLoopAddBtree(
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/* Automatic indexes */
if( !pBuilder->pOrSet
- && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0
&& (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
&& pSrc->pIndex==0
&& !pSrc->viaCoroutine
@@ -122177,10 +123626,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
/* Seed the search with a single WherePath containing zero WhereLoops.
**
- ** TUNING: Do not let the number of iterations go above 28. If the cost
- ** of computing an automatic index is not paid back within the first 28
+ ** TUNING: Do not let the number of iterations go above 25. If the cost
+ ** of computing an automatic index is not paid back within the first 25
** rows, then do not use the automatic index. */
- aFrom[0].nRow = MIN(pParse->nQueryLoop, 48); assert( 48==sqlite3LogEst(28) );
+ aFrom[0].nRow = MIN(pParse->nQueryLoop, 46); assert( 46==sqlite3LogEst(25) );
nFrom = 1;
assert( aFrom[0].isOrdered==0 );
if( nOrderBy ){
@@ -122418,7 +123867,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
pWInfo->revMask = pFrom->revLoop;
}
if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
- && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0
+ && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr
){
Bitmask revMask = 0;
int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy,
@@ -122823,6 +124272,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
}
#ifdef WHERETRACE_ENABLED /* !=0 */
if( sqlite3WhereTrace ){
+ int ii;
sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
if( pWInfo->nOBSat>0 ){
sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
@@ -122977,12 +124427,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
if( op ){
sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb);
sqlite3VdbeSetP4KeyInfo(pParse, pIx);
- if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0
- && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0
- && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
- ){
- sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */
- }
VdbeComment((v, "%s", pIx->zName));
}
}
@@ -123075,6 +124519,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
}
+ sqlite3DbFree(db, pLevel->u.in.aInLoop);
}
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
if( pLevel->addrSkip ){
@@ -123083,16 +124528,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeJumpHere(v, pLevel->addrSkip);
sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
}
- if( pLevel->addrLikeRep ){
- int op;
- if( sqlite3VdbeGetOp(v, pLevel->addrLikeRep-1)->p1 ){
- op = OP_DecrJumpZero;
- }else{
- op = OP_JumpZeroIncr;
- }
- sqlite3VdbeAddOp2(v, op, pLevel->iLikeRepCntr, pLevel->addrLikeRep);
- VdbeCoverage(v);
- }
if( pLevel->iLeftJoin ){
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
@@ -123286,28 +124721,6 @@ struct TrigEvent { int a; IdList * b; };
struct AttachKey { int type; Token key; };
- /*
- ** For a compound SELECT statement, make sure p->pPrior->pNext==p for
- ** all elements in the list. And make sure list length does not exceed
- ** SQLITE_LIMIT_COMPOUND_SELECT.
- */
- static void parserDoubleLinkSelect(Parse *pParse, Select *p){
- if( p->pPrior ){
- Select *pNext = 0, *pLoop;
- int mxSelect, cnt = 0;
- for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
- pLoop->pNext = pNext;
- pLoop->selFlags |= SF_Compound;
- }
- if( (p->selFlags & SF_MultiValue)==0 &&
- (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
- cnt>mxSelect
- ){
- sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
- }
- }
- }
-
/* This is a utility routine used to set the ExprSpan.zStart and
** ExprSpan.zEnd values of pOut so that the span covers the complete
** range of text beginning with pStart and going to the end of pEnd.
@@ -125624,10 +127037,27 @@ static void yy_reduce(
break;
case 112: /* select ::= with selectnowith */
{
- Select *p = yymsp[0].minor.yy3;
+ Select *p = yymsp[0].minor.yy3, *pNext, *pLoop;
if( p ){
+ int cnt = 0, mxSelect;
p->pWith = yymsp[-1].minor.yy59;
- parserDoubleLinkSelect(pParse, p);
+ if( p->pPrior ){
+ u16 allValues = SF_Values;
+ pNext = 0;
+ for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
+ pLoop->pNext = pNext;
+ pLoop->selFlags |= SF_Compound;
+ allValues &= pLoop->selFlags;
+ }
+ if( allValues ){
+ p->selFlags |= SF_AllValues;
+ }else if(
+ (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
+ && cnt>mxSelect
+ ){
+ sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
+ }
+ }
}else{
sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy59);
}
@@ -125645,14 +127075,12 @@ static void yy_reduce(
SrcList *pFrom;
Token x;
x.n = 0;
- parserDoubleLinkSelect(pParse, pRhs);
pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
}
if( pRhs ){
pRhs->op = (u8)yymsp[-1].minor.yy328;
pRhs->pPrior = yymsp[-2].minor.yy3;
- pRhs->selFlags &= ~SF_MultiValue;
if( yymsp[-1].minor.yy328!=TK_ALL ) pParse->hasCompound = 1;
}else{
sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy3);
@@ -125699,16 +127127,13 @@ static void yy_reduce(
break;
case 121: /* values ::= values COMMA LP exprlist RP */
{
- Select *pRight, *pLeft = yymsp[-4].minor.yy3;
- pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
- if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
+ Select *pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
if( pRight ){
pRight->op = TK_ALL;
- pLeft = yymsp[-4].minor.yy3;
- pRight->pPrior = pLeft;
+ pRight->pPrior = yymsp[-4].minor.yy3;
yygotominor.yy3 = pRight;
}else{
- yygotominor.yy3 = pLeft;
+ yygotominor.yy3 = yymsp[-4].minor.yy3;
}
}
break;
@@ -125993,7 +127418,7 @@ static void yy_reduce(
break;
case 193: /* expr ::= expr COLLATE ID|STRING */
{
- yygotominor.yy346.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy346.pExpr, &yymsp[0].minor.yy0, 1);
+ yygotominor.yy346.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy346.pExpr, &yymsp[0].minor.yy0);
yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart;
yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
@@ -126156,7 +127581,7 @@ static void yy_reduce(
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0);
if( yygotominor.yy346.pExpr ){
yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy14;
- sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
}else{
sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14);
}
@@ -126171,8 +127596,8 @@ static void yy_reduce(
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
if( yygotominor.yy346.pExpr ){
yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3;
- ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery);
- sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
+ ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
}
@@ -126185,8 +127610,8 @@ static void yy_reduce(
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0);
if( yygotominor.yy346.pExpr ){
yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3;
- ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery);
- sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
+ ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
}
@@ -126201,8 +127626,8 @@ static void yy_reduce(
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy346.pExpr, 0, 0);
if( yygotominor.yy346.pExpr ){
yygotominor.yy346.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
- ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery);
- sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
+ ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
}else{
sqlite3SrcListDelete(pParse->db, pSrc);
}
@@ -126216,8 +127641,8 @@ static void yy_reduce(
Expr *p = yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
p->x.pSelect = yymsp[-1].minor.yy3;
- ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
- sqlite3ExprSetHeightAndFlags(pParse, p);
+ ExprSetProperty(p, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, p);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
}
@@ -126230,7 +127655,7 @@ static void yy_reduce(
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy132, 0, 0);
if( yygotominor.yy346.pExpr ){
yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy132 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy132) : yymsp[-2].minor.yy14;
- sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
}else{
sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14);
sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy132);
@@ -126273,7 +127698,7 @@ static void yy_reduce(
break;
case 244: /* idxlist ::= idxlist COMMA nm collate sortorder */
{
- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1);
+ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, p);
sqlite3ExprListSetName(pParse,yygotominor.yy14,&yymsp[-2].minor.yy0,1);
sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index");
@@ -126282,7 +127707,7 @@ static void yy_reduce(
break;
case 245: /* idxlist ::= nm collate sortorder */
{
- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1);
+ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, p);
sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index");
@@ -127472,7 +128897,10 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
sqlite3 *db = pParse->db; /* The database connection */
int mxSqlLen; /* Max length of an SQL string */
- assert( zSql!=0 );
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( zSql==0 || pzErrMsg==0 ) return SQLITE_MISUSE_BKPT;
+#endif
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
if( db->nVdbeActive==0 ){
db->u1.isInterrupted = 0;
@@ -127512,8 +128940,10 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
break;
}
case TK_ILLEGAL: {
- sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"",
+ sqlite3DbFree(db, *pzErrMsg);
+ *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
&pParse->sLastToken);
+ nErr++;
goto abort_parse;
}
case TK_SEMI: {
@@ -127531,22 +128961,17 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
}
}
abort_parse:
- assert( nErr==0 );
- if( zSql[i]==0 && pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
+ if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
if( lastTokenParsed!=TK_SEMI ){
sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
pParse->zTail = &zSql[i];
}
- if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
- sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
- }
+ sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
}
#ifdef YYTRACKMAXSTACKDEPTH
- sqlite3_mutex_enter(sqlite3MallocMutex());
sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
sqlite3ParserStackPeak(pEngine)
);
- sqlite3_mutex_leave(sqlite3MallocMutex());
#endif /* YYDEBUG */
sqlite3ParserFree(pEngine, sqlite3_free);
db->lookaside.bEnabled = enableLookaside;
@@ -127600,7 +129025,9 @@ abort_parse:
pParse->pZombieTab = p->pNextZombie;
sqlite3DeleteTable(db, p);
}
- assert( nErr==0 || pParse->rc!=SQLITE_OK );
+ if( nErr>0 && pParse->rc==SQLITE_OK ){
+ pParse->rc = SQLITE_ERROR;
+ }
return nErr;
}
@@ -127708,7 +129135,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[];
** to recognize the end of a trigger can be omitted. All we have to do
** is look for a semicolon that is not part of an string or comment.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *zSql){
+SQLITE_API int sqlite3_complete(const char *zSql){
u8 state = 0; /* Current state, using numbers defined in header comment */
u8 token; /* Value of the next token */
@@ -127873,10 +129300,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *zSql){
** above, except that the parameter is required to be UTF-16 encoded, not
** UTF-8.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *zSql){
+SQLITE_API int sqlite3_complete16(const void *zSql){
sqlite3_value *pVal;
char const *zSql8;
- int rc;
+ int rc = SQLITE_NOMEM;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
@@ -128023,36 +129450,24 @@ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns
** a pointer to the to the sqlite3_version[] string constant.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void){ return sqlite3_version; }
+SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; }
/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a
** pointer to a string constant whose value is the same as the
** SQLITE_SOURCE_ID C preprocessor macro.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
+SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function
** returns an integer equal to SQLITE_VERSION_NUMBER.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
+SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns
** zero if and only if SQLite was compiled with mutexing code omitted due to
** the SQLITE_THREADSAFE compile-time option being set to 0.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
-
-/*
-** When compiling the test fixture or with debugging enabled (on Win32),
-** this variable being set to non-zero will cause OSTRACE macros to emit
-** extra diagnostic information.
-*/
-#ifdef SQLITE_HAVE_OS_TRACE
-# ifndef SQLITE_DEBUG_OS_TRACE
-# define SQLITE_DEBUG_OS_TRACE 0
-# endif
- int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
-#endif
+SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
/*
@@ -128061,7 +129476,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void){ return SQLITE_THREADSAFE
** I/O active are written using this function. These messages
** are intended for debugging activity only.
*/
-SQLITE_API void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...) = 0;
+/* not-private */ void (*sqlite3IoTrace)(const char*, ...) = 0;
#endif
/*
@@ -128113,7 +129528,7 @@ SQLITE_API char *sqlite3_data_directory = 0;
** * Recursive calls to this routine from thread X return immediately
** without blocking.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){
+SQLITE_API int sqlite3_initialize(void){
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
int rc; /* Result code */
#ifdef SQLITE_EXTRA_INIT
@@ -128127,11 +129542,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){
}
#endif
- /* If the following assert() fails on some obscure processor/compiler
- ** combination, the work-around is to set the correct pointer
- ** size at compile-time using -DSQLITE_PTRSIZE=n compile-time option */
- assert( SQLITE_PTRSIZE==sizeof(char*) );
-
/* 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
@@ -128274,7 +129684,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){
** on when SQLite is already shut down. If SQLite is already shut down
** when this routine is invoked, then this routine is a harmless no-op.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void){
+SQLITE_API int sqlite3_shutdown(void){
#ifdef SQLITE_OMIT_WSD
int rc = sqlite3_wsd_init(4096, 24);
if( rc!=SQLITE_OK ){
@@ -128328,7 +129738,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void){
** threadsafe. Failure to heed these warnings can lead to unpredictable
** behavior.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_config(int op, ...){
+SQLITE_API int sqlite3_config(int op, ...){
va_list ap;
int rc = SQLITE_OK;
@@ -128344,28 +129754,26 @@ SQLITE_API int SQLITE_CDECL sqlite3_config(int op, ...){
*/
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-54466-46756 */
case SQLITE_CONFIG_SINGLETHREAD: {
- /* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to
- ** Single-thread. */
- sqlite3GlobalConfig.bCoreMutex = 0; /* Disable mutex on core */
- sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */
+ /* Disable all mutexing */
+ sqlite3GlobalConfig.bCoreMutex = 0;
+ sqlite3GlobalConfig.bFullMutex = 0;
break;
}
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */
case SQLITE_CONFIG_MULTITHREAD: {
- /* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to
- ** Multi-thread. */
- sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */
- sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */
+ /* Disable mutexing of database connections */
+ /* Enable mutexing of core data structures */
+ sqlite3GlobalConfig.bCoreMutex = 1;
+ sqlite3GlobalConfig.bFullMutex = 0;
break;
}
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */
case SQLITE_CONFIG_SERIALIZED: {
- /* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to
- ** Serialized. */
- sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */
- sqlite3GlobalConfig.bFullMutex = 1; /* Enable mutex on connections */
+ /* Enable all mutexing */
+ sqlite3GlobalConfig.bCoreMutex = 1;
+ sqlite3GlobalConfig.bFullMutex = 1;
break;
}
#endif
@@ -128477,8 +129885,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_config(int op, ...){
case SQLITE_CONFIG_HEAP: {
/* EVIDENCE-OF: R-19854-42126 There are three arguments to
** SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the
- ** number of bytes in the memory buffer, and the minimum allocation size.
- */
+ ** number of bytes in the memory buffer, and the minimum allocation size. */
sqlite3GlobalConfig.pHeap = va_arg(ap, void*);
sqlite3GlobalConfig.nHeap = va_arg(ap, int);
sqlite3GlobalConfig.mnReq = va_arg(ap, int);
@@ -128583,9 +129990,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_config(int op, ...){
** compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE
** compile-time option.
*/
- if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){
- mxMmap = SQLITE_MAX_MMAP_SIZE;
- }
+ if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ) mxMmap = SQLITE_MAX_MMAP_SIZE;
if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE;
if( szMmap>mxMmap) szMmap = mxMmap;
sqlite3GlobalConfig.mxMmap = mxMmap;
@@ -128685,7 +130090,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
/*
** Return the mutex associated with a database connection.
*/
-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3 *db){
+SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -128699,7 +130104,7 @@ SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3 *db){
** Free up as much memory as we can from the given database
** connection.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3 *db){
+SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){
int i;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -128722,7 +130127,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3 *db){
/*
** Configuration settings for an individual database connection
*/
-SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3 *db, int op, ...){
+SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
va_list ap;
int rc;
va_start(ap, op);
@@ -128841,7 +130246,7 @@ static int nocaseCollatingFunc(
/*
** Return the ROWID of the most recent insert
*/
-SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3 *db){
+SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -128854,7 +130259,7 @@ SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3 *db){
/*
** Return the number of changes in the most recent call to sqlite3_exec().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3 *db){
+SQLITE_API int sqlite3_changes(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -128867,7 +130272,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3 *db){
/*
** Return the number of changes since the database handle was opened.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3 *db){
+SQLITE_API int sqlite3_total_changes(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -129009,8 +130414,8 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
** unclosed resources, and arranges for deallocation when the last
** prepare statement or sqlite3_backup closes.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
-SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
+SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
+SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
/*
@@ -129193,7 +130598,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
** Return a static string containing the name corresponding to the error code
** specified in the argument.
*/
-#if defined(SQLITE_NEED_ERR_NAME)
+#if (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) || defined(SQLITE_TEST)
SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
const char *zName = 0;
int i, origRc = rc;
@@ -129417,13 +130822,13 @@ SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
** This routine sets the busy callback for an Sqlite database to the
** given callback function with the given argument.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(
+SQLITE_API int sqlite3_busy_handler(
sqlite3 *db,
int (*xBusy)(void*,int),
void *pArg
){
#ifdef SQLITE_ENABLE_API_ARMOR
- if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE;
#endif
sqlite3_mutex_enter(db->mutex);
db->busyHandler.xFunc = xBusy;
@@ -129440,7 +130845,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(
** given callback function with the given argument. The progress callback will
** be invoked every nOps opcodes.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(
+SQLITE_API void sqlite3_progress_handler(
sqlite3 *db,
int nOps,
int (*xProgress)(void*),
@@ -129471,7 +130876,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(
** This routine installs a default busy handler that waits for the
** specified number of milliseconds before returning 0.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3 *db, int ms){
+SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
@@ -129487,7 +130892,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3 *db, int ms){
/*
** Cause any pending operation to stop at its earliest opportunity.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3 *db){
+SQLITE_API void sqlite3_interrupt(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -129604,7 +131009,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
/*
** Create new user functions.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
+SQLITE_API int sqlite3_create_function(
sqlite3 *db,
const char *zFunc,
int nArg,
@@ -129618,7 +131023,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
xFinal, 0);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
+SQLITE_API int sqlite3_create_function_v2(
sqlite3 *db,
const char *zFunc,
int nArg,
@@ -129661,7 +131066,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
+SQLITE_API int sqlite3_create_function16(
sqlite3 *db,
const void *zFunctionName,
int nArg,
@@ -129701,7 +131106,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
** A global function must exist in order for name resolution to work
** properly.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(
+SQLITE_API int sqlite3_overload_function(
sqlite3 *db,
const char *zName,
int nArg
@@ -129733,7 +131138,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(
** trace is a pointer to a function that is invoked at the start of each
** SQL statement.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
+SQLITE_API void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
void *pOld;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -129757,7 +131162,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,
** profile is a pointer to a function that is invoked at the conclusion of
** each SQL statement that is run.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_profile(
+SQLITE_API void *sqlite3_profile(
sqlite3 *db,
void (*xProfile)(void*,const char*,sqlite_uint64),
void *pArg
@@ -129784,7 +131189,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_profile(
** If the invoked function returns non-zero, then the commit becomes a
** rollback.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(
+SQLITE_API void *sqlite3_commit_hook(
sqlite3 *db, /* Attach the hook to this database */
int (*xCallback)(void*), /* Function to invoke on each commit */
void *pArg /* Argument to the function */
@@ -129809,7 +131214,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(
** Register a callback to be invoked each time a row is updated,
** inserted or deleted using this database connection.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
+SQLITE_API void *sqlite3_update_hook(
sqlite3 *db, /* Attach the hook to this database */
void (*xCallback)(void*,int,char const *,char const *,sqlite_int64),
void *pArg /* Argument to the function */
@@ -129834,7 +131239,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
** Register a callback to be invoked each time a transaction is rolled
** back by this database connection.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(
+SQLITE_API void *sqlite3_rollback_hook(
sqlite3 *db, /* Attach the hook to this database */
void (*xCallback)(void*), /* Callback function */
void *pArg /* Argument to the function */
@@ -129888,7 +131293,7 @@ SQLITE_PRIVATE int sqlite3WalDefaultHook(
** using sqlite3_wal_hook() disables the automatic checkpoint mechanism
** configured by this function.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
+SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
#ifdef SQLITE_OMIT_WAL
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(nFrame);
@@ -129909,7 +131314,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame
** Register a callback to be invoked each time a transaction is written
** into the write-ahead-log by this database connection.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
+SQLITE_API void *sqlite3_wal_hook(
sqlite3 *db, /* Attach the hook to this db handle */
int(*xCallback)(void *, sqlite3*, const char*, int),
void *pArg /* First argument passed to xCallback() */
@@ -129936,7 +131341,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
/*
** Checkpoint database zDb.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
+SQLITE_API int sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -129991,7 +131396,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
** to contains a zero-length string, all attached databases are
** checkpointed.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
+SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
/* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to
** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */
return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0);
@@ -130080,7 +131485,7 @@ SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3 *db){
+SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
const char *z;
if( !db ){
return sqlite3ErrStr(SQLITE_NOMEM);
@@ -130108,7 +131513,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3 *db){
** Return UTF-16 encoded English language explanation of the most recent
** error.
*/
-SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3 *db){
+SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
static const u16 outOfMem[] = {
'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0
};
@@ -130153,7 +131558,7 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3 *db){
** Return the most recent error code generated by an SQLite routine. If NULL is
** passed to this function, we assume a malloc() failed during sqlite3_open().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db){
+SQLITE_API int sqlite3_errcode(sqlite3 *db){
if( db && !sqlite3SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
@@ -130162,7 +131567,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db){
}
return db->errCode & db->errMask;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db){
+SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){
if( db && !sqlite3SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
@@ -130177,7 +131582,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db){
** argument. For now, this simply calls the internal sqlite3ErrStr()
** function.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int rc){
+SQLITE_API const char *sqlite3_errstr(int rc){
return sqlite3ErrStr(rc);
}
@@ -130325,7 +131730,7 @@ static const int aHardLimit[] = {
** It merely prevents new constructs that exceed the limit
** from forming.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
+SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
int oldLimit;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -130418,30 +131823,18 @@ SQLITE_PRIVATE int sqlite3ParseUri(
int eState; /* Parser state when parsing URI */
int iIn; /* Input character index */
int iOut = 0; /* Output character index */
- u64 nByte = nUri+2; /* Bytes of space to allocate */
+ int nByte = nUri+2; /* Bytes of space to allocate */
/* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen
** method that there may be extra parameters following the file-name. */
flags |= SQLITE_OPEN_URI;
for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
- zFile = sqlite3_malloc64(nByte);
+ zFile = sqlite3_malloc(nByte);
if( !zFile ) return SQLITE_NOMEM;
iIn = 5;
-#ifdef SQLITE_ALLOW_URI_AUTHORITY
- if( strncmp(zUri+5, "///", 3)==0 ){
- iIn = 7;
- /* The following condition causes URIs with five leading / characters
- ** like file://///host/path to be converted into UNCs like //host/path.
- ** The correct URI for that UNC has only two or four leading / characters
- ** file://host/path or file:////host/path. But 5 leading slashes is a
- ** common error, we are told, so we handle it as a special case. */
- if( strncmp(zUri+7, "///", 3)==0 ){ iIn++; }
- }else if( strncmp(zUri+5, "//localhost/", 12)==0 ){
- iIn = 16;
- }
-#else
+#ifndef SQLITE_ALLOW_URI_AUTHORITY
/* Discard the scheme and authority segments of the URI. */
if( zUri[5]=='/' && zUri[6]=='/' ){
iIn = 7;
@@ -130591,7 +131984,7 @@ SQLITE_PRIVATE int sqlite3ParseUri(
}
}else{
- zFile = sqlite3_malloc64(nUri+2);
+ zFile = sqlite3_malloc(nUri+2);
if( !zFile ) return SQLITE_NOMEM;
memcpy(zFile, zUri, nUri);
zFile[nUri] = '\0';
@@ -130728,9 +132121,6 @@ static int openDatabase(
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
| SQLITE_AutoIndex
#endif
-#if SQLITE_DEFAULT_CKPTFULLFSYNC
- | SQLITE_CkptFullFSync
-#endif
#if SQLITE_DEFAULT_FILE_FORMAT<4
| SQLITE_LegacyFileFmt
#endif
@@ -130863,13 +132253,6 @@ static int openDatabase(
}
#endif
-#ifdef SQLITE_ENABLE_DBSTAT_VTAB
- if( !db->mallocFailed && rc==SQLITE_OK){
- int sqlite3_dbstat_register(sqlite3*);
- rc = sqlite3_dbstat_register(db);
- }
-#endif
-
/* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
** mode. Doing nothing at all also makes NORMAL the default.
@@ -130891,8 +132274,7 @@ static int openDatabase(
opendb_out:
sqlite3_free(zOpen);
if( db ){
- assert( db->mutex!=0 || isThreadsafe==0
- || sqlite3GlobalConfig.bFullMutex==0 );
+ assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );
sqlite3_mutex_leave(db->mutex);
}
rc = sqlite3_errcode(db);
@@ -130917,14 +132299,14 @@ opendb_out:
/*
** Open a new database handle.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_open(
+SQLITE_API int sqlite3_open(
const char *zFilename,
sqlite3 **ppDb
){
return openDatabase(zFilename, ppDb,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
+SQLITE_API int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
@@ -130937,7 +132319,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
/*
** Open a new database handle.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_open16(
+SQLITE_API int sqlite3_open16(
const void *zFilename,
sqlite3 **ppDb
){
@@ -130976,7 +132358,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_open16(
/*
** Register a new collation sequence with the database handle db.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
+SQLITE_API int sqlite3_create_collation(
sqlite3* db,
const char *zName,
int enc,
@@ -130989,7 +132371,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
/*
** Register a new collation sequence with the database handle db.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
+SQLITE_API int sqlite3_create_collation_v2(
sqlite3* db,
const char *zName,
int enc,
@@ -131014,7 +132396,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
/*
** Register a new collation sequence with the database handle db.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
+SQLITE_API int sqlite3_create_collation16(
sqlite3* db,
const void *zName,
int enc,
@@ -131044,7 +132426,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
+SQLITE_API int sqlite3_collation_needed(
sqlite3 *db,
void *pCollNeededArg,
void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
@@ -131065,7 +132447,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
+SQLITE_API int sqlite3_collation_needed16(
sqlite3 *db,
void *pCollNeededArg,
void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
@@ -131087,7 +132469,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
** This function is now an anachronism. It used to be used to recover from a
** malloc() failure, but SQLite now does this automatically.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_global_recover(void){
+SQLITE_API int sqlite3_global_recover(void){
return SQLITE_OK;
}
#endif
@@ -131098,7 +132480,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_global_recover(void){
** by default. Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3 *db){
+SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -131150,7 +132532,7 @@ SQLITE_PRIVATE int sqlite3CantopenError(int lineno){
** SQLite no longer uses thread-specific data so this routine is now a
** no-op. It is retained for historical compatibility.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_thread_cleanup(void){
+SQLITE_API void sqlite3_thread_cleanup(void){
}
#endif
@@ -131158,7 +132540,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_thread_cleanup(void){
** Return meta information about a specific column of a database table.
** See comment in sqlite3.h (sqlite.h.in) for details.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
+SQLITE_API int sqlite3_table_column_metadata(
sqlite3 *db, /* Connection handle */
const char *zDbName, /* Database name or NULL */
const char *zTableName, /* Table name */
@@ -131174,19 +132556,13 @@ SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
Table *pTab = 0;
Column *pCol = 0;
int iCol = 0;
+
char const *zDataType = 0;
char const *zCollSeq = 0;
int notnull = 0;
int primarykey = 0;
int autoinc = 0;
-
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){
- return SQLITE_MISUSE_BKPT;
- }
-#endif
-
/* Ensure the database schema has been loaded */
sqlite3_mutex_enter(db->mutex);
sqlite3BtreeEnterAll(db);
@@ -131276,7 +132652,7 @@ error_out:
/*
** Sleep for a little while. Return the amount of time slept.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int ms){
+SQLITE_API int sqlite3_sleep(int ms){
sqlite3_vfs *pVfs;
int rc;
pVfs = sqlite3_vfs_find(0);
@@ -131292,7 +132668,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int ms){
/*
** Enable or disable the extended result codes.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3 *db, int onoff){
+SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
@@ -131305,7 +132681,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3 *db, int ono
/*
** Invoke the xFileControl method on a particular database.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
+SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
int rc = SQLITE_ERROR;
Btree *pBtree;
@@ -131333,13 +132709,13 @@ SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3 *db, const char *zDbN
sqlite3BtreeLeave(pBtree);
}
sqlite3_mutex_leave(db->mutex);
- return rc;
+ return rc;
}
/*
** Interface to the testing logic.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...){
+SQLITE_API int sqlite3_test_control(int op, ...){
int rc = 0;
#ifndef SQLITE_OMIT_BUILTIN_TEST
va_list ap;
@@ -131636,35 +133012,6 @@ SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...){
if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR;
break;
}
-
- /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum);
- **
- ** This test control is used to create imposter tables. "db" is a pointer
- ** to the database connection. dbName is the database name (ex: "main" or
- ** "temp") which will receive the imposter. "onOff" turns imposter mode on
- ** or off. "tnum" is the root page of the b-tree to which the imposter
- ** table should connect.
- **
- ** Enable imposter mode only when the schema has already been parsed. Then
- ** run a single CREATE TABLE statement to construct the imposter table in
- ** the parsed schema. Then turn imposter mode back off again.
- **
- ** If onOff==0 and tnum>0 then reset the schema for all databases, causing
- ** the schema to be reparsed the next time it is needed. This has the
- ** effect of erasing all imposter tables.
- */
- case SQLITE_TESTCTRL_IMPOSTER: {
- sqlite3 *db = va_arg(ap, sqlite3*);
- sqlite3_mutex_enter(db->mutex);
- db->init.iDb = sqlite3FindDbName(db, va_arg(ap,const char*));
- db->init.busy = db->init.imposterTable = va_arg(ap,int);
- db->init.newTnum = va_arg(ap,int);
- if( db->init.busy==0 && db->init.newTnum>0 ){
- sqlite3ResetAllSchemasOfConnection(db);
- }
- sqlite3_mutex_leave(db->mutex);
- break;
- }
}
va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
@@ -131682,7 +133029,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...){
** parameter if it exists. If the parameter does not exist, this routine
** returns a NULL pointer.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam){
+SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
if( zFilename==0 || zParam==0 ) return 0;
zFilename += sqlite3Strlen30(zFilename) + 1;
while( zFilename[0] ){
@@ -131697,7 +133044,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilenam
/*
** Return a boolean value for a query parameter.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
+SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
const char *z = sqlite3_uri_parameter(zFilename, zParam);
bDflt = bDflt!=0;
return z ? sqlite3GetBoolean(z, bDflt) : bDflt;
@@ -131706,7 +133053,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFilename, const c
/*
** Return a 64-bit integer value for a query parameter.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(
+SQLITE_API sqlite3_int64 sqlite3_uri_int64(
const char *zFilename, /* Filename as passed to xOpen */
const char *zParam, /* URI parameter sought */
sqlite3_int64 bDflt /* return if parameter is missing */
@@ -131738,7 +133085,7 @@ SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
** Return the filename of the database associated with a database
** connection.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName){
+SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
Btree *pBt;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
@@ -131754,7 +133101,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const cha
** Return 1 if database is read-only or 0 if read/write. Return -1 if
** no such database exists.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
+SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
Btree *pBt;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
@@ -131913,7 +133260,7 @@ static void leaveMutex(void){
** on the same "db". If xNotify==0 then any prior callbacks are immediately
** cancelled.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
+SQLITE_API int sqlite3_unlock_notify(
sqlite3 *db,
void (*xNotify)(void **, int),
void *pArg
@@ -132807,11 +134154,6 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi
#ifdef SQLITE_COVERAGE_TEST
# define ALWAYS(x) (1)
# define NEVER(X) (0)
-#elif defined(SQLITE_DEBUG)
-# define ALWAYS(x) sqlite3Fts3Always((x)!=0)
-# define NEVER(x) sqlite3Fts3Never((x)!=0)
-SQLITE_PRIVATE int sqlite3Fts3Always(int b);
-SQLITE_PRIVATE int sqlite3Fts3Never(int b);
#else
# define ALWAYS(x) (x)
# define NEVER(x) (x)
@@ -133212,7 +134554,6 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int);
)
/* fts3.c */
-SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char**,const char*,...);
SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64);
SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *);
@@ -133302,13 +134643,6 @@ static int fts3EvalStart(Fts3Cursor *pCsr);
static int fts3TermSegReaderCursor(
Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **);
-#ifndef SQLITE_AMALGAMATION
-# if defined(SQLITE_DEBUG)
-SQLITE_PRIVATE int sqlite3Fts3Always(int b) { assert( b ); return b; }
-SQLITE_PRIVATE int sqlite3Fts3Never(int b) { assert( !b ); return b; }
-# endif
-#endif
-
/*
** Write a 64-bit variable-length integer to memory starting at p[0].
** The length of data written will be between 1 and FTS3_VARINT_MAX bytes.
@@ -133418,7 +134752,7 @@ SQLITE_PRIVATE void sqlite3Fts3Dequote(char *z){
/* If the first byte was a '[', then the close-quote character is a ']' */
if( quote=='[' ) quote = ']';
- while( z[iIn] ){
+ while( ALWAYS(z[iIn]) ){
if( z[iIn]==quote ){
if( z[iIn+1]!=quote ) break;
z[iOut++] = quote;
@@ -133498,17 +134832,6 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){
}
/*
-** Write an error message into *pzErr
-*/
-SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){
- va_list ap;
- sqlite3_free(*pzErr);
- va_start(ap, zFormat);
- *pzErr = sqlite3_vmprintf(zFormat, ap);
- va_end(ap);
-}
-
-/*
** Construct one or more SQL statements from the format string given
** and then evaluate those statements. The success code is written
** into *pRc.
@@ -133917,16 +135240,11 @@ static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){
** 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 */
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;
@@ -133969,6 +135287,7 @@ static int fts3PrefixParameter(
aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex);
*apIndex = aIndex;
+ *pnIndex = nIndex;
if( !aIndex ){
return SQLITE_NOMEM;
}
@@ -133978,20 +135297,13 @@ static int fts3PrefixParameter(
const char *p = zParam;
int i;
for(i=1; i<nIndex; i++){
- int nPrefix = 0;
+ int nPrefix;
if( fts3GobbleInt(&p, &nPrefix) ) return SQLITE_ERROR;
- assert( nPrefix>=0 );
- if( nPrefix==0 ){
- nIndex--;
- i--;
- }else{
- aIndex[i].nPrefix = nPrefix;
- }
+ aIndex[i].nPrefix = nPrefix;
p++;
}
}
- *pnIndex = nIndex;
return SQLITE_OK;
}
@@ -134026,8 +135338,7 @@ static int fts3ContentColumns(
const char *zTbl, /* Name of content table */
const char ***pazCol, /* OUT: Malloc'd array of column names */
int *pnCol, /* OUT: Size of array *pazCol */
- int *pnStr, /* OUT: Bytes of string content */
- char **pzErr /* OUT: error message */
+ int *pnStr /* OUT: Bytes of string content */
){
int rc = SQLITE_OK; /* Return code */
char *zSql; /* "SELECT *" statement on zTbl */
@@ -134038,9 +135349,6 @@ static int fts3ContentColumns(
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
- if( rc!=SQLITE_OK ){
- sqlite3Fts3ErrMsg(pzErr, "%s", sqlite3_errmsg(db));
- }
}
sqlite3_free(zSql);
@@ -134119,7 +135427,7 @@ static int fts3InitVtab(
const char **aCol; /* Array of column names */
sqlite3_tokenizer *pTokenizer = 0; /* Tokenizer for this table */
- int nIndex = 0; /* Size of aIndex[] array */
+ int nIndex; /* Size of aIndex[] array */
struct Fts3Index *aIndex = 0; /* Array of indexes for this table */
/* The results of parsing supported FTS4 key=value options: */
@@ -134207,13 +135515,13 @@ static int fts3InitVtab(
}
}
if( iOpt==SizeofArray(aFts4Opt) ){
- sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
+ *pzErr = sqlite3_mprintf("unrecognized parameter: %s", z);
rc = SQLITE_ERROR;
}else{
switch( iOpt ){
case 0: /* MATCHINFO */
if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
- sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
+ *pzErr = sqlite3_mprintf("unrecognized matchinfo: %s", zVal);
rc = SQLITE_ERROR;
}
bNoDocsize = 1;
@@ -134241,7 +135549,7 @@ static int fts3InitVtab(
if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
&& (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
){
- sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
+ *pzErr = sqlite3_mprintf("unrecognized order: %s", zVal);
rc = SQLITE_ERROR;
}
bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
@@ -134292,7 +135600,7 @@ static int fts3InitVtab(
if( nCol==0 ){
sqlite3_free((void*)aCol);
aCol = 0;
- rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr);
+ rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
/* If a languageid= option was specified, remove the language id
** column from the aCol[] array. */
@@ -134327,7 +135635,7 @@ static int fts3InitVtab(
rc = fts3PrefixParameter(zPrefix, &nIndex, &aIndex);
if( rc==SQLITE_ERROR ){
assert( zPrefix );
- sqlite3Fts3ErrMsg(pzErr, "error parsing prefix parameter: %s", zPrefix);
+ *pzErr = sqlite3_mprintf("error parsing prefix parameter: %s", zPrefix);
}
if( rc!=SQLITE_OK ) goto fts3_init_out;
@@ -134409,7 +135717,7 @@ static int fts3InitVtab(
}
for(i=0; i<nNotindexed; i++){
if( azNotindexed[i] ){
- sqlite3Fts3ErrMsg(pzErr, "no such column: %s", azNotindexed[i]);
+ *pzErr = sqlite3_mprintf("no such column: %s", azNotindexed[i]);
rc = SQLITE_ERROR;
}
}
@@ -134417,7 +135725,7 @@ static int fts3InitVtab(
if( rc==SQLITE_OK && (zCompress==0)!=(zUncompress==0) ){
char const *zMiss = (zCompress==0 ? "compress" : "uncompress");
rc = SQLITE_ERROR;
- sqlite3Fts3ErrMsg(pzErr, "missing %s parameter in fts4 constructor", zMiss);
+ *pzErr = sqlite3_mprintf("missing %s parameter in fts4 constructor", zMiss);
}
p->zReadExprlist = fts3ReadExprList(p, zUncompress, &rc);
p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc);
@@ -135513,33 +136821,26 @@ static int fts3DoclistOrMerge(
**
** The right-hand input doclist is overwritten by this function.
*/
-static int fts3DoclistPhraseMerge(
+static void fts3DoclistPhraseMerge(
int bDescDoclist, /* True if arguments are desc */
int nDist, /* Distance from left to right (1=adjacent) */
char *aLeft, int nLeft, /* Left doclist */
- char **paRight, int *pnRight /* IN/OUT: Right/output doclist */
+ char *aRight, int *pnRight /* IN/OUT: Right/output doclist */
){
sqlite3_int64 i1 = 0;
sqlite3_int64 i2 = 0;
sqlite3_int64 iPrev = 0;
- char *aRight = *paRight;
char *pEnd1 = &aLeft[nLeft];
char *pEnd2 = &aRight[*pnRight];
char *p1 = aLeft;
char *p2 = aRight;
char *p;
int bFirstOut = 0;
- char *aOut;
+ char *aOut = aRight;
assert( nDist>0 );
- if( bDescDoclist ){
- aOut = sqlite3_malloc(*pnRight + FTS3_VARINT_MAX);
- if( aOut==0 ) return SQLITE_NOMEM;
- }else{
- aOut = aRight;
- }
- p = aOut;
+ p = aOut;
fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1);
fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2);
@@ -135568,12 +136869,6 @@ static int fts3DoclistPhraseMerge(
}
*pnRight = (int)(p - aOut);
- if( bDescDoclist ){
- sqlite3_free(aRight);
- *paRight = aOut;
- }
-
- return SQLITE_OK;
}
/*
@@ -135698,22 +136993,8 @@ static int fts3TermSelectMerge(
){
if( pTS->aaOutput[0]==0 ){
/* If this is the first term selected, copy the doclist to the output
- ** buffer using memcpy().
- **
- ** Add FTS3_VARINT_MAX bytes of unused space to the end of the
- ** allocation. This is so as to ensure that the buffer is big enough
- ** to hold the current doclist AND'd with any other doclist. If the
- ** doclists are stored in order=ASC order, this padding would not be
- ** required (since the size of [doclistA AND doclistB] is always less
- ** than or equal to the size of [doclistA] in that case). But this is
- ** not true for order=DESC. For example, a doclist containing (1, -1)
- ** may be smaller than (-1), as in the first example the -1 may be stored
- ** as a single-byte delta, whereas in the second it must be stored as a
- ** FTS3_VARINT_MAX byte varint.
- **
- ** Similar padding is added in the fts3DoclistOrMerge() function.
- */
- pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1);
+ ** buffer using memcpy(). */
+ pTS->aaOutput[0] = sqlite3_malloc(nDoclist);
pTS->anOutput[0] = nDoclist;
if( pTS->aaOutput[0] ){
memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
@@ -135810,7 +137091,7 @@ static int fts3SegReaderCursor(
** calls out here. */
if( iLevel<0 && p->aIndex ){
Fts3SegReader *pSeg = 0;
- rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg);
+ rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix, &pSeg);
if( rc==SQLITE_OK && pSeg ){
rc = fts3SegReaderCursorAppend(pCsr, pSeg);
}
@@ -136213,17 +137494,10 @@ static int fts3FilterMethod(
** row by docid.
*/
if( eSearch==FTS3_FULLSCAN_SEARCH ){
- if( pDocidGe || pDocidLe ){
- zSql = sqlite3_mprintf(
- "SELECT %s WHERE rowid BETWEEN %lld AND %lld ORDER BY rowid %s",
- p->zReadExprlist, pCsr->iMinDocid, pCsr->iMaxDocid,
- (pCsr->bDesc ? "DESC" : "ASC")
- );
- }else{
- zSql = sqlite3_mprintf("SELECT %s ORDER BY rowid %s",
- p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
- );
- }
+ zSql = sqlite3_mprintf(
+ "SELECT %s ORDER BY rowid %s",
+ p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
+ );
if( zSql ){
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
sqlite3_free(zSql);
@@ -136459,31 +137733,11 @@ static void fts3ReversePoslist(char *pStart, char **ppPoslist){
char *p = &(*ppPoslist)[-2];
char c = 0;
- /* Skip backwards passed any trailing 0x00 bytes added by NearTrim() */
while( p>pStart && (c=*p--)==0 );
-
- /* Search backwards for a varint with value zero (the end of the previous
- ** poslist). This is an 0x00 byte preceded by some byte that does not
- ** have the 0x80 bit set. */
while( p>pStart && (*p & 0x80) | c ){
c = *p--;
}
- assert( p==pStart || c==0 );
-
- /* At this point p points to that preceding byte without the 0x80 bit
- ** set. So to find the start of the poslist, skip forward 2 bytes then
- ** over a varint.
- **
- ** Normally. The other case is that p==pStart and the poslist to return
- ** is the first in the doclist. In this case do not skip forward 2 bytes.
- ** The second part of the if condition (c==0 && *ppPoslist>&p[2])
- ** is required for cases where the first byte of a doclist and the
- ** doclist is empty. For example, if the first docid is 10, a doclist
- ** that begins with:
- **
- ** 0x0A 0x00 <next docid delta varint>
- */
- if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; }
+ if( p>pStart ){ p = &p[2]; }
while( *p++&0x80 );
*ppPoslist = p;
}
@@ -136554,8 +137808,6 @@ static void fts3SnippetFunc(
}
if( !zEllipsis || !zEnd || !zStart ){
sqlite3_result_error_nomem(pContext);
- }else if( nToken==0 ){
- sqlite3_result_text(pContext, "", -1, SQLITE_STATIC);
}else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){
sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken);
}
@@ -136991,17 +138243,14 @@ static void fts3EvalAllocateReaders(
** This function assumes that pList points to a buffer allocated using
** sqlite3_malloc(). This function takes responsibility for eventually
** freeing the buffer.
-**
-** SQLITE_OK is returned if successful, or SQLITE_NOMEM if an error occurs.
*/
-static int fts3EvalPhraseMergeToken(
+static void fts3EvalPhraseMergeToken(
Fts3Table *pTab, /* FTS Table pointer */
Fts3Phrase *p, /* Phrase to merge pList/nList into */
int iToken, /* Token pList/nList corresponds to */
char *pList, /* Pointer to doclist */
int nList /* Number of bytes in pList */
){
- int rc = SQLITE_OK;
assert( iToken!=p->iDoclistToken );
if( pList==0 ){
@@ -137040,16 +138289,13 @@ static int fts3EvalPhraseMergeToken(
nDiff = p->iDoclistToken - iToken;
}
- rc = fts3DoclistPhraseMerge(
- pTab->bDescIdx, nDiff, pLeft, nLeft, &pRight, &nRight
- );
+ fts3DoclistPhraseMerge(pTab->bDescIdx, nDiff, pLeft, nLeft, pRight,&nRight);
sqlite3_free(pLeft);
p->doclist.aAll = pRight;
p->doclist.nAll = nRight;
}
if( iToken>p->iDoclistToken ) p->iDoclistToken = iToken;
- return rc;
}
/*
@@ -137075,7 +138321,7 @@ static int fts3EvalPhraseLoad(
char *pThis = 0;
rc = fts3TermSelect(pTab, pToken, p->iColumn, &nThis, &pThis);
if( rc==SQLITE_OK ){
- rc = fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis);
+ fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis);
}
}
assert( pToken->pSegcsr==0 );
@@ -137617,14 +138863,12 @@ static void fts3EvalStartReaders(
){
if( pExpr && SQLITE_OK==*pRc ){
if( pExpr->eType==FTSQUERY_PHRASE ){
+ int i;
int nToken = pExpr->pPhrase->nToken;
- if( nToken ){
- int i;
- for(i=0; i<nToken; i++){
- if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
- }
- pExpr->bDeferred = (i==nToken);
+ for(i=0; i<nToken; i++){
+ if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
}
+ pExpr->bDeferred = (i==nToken);
*pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase);
}else{
fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc);
@@ -137880,12 +139124,8 @@ static int fts3EvalSelectDeferred(
rc = fts3TermSelect(pTab, pToken, pTC->iCol, &nList, &pList);
assert( rc==SQLITE_OK || pList==0 );
if( rc==SQLITE_OK ){
- rc = fts3EvalPhraseMergeToken(
- pTab, pTC->pPhrase, pTC->iToken,pList,nList
- );
- }
- if( rc==SQLITE_OK ){
int nCount;
+ fts3EvalPhraseMergeToken(pTab, pTC->pPhrase, pTC->iToken,pList,nList);
nCount = fts3DoclistCountDocids(
pTC->pPhrase->doclist.aAll, pTC->pPhrase->doclist.nAll
);
@@ -138746,6 +139986,7 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
if( iDocid!=pCsr->iPrevId || pExpr->bEof ){
int rc = SQLITE_OK;
int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */
+ int iMul; /* +1 if csr dir matches index dir, else -1 */
int bOr = 0;
u8 bEof = 0;
u8 bTreeEof = 0;
@@ -138787,8 +140028,7 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
pIter = pPhrase->pOrPoslist;
iDocid = pPhrase->iOrDocid;
if( pCsr->bDesc==bDescDoclist ){
- bEof = !pPhrase->doclist.nAll ||
- (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
+ bEof = (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
sqlite3Fts3DoclistNext(
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
@@ -138869,7 +140109,7 @@ SQLITE_PRIVATE int sqlite3Fts3Corrupt(){
#ifdef _WIN32
__declspec(dllexport)
#endif
-SQLITE_API int SQLITE_STDCALL sqlite3_fts3_init(
+SQLITE_API int sqlite3_fts3_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -139000,7 +140240,7 @@ static int fts3auxConnectMethod(
return SQLITE_OK;
bad_args:
- sqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor");
+ *pzErr = sqlite3_mprintf("invalid arguments to fts4aux constructor");
return SQLITE_ERROR;
}
@@ -140458,13 +141698,13 @@ SQLITE_PRIVATE int sqlite3Fts3ExprParse(
sqlite3Fts3ExprFree(*ppExpr);
*ppExpr = 0;
if( rc==SQLITE_TOOBIG ){
- sqlite3Fts3ErrMsg(pzErr,
+ *pzErr = sqlite3_mprintf(
"FTS expression tree is too large (maximum depth %d)",
SQLITE_FTS3_MAX_EXPR_DEPTH
);
rc = SQLITE_ERROR;
}else if( rc==SQLITE_ERROR ){
- sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z);
+ *pzErr = sqlite3_mprintf("malformed MATCH expression: [%s]", z);
}
}
@@ -141837,7 +143077,7 @@ static void scalarFunc(
if( argc==2 ){
void *pOld;
int n = sqlite3_value_bytes(argv[1]);
- if( zName==0 || n!=sizeof(pPtr) ){
+ if( n!=sizeof(pPtr) ){
sqlite3_result_error(context, "argument type mismatch", -1);
return;
}
@@ -141848,9 +143088,7 @@ static void scalarFunc(
return;
}
}else{
- if( zName ){
- pPtr = sqlite3Fts3HashFind(pHash, zName, nName);
- }
+ pPtr = sqlite3Fts3HashFind(pHash, zName, nName);
if( !pPtr ){
char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
sqlite3_result_error(context, zErr, -1);
@@ -141931,16 +143169,12 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
zEnd = &zCopy[strlen(zCopy)];
z = (char *)sqlite3Fts3NextToken(zCopy, &n);
- if( z==0 ){
- assert( n==0 );
- z = zCopy;
- }
z[n] = '\0';
sqlite3Fts3Dequote(z);
m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1);
if( !m ){
- sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z);
+ *pzErr = sqlite3_mprintf("unknown tokenizer: %s", z);
rc = SQLITE_ERROR;
}else{
char const **aArg = 0;
@@ -141963,7 +143197,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
rc = m->xCreate(iArg, aArg, ppTok);
assert( rc!=SQLITE_OK || *ppTok );
if( rc!=SQLITE_OK ){
- sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer");
+ *pzErr = sqlite3_mprintf("unknown tokenizer");
}else{
(*ppTok)->pModule = m;
}
@@ -142047,9 +143281,9 @@ static void testFunc(
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
if( !p ){
- char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName);
- sqlite3_result_error(context, zErr2, -1);
- sqlite3_free(zErr2);
+ char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
+ sqlite3_result_error(context, zErr, -1);
+ sqlite3_free(zErr);
return;
}
@@ -142584,7 +143818,7 @@ static int fts3tokQueryTokenizer(
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
if( !p ){
- sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName);
+ *pzErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
return SQLITE_ERROR;
}
@@ -143281,7 +144515,7 @@ static int fts3SqlStmt(
/* 25 */ "",
/* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?",
-/* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'",
+/* 27 */ "SELECT DISTINCT level / (1024 * ?) FROM %Q.'%q_segdir'",
/* This statement is used to determine which level to read the input from
** when performing an incremental merge. It returns the absolute level number
@@ -144580,10 +145814,7 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(
** an array of pending terms by term. This occurs as part of flushing
** the contents of the pending-terms hash table to the database.
*/
-static int SQLITE_CDECL fts3CompareElemByTerm(
- const void *lhs,
- const void *rhs
-){
+static int fts3CompareElemByTerm(const void *lhs, const void *rhs){
char *z1 = fts3HashKey(*(Fts3HashElem **)lhs);
char *z2 = fts3HashKey(*(Fts3HashElem **)rhs);
int n1 = fts3HashKeysize(*(Fts3HashElem **)lhs);
@@ -146399,8 +147630,7 @@ static int fts3DoOptimize(Fts3Table *p, int bReturnDone){
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
if( rc==SQLITE_OK ){
int rc2;
- sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
- sqlite3_bind_int(pAllLangid, 2, p->nIndex);
+ sqlite3_bind_int(pAllLangid, 1, p->nIndex);
while( sqlite3_step(pAllLangid)==SQLITE_ROW ){
int i;
int iLangid = sqlite3_column_int(pAllLangid, 0);
@@ -147732,7 +148962,7 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){
pHint->n = i;
i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel);
i += fts3GetVarint32(&pHint->a[i], pnInput);
- if( i!=nHint ) return FTS_CORRUPT_VTAB;
+ if( i!=nHint ) return SQLITE_CORRUPT_VTAB;
return SQLITE_OK;
}
@@ -148100,8 +149330,7 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
if( rc==SQLITE_OK ){
int rc2;
- sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
- sqlite3_bind_int(pAllLangid, 2, p->nIndex);
+ sqlite3_bind_int(pAllLangid, 1, p->nIndex);
while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){
int iLangid = sqlite3_column_int(pAllLangid, 0);
int i;
@@ -148114,6 +149343,7 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
}
/* This block calculates the checksum according to the %_content table */
+ rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
if( rc==SQLITE_OK ){
sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule;
sqlite3_stmt *pStmt = 0;
@@ -148210,7 +149440,7 @@ static int fts3DoIntegrityCheck(
int rc;
int bOk = 0;
rc = fts3IntegrityCheck(p, &bOk);
- if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB;
+ if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_CORRUPT_VTAB;
return rc;
}
@@ -148648,7 +149878,6 @@ SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){
#define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */
#define FTS3_MATCHINFO_LCS 's' /* nCol values */
#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */
-#define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */
/*
** The default value for the second argument to matchinfo().
@@ -149304,12 +150533,8 @@ static int fts3SnippetText(
** required. They are required if (a) this is not the first fragment,
** or (b) this fragment does not begin at position 0 of its column.
*/
- if( rc==SQLITE_OK ){
- if( iPos>0 || iFragment>0 ){
- rc = fts3StringAppend(pOut, zEllipsis, -1);
- }else if( iBegin ){
- rc = fts3StringAppend(pOut, zDoc, iBegin);
- }
+ if( rc==SQLITE_OK && (iPos>0 || iFragment>0) ){
+ rc = fts3StringAppend(pOut, zEllipsis, -1);
}
if( rc!=SQLITE_OK || iCurrent<iPos ) continue;
}
@@ -149431,51 +150656,6 @@ static int fts3ExprLocalHitsCb(
return rc;
}
-/*
-** fts3ExprIterate() callback used to gather information for the matchinfo
-** directive 'y'.
-*/
-static int fts3ExprLHitsCb(
- Fts3Expr *pExpr, /* Phrase expression node */
- int iPhrase, /* Phrase number */
- void *pCtx /* Pointer to MatchInfo structure */
-){
- MatchInfo *p = (MatchInfo *)pCtx;
- Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
- int rc = SQLITE_OK;
- int iStart = iPhrase * p->nCol;
- Fts3Expr *pEof; /* Ancestor node already at EOF */
-
- /* This must be a phrase */
- assert( pExpr->pPhrase );
-
- /* Initialize all output integers to zero. */
- memset(&p->aMatchinfo[iStart], 0, sizeof(u32) * p->nCol);
-
- /* Check if this or any parent node is at EOF. If so, then all output
- ** values are zero. */
- for(pEof=pExpr; pEof && pEof->bEof==0; pEof=pEof->pParent);
-
- if( pEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
- Fts3Phrase *pPhrase = pExpr->pPhrase;
- char *pIter = pPhrase->doclist.pList;
- int iCol = 0;
-
- while( 1 ){
- int nHit = fts3ColumnlistCount(&pIter);
- if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
- p->aMatchinfo[iStart + iCol] = (u32)nHit;
- }
- assert( *pIter==0x00 || *pIter==0x01 );
- if( *pIter!=0x01 ) break;
- pIter++;
- pIter += fts3GetVarint32(pIter, &iCol);
- }
- }
-
- return rc;
-}
-
static int fts3MatchinfoCheck(
Fts3Table *pTab,
char cArg,
@@ -149488,11 +150668,10 @@ static int fts3MatchinfoCheck(
|| (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize)
|| (cArg==FTS3_MATCHINFO_LCS)
|| (cArg==FTS3_MATCHINFO_HITS)
- || (cArg==FTS3_MATCHINFO_LHITS)
){
return SQLITE_OK;
}
- sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg);
+ *pzErr = sqlite3_mprintf("unrecognized matchinfo request: %c", cArg);
return SQLITE_ERROR;
}
@@ -149512,10 +150691,6 @@ static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
nVal = pInfo->nCol;
break;
- case FTS3_MATCHINFO_LHITS:
- nVal = pInfo->nCol * pInfo->nPhrase;
- break;
-
default:
assert( cArg==FTS3_MATCHINFO_HITS );
nVal = pInfo->nCol * pInfo->nPhrase * 3;
@@ -149770,10 +150945,6 @@ static int fts3MatchinfoValues(
}
break;
- case FTS3_MATCHINFO_LHITS:
- (void)fts3ExprIterate(pCsr->pExpr, fts3ExprLHitsCb, (void*)pInfo);
- break;
-
default: {
Fts3Expr *pExpr;
assert( zArg[i]==FTS3_MATCHINFO_HITS );
@@ -149929,7 +151100,7 @@ SQLITE_PRIVATE void sqlite3Fts3Snippet(
*/
for(iRead=0; iRead<pTab->nColumn; iRead++){
SnippetFragment sF = {0, 0, 0, 0};
- int iS = 0;
+ int iS;
if( iCol>=0 && iRead!=iCol ) continue;
/* Find the best snippet of nFToken tokens in column iRead. */
@@ -153786,19 +154957,11 @@ static int rtreeUpdate(
if( nData>1 ){
int ii;
- /* Populate the cell.aCoord[] array. The first coordinate is azData[3].
- **
- ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared
- ** with "column" that are interpreted as table constraints.
- ** Example: CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5));
- ** This problem was discovered after years of use, so we silently ignore
- ** these kinds of misdeclared tables to avoid breaking any legacy.
- */
- assert( nData<=(pRtree->nDim*2 + 3) );
-
+ /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
+ assert( nData==(pRtree->nDim*2 + 3) );
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
- for(ii=0; ii<nData-4; ii+=2){
+ for(ii=0; ii<(pRtree->nDim*2); ii+=2){
cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
@@ -153809,7 +154972,7 @@ static int rtreeUpdate(
}else
#endif
{
- for(ii=0; ii<nData-4; ii+=2){
+ for(ii=0; ii<(pRtree->nDim*2); ii+=2){
cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
@@ -154380,7 +155543,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
/*
** Register a new geometry function for use with the r-tree MATCH operator.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
+SQLITE_API int sqlite3_rtree_geometry_callback(
sqlite3 *db, /* Register SQL function on this connection */
const char *zGeom, /* Name of the new SQL function */
int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */
@@ -154404,7 +155567,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
** Register a new 2nd-generation geometry function for use with the
** r-tree MATCH operator.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
+SQLITE_API int sqlite3_rtree_query_callback(
sqlite3 *db, /* Register SQL function on this connection */
const char *zQueryFunc, /* Name of new SQL function */
int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */
@@ -154429,7 +155592,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
#ifdef _WIN32
__declspec(dllexport)
#endif
-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_init(
+SQLITE_API int sqlite3_rtree_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -154934,7 +156097,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
#ifdef _WIN32
__declspec(dllexport)
#endif
-SQLITE_API int SQLITE_STDCALL sqlite3_icu_init(
+SQLITE_API int sqlite3_icu_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -155209,631 +156372,3 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
/************** End of fts3_icu.c ********************************************/
-/************** Begin file dbstat.c ******************************************/
-/*
-** 2010 July 12
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains an implementation of the "dbstat" virtual table.
-**
-** The dbstat virtual table is used to extract low-level formatting
-** information from an SQLite database in order to implement the
-** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script
-** for an example implementation.
-*/
-
-#if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \
- && !defined(SQLITE_OMIT_VIRTUALTABLE)
-
-/*
-** Page paths:
-**
-** The value of the 'path' column describes the path taken from the
-** root-node of the b-tree structure to each page. The value of the
-** root-node path is '/'.
-**
-** The value of the path for the left-most child page of the root of
-** a b-tree is '/000/'. (Btrees store content ordered from left to right
-** so the pages to the left have smaller keys than the pages to the right.)
-** The next to left-most child of the root page is
-** '/001', and so on, each sibling page identified by a 3-digit hex
-** value. The children of the 451st left-most sibling have paths such
-** as '/1c2/000/, '/1c2/001/' etc.
-**
-** Overflow pages are specified by appending a '+' character and a
-** six-digit hexadecimal value to the path to the cell they are linked
-** from. For example, the three overflow pages in a chain linked from
-** the left-most cell of the 450th child of the root page are identified
-** by the paths:
-**
-** '/1c2/000+000000' // First page in overflow chain
-** '/1c2/000+000001' // Second page in overflow chain
-** '/1c2/000+000002' // Third page in overflow chain
-**
-** If the paths are sorted using the BINARY collation sequence, then
-** the overflow pages associated with a cell will appear earlier in the
-** sort-order than its child page:
-**
-** '/1c2/000/' // Left-most child of 451st child of root
-*/
-#define VTAB_SCHEMA \
- "CREATE TABLE xx( " \
- " name STRING, /* Name of table or index */" \
- " path INTEGER, /* Path to page from root */" \
- " pageno INTEGER, /* Page number */" \
- " pagetype STRING, /* 'internal', 'leaf' or 'overflow' */" \
- " ncell INTEGER, /* Cells on page (0 for overflow) */" \
- " payload INTEGER, /* Bytes of payload on this page */" \
- " unused INTEGER, /* Bytes of unused space on this page */" \
- " mx_payload INTEGER, /* Largest payload size of all cells */" \
- " pgoffset INTEGER, /* Offset of page in file */" \
- " pgsize INTEGER /* Size of the page */" \
- ");"
-
-
-typedef struct StatTable StatTable;
-typedef struct StatCursor StatCursor;
-typedef struct StatPage StatPage;
-typedef struct StatCell StatCell;
-
-struct StatCell {
- int nLocal; /* Bytes of local payload */
- u32 iChildPg; /* Child node (or 0 if this is a leaf) */
- int nOvfl; /* Entries in aOvfl[] */
- u32 *aOvfl; /* Array of overflow page numbers */
- int nLastOvfl; /* Bytes of payload on final overflow page */
- int iOvfl; /* Iterates through aOvfl[] */
-};
-
-struct StatPage {
- u32 iPgno;
- DbPage *pPg;
- int iCell;
-
- char *zPath; /* Path to this page */
-
- /* Variables populated by statDecodePage(): */
- u8 flags; /* Copy of flags byte */
- int nCell; /* Number of cells on page */
- int nUnused; /* Number of unused bytes on page */
- StatCell *aCell; /* Array of parsed cells */
- u32 iRightChildPg; /* Right-child page number (or 0) */
- int nMxPayload; /* Largest payload of any cell on this page */
-};
-
-struct StatCursor {
- sqlite3_vtab_cursor base;
- sqlite3_stmt *pStmt; /* Iterates through set of root pages */
- int isEof; /* After pStmt has returned SQLITE_DONE */
-
- StatPage aPage[32];
- int iPage; /* Current entry in aPage[] */
-
- /* Values to return. */
- char *zName; /* Value of 'name' column */
- char *zPath; /* Value of 'path' column */
- u32 iPageno; /* Value of 'pageno' column */
- char *zPagetype; /* Value of 'pagetype' column */
- int nCell; /* Value of 'ncell' column */
- int nPayload; /* Value of 'payload' column */
- int nUnused; /* Value of 'unused' column */
- int nMxPayload; /* Value of 'mx_payload' column */
- i64 iOffset; /* Value of 'pgOffset' column */
- int szPage; /* Value of 'pgSize' column */
-};
-
-struct StatTable {
- sqlite3_vtab base;
- sqlite3 *db;
-};
-
-#ifndef get2byte
-# define get2byte(x) ((x)[0]<<8 | (x)[1])
-#endif
-
-/*
-** Connect to or create a statvfs virtual table.
-*/
-static int statConnect(
- sqlite3 *db,
- void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVtab,
- char **pzErr
-){
- StatTable *pTab = 0;
- int rc = SQLITE_OK;
-
- rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
- if( rc==SQLITE_OK ){
- pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
- if( pTab==0 ) rc = SQLITE_NOMEM;
- }
-
- assert( rc==SQLITE_OK || pTab==0 );
- if( rc==SQLITE_OK ){
- memset(pTab, 0, sizeof(StatTable));
- pTab->db = db;
- }
-
- *ppVtab = (sqlite3_vtab*)pTab;
- return rc;
-}
-
-/*
-** Disconnect from or destroy a statvfs virtual table.
-*/
-static int statDisconnect(sqlite3_vtab *pVtab){
- sqlite3_free(pVtab);
- return SQLITE_OK;
-}
-
-/*
-** There is no "best-index". This virtual table always does a linear
-** scan of the binary VFS log file.
-*/
-static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
-
- /* Records are always returned in ascending order of (name, path).
- ** If this will satisfy the client, set the orderByConsumed flag so that
- ** SQLite does not do an external sort.
- */
- if( ( pIdxInfo->nOrderBy==1
- && pIdxInfo->aOrderBy[0].iColumn==0
- && pIdxInfo->aOrderBy[0].desc==0
- ) ||
- ( pIdxInfo->nOrderBy==2
- && pIdxInfo->aOrderBy[0].iColumn==0
- && pIdxInfo->aOrderBy[0].desc==0
- && pIdxInfo->aOrderBy[1].iColumn==1
- && pIdxInfo->aOrderBy[1].desc==0
- )
- ){
- pIdxInfo->orderByConsumed = 1;
- }
-
- pIdxInfo->estimatedCost = 10.0;
- return SQLITE_OK;
-}
-
-/*
-** Open a new statvfs cursor.
-*/
-static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
- StatTable *pTab = (StatTable *)pVTab;
- StatCursor *pCsr;
- int rc;
-
- pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor));
- if( pCsr==0 ){
- rc = SQLITE_NOMEM;
- }else{
- memset(pCsr, 0, sizeof(StatCursor));
- pCsr->base.pVtab = pVTab;
-
- rc = sqlite3_prepare_v2(pTab->db,
- "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
- " UNION ALL "
- "SELECT name, rootpage, type FROM sqlite_master WHERE rootpage!=0"
- " ORDER BY name", -1,
- &pCsr->pStmt, 0
- );
- if( rc!=SQLITE_OK ){
- sqlite3_free(pCsr);
- pCsr = 0;
- }
- }
-
- *ppCursor = (sqlite3_vtab_cursor *)pCsr;
- return rc;
-}
-
-static void statClearPage(StatPage *p){
- int i;
- if( p->aCell ){
- for(i=0; i<p->nCell; i++){
- sqlite3_free(p->aCell[i].aOvfl);
- }
- sqlite3_free(p->aCell);
- }
- sqlite3PagerUnref(p->pPg);
- sqlite3_free(p->zPath);
- memset(p, 0, sizeof(StatPage));
-}
-
-static void statResetCsr(StatCursor *pCsr){
- int i;
- sqlite3_reset(pCsr->pStmt);
- for(i=0; i<ArraySize(pCsr->aPage); i++){
- statClearPage(&pCsr->aPage[i]);
- }
- pCsr->iPage = 0;
- sqlite3_free(pCsr->zPath);
- pCsr->zPath = 0;
-}
-
-/*
-** Close a statvfs cursor.
-*/
-static int statClose(sqlite3_vtab_cursor *pCursor){
- StatCursor *pCsr = (StatCursor *)pCursor;
- statResetCsr(pCsr);
- sqlite3_finalize(pCsr->pStmt);
- sqlite3_free(pCsr);
- return SQLITE_OK;
-}
-
-static void getLocalPayload(
- int nUsable, /* Usable bytes per page */
- u8 flags, /* Page flags */
- int nTotal, /* Total record (payload) size */
- int *pnLocal /* OUT: Bytes stored locally */
-){
- int nLocal;
- int nMinLocal;
- int nMaxLocal;
-
- if( flags==0x0D ){ /* Table leaf node */
- nMinLocal = (nUsable - 12) * 32 / 255 - 23;
- nMaxLocal = nUsable - 35;
- }else{ /* Index interior and leaf nodes */
- nMinLocal = (nUsable - 12) * 32 / 255 - 23;
- nMaxLocal = (nUsable - 12) * 64 / 255 - 23;
- }
-
- nLocal = nMinLocal + (nTotal - nMinLocal) % (nUsable - 4);
- if( nLocal>nMaxLocal ) nLocal = nMinLocal;
- *pnLocal = nLocal;
-}
-
-static int statDecodePage(Btree *pBt, StatPage *p){
- int nUnused;
- int iOff;
- int nHdr;
- int isLeaf;
- int szPage;
-
- u8 *aData = sqlite3PagerGetData(p->pPg);
- u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
-
- p->flags = aHdr[0];
- p->nCell = get2byte(&aHdr[3]);
- p->nMxPayload = 0;
-
- isLeaf = (p->flags==0x0A || p->flags==0x0D);
- nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;
-
- nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
- nUnused += (int)aHdr[7];
- iOff = get2byte(&aHdr[1]);
- while( iOff ){
- nUnused += get2byte(&aData[iOff+2]);
- iOff = get2byte(&aData[iOff]);
- }
- p->nUnused = nUnused;
- p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
- szPage = sqlite3BtreeGetPageSize(pBt);
-
- if( p->nCell ){
- int i; /* Used to iterate through cells */
- int nUsable; /* Usable bytes per page */
-
- sqlite3BtreeEnter(pBt);
- nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
- sqlite3BtreeLeave(pBt);
- p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell));
- if( p->aCell==0 ) return SQLITE_NOMEM;
- memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
-
- for(i=0; i<p->nCell; i++){
- StatCell *pCell = &p->aCell[i];
-
- iOff = get2byte(&aData[nHdr+i*2]);
- if( !isLeaf ){
- pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
- iOff += 4;
- }
- if( p->flags==0x05 ){
- /* A table interior node. nPayload==0. */
- }else{
- u32 nPayload; /* Bytes of payload total (local+overflow) */
- int nLocal; /* Bytes of payload stored locally */
- iOff += getVarint32(&aData[iOff], nPayload);
- if( p->flags==0x0D ){
- u64 dummy;
- iOff += sqlite3GetVarint(&aData[iOff], &dummy);
- }
- if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
- getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
- pCell->nLocal = nLocal;
- assert( nLocal>=0 );
- assert( nPayload>=(u32)nLocal );
- assert( nLocal<=(nUsable-35) );
- if( nPayload>(u32)nLocal ){
- int j;
- int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
- 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;
- pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
- for(j=1; j<nOvfl; j++){
- int rc;
- u32 iPrev = pCell->aOvfl[j-1];
- DbPage *pPg = 0;
- rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg);
- if( rc!=SQLITE_OK ){
- assert( pPg==0 );
- return rc;
- }
- pCell->aOvfl[j] = sqlite3Get4byte(sqlite3PagerGetData(pPg));
- sqlite3PagerUnref(pPg);
- }
- }
- }
- }
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Populate the pCsr->iOffset and pCsr->szPage member variables. Based on
-** the current value of pCsr->iPageno.
-*/
-static void statSizeAndOffset(StatCursor *pCsr){
- StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab;
- Btree *pBt = pTab->db->aDb[0].pBt;
- Pager *pPager = sqlite3BtreePager(pBt);
- sqlite3_file *fd;
- sqlite3_int64 x[2];
-
- /* The default page size and offset */
- pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
- pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1);
-
- /* If connected to a ZIPVFS backend, override the page size and
- ** offset with actual values obtained from ZIPVFS.
- */
- fd = sqlite3PagerFile(pPager);
- x[0] = pCsr->iPageno;
- if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
- pCsr->iOffset = x[0];
- pCsr->szPage = (int)x[1];
- }
-}
-
-/*
-** Move a statvfs cursor to the next entry in the file.
-*/
-static int statNext(sqlite3_vtab_cursor *pCursor){
- int rc;
- int nPayload;
- StatCursor *pCsr = (StatCursor *)pCursor;
- StatTable *pTab = (StatTable *)pCursor->pVtab;
- Btree *pBt = pTab->db->aDb[0].pBt;
- Pager *pPager = sqlite3BtreePager(pBt);
-
- sqlite3_free(pCsr->zPath);
- pCsr->zPath = 0;
-
-statNextRestart:
- if( pCsr->aPage[0].pPg==0 ){
- rc = sqlite3_step(pCsr->pStmt);
- if( rc==SQLITE_ROW ){
- int nPage;
- u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1);
- sqlite3PagerPagecount(pPager, &nPage);
- if( nPage==0 ){
- pCsr->isEof = 1;
- return sqlite3_reset(pCsr->pStmt);
- }
- rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
- pCsr->aPage[0].iPgno = iRoot;
- pCsr->aPage[0].iCell = 0;
- pCsr->aPage[0].zPath = sqlite3_mprintf("/");
- pCsr->iPage = 0;
- }else{
- pCsr->isEof = 1;
- return sqlite3_reset(pCsr->pStmt);
- }
- }else{
-
- /* Page p itself has already been visited. */
- StatPage *p = &pCsr->aPage[pCsr->iPage];
-
- while( p->iCell<p->nCell ){
- StatCell *pCell = &p->aCell[p->iCell];
- if( pCell->iOvfl<pCell->nOvfl ){
- int nUsable;
- sqlite3BtreeEnter(pBt);
- nUsable = sqlite3BtreeGetPageSize(pBt) -
- sqlite3BtreeGetReserveNoMutex(pBt);
- sqlite3BtreeLeave(pBt);
- pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
- pCsr->iPageno = pCell->aOvfl[pCell->iOvfl];
- pCsr->zPagetype = "overflow";
- pCsr->nCell = 0;
- pCsr->nMxPayload = 0;
- pCsr->zPath = sqlite3_mprintf(
- "%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl
- );
- if( pCell->iOvfl<pCell->nOvfl-1 ){
- pCsr->nUnused = 0;
- pCsr->nPayload = nUsable - 4;
- }else{
- pCsr->nPayload = pCell->nLastOvfl;
- pCsr->nUnused = nUsable - 4 - pCsr->nPayload;
- }
- pCell->iOvfl++;
- statSizeAndOffset(pCsr);
- return SQLITE_OK;
- }
- if( p->iRightChildPg ) break;
- p->iCell++;
- }
-
- if( !p->iRightChildPg || p->iCell>p->nCell ){
- statClearPage(p);
- if( pCsr->iPage==0 ) return statNext(pCursor);
- pCsr->iPage--;
- goto statNextRestart; /* Tail recursion */
- }
- pCsr->iPage++;
- assert( p==&pCsr->aPage[pCsr->iPage-1] );
-
- if( p->iCell==p->nCell ){
- p[1].iPgno = p->iRightChildPg;
- }else{
- p[1].iPgno = p->aCell[p->iCell].iChildPg;
- }
- rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg);
- p[1].iCell = 0;
- p[1].zPath = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
- p->iCell++;
- }
-
-
- /* Populate the StatCursor fields with the values to be returned
- ** by the xColumn() and xRowid() methods.
- */
- if( rc==SQLITE_OK ){
- int i;
- StatPage *p = &pCsr->aPage[pCsr->iPage];
- pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
- pCsr->iPageno = p->iPgno;
-
- rc = statDecodePage(pBt, p);
- if( rc==SQLITE_OK ){
- statSizeAndOffset(pCsr);
-
- switch( p->flags ){
- case 0x05: /* table internal */
- case 0x02: /* index internal */
- pCsr->zPagetype = "internal";
- break;
- case 0x0D: /* table leaf */
- case 0x0A: /* index leaf */
- pCsr->zPagetype = "leaf";
- break;
- default:
- pCsr->zPagetype = "corrupted";
- break;
- }
- pCsr->nCell = p->nCell;
- pCsr->nUnused = p->nUnused;
- pCsr->nMxPayload = p->nMxPayload;
- pCsr->zPath = sqlite3_mprintf("%s", p->zPath);
- nPayload = 0;
- for(i=0; i<p->nCell; i++){
- nPayload += p->aCell[i].nLocal;
- }
- pCsr->nPayload = nPayload;
- }
- }
-
- return rc;
-}
-
-static int statEof(sqlite3_vtab_cursor *pCursor){
- StatCursor *pCsr = (StatCursor *)pCursor;
- return pCsr->isEof;
-}
-
-static int statFilter(
- sqlite3_vtab_cursor *pCursor,
- int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv
-){
- StatCursor *pCsr = (StatCursor *)pCursor;
-
- statResetCsr(pCsr);
- return statNext(pCursor);
-}
-
-static int statColumn(
- sqlite3_vtab_cursor *pCursor,
- sqlite3_context *ctx,
- int i
-){
- StatCursor *pCsr = (StatCursor *)pCursor;
- switch( i ){
- case 0: /* name */
- sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_STATIC);
- break;
- case 1: /* path */
- sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT);
- break;
- case 2: /* pageno */
- sqlite3_result_int64(ctx, pCsr->iPageno);
- break;
- case 3: /* pagetype */
- sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC);
- break;
- case 4: /* ncell */
- sqlite3_result_int(ctx, pCsr->nCell);
- break;
- case 5: /* payload */
- sqlite3_result_int(ctx, pCsr->nPayload);
- break;
- case 6: /* unused */
- sqlite3_result_int(ctx, pCsr->nUnused);
- break;
- case 7: /* mx_payload */
- sqlite3_result_int(ctx, pCsr->nMxPayload);
- break;
- case 8: /* pgoffset */
- sqlite3_result_int64(ctx, pCsr->iOffset);
- break;
- case 9: /* pgsize */
- sqlite3_result_int(ctx, pCsr->szPage);
- break;
- }
- return SQLITE_OK;
-}
-
-static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
- StatCursor *pCsr = (StatCursor *)pCursor;
- *pRowid = pCsr->iPageno;
- return SQLITE_OK;
-}
-
-/*
-** Invoke this routine to register the "dbstat" virtual table module
-*/
-SQLITE_API int SQLITE_STDCALL sqlite3_dbstat_register(sqlite3 *db){
- static sqlite3_module dbstat_module = {
- 0, /* iVersion */
- statConnect, /* xCreate */
- statConnect, /* xConnect */
- statBestIndex, /* xBestIndex */
- statDisconnect, /* xDisconnect */
- statDisconnect, /* xDestroy */
- statOpen, /* xOpen - open a cursor */
- statClose, /* xClose - close a cursor */
- statFilter, /* xFilter - configure scan constraints */
- statNext, /* xNext - advance a cursor */
- statEof, /* xEof - check for end of scan */
- statColumn, /* xColumn - read data */
- statRowid, /* xRowid - read data */
- 0, /* xUpdate */
- 0, /* xBegin */
- 0, /* xSync */
- 0, /* xCommit */
- 0, /* xRollback */
- 0, /* xFindMethod */
- 0, /* xRename */
- };
- return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
-}
-#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
-
-/************** End of dbstat.c **********************************************/