Index: src/sqlite3.c
==================================================================
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.8.9. By combining all the individual C code files into this
+** version 3.8.10. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
** of 5% or more are commonly seen when SQLite is compiled as a single
** translation unit.
@@ -68,10 +68,11 @@
#if defined(_MSC_VER)
#pragma warning(disable : 4054)
#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)
#pragma warning(disable : 4210)
#pragma warning(disable : 4232)
@@ -315,13 +316,13 @@
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.8.9"
-#define SQLITE_VERSION_NUMBER 3008009
-#define SQLITE_SOURCE_ID "2015-04-06 11:04:51 3ad829e50faca538db3abb2afb898b5521550c5c"
+#define SQLITE_VERSION "3.8.10"
+#define SQLITE_VERSION_NUMBER 3008010
+#define SQLITE_SOURCE_ID "2015-05-05 18:52:54 04afa3febee32854fbb09ef8d4ffffd432119716"
/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
@@ -474,10 +475,11 @@
# define double sqlite3_int64
#endif
/*
** CAPI3REF: Closing A Database Connection
+** DESTRUCTOR: sqlite3
**
** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
** for the [sqlite3] object.
** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
** the [sqlite3] object is successfully destroyed and all associated
@@ -525,10 +527,11 @@
*/
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()],
** that allows an application to run multiple statements of SQL
** without having to use a lot of C code.
@@ -1582,10 +1585,11 @@
*/
SQLITE_API int SQLITE_CDECL 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
** [sqlite3_config()] except that the changes apply to a single
** [database connection] (specified in the first argument).
@@ -2079,19 +2083,21 @@
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
/*
** 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);
/*
** CAPI3REF: Last Insert Rowid
+** METHOD: sqlite3
**
** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
** has a unique 64-bit signed
** integer key called the [ROWID | "rowid"]. ^The rowid is always available
** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
@@ -2139,10 +2145,11 @@
*/
SQLITE_API sqlite3_int64 SQLITE_STDCALL 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
** statement on the database connection specified by the only parameter.
** ^Executing any other type of SQL statement does not modify the value
@@ -2191,10 +2198,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** since the database connection was opened, including those executed as
** part of trigger programs. ^Executing any other type of SQL statement
@@ -2214,10 +2222,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** called in response to a user action such as pressing "Cancel"
** or Ctrl-C where the user wants a long query operation to halt
@@ -2290,10 +2299,11 @@
SQLITE_API int SQLITE_STDCALL 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
** an attempt is made to access a database table associated with
** [database connection] D when another thread
@@ -2349,10 +2359,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** will sleep multiple times until at least "ms" milliseconds of sleeping
** have accumulated. ^After at least "ms" milliseconds of sleeping,
@@ -2371,10 +2382,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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.
**
** Definition: A result table is memory data structure created by the
@@ -2706,10 +2718,11 @@
*/
SQLITE_API void SQLITE_STDCALL 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.
** ^The authorizer callback is invoked as SQL statements are being compiled
** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
@@ -2862,10 +2875,11 @@
#define SQLITE_COPY 0 /* No longer used */
#define SQLITE_RECURSIVE 33 /* NULL NULL */
/*
** 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.
**
** ^The callback function registered by sqlite3_trace() is invoked at
@@ -2894,10 +2908,11 @@
SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL 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
** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
** database connection D. An example use for this
@@ -2927,10 +2942,11 @@
*/
SQLITE_API void SQLITE_STDCALL 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
** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte
** order for sqlite3_open16(). ^(A [database connection] handle is usually
@@ -3212,10 +3228,11 @@
SQLITE_API sqlite3_int64 SQLITE_STDCALL 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.
@@ -3257,37 +3274,38 @@
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);
/*
-** CAPI3REF: SQL Statement Object
+** CAPI3REF: Prepared Statement Object
** KEYWORDS: {prepared statement} {prepared statements}
**
-** 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".
+** An instance of this object represents a single SQL statement that
+** has been compiled into binary form and is ready to be evaluated.
**
-** The life of a statement object goes something like this:
+** 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:
**
**
-** - Create the object using [sqlite3_prepare_v2()] or a related
-** function.
-**
- Bind values to [host parameters] using the sqlite3_bind_*()
+**
- Create the prepared statement object using [sqlite3_prepare_v2()].
+**
- Bind values to [parameters] using the sqlite3_bind_*()
** interfaces.
**
- Run the SQL by calling [sqlite3_step()] one or more times.
-**
- Reset the statement using [sqlite3_reset()] then go back
+**
- Reset the prepared statement using [sqlite3_reset()] then go back
** to step 2. Do this zero or more times.
**
- Destroy the object using [sqlite3_finalize()].
**
-**
-** 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
** [database connection] whose limit is to be set or queried. The
** second parameter is one of the [limit categories] that define a
@@ -3395,10 +3413,12 @@
#define SQLITE_LIMIT_WORKER_THREADS 11
/*
** 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.
**
** The first argument, "db", is a [database connection] obtained from a
@@ -3502,19 +3522,21 @@
const void **pzTail /* OUT: Pointer to unused portion of zSql */
);
/*
** 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);
/*
** 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
** the content of the database file.
**
@@ -3542,10 +3564,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** [sqlite3_step(S)] but has not run to completion and/or has not
** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S)
@@ -3616,10 +3639,11 @@
/*
** 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
** templates:
**
@@ -3734,10 +3758,11 @@
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);
/*
** 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
** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
** placeholders for values that are [sqlite3_bind_blob | bound]
@@ -3754,10 +3779,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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.
** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA"
** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA"
@@ -3781,10 +3807,11 @@
*/
SQLITE_API const char *SQLITE_STDCALL 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
** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero
** is returned if no matching parameter is found. ^The parameter
@@ -3797,19 +3824,21 @@
*/
SQLITE_API int SQLITE_STDCALL 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*);
/*
** 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
** statement that does not return data (for example an [UPDATE]).
**
@@ -3817,10 +3846,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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()
** interface returns a pointer to a zero-terminated UTF-8 string
** and sqlite3_column_name16() returns a pointer to a zero-terminated
@@ -3846,10 +3876,11 @@
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);
/*
** 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
** [SELECT] statement.
** ^The name of the database or table or column can be returned as
@@ -3898,10 +3929,11 @@
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);
/*
** 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
** returned result set of that [SELECT] is a table column (not an
** expression or subquery) then the declared type of the table
@@ -3930,10 +3962,11 @@
SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int);
SQLITE_API const void *SQLITE_STDCALL 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
** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
** must be called one or more times to evaluate the statement.
@@ -4009,10 +4042,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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.
** ^If prepared statement P does not have results ready to return
** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
@@ -4062,10 +4096,11 @@
#define SQLITE3_TEXT 3
/*
** CAPI3REF: Result Values From A Query
** KEYWORDS: {column access functions}
+** METHOD: sqlite3_stmt
**
** These routines form the "result set" interface.
**
** ^These routines return information about a single column of the current
** result row of a query. ^In every case the first argument is a pointer
@@ -4234,10 +4269,11 @@
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);
/*
** 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
** or if the statement is never been evaluated, then sqlite3_finalize() returns
** SQLITE_OK. ^If the most recent evaluation of statement S failed, then
@@ -4261,10 +4297,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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.
** ^Any SQL statement variables that had values bound to them using
** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values.
@@ -4290,10 +4327,11 @@
/*
** 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
** of existing SQL functions or aggregates. The only differences between
** these routines are the text encoding expected for
@@ -4459,10 +4497,11 @@
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
** the function or aggregate.
**
@@ -4517,10 +4556,11 @@
SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
SQLITE_API int SQLITE_STDCALL 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.
**
** ^The first time the sqlite3_aggregate_context(C,N) routine is called
@@ -4561,10 +4601,11 @@
*/
SQLITE_API void *SQLITE_STDCALL 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)
** of the [sqlite3_create_function()]
** and [sqlite3_create_function16()] routines that originally
@@ -4575,10 +4616,11 @@
*/
SQLITE_API void *SQLITE_STDCALL 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)
** of the [sqlite3_create_function()]
** and [sqlite3_create_function16()] routines that originally
@@ -4586,10 +4628,11 @@
*/
SQLITE_API sqlite3 *SQLITE_STDCALL 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
** multiple invocations of the same SQL function during query execution, under
** some circumstances the associated metadata may be preserved. An example
@@ -4658,10 +4701,11 @@
#define SQLITE_STATIC ((sqlite3_destructor_type)0)
#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1)
/*
** 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
** [sqlite3_create_function()] and [sqlite3_create_function16()]
** for additional information.
@@ -4793,10 +4837,11 @@
SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*);
SQLITE_API void SQLITE_STDCALL 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.
**
** ^The name of the collation is a UTF-8 string
@@ -4895,10 +4940,11 @@
int(*xCompare)(void*,int,const void*,int,const void*)
);
/*
** 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
** [database connection] to be invoked whenever an undefined collation
** sequence is required.
@@ -5102,10 +5148,11 @@
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,
** respectively. ^Autocommit mode is on by default.
** ^Autocommit mode is disabled by a [BEGIN] statement.
@@ -5124,10 +5171,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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]
** returned by sqlite3_db_handle is the same [database connection]
** that was the first argument
@@ -5136,10 +5184,11 @@
*/
SQLITE_API sqlite3 *SQLITE_STDCALL 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
** has the name "main". If there is no attached database N on the database
** connection D, or if database N is a temporary or in-memory database, then
@@ -5152,19 +5201,21 @@
*/
SQLITE_API const char *SQLITE_STDCALL 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);
/*
** 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
** then this interface returns a pointer to the first prepared statement
** associated with the database connection pDb. ^If no prepared statement
@@ -5176,10 +5227,11 @@
*/
SQLITE_API sqlite3_stmt *SQLITE_STDCALL 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].
** ^Any callback set by a previous call to sqlite3_commit_hook()
** for the same database connection is overridden.
@@ -5225,10 +5277,11 @@
SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
SQLITE_API void *SQLITE_STDCALL 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
** to be invoked whenever a row is updated, inserted or deleted in
** a rowid table.
@@ -5331,10 +5384,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** [sqlite3_release_memory()] interface, this interface is in effect even
** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
@@ -5408,10 +5462,11 @@
SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL 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
** on [database connection] X.)^ ^The sqlite3_table_column_metadata()
** interface returns SQLITE_OK and fills in the non-NULL pointers in
@@ -5486,10 +5541,11 @@
int *pAutoinc /* OUTPUT: True if column is auto-increment */
);
/*
** CAPI3REF: Load An Extension
+** METHOD: sqlite3
**
** ^This interface loads an SQLite extension library from the named file.
**
** ^The sqlite3_load_extension() interface attempts to load an
** [SQLite extension] library contained in the file zFile. If
@@ -5527,10 +5583,11 @@
char **pzErrMsg /* Put error message here if not 0 */
);
/*
** 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
** [extension loading] while evaluating user-entered SQL, the following API
** is provided to turn the [sqlite3_load_extension()] mechanism on and off.
@@ -5776,10 +5833,11 @@
#define SQLITE_INDEX_CONSTRAINT_GE 32
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
/*
** 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
** creating a new [virtual table] using the module and before using a
** preexisting [virtual table] for the module.
@@ -5872,10 +5930,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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].
** But global versions of those functions
** must exist in order to be overloaded.)^
@@ -5914,10 +5973,12 @@
*/
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;
** in other words, the same BLOB that would be selected by:
**
@@ -5995,10 +6056,11 @@
sqlite3_blob **ppBlob
);
/*
** 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
** by the rowid value passed as the second argument. Only the row can be
** changed. ^The database, table and column on which the blob handle is open
@@ -6019,10 +6081,11 @@
*/
SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL 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
** handle is still closed.)^
**
@@ -6041,10 +6104,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** incremental blob I/O routines can only read or overwriting existing
** blob content; they cannot change the size of a blob.
@@ -6056,10 +6120,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** from the open BLOB, starting at offset iOffset.)^
**
@@ -6084,10 +6149,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** into the open BLOB, starting at offset iOffset.)^
**
@@ -6411,10 +6477,11 @@
#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */
#define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */
/*
** 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
** when the [threading mode] is Serialized.
** ^If the [threading mode] is Single-thread or Multi-thread then this
@@ -6422,10 +6489,11 @@
*/
SQLITE_API sqlite3_mutex *SQLITE_STDCALL 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
** with a particular database identified by the second argument. ^The
** name of the database is "main" for the main database or "temp" for the
@@ -6638,10 +6706,11 @@
#define SQLITE_STATUS_SCRATCH_SIZE 8
#define SQLITE_STATUS_MALLOC_COUNT 9
/*
** 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
** database connection object to be interrogated. ^The second argument
** is an integer constant, taken from the set of
@@ -6766,10 +6835,11 @@
#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
/*
** CAPI3REF: Prepared Statement Status
+** METHOD: sqlite3_stmt
**
** ^(Each prepared statement maintains various
** [SQLITE_STMTSTATUS counters] that measure the number
** of times it has performed specific operations.)^ These counters can
** be used to monitor the performance characteristics of the prepared
@@ -7269,10 +7339,11 @@
SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p);
SQLITE_API int SQLITE_STDCALL 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
** individual tables within the shared-cache cannot be obtained. See
** [SQLite Shared-Cache Mode] for a description of shared-cache locking.
@@ -7439,10 +7510,11 @@
*/
SQLITE_API void SQLITE_CDECL 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.
**
** ^(The callback is invoked by SQLite after the commit has taken place and
@@ -7478,10 +7550,11 @@
void*
);
/*
** 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
** to automatically [checkpoint]
** after committing a transaction if there are N or
@@ -7508,10 +7581,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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).)^
**
** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the
@@ -7529,10 +7603,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** information is written back into integers pointed to by L and C.)^
** ^(The M parameter must be a valid [checkpoint mode]:)^
@@ -7783,10 +7858,11 @@
#define SQLITE_SCANSTAT_EXPLAIN 4
#define SQLITE_SCANSTAT_SELECTID 5
/*
** 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
** interface to compare the predicted and the measured performance and
** issue warnings and/or rerun [ANALYZE] if discrepancies are found.
@@ -7820,10 +7896,11 @@
void *pOut /* Result written here */
);
/*
** 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.
@@ -8430,10 +8507,36 @@
#else
# define ALWAYS(X) (X)
# define NEVER(X) (X)
#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.
*/
@@ -9841,37 +9944,36 @@
/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
** are encoded into bitvectors as follows:
*/
#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */
-#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_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_INITIALIZER {\
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\
-/* 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, 0x05, 0x05, 0x00, 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, 0x02, 0x02, 0x01, 0x00, 0x00,}
+/* 152 */ 0x00, 0x10, 0x10, 0x01, 0x00, 0x00,}
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
/*
@@ -9926,10 +10028,11 @@
#endif
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*);
SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
@@ -11063,10 +11166,11 @@
#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */
#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */
#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 */
/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
@@ -11393,38 +11497,12 @@
int iSavepoint; /* Depth of the SAVEPOINT stack */
VTable *pNext; /* Next in linked list (see above) */
};
/*
-** 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.
+** The schema for each SQL table and view is represented in memory
+** by an instance of the following structure.
*/
struct Table {
char *zName; /* Name of the table or view */
Column *aCol; /* Information about each column */
Index *pIndex; /* List of SQL indexes on this table. */
@@ -11432,15 +11510,15 @@
FKey *pFKey; /* Linked list of all foreign keys in this table */
char *zColAff; /* String defining the affinity of each column */
#ifndef SQLITE_OMIT_CHECK
ExprList *pCheck; /* All CHECK constraints */
#endif
- 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 */
+ int tnum; /* Root BTree page for this table */
+ i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */
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 */
#endif
u8 tabFlags; /* Mask of TF_* values */
@@ -11458,17 +11536,24 @@
Table *pNextZombie; /* Next on the Parse.pZombieTab list */
};
/*
** 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 */
#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
#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 */
/*
** Test to see whether or not a table is a virtual table. This is
** done as a macro so that it will be optimized out when virtual
@@ -12221,11 +12306,11 @@
#define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */
#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
#define SF_Compound 0x0040 /* Part of a compound query */
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
-#define SF_AllValues 0x0100 /* All terms of compound are VALUES */
+#define SF_MultiValue 0x0100 /* Single VALUES term with multiple rows */
#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() */
@@ -12605,24 +12690,24 @@
*
* (op == TK_INSERT)
* 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.
- * target -> A token holding the quoted name of the table to insert into.
+ * zTarget -> Dequoted 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 ... () VALUES ...
* statement, then this stores the column-names to be
* inserted into.
*
* (op == TK_DELETE)
- * target -> A token holding the quoted name of the table to delete from.
+ * zTarget -> Dequoted name of the table to delete from.
* pWhere -> The WHERE clause of the DELETE statement if one is specified.
* Otherwise NULL.
*
* (op == TK_UPDATE)
- * target -> A token holding the quoted name of the table to update rows of.
+ * zTarget -> Dequoted name of the table to update.
* 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
* them to. See sqlite3Update() documentation of "pChanges"
* argument.
@@ -12630,12 +12715,12 @@
*/
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 statment or RHS of INSERT INTO .. SELECT ... */
- Token target; /* Target table for DELETE, UPDATE, INSERT */
+ Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */
+ char *zTarget; /* 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 */
TriggerStep *pNext; /* Next in the link-list */
TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */
@@ -12664,12 +12749,11 @@
sqlite3 *db; /* Optional database for lookaside. Can be NULL */
char *zBase; /* A base allocation. Not from malloc. */
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 string length */
- u8 useMalloc; /* 0: none, 1: sqlite3DbMalloc, 2: sqlite3_malloc */
+ int mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
};
#define STRACCUM_NOMEM 1
#define STRACCUM_TOOBIG 2
@@ -12982,11 +13066,11 @@
SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list);
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_TEST) || defined(SQLITE_DEBUG)
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...);
#endif
#if defined(SQLITE_TEST)
SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
#endif
@@ -13329,11 +13413,11 @@
SQLITE_PRIVATE void sqlite3Error(sqlite3*,int);
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_TEST)
+#if defined(SQLITE_NEED_ERR_NAME)
SQLITE_PRIVATE const char *sqlite3ErrName(int);
#endif
SQLITE_PRIVATE const char *sqlite3ErrStr(int);
SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
@@ -13423,11 +13507,11 @@
FuncDestructor *pDestructor
);
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
-SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
+SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, 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);
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
@@ -19807,20 +19891,10 @@
*/
#ifdef MEMORY_DEBUG
# 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.
*/
#ifdef SQLITE_PERFORMANCE_TRACE
@@ -21401,10 +21475,11 @@
/*
** 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;
}
/*
@@ -21515,45 +21590,52 @@
case '0': flag_zeropad = 1; break;
default: done = 1; break;
}
}while( !done && (c=(*++fmt))!=0 );
/* Get the field width */
- width = 0;
if( c=='*' ){
if( bArgList ){
width = (int)getIntArg(pArgList);
}else{
width = va_arg(ap,int);
}
if( width<0 ){
flag_leftjustify = 1;
- width = -width;
+ width = width >= -2147483647 ? -width : 0;
}
c = *++fmt;
}else{
+ unsigned wx = 0;
while( c>='0' && c<='9' ){
- width = width*10 + c - '0';
+ wx = wx*10 + c - '0';
c = *++fmt;
}
+ testcase( wx>0x7fffffff );
+ width = wx & 0x7fffffff;
}
+
/* Get the precision */
if( c=='.' ){
- precision = 0;
c = *++fmt;
if( c=='*' ){
if( bArgList ){
precision = (int)getIntArg(pArgList);
}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' ){
- precision = precision*10 + c - '0';
+ px = px*10 + c - '0';
c = *++fmt;
}
+ testcase( px>0x7fffffff );
+ precision = px & 0x7fffffff;
}
}else{
precision = -1;
}
/* Get the conversion type modifier */
@@ -21713,11 +21795,12 @@
if( flag_plussign ) prefix = '+';
else if( flag_blanksign ) prefix = ' ';
else prefix = 0;
}
if( xtype==etGENERIC && precision>0 ) precision--;
- for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
+ testcase( precision>0xfff );
+ for(idx=precision&0xfff, 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;
if( sqlite3IsNaN((double)realvalue) ){
bufpt = "NaN";
@@ -21768,12 +21851,13 @@
if( xtype==etEXP ){
e2 = 0;
}else{
e2 = exp;
}
- if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
- bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
+ if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
+ bufpt = zExtra
+ = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
if( bufpt==0 ){
setStrAccumError(pAccum, STRACCUM_NOMEM);
return;
}
}
@@ -22001,17 +22085,17 @@
** Return the number of bytes of text that StrAccum is able to accept
** after the attempted enlargement. The value returned might be zero.
*/
static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
char *zNew;
- assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */
+ assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
if( p->accError ){
testcase(p->accError==STRACCUM_TOOBIG);
testcase(p->accError==STRACCUM_NOMEM);
return 0;
}
- if( !p->useMalloc ){
+ if( p->mxAlloc==0 ){
N = p->nAlloc - p->nChar - 1;
setStrAccumError(p, STRACCUM_TOOBIG);
return N;
}else{
char *zOld = (p->zText==p->zBase ? 0 : p->zText);
@@ -22027,14 +22111,14 @@
setStrAccumError(p, STRACCUM_TOOBIG);
return 0;
}else{
p->nAlloc = (int)szNew;
}
- if( p->useMalloc==1 ){
+ if( p->db ){
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
}else{
- zNew = sqlite3_realloc(zOld, p->nAlloc);
+ zNew = sqlite3_realloc64(zOld, p->nAlloc);
}
if( zNew ){
assert( p->zText!=0 || p->nChar==0 );
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
@@ -22050,11 +22134,14 @@
/*
** Append N copies of character c to the given string buffer.
*/
SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){
- if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return;
+ testcase( p->nChar + (i64)N > 0x7fffffff );
+ if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
+ return;
+ }
while( (N--)>0 ) p->zText[p->nChar++] = c;
}
/*
** The StrAccum "p" is not large enough to accept N new bytes of z[].
@@ -22075,11 +22162,11 @@
/*
** Append N bytes of text from z to the StrAccum object. Increase the
** size of the memory allocation for StrAccum if necessary.
*/
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
- assert( z!=0 );
+ assert( z!=0 || N==0 );
assert( p->zText!=0 || p->nChar==0 || p->accError );
assert( N>=0 );
assert( p->accError==0 || p->nAlloc==0 );
if( p->nChar+N >= p->nAlloc ){
enlargeAndAppend(p,z,N);
@@ -22104,16 +22191,12 @@
** pointer if any kind of error was encountered.
*/
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
if( p->zText ){
p->zText[p->nChar] = 0;
- 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->mxAlloc>0 && p->zText==p->zBase ){
+ p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
if( p->zText ){
memcpy(p->zText, p->zBase, p->nChar+1);
}else{
setStrAccumError(p, STRACCUM_NOMEM);
}
@@ -22125,29 +22208,35 @@
/*
** Reset an StrAccum string. Reclaim all malloced memory.
*/
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
if( p->zText!=p->zBase ){
- if( p->useMalloc==1 ){
- sqlite3DbFree(p->db, p->zText);
- }else{
- sqlite3_free(p->zText);
- }
+ sqlite3DbFree(p->db, p->zText);
}
p->zText = 0;
}
/*
-** Initialize a string accumulator
+** 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.
*/
-SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
+SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
p->zText = p->zBase = zBase;
- p->db = 0;
+ p->db = db;
p->nChar = 0;
p->nAlloc = n;
p->mxAlloc = mx;
- p->useMalloc = 1;
p->accError = 0;
}
/*
** Print into memory obtained from sqliteMalloc(). Use the internal
@@ -22156,13 +22245,12 @@
SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
char *z;
char zBase[SQLITE_PRINT_BUF_SIZE];
StrAccum acc;
assert( db!=0 );
- sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
+ sqlite3StrAccumInit(&acc, db, 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 ){
db->mallocFailed = 1;
}
@@ -22216,12 +22304,11 @@
}
#endif
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
- sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
- acc.useMalloc = 2;
+ sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
return z;
}
@@ -22262,12 +22349,11 @@
(void)SQLITE_MISUSE_BKPT;
if( zBuf ) zBuf[0] = 0;
return zBuf;
}
#endif
- sqlite3StrAccumInit(&acc, zBuf, n, 0);
- acc.useMalloc = 0;
+ sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
return sqlite3StrAccumFinish(&acc);
}
SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
char *z;
@@ -22289,12 +22375,11 @@
*/
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, zMsg, sizeof(zMsg), 0);
- acc.useMalloc = 0;
+ sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
sqlite3StrAccumFinish(&acc));
}
@@ -22308,22 +22393,21 @@
renderLogMsg(iErrCode, zFormat, ap);
va_end(ap);
}
}
-#if defined(SQLITE_DEBUG)
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
/*
** A version of printf() that understands %lld. Used for debugging.
** The printf() built into some versions of windows does not understand %lld
** and segfaults if you give it a long long int.
*/
SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
va_list ap;
StrAccum acc;
char zBuf[500];
- sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
- acc.useMalloc = 0;
+ sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
va_start(ap,zFormat);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
va_end(ap);
sqlite3StrAccumFinish(&acc);
fprintf(stdout,"%s", zBuf);
@@ -22346,11 +22430,11 @@
*/
/* Add a new subitem to the tree. The moreToFollow flag indicates that this
** is not the last item in the tree. */
SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
if( p==0 ){
- p = sqlite3_malloc( sizeof(*p) );
+ p = sqlite3_malloc64( sizeof(*p) );
if( p==0 ) return 0;
memset(p, 0, sizeof(*p));
}else{
p->iLevel++;
}
@@ -22369,12 +22453,11 @@
SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
va_list ap;
int i;
StrAccum acc;
char zBuf[500];
- sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
- acc.useMalloc = 0;
+ sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
if( p ){
for(i=0; iiLevel && ibLine)-1; i++){
sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4);
}
sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
@@ -23993,10 +24076,11 @@
}else{
return 0;
}
}
#endif
+ while( zNum[0]=='0' ) zNum++;
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
v = v*10 + c;
}
/* The longest decimal representation of a 32 bit integer is 10 digits:
@@ -25247,10 +25331,21 @@
#if SQLITE_ENABLE_LOCKING_STYLE
# include
# include
# include
#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 */
# include
# include
@@ -25443,20 +25538,10 @@
*/
#ifdef MEMORY_DEBUG
# 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.
*/
#ifdef SQLITE_PERFORMANCE_TRACE
@@ -25995,11 +26080,11 @@
return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
#endif
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+#ifdef SQLITE_HAVE_OS_TRACE
/*
** Helper function for printing out trace information from debugging
** binaries. This returns the string representation of the supplied
** integer lock-type.
*/
@@ -26258,11 +26343,11 @@
struct vxworksFileId *pCandidate; /* For looping over existing file IDs */
int n; /* Length of zAbsoluteName string */
assert( zAbsoluteName[0]=='/' );
n = (int)strlen(zAbsoluteName);
- pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) );
+ pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) );
if( pNew==0 ) return 0;
pNew->zCanonicalName = (char*)&pNew[1];
memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
n = vxworksSimplifyName(pNew->zCanonicalName, n);
@@ -26662,11 +26747,11 @@
pInode = inodeList;
while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
pInode = pInode->pNext;
}
if( pInode==0 ){
- pInode = sqlite3_malloc( sizeof(*pInode) );
+ pInode = sqlite3_malloc64( sizeof(*pInode) );
if( pInode==0 ){
return SQLITE_NOMEM;
}
memset(pInode, 0, sizeof(*pInode));
memcpy(&pInode->fileId, &fileId, sizeof(fileId));
@@ -29183,11 +29268,11 @@
case SQLITE_FCNTL_VFSNAME: {
*(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
return SQLITE_OK;
}
case SQLITE_FCNTL_TEMPFILENAME: {
- char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
+ char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname );
if( zTFile ){
unixGetTempname(pFile->pVfs->mxPathname, zTFile);
*(char**)pArg = zTFile;
}
return SQLITE_OK;
@@ -29624,11 +29709,11 @@
unixInodeInfo *pInode; /* The inode of fd */
char *zShmFilename; /* Name of the file used for SHM */
int nShmFilename; /* Size of the SHM filename in bytes */
/* Allocate space for the new unixShm object. */
- p = sqlite3_malloc( sizeof(*p) );
+ p = sqlite3_malloc64( sizeof(*p) );
if( p==0 ) return SQLITE_NOMEM;
memset(p, 0, sizeof(*p));
assert( pDbFd->pShm==0 );
/* Check to see if a unixShmNode object already exists. Reuse an existing
@@ -29655,11 +29740,11 @@
#ifdef SQLITE_SHM_DIRECTORY
nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
#else
nShmFilename = 6 + (int)strlen(zBasePath);
#endif
- pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
+ pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename );
if( pShmNode==0 ){
rc = SQLITE_NOMEM;
goto shm_open_err;
}
memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
@@ -29865,11 +29950,11 @@
if( pMem==MAP_FAILED ){
rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
goto shmpage_out;
}
}else{
- pMem = sqlite3_malloc(szRegion);
+ pMem = sqlite3_malloc64(szRegion);
if( pMem==0 ){
rc = SQLITE_NOMEM;
goto shmpage_out;
}
memset(pMem, 0, szRegion);
@@ -30702,11 +30787,11 @@
else if( pLockingStyle == &afpIoMethods ){
/* AFP locking uses the file path so it needs to be included in
** the afpLockingContext.
*/
afpLockingContext *pCtx;
- pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
+ pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) );
if( pCtx==0 ){
rc = SQLITE_NOMEM;
}else{
/* NB: zFilename exists and remains valid until the file is closed
** according to requirement F11141. So we do not need to make a
@@ -30732,11 +30817,11 @@
*/
char *zLockFile;
int nFilename;
assert( zFilename!=0 );
nFilename = (int)strlen(zFilename) + 6;
- zLockFile = (char *)sqlite3_malloc(nFilename);
+ zLockFile = (char *)sqlite3_malloc64(nFilename);
if( zLockFile==0 ){
rc = SQLITE_NOMEM;
}else{
sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
}
@@ -31109,11 +31194,11 @@
UnixUnusedFd *pUnused;
pUnused = findReusableFd(zName, flags);
if( pUnused ){
fd = pUnused->fd;
}else{
- pUnused = sqlite3_malloc(sizeof(*pUnused));
+ pUnused = sqlite3_malloc64(sizeof(*pUnused));
if( !pUnused ){
return SQLITE_NOMEM;
}
}
p->pUnused = pUnused;
@@ -31489,11 +31574,11 @@
** that we always use the same random number sequence. This makes the
** tests repeatable.
*/
memset(zBuf, 0, nBuf);
randomnessPid = osGetpid(0);
-#if !defined(SQLITE_TEST)
+#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
{
int fd, got;
fd = robust_open("/dev/urandom", O_RDONLY, 0);
if( fd<0 ){
time_t t;
@@ -31901,11 +31986,11 @@
*/
pUnused = findReusableFd(path, openFlags);
if( pUnused ){
fd = pUnused->fd;
}else{
- pUnused = sqlite3_malloc(sizeof(*pUnused));
+ pUnused = sqlite3_malloc64(sizeof(*pUnused));
if( !pUnused ){
return SQLITE_NOMEM;
}
}
if( fd<0 ){
@@ -31934,11 +32019,11 @@
default:
return SQLITE_CANTOPEN_BKPT;
}
}
- pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew));
+ pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew));
if( pNew==NULL ){
rc = SQLITE_NOMEM;
goto end_create_proxy;
}
memset(pNew, 0, sizeof(unixFile));
@@ -31967,21 +32052,22 @@
SQLITE_API int sqlite3_hostid_num = 0;
#endif
#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.
*/
static int proxyGetHostID(unsigned char *pHostID, int *pError){
assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
memset(pHostID, 0, PROXY_HOSTIDLEN);
-# if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
- (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
+#ifdef HAVE_GETHOSTUUID
{
struct timespec timeout = {1, 0}; /* 1 sec timeout */
if( gethostuuid(pHostID, &timeout) ){
int err = errno;
if( pError ){
@@ -32395,11 +32481,11 @@
return rc;
}
/*
** Given the name of a database file, compute the name of its conch file.
-** Store the conch filename in memory obtained from sqlite3_malloc().
+** Store the conch filename in memory obtained from sqlite3_malloc64().
** Make *pConchPath point to the new name. Return SQLITE_OK on success
** or SQLITE_NOMEM if unable to obtain memory.
**
** The caller is responsible for ensuring that the allocated memory
** space is eventually freed.
@@ -32411,11 +32497,11 @@
int len = (int)strlen(dbPath); /* Length of database filename - dbPath */
char *conchPath; /* buffer in which to construct conch name */
/* Allocate space for the conch filename and initialize the name to
** the name of the original database file. */
- *pConchPath = conchPath = (char *)sqlite3_malloc(len + 8);
+ *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8);
if( conchPath==0 ){
return SQLITE_NOMEM;
}
memcpy(conchPath, dbPath, len+1);
@@ -32527,11 +32613,11 @@
}
OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h,
(lockPath ? lockPath : ":auto:"), osGetpid(0)));
- pCtx = sqlite3_malloc( sizeof(*pCtx) );
+ pCtx = sqlite3_malloc64( sizeof(*pCtx) );
if( pCtx==0 ){
return SQLITE_NOMEM;
}
memset(pCtx, 0, sizeof(*pCtx));
@@ -32971,20 +33057,10 @@
*/
#ifdef MEMORY_DEBUG
# 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.
*/
#ifdef SQLITE_PERFORMANCE_TRACE
@@ -35884,11 +35960,11 @@
** Used only when SQLITE_NO_SYNC is not defined.
*/
BOOL rc;
#endif
#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
- (defined(SQLITE_TEST) && defined(SQLITE_DEBUG))
+ defined(SQLITE_HAVE_OS_TRACE)
/*
** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or
** OSTRACE() macros.
*/
winFile *pFile = (winFile*)id;
@@ -36561,11 +36637,11 @@
DWORD lastErrno; /* The Windows errno from the last I/O error */
int nRef; /* Number of winShm objects pointing to this */
winShm *pFirst; /* All winShm objects pointing to this */
winShmNode *pNext; /* Next in list of all winShmNode objects */
-#ifdef SQLITE_DEBUG
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
u8 nextShmId; /* Next available winShm.id value */
#endif
};
/*
@@ -36592,11 +36668,11 @@
winShmNode *pShmNode; /* The underlying winShmNode object */
winShm *pNext; /* Next winShm with the same winShmNode */
u8 hasMutex; /* True if holding the winShmNode mutex */
u16 sharedMask; /* Mask of shared locks held */
u16 exclMask; /* Mask of exclusive locks held */
-#ifdef SQLITE_DEBUG
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
u8 id; /* Id of this connection with its winShmNode */
#endif
};
/*
@@ -36783,11 +36859,11 @@
if( rc ) goto shm_open_err;
}
/* Make the new connection a child of the winShmNode */
p->pShmNode = pShmNode;
-#ifdef SQLITE_DEBUG
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
p->id = pShmNode->nextShmId++;
#endif
pShmNode->nRef++;
pDbFd->pShm = p;
winShmLeaveMutex();
@@ -37052,11 +37128,11 @@
goto shmpage_out;
}
}
/* Map the requested memory region into this processes address space. */
- apNew = (struct ShmRegion *)sqlite3_realloc(
+ apNew = (struct ShmRegion *)sqlite3_realloc64(
pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
);
if( !apNew ){
rc = SQLITE_IOERR_NOMEM;
goto shmpage_out;
@@ -38499,11 +38575,11 @@
** Write up to nBuf bytes of randomness into zBuf.
*/
static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
int n = 0;
UNUSED_PARAMETER(pVfs);
-#if defined(SQLITE_TEST)
+#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
n = nBuf;
memset(zBuf, 0, nBuf);
#else
if( sizeof(SYSTEMTIME)<=nBuf-n ){
SYSTEMTIME x;
@@ -38533,11 +38609,10 @@
LARGE_INTEGER i;
osQueryPerformanceCounter(&i);
memcpy(&zBuf[n], &i, sizeof(i));
n += sizeof(i);
}
-#endif
#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);
@@ -38550,10 +38625,11 @@
osUuidCreateSequential(&id);
memcpy(zBuf, &id, sizeof(UUID));
n += sizeof(UUID);
}
#endif
+#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
return n;
}
/*
@@ -39104,11 +39180,11 @@
/* Allocate the Bitvec to be tested and a linear array of
** bits to act as the reference */
pBitvec = sqlite3BitvecCreate( sz );
pV = sqlite3MallocZero( (sz+7)/8 + 1 );
- pTmpSpace = sqlite3_malloc(BITVEC_SZ);
+ pTmpSpace = sqlite3_malloc64(BITVEC_SZ);
if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end;
/* NULL pBitvec tests */
sqlite3BitvecSet(0, 1);
sqlite3BitvecClear(0, 1, pTmpSpace);
@@ -44593,13 +44669,11 @@
Pgno nTruncate, /* Database size after this commit */
int isCommit /* True if this is a commit */
){
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 );
#ifdef SQLITE_DEBUG
/* Verify that the page list is in accending order */
@@ -44612,11 +44686,10 @@
if( isCommit ){
/* If a WAL transaction is being committed, there is no point in writing
** any pages with page numbers greater than nTruncate into the WAL file.
** They will never be read by any client. So remove them from the pDirty
** list here. */
- PgHdr *p;
PgHdr **ppNext = &pList;
nList = 0;
for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
if( p->pgno<=nTruncate ){
ppNext = &p->pDirty;
@@ -44632,11 +44705,10 @@
if( pList->pgno==1 ) pager_write_changecounter(pList);
rc = sqlite3WalFrames(pPager->pWal,
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);
}
}
@@ -48563,10 +48635,12 @@
}else if( state==PAGER_OPEN ){
pager_unlock(pPager);
}
assert( state==pPager->eState );
}
+ }else if( eMode==PAGER_JOURNALMODE_OFF ){
+ sqlite3OsClose(pPager->jfd);
}
}
/* Return the new journal mode */
return (int)pPager->journalMode;
@@ -49345,11 +49419,11 @@
/* Enlarge the pWal->apWiData[] array if required */
if( pWal->nWiData<=iPage ){
int nByte = sizeof(u32*)*(iPage+1);
volatile u32 **apNew;
- apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte);
+ apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
if( !apNew ){
*ppPage = 0;
return SQLITE_NOMEM;
}
memset((void*)&apNew[pWal->nWiData], 0,
@@ -49970,11 +50044,11 @@
goto finished;
}
/* Malloc a buffer to read frames into. */
szFrame = szPage + WAL_FRAME_HDRSIZE;
- aFrame = (u8 *)sqlite3_malloc(szFrame);
+ aFrame = (u8 *)sqlite3_malloc64(szFrame);
if( !aFrame ){
rc = SQLITE_NOMEM;
goto recovery_error;
}
aData = &aFrame[WAL_FRAME_HDRSIZE];
@@ -50363,21 +50437,21 @@
/* Allocate space for the WalIterator object. */
nSegment = walFramePage(iLast) + 1;
nByte = sizeof(WalIterator)
+ (nSegment-1)*sizeof(struct WalSegment)
+ iLast*sizeof(ht_slot);
- p = (WalIterator *)sqlite3_malloc(nByte);
+ p = (WalIterator *)sqlite3_malloc64(nByte);
if( !p ){
return SQLITE_NOMEM;
}
memset(p, 0, nByte);
p->nSegment = nSegment;
/* Allocate temporary space used by the merge-sort routine. This block
** of memory will be freed before this function returns.
*/
- aTmp = (ht_slot *)sqlite3_malloc(
+ aTmp = (ht_slot *)sqlite3_malloc64(
sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
);
if( !aTmp ){
rc = SQLITE_NOMEM;
}
@@ -50553,10 +50627,18 @@
** cannot be backfilled from the WAL.
*/
mxSafeFrame = pWal->hdr.mxFrame;
mxPage = pWal->hdr.nPage;
for(i=1; iaReadMark[i];
if( mxSafeFrame>y ){
assert( y<=pWal->hdr.mxFrame );
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
if( rc==SQLITE_OK ){
@@ -55393,11 +55475,11 @@
}
assert( nReserve>=0 && nReserve<=255 );
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
((pageSize-1)&pageSize)==0 ){
assert( (pageSize & 7)==0 );
- assert( !pBt->pPage1 && !pBt->pCursor );
+ assert( !pBt->pCursor );
pBt->pageSize = (u32)pageSize;
freeTempSpace(pBt);
}
rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve);
pBt->usableSize = pBt->pageSize - (u16)nReserve;
@@ -57415,17 +57497,22 @@
*/
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]apPage[pCur->iPage]->nCell );
assert( pCur->info.nSize>0 );
- *pAmt = pCur->info.nLocal;
+ assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
+ assert( pCur->info.pPayloadapPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
+ amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload);
+ if( pCur->info.nLocalinfo.nLocal;
+ *pAmt = amt;
return (void*)pCur->info.pPayload;
}
/*
@@ -59699,11 +59786,10 @@
if( iParentIdx==0 ){
nxDiv = 0;
}else if( iParentIdx==i ){
nxDiv = i-2+bBulk;
}else{
- assert( bBulk==0 );
nxDiv = iParentIdx-1;
}
i = 2-bBulk;
}
nOld = i+1;
@@ -61487,10 +61573,61 @@
iPage = get4byte(pOvflData);
sqlite3PagerUnref(pOvflPage);
}
}
#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]zPfx;
int saved_v1 = pCheck->v1;
int saved_v2 = pCheck->v2;
@@ -61665,19 +61803,19 @@
/* Check for complete coverage of the page
*/
data = pPage->aData;
hdr = pPage->hdrOffset;
- hit = sqlite3PageMalloc( pBt->pageSize );
+ heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
pCheck->zPfx = 0;
- if( hit==0 ){
+ if( heap==0 ){
pCheck->mallocFailed = 1;
}else{
int contentOffset = get2byteNotZero(&data[hdr+5]);
assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */
- memset(hit+contentOffset, 0, usableSize-contentOffset);
- memset(hit, 1, contentOffset);
+ heap[0] = 0;
+ btreeHeapInsert(heap, contentOffset-1);
/* 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]);
/* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page
** immediately follows the b-tree page header. */
@@ -61685,20 +61823,19 @@
/* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte
** integer offsets to the cell contents. */
for(i=0; i=usableSize ){
pCheck->zPfx = 0;
checkAppendMsg(pCheck,
"Corruption detected in cell %d on page %d",i,iPage);
}else{
- for(j=pc+size-1; j>=pc; j--) hit[j]++;
+ btreeHeapInsert(heap, (pc<<16)|(pc+size-1));
}
}
/* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header
** is the offset of the first freeblock, or zero if there are no
** freeblocks on the page. */
@@ -61706,11 +61843,11 @@
while( i>0 ){
int size, j;
assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */
size = get2byte(&data[i+2]);
assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */
- for(j=i+size-1; j>=i; j--) hit[j]++;
+ btreeHeapInsert(heap, (i<<16)|(i+size-1));
/* 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
** chain. */
j = get2byte(&data[i]);
@@ -61718,31 +61855,37 @@
** increasing offset. */
assert( j==0 || j>i+size ); /* Enforced by btreeInitPage() */
assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */
i = j;
}
- for(i=cnt=0; i1 ){
+ cnt = 0;
+ assert( heap[0]>0 );
+ assert( (heap[1]>>16)==0 );
+ btreeHeapPull(heap,&prev);
+ while( btreeHeapPull(heap,&x) ){
+ if( (prev&0xffff)+1>(x>>16) ){
checkAppendMsg(pCheck,
- "Multiple uses for byte %d of page %d", i, iPage);
+ "Multiple uses for byte %u of page %d", x>>16, 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( cnt!=data[hdr+7] ){
+ if( heap[0]==0 && cnt!=data[hdr+7] ){
checkAppendMsg(pCheck,
"Fragmentation of %d bytes reported as %d on page %d",
cnt, data[hdr+7], iPage);
}
}
- sqlite3PageFree(hit);
+ sqlite3PageFree(heap);
releasePage(pPage);
end_of_check:
pCheck->zPfx = saved_zPfx;
pCheck->v1 = saved_v1;
@@ -61802,12 +61945,11 @@
sqlite3BtreeLeave(p);
return 0;
}
i = PENDING_BYTE_PAGE(pBt);
if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
- sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
- sCheck.errMsg.useMalloc = 2;
+ sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
/* Check the integrity of the freelist
*/
sCheck.zPfx = "Main freelist: ";
checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
@@ -63139,14 +63281,15 @@
return SQLITE_NOMEM;
}
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;
}
/*
@@ -64586,11 +64729,11 @@
int i;
int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField;
Mem *aMem = pRec->aMem;
sqlite3 *db = aMem[0].db;
for(i=0; ipKeyInfo);
sqlite3DbFree(db, pRec);
}
}
@@ -66422,18 +66565,35 @@
pVtabCursor->pVtab->nRef--;
pModule->xClose(pVtabCursor);
}
#endif
}
+
+/*
+** Close all cursors in the current frame.
+*/
+static void closeCursorsInFrame(Vdbe *p){
+ if( p->apCsr ){
+ int i;
+ for(i=0; inCursor; 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
v->aOnceFlag = pFrame->aOnceFlag;
v->nOnceFlag = pFrame->nOnceFlag;
@@ -66464,21 +66624,11 @@
sqlite3VdbeFrameRestore(pFrame);
p->pFrame = 0;
p->nFrame = 0;
}
assert( p->nFrame==0 );
-
- if( p->apCsr ){
- int i;
- for(i=0; inCursor; i++){
- VdbeCursor *pC = p->apCsr[i];
- if( pC ){
- sqlite3VdbeFreeCursor(p, pC);
- p->apCsr[i] = 0;
- }
- }
- }
+ closeCursorsInFrame(p);
if( p->aMem ){
releaseMemArray(&p->aMem[1], p->nMem);
}
while( p->pDelFrame ){
VdbeFrame *pDel = p->pDelFrame;
@@ -68219,11 +68369,11 @@
** If database corruption is discovered, set pPKey2->errCode to
** SQLITE_CORRUPT and return 0. If an OOM error is encountered,
** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the
** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db).
*/
-static int vdbeRecordCompareWithSkip(
+SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2, /* Right key */
int bSkip /* If true, skip the first field */
){
u32 d1; /* Offset into aKey[] of next data element */
@@ -68405,11 +68555,11 @@
}
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2 /* Right key */
){
- return vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
+ return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
}
/*
** This function is an optimized version of sqlite3VdbeRecordCompare()
@@ -68493,11 +68643,11 @@
}else if( vr2;
}else if( pPKey2->nField>1 ){
/* The first fields of the two keys are equal. Compare the trailing
** fields. */
- res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
+ res = sqlite3VdbeRecordCompareWithSkip(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. */
res = pPKey2->default_rc;
}
@@ -68541,11 +68691,11 @@
if( res==0 ){
res = nStr - pPKey2->aMem[0].n;
if( res==0 ){
if( pPKey2->nField>1 ){
- res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
+ res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
}else{
res = pPKey2->default_rc;
}
}else if( res>0 ){
res = pPKey2->r2;
@@ -70483,21 +70633,22 @@
Mem *pVar; /* Value of a host parameter */
StrAccum out; /* Accumulate the output here */
char zBase[100]; /* Initial working space */
db = p->db;
- sqlite3StrAccumInit(&out, zBase, sizeof(zBase),
+ sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
- out.db = db;
if( db->nVdbeExec>1 ){
while( *zRawSql ){
const char *zStart = zRawSql;
while( *(zRawSql++)!='\n' && *zRawSql );
sqlite3StrAccumAppend(&out, "-- ", 3);
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);
assert( n>0 );
sqlite3StrAccumAppend(&out, zRawSql, n);
@@ -70510,14 +70661,16 @@
sqlite3GetInt32(&zRawSql[1], &idx);
}else{
idx = nextIndex;
}
}else{
- assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' );
+ assert( zRawSql[0]==':' || 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 );
}
zRawSql += nToken;
nextIndex = idx + 1;
@@ -71188,21 +71341,38 @@
assert( n==(db->nSavepoint + db->isTransactionSavepoint) );
return 1;
}
#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.
** This is the core of sqlite3_step().
*/
SQLITE_PRIVATE int sqlite3VdbeExec(
Vdbe *p /* The VDBE */
){
- int pc=0; /* The program counter */
Op *aOp = p->aOp; /* Copy of p->aOp */
- Op *pOp; /* Current operation */
+ Op *pOp = aOp; /* Current operation */
+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+ Op *pOrigOp; /* Value of pOp at the top of the loop */
+#endif
int rc = SQLITE_OK; /* Value to return */
sqlite3 *db = p->db; /* The database */
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
u8 encoding = ENC(db); /* The database encoding */
int iCompare = 0; /* Result of last OP_Compare operation */
@@ -71274,27 +71444,26 @@
}
if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n");
}
sqlite3EndBenignMalloc();
#endif
- for(pc=p->pc; rc==SQLITE_OK; pc++){
- assert( pc>=0 && pcnOp );
+ for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){
+ assert( pOp>=aOp && pOp<&aOp[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[pc]++;
+ if( p->anExec ) p->anExec[(int)(pOp-aOp)]++;
#endif
/* Only allow tracing if SQLITE_DEBUG is defined.
*/
#ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){
- sqlite3VdbePrintOp(stdout, pc, pOp);
+ sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp);
}
#endif
/* Check to see if we need to simulate an interrupt. This only happens
@@ -71307,27 +71476,13 @@
sqlite3_interrupt(db);
}
}
#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) );
assert( memIsValid(&aMem[pOp->p1]) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
@@ -71356,10 +71511,13 @@
assert( pOp->p3>0 );
assert( pOp->p3<=(p->nMem-p->nCursor) );
memAboutToChange(p, &aMem[pOp->p3]);
}
#endif
+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+ pOrigOp = pOp;
+#endif
switch( pOp->opcode ){
/*****************************************************************************
** What follows is a massive switch statement where each case implements a
@@ -71379,11 +71537,11 @@
** case statement is followed by a comment of the form "/# same as ... #/"
** that comment is used to determine the particular value of the opcode.
**
** 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_prerelease, out2, out3. See
+** Keywords include: in1, in2, in3, out2, out3. See
** the mkopcodeh.awk script for additional information.
**
** Documentation about VDBE opcodes is generated by scanning this file
** for lines of that contain "Opcode:". That line and all subsequent
** comment lines are used in the generation of the opcode.html documentation
@@ -71407,11 +71565,12 @@
** is sometimes set to 1 instead of 0 as a hint to the command-line shell
** that this Goto is the bottom of a loop and that the lines from P2 down
** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: { /* jump */
- pc = pOp->p2 - 1;
+jump_to_p2_and_check_for_interrupt:
+ pOp = &aOp[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
** completion. Check to see if sqlite3_interrupt() has been called
** or if the progress callback needs to be invoked.
@@ -71452,13 +71611,17 @@
assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
pIn1 = &aMem[pOp->p1];
assert( VdbeMemDynamic(pIn1)==0 );
memAboutToChange(p, pIn1);
pIn1->flags = MEM_Int;
- pIn1->u.i = pc;
+ pIn1->u.i = (int)(pOp-aOp);
REGISTER_TRACE(pOp->p1, pIn1);
- pc = pOp->p2 - 1;
+
+ /* Most jump operations do a goto to this spot in order to update
+ ** the pOp pointer. */
+jump_to_p2:
+ pOp = &aOp[pOp->p2 - 1];
break;
}
/* Opcode: Return P1 * * * *
**
@@ -71466,11 +71629,11 @@
** the jump, register P1 becomes undefined.
*/
case OP_Return: { /* in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags==MEM_Int );
- pc = (int)pIn1->u.i;
+ pOp = &aOp[pIn1->u.i];
pIn1->flags = MEM_Undefined;
break;
}
/* Opcode: InitCoroutine P1 P2 P3 * *
@@ -71490,11 +71653,11 @@
assert( pOp->p3>=0 && pOp->p3nOp );
pOut = &aMem[pOp->p1];
assert( !VdbeMemDynamic(pOut) );
pOut->u.i = pOp->p3 - 1;
pOut->flags = MEM_Int;
- if( pOp->p2 ) pc = pOp->p2 - 1;
+ if( pOp->p2 ) goto jump_to_p2;
break;
}
/* Opcode: EndCoroutine P1 * * * *
**
@@ -71510,11 +71673,11 @@
assert( pIn1->flags==MEM_Int );
assert( pIn1->u.i>=0 && pIn1->u.inOp );
pCaller = &aOp[pIn1->u.i];
assert( pCaller->opcode==OP_Yield );
assert( pCaller->p2>=0 && pCaller->p2nOp );
- pc = pCaller->p2 - 1;
+ pOp = &aOp[pCaller->p2 - 1];
pIn1->flags = MEM_Undefined;
break;
}
/* Opcode: Yield P1 P2 * * *
@@ -71534,13 +71697,13 @@
int pcDest;
pIn1 = &aMem[pOp->p1];
assert( VdbeMemDynamic(pIn1)==0 );
pIn1->flags = MEM_Int;
pcDest = (int)pIn1->u.i;
- pIn1->u.i = pc;
+ pIn1->u.i = (int)(pOp - aOp);
REGISTER_TRACE(pOp->p1, pIn1);
- pc = pcDest;
+ pOp = &aOp[pcDest];
break;
}
/* Opcode: HaltIfNull P1 P2 P3 P4 P5
** Synopsis: if r[P3]=null halt
@@ -71587,34 +71750,38 @@
** is the same as executing Halt.
*/
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. */
- VdbeFrame *pFrame = p->pFrame;
+ pFrame = p->pFrame;
p->pFrame = pFrame->pParent;
p->nFrame--;
sqlite3VdbeSetChanges(db, p->nChange);
- pc = sqlite3VdbeFrameRestore(pFrame);
+ pcx = sqlite3VdbeFrameRestore(pFrame);
lastRowid = db->lastRowid;
if( pOp->p2==OE_Ignore ){
- /* Instruction pc is the OP_Program that invoked the sub-program
+ /* Instruction pcx 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. */
- pc = p->aOp[pc].p2-1;
+ pcx = p->aOp[pcx].p2-1;
}
aOp = p->aOp;
aMem = p->aMem;
+ pOp = &aOp[pcx];
break;
}
p->rc = pOp->p1;
p->errorAction = (u8)pOp->p2;
- p->pc = pc;
+ p->pc = pcx;
if( p->rc ){
if( pOp->p5 ){
static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
"FOREIGN KEY" };
assert( pOp->p5>=1 && pOp->p5<=4 );
@@ -71634,11 +71801,11 @@
}else if( pOp->p4.z ){
sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
}else{
sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType);
}
- sqlite3_log(pOp->p1, zLogFmt, pc, p->zSql, p->zErrMsg);
+ sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
}
rc = sqlite3VdbeHalt(p);
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
if( rc==SQLITE_BUSY ){
p->rc = rc = SQLITE_BUSY;
@@ -71653,11 +71820,12 @@
/* Opcode: Integer P1 P2 * * *
** Synopsis: r[P2]=P1
**
** The 32-bit integer value P1 is written into register P2.
*/
-case OP_Integer: { /* out2-prerelease */
+case OP_Integer: { /* out2 */
+ pOut = out2Prerelease(p, pOp);
pOut->u.i = pOp->p1;
break;
}
/* Opcode: Int64 * P2 * P4 *
@@ -71664,11 +71832,12 @@
** Synopsis: r[P2]=P4
**
** P4 is a pointer to a 64-bit integer value.
** Write that value into register P2.
*/
-case OP_Int64: { /* out2-prerelease */
+case OP_Int64: { /* out2 */
+ pOut = out2Prerelease(p, pOp);
assert( pOp->p4.pI64!=0 );
pOut->u.i = *pOp->p4.pI64;
break;
}
@@ -71677,11 +71846,12 @@
** Synopsis: r[P2]=P4
**
** 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-prerelease */
+case OP_Real: { /* same as TK_FLOAT, out2 */
+ pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Real;
assert( !sqlite3IsNaN(*pOp->p4.pReal) );
pOut->u.r = *pOp->p4.pReal;
break;
}
@@ -71693,12 +71863,13 @@
** 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
** this transformation, the length of string P4 is computed and stored
** as the P1 parameter.
*/
-case OP_String8: { /* same as TK_STRING, out2-prerelease */
+case OP_String8: { /* same as TK_STRING, out2 */
assert( pOp->p4.z!=0 );
+ pOut = out2Prerelease(p, pOp);
pOp->opcode = OP_String;
pOp->p1 = sqlite3Strlen30(pOp->p4.z);
#ifndef SQLITE_OMIT_UTF16
if( encoding!=SQLITE_UTF8 ){
@@ -71731,12 +71902,13 @@
** 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-prerelease */
+case OP_String: { /* out2 */
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);
@@ -71760,13 +71932,14 @@
**
** If the P1 value is non-zero, then also set the MEM_Cleared flag so that
** NULL values will not compare equal even if SQLITE_NULLEQ is set on
** OP_Ne or OP_Eq.
*/
-case OP_Null: { /* out2-prerelease */
+case OP_Null: { /* out2 */
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;
while( cnt>0 ){
pOut++;
@@ -71797,12 +71970,13 @@
** Synopsis: r[P2]=P4 (len=P1)
**
** P4 points to a blob of data P1 bytes long. Store this
** blob in register P2.
*/
-case OP_Blob: { /* out2-prerelease */
+case OP_Blob: { /* out2 */
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);
break;
}
@@ -71813,19 +71987,20 @@
** Transfer the values of bound parameter P1 into register P2
**
** 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-prerelease */
+case OP_Variable: { /* out2 */
Mem *pVar; /* Value being transferred */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] );
pVar = &p->aVar[pOp->p1 - 1];
if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
}
+ pOut = out2Prerelease(p, pOp);
sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
@@ -71856,14 +72031,15 @@
assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
memAboutToChange(p, pOut);
sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
- if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){
- pOut->pScopyFrom += p1 - pOp->p2;
+ if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrompScopyFrom += pOp->p2 - p1;
}
#endif
+ Deephemeralize(pOut);
REGISTER_TRACE(p2++, pOut);
pIn1++;
pOut++;
}while( --n );
break;
@@ -71998,11 +72174,11 @@
}
if( db->mallocFailed ) goto no_mem;
/* Return SQLITE_ROW
*/
- p->pc = pc + 1;
+ p->pc = (int)(pOp - aOp) + 1;
rc = SQLITE_ROW;
goto vdbe_return;
}
/* Opcode: Concat P1 P2 P3 * *
@@ -72244,11 +72420,11 @@
REGISTER_TRACE(pOp->p2+i, pArg);
}
assert( pOp->p4type==P4_FUNCDEF );
ctx.pFunc = pOp->p4.pFunc;
- ctx.iOp = pc;
+ ctx.iOp = (int)(pOp - aOp);
ctx.pVdbe = p;
MemSetTypeFlag(ctx.pOut, MEM_Null);
ctx.fErrorOrAux = 0;
db->lastRowid = lastRowid;
(*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
@@ -72258,11 +72434,11 @@
if( ctx.fErrorOrAux ){
if( ctx.isError ){
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
rc = ctx.isError;
}
- sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
+ sqlite3VdbeDeleteAuxData(p, (int)(pOp - aOp), pOp->p1);
}
/* Copy the result of the function into register P3 */
sqlite3VdbeChangeEncoding(ctx.pOut, encoding);
if( sqlite3VdbeMemTooBig(ctx.pOut) ){
@@ -72387,12 +72563,11 @@
if( (pIn1->flags & MEM_Int)==0 ){
if( pOp->p2==0 ){
rc = SQLITE_MISMATCH;
goto abort_due_to_error;
}else{
- pc = pOp->p2 - 1;
- break;
+ goto jump_to_p2;
}
}
}
MemSetTypeFlag(pIn1, MEM_Int);
break;
@@ -72574,11 +72749,11 @@
MemSetTypeFlag(pOut, MEM_Null);
REGISTER_TRACE(pOp->p2, pOut);
}else{
VdbeBranchTaken(2,3);
if( pOp->p5 & SQLITE_JUMPIFNULL ){
- pc = pOp->p2-1;
+ goto jump_to_p2;
}
}
break;
}
}else{
@@ -72625,10 +72800,16 @@
case OP_Lt: res = res<0; break;
case OP_Le: res = res<=0; break;
case OP_Gt: res = res>0; break;
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);
MemSetTypeFlag(pOut, MEM_Int);
@@ -72635,18 +72816,13 @@
pOut->u.i = res;
REGISTER_TRACE(pOp->p2, pOut);
}else{
VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
if( res ){
- pc = pOp->p2-1;
+ goto jump_to_p2;
}
}
- /* 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;
break;
}
/* Opcode: Permutation * * * P4 *
**
@@ -72737,15 +72913,15 @@
** in the most recent OP_Compare instruction the P1 vector was less than
** equal to, or greater than the P2 vector, respectively.
*/
case OP_Jump: { /* jump */
if( iCompare<0 ){
- pc = pOp->p1 - 1; VdbeBranchTaken(0,3);
+ VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1];
}else if( iCompare==0 ){
- pc = pOp->p2 - 1; VdbeBranchTaken(1,3);
+ VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1];
}else{
- pc = pOp->p3 - 1; VdbeBranchTaken(2,3);
+ VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1];
}
break;
}
/* Opcode: And P1 P2 P3 * *
@@ -72851,11 +73027,11 @@
*/
case OP_Once: { /* jump */
assert( pOp->p1nOnceFlag );
VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
if( p->aOnceFlag[pOp->p1] ){
- pc = pOp->p2-1;
+ goto jump_to_p2;
}else{
p->aOnceFlag[pOp->p1] = 1;
}
break;
}
@@ -72886,11 +73062,11 @@
#endif
if( pOp->opcode==OP_IfNot ) c = !c;
}
VdbeBranchTaken(c!=0, 2);
if( c ){
- pc = pOp->p2-1;
+ goto jump_to_p2;
}
break;
}
/* Opcode: IsNull P1 P2 * * *
@@ -72900,11 +73076,11 @@
*/
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 ){
- pc = pOp->p2 - 1;
+ goto jump_to_p2;
}
break;
}
/* Opcode: NotNull P1 P2 * * *
@@ -72914,11 +73090,11 @@
*/
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 ){
- pc = pOp->p2 - 1;
+ goto jump_to_p2;
}
break;
}
/* Opcode: Column P1 P2 P3 P4 P5
@@ -73128,11 +73304,11 @@
rc = SQLITE_CORRUPT_BKPT;
goto op_column_error;
}
}
- /* If after trying to extra new entries from the header, nHdrParsed is
+ /* If after trying to extract 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.
*/
if( pC->nHdrParsed<=p2 ){
if( pOp->p4type==P4_MEM ){
@@ -73252,11 +73428,11 @@
u8 *zNewRecord; /* A buffer to hold the data for the new record */
Mem *pRec; /* The new record */
u64 nData; /* Number of bytes of data space */
int nHdr; /* Number of bytes of header space */
i64 nByte; /* Data space required for this record */
- int nZero; /* Number of zero bytes at the end of the record */
+ i64 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 */
Mem *pLast; /* Last field of the record */
int nField; /* Number of fields in the record */
@@ -73344,11 +73520,11 @@
nVarint = sqlite3VarintLen(nHdr);
nHdr += nVarint;
if( nVarintdb->aLimit[SQLITE_LIMIT_LENGTH] ){
+ if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
/* Make sure the output register has a buffer large enough to store
** the new record. The output register (pOp->p3) is not allowed to
@@ -73395,18 +73571,19 @@
**
** Store the number of entries (an integer value) in the table or index
** opened by cursor P1 in register P2
*/
#ifndef SQLITE_OMIT_BTREECOUNT
-case OP_Count: { /* out2-prerelease */
+case OP_Count: { /* out2 */
i64 nEntry;
BtCursor *pCrsr;
pCrsr = p->apCsr[pOp->p1]->pCursor;
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;
}
#endif
@@ -73516,11 +73693,11 @@
if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}
db->autoCommit = 1;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pc = pc;
+ p->pc = (int)(pOp - aOp);
db->autoCommit = 0;
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
db->isTransactionSavepoint = 0;
@@ -73575,11 +73752,11 @@
}else{
db->nDeferredCons = pSavepoint->nDeferredCons;
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
}
- if( !isTransaction ){
+ if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){
rc = sqlite3VtabSavepoint(db, p1, iSavepoint);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}
}
@@ -73635,11 +73812,11 @@
}else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}else{
db->autoCommit = (u8)desiredAutoCommit;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pc = pc;
+ p->pc = (int)(pOp - aOp);
db->autoCommit = (u8)(1-desiredAutoCommit);
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
}
@@ -73712,11 +73889,11 @@
pBt = db->aDb[pOp->p1].pBt;
if( pBt ){
rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
if( rc==SQLITE_BUSY ){
- p->pc = pc;
+ p->pc = (int)(pOp - aOp);
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
@@ -73791,11 +73968,11 @@
**
** There must be a read-lock on the database (either a transaction
** must be started or there must be an open cursor) before
** executing this instruction.
*/
-case OP_ReadCookie: { /* out2-prerelease */
+case OP_ReadCookie: { /* out2 */
int iMeta;
int iDb;
int iCookie;
assert( p->bIsReader );
@@ -73805,10 +73982,11 @@
assert( iDb>=0 && iDbnDb );
assert( db->aDb[iDb].pBt!=0 );
assert( DbMaskTest(p->btreeMask, iDb) );
sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
+ pOut = out2Prerelease(p, pOp);
pOut->u.i = iMeta;
break;
}
/* Opcode: SetCookie P1 P2 P3 * *
@@ -74126,11 +74304,11 @@
VdbeCursor *pC;
assert( pOp->p1>=0 && pOp->p1nCursor );
pC = p->apCsr[pOp->p1];
assert( pC->pSorter );
if( (pC->seqCount++)==0 ){
- pc = pOp->p2 - 1;
+ goto jump_to_p2;
}
break;
}
/* Opcode: OpenPseudo P1 P2 P3 * *
@@ -74303,11 +74481,11 @@
** loss of information, then special processing is required... */
if( (pIn3->flags & MEM_Int)==0 ){
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 */
- pc = pOp->p2 - 1; VdbeBranchTaken(1,2);
+ VdbeBranchTaken(1,2); goto jump_to_p2;
break;
}
/* If the approximation iKey is larger than the actual real search
** term, substitute >= for > and < for <=. e.g. if the search term
@@ -74394,11 +74572,11 @@
}
}
assert( pOp->p2>0 );
VdbeBranchTaken(res!=0,2);
if( res ){
- pc = pOp->p2 - 1;
+ goto jump_to_p2;
}
break;
}
/* Opcode: Seek P1 P2 * * *
@@ -74488,10 +74666,11 @@
*/
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;
char *pFree;
UnpackedRecord *pIdxKey;
@@ -74510,11 +74689,11 @@
pC->seekOp = pOp->opcode;
#endif
pIn3 = &aMem[pOp->p3];
assert( pC->pCursor!=0 );
assert( pC->isTable==0 );
- pFree = 0; /* Not needed. Only used to suppress a compiler warning. */
+ pFree = 0;
if( pOp->p4.i>0 ){
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p4.i;
r.aMem = pIn3;
for(ii=0; iiflags & MEM_Blob );
ExpandBlob(pIn3);
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; iinField; ii++){
if( pIdxKey->aMem[ii].flags & MEM_Null ){
- pc = pOp->p2 - 1; VdbeBranchTaken(1,2);
+ takeJump = 1;
break;
}
}
}
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res);
- if( pOp->p4.i==0 ){
- sqlite3DbFree(db, pFree);
- }
+ sqlite3DbFree(db, pFree);
if( rc!=SQLITE_OK ){
break;
}
pC->seekResult = res;
alreadyExists = (res==0);
@@ -74558,14 +74736,14 @@
pC->nullRow = 1-alreadyExists;
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
if( pOp->opcode==OP_Found ){
VdbeBranchTaken(alreadyExists!=0,2);
- if( alreadyExists ) pc = pOp->p2 - 1;
+ if( alreadyExists ) goto jump_to_p2;
}else{
- VdbeBranchTaken(alreadyExists==0,2);
- if( !alreadyExists ) pc = pOp->p2 - 1;
+ VdbeBranchTaken(takeJump||alreadyExists==0,2);
+ if( takeJump || !alreadyExists ) goto jump_to_p2;
}
break;
}
/* Opcode: NotExists P1 P2 P3 * *
@@ -74610,14 +74788,12 @@
pC->movetoTarget = iKey; /* Used by OP_Delete */
pC->nullRow = 0;
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;
}
/* Opcode: Sequence P1 P2 * * *
** Synopsis: r[P2]=cursor[P1].ctr++
@@ -74625,13 +74801,14 @@
** Find the next available sequence number for cursor P1.
** Write the sequence number into register P2.
** The sequence number on the cursor is incremented after this
** instruction.
*/
-case OP_Sequence: { /* out2-prerelease */
+case OP_Sequence: { /* out2 */
assert( pOp->p1>=0 && pOp->p1nCursor );
assert( p->apCsr[pOp->p1]!=0 );
+ pOut = out2Prerelease(p, pOp);
pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
break;
}
@@ -74648,20 +74825,21 @@
** allowed to be less than this value. When this value reaches its maximum,
** an SQLITE_FULL error is generated. The P3 register is updated with the '
** generated record number. This P3 mechanism is used to help implement the
** AUTOINCREMENT feature.
*/
-case OP_NewRowid: { /* out2-prerelease */
+case OP_NewRowid: { /* out2 */
i64 v; /* The new rowid */
VdbeCursor *pC; /* Cursor of table to get the new rowid */
int res; /* Result of an sqlite3BtreeLast() */
int cnt; /* Counter to limit the number of searches */
Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */
VdbeFrame *pFrame; /* Root frame of VDBE */
v = 0;
res = 0;
+ pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
if( NEVER(pC->pCursor==0) ){
/* The zero initialization above is all that is needed */
@@ -74971,13 +75149,11 @@
pIn3 = &aMem[pOp->p3];
nKeyCol = pOp->p4.i;
res = 0;
rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
VdbeBranchTaken(res!=0,2);
- if( res ){
- pc = pOp->p2-1;
- }
+ if( res ) goto jump_to_p2;
break;
};
/* Opcode: SorterData P1 P2 P3 * *
** Synopsis: r[P2]=data
@@ -75102,16 +75278,17 @@
**
** P1 can be either an ordinary table or a virtual table. There used to
** be a separate OP_VRowid opcode for use with virtual tables, but this
** one opcode now works for both table types.
*/
-case OP_Rowid: { /* out2-prerelease */
+case OP_Rowid: { /* out2 */
VdbeCursor *pC;
i64 v;
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
+ pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->pseudoTableReg==0 || pC->nullRow );
if( pC->nullRow ){
@@ -75160,11 +75337,11 @@
sqlite3BtreeClearCursor(pC->pCursor);
}
break;
}
-/* Opcode: Last P1 P2 * * *
+/* Opcode: Last P1 P2 P3 * *
**
** 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.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
@@ -75187,16 +75364,17 @@
assert( pCrsr!=0 );
rc = sqlite3BtreeLast(pCrsr, &res);
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 ) pc = pOp->p2 - 1;
+ if( res ) goto jump_to_p2;
}
break;
}
@@ -75256,13 +75434,11 @@
pC->cacheStatus = CACHE_STALE;
}
pC->nullRow = (u8)res;
assert( pOp->p2>0 && pOp->p2nOp );
VdbeBranchTaken(res!=0,2);
- if( res ){
- pc = pOp->p2 - 1;
- }
+ if( res ) goto jump_to_p2;
break;
}
/* Opcode: Next P1 P2 P3 P4 P5
**
@@ -75369,15 +75545,15 @@
next_tail:
pC->cacheStatus = CACHE_STALE;
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;
}
goto check_for_interrupt;
}
@@ -75481,15 +75657,16 @@
** the end of the index key pointed to by cursor P1. This integer should be
** the rowid of the table entry to which this index entry points.
**
** See also: Rowid, MakeRecord.
*/
-case OP_IdxRowid: { /* out2-prerelease */
+case OP_IdxRowid: { /* out2 */
BtCursor *pCrsr;
VdbeCursor *pC;
i64 rowid;
+ pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
pCrsr = pC->pCursor;
assert( pCrsr!=0 );
@@ -75598,13 +75775,11 @@
}else{
assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT );
res++;
}
VdbeBranchTaken(res>0,2);
- if( res>0 ){
- pc = pOp->p2 - 1 ;
- }
+ if( res>0 ) goto jump_to_p2;
break;
}
/* Opcode: Destroy P1 P2 P3 * *
**
@@ -75624,15 +75799,16 @@
** the last one in the database) then a zero is stored in register P2.
** If AUTOVACUUM is disabled then a zero is stored in register P2.
**
** See also: Clear
*/
-case OP_Destroy: { /* out2-prerelease */
+case OP_Destroy: { /* out2 */
int iMoved;
int iDb;
assert( p->readOnly==0 );
+ pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Null;
if( db->nVdbeRead > db->nVDestroy+1 ){
rc = SQLITE_LOCKED;
p->errorAction = OE_Abort;
}else{
@@ -75737,16 +75913,17 @@
** P1>1. Write the root page number of the new table into
** register P2.
**
** See documentation on OP_CreateTable for additional information.
*/
-case OP_CreateIndex: /* out2-prerelease */
-case OP_CreateTable: { /* out2-prerelease */
+case OP_CreateIndex: /* out2 */
+case OP_CreateTable: { /* out2 */
int pgno;
int flags;
Db *pDb;
+ pOut = out2Prerelease(p, pOp);
pgno = 0;
assert( pOp->p1>=0 && pOp->p1nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) );
assert( p->readOnly==0 );
pDb = &db->aDb[pOp->p1];
@@ -75968,16 +76145,16 @@
if( (pIn1->flags & MEM_RowSet)==0
|| sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
){
/* 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 */
- sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
VdbeBranchTaken(0,2);
+ sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
}
goto check_for_interrupt;
}
/* Opcode: RowSetTest P1 P2 P3 P4
@@ -76024,14 +76201,11 @@
assert( pOp->p4type==P4_INT32 );
assert( iSet==-1 || iSet>=0 );
if( iSet ){
exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
VdbeBranchTaken(exists!=0,2);
- if( exists ){
- pc = pOp->p2 - 1;
- break;
- }
+ if( exists ) goto jump_to_p2;
}
if( iSet>=0 ){
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
}
break;
@@ -76116,11 +76290,11 @@
pRt->u.pFrame = pFrame;
pFrame->v = p;
pFrame->nChildMem = nMem;
pFrame->nChildCsr = pProgram->nCsr;
- pFrame->pc = pc;
+ pFrame->pc = (int)(pOp - aOp);
pFrame->aMem = p->aMem;
pFrame->nMem = p->nMem;
pFrame->apCsr = p->apCsr;
pFrame->nCursor = p->nCursor;
pFrame->aOp = p->aOp;
@@ -76139,11 +76313,11 @@
}
}else{
pFrame = pRt->u.pFrame;
assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
assert( pProgram->nCsr==pFrame->nChildCsr );
- assert( pc==pFrame->pc );
+ assert( (int)(pOp - aOp)==pFrame->pc );
}
p->nFrame++;
pFrame->pParent = p->pFrame;
pFrame->lastRowid = lastRowid;
@@ -76160,11 +76334,11 @@
p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
p->nOnceFlag = pProgram->nOnce;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
p->anExec = 0;
#endif
- pc = -1;
+ pOp = &aOp[-1];
memset(p->aOnceFlag, 0, p->nOnceFlag);
break;
}
@@ -76178,13 +76352,14 @@
**
** The address of the cell in the parent frame is determined by adding
** the value of the P1 argument to the value of the P1 argument to the
** calling OP_Program instruction.
*/
-case OP_Param: { /* out2-prerelease */
+case OP_Param: { /* out2 */
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);
break;
}
@@ -76224,14 +76399,14 @@
** (immediate foreign key constraint violations).
*/
case OP_FkIfZero: { /* jump */
if( pOp->p1 ){
VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2);
- if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
+ if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
}else{
VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2);
- if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
+ if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
}
break;
}
#endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */
@@ -76278,13 +76453,11 @@
*/
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 ){
- pc = pOp->p2 - 1;
- }
+ if( pIn1->u.i>0 ) goto jump_to_p2;
break;
}
/* Opcode: IfNeg P1 P2 P3 * *
** Synopsis: r[P1]+=P3, if r[P1]<0 goto P2
@@ -76295,13 +76468,11 @@
case OP_IfNeg: { /* 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 ){
- pc = pOp->p2 - 1;
- }
+ 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
@@ -76314,11 +76485,11 @@
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
VdbeBranchTaken(pIn1->u.i<0, 2);
if( pIn1->u.i ){
pIn1->u.i += pOp->p3;
- pc = pOp->p2 - 1;
+ goto jump_to_p2;
}
break;
}
/* Opcode: DecrJumpZero P1 P2 * * *
@@ -76330,13 +76501,11 @@
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 ){
- pc = pOp->p2 - 1;
- }
+ if( pIn1->u.i==0 ) goto jump_to_p2;
break;
}
/* Opcode: JumpZeroIncr P1 P2 * * *
@@ -76348,13 +76517,11 @@
*/
case OP_JumpZeroIncr: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
VdbeBranchTaken(pIn1->u.i==0, 2);
- if( (pIn1->u.i++)==0 ){
- pc = pOp->p2 - 1;
- }
+ if( (pIn1->u.i++)==0 ) goto jump_to_p2;
break;
}
/* Opcode: AggStep * P2 P3 P4 P5
** Synopsis: accum=r[P3] step(r[P2@P5])
@@ -76392,11 +76559,11 @@
pMem->n++;
sqlite3VdbeMemInit(&t, db, MEM_Null);
ctx.pOut = &t;
ctx.isError = 0;
ctx.pVdbe = p;
- ctx.iOp = pc;
+ ctx.iOp = (int)(pOp - aOp);
ctx.skipFlag = 0;
(ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
if( ctx.isError ){
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
rc = ctx.isError;
@@ -76487,19 +76654,20 @@
**
** If changing into or out of WAL mode the procedure is more complicated.
**
** Write a string containing the final journal-mode to register P2.
*/
-case OP_JournalMode: { /* out2-prerelease */
+case OP_JournalMode: { /* out2 */
Btree *pBt; /* Btree to change journal mode of */
Pager *pPager; /* Pager associated with pBt */
int eNew; /* New journal mode */
int eOld; /* The old journal mode */
#ifndef SQLITE_OMIT_WAL
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
|| eNew==PAGER_JOURNALMODE_PERSIST
|| eNew==PAGER_JOURNALMODE_OFF
@@ -76571,11 +76739,10 @@
if( rc ){
eNew = eOld;
}
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);
pOut->enc = SQLITE_UTF8;
sqlite3VdbeChangeEncoding(pOut, encoding);
@@ -76612,12 +76779,12 @@
assert( p->readOnly==0 );
pBt = db->aDb[pOp->p1].pBt;
rc = sqlite3BtreeIncrVacuum(pBt);
VdbeBranchTaken(rc==SQLITE_DONE,2);
if( rc==SQLITE_DONE ){
- pc = pOp->p2 - 1;
rc = SQLITE_OK;
+ goto jump_to_p2;
}
break;
}
#endif
@@ -76766,12 +76933,13 @@
pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
if( pCur ){
pCur->pVtabCursor = pVtabCursor;
pVtab->nRef++;
}else{
- db->mallocFailed = 1;
+ assert( db->mallocFailed );
pModule->xClose(pVtabCursor);
+ goto no_mem;
}
}
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -76823,29 +76991,23 @@
assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
nArg = (int)pArgc->u.i;
iQuery = (int)pQuery->u.i;
/* Invoke the xFilter method */
- {
- res = 0;
- apArg = p->apArg;
- for(i = 0; ixFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
- sqlite3VtabImportErrmsg(p, pVtab);
- if( rc==SQLITE_OK ){
- res = pModule->xEof(pVtabCursor);
- }
- VdbeBranchTaken(res!=0,2);
- if( res ){
- pc = pOp->p2 - 1;
- }
+ res = 0;
+ apArg = p->apArg;
+ for(i = 0; ixFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
+ sqlite3VtabImportErrmsg(p, pVtab);
+ if( rc==SQLITE_OK ){
+ res = pModule->xEof(pVtabCursor);
}
pCur->nullRow = 0;
-
+ VdbeBranchTaken(res!=0,2);
+ if( res ) goto jump_to_p2;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -76928,11 +77090,11 @@
res = pModule->xEof(pCur->pVtabCursor);
}
VdbeBranchTaken(!res,2);
if( !res ){
/* If there is data, jump to P2 */
- pc = pOp->p2 - 1;
+ goto jump_to_p2_and_check_for_interrupt;
}
goto check_for_interrupt;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -77051,11 +77213,12 @@
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/* Opcode: Pagecount P1 P2 * * *
**
** Write the current number of pages in database P1 to memory cell P2.
*/
-case OP_Pagecount: { /* out2-prerelease */
+case OP_Pagecount: { /* out2 */
+ pOut = out2Prerelease(p, pOp);
pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt);
break;
}
#endif
@@ -77067,14 +77230,15 @@
** Do not let the maximum page count fall below the current page count and
** do not change the maximum page count value if P3==0.
**
** Store the maximum page count after the change in register P2.
*/
-case OP_MaxPgcnt: { /* out2-prerelease */
+case OP_MaxPgcnt: { /* out2 */
unsigned int newMax;
Btree *pBt;
+ pOut = out2Prerelease(p, pOp);
pBt = db->aDb[pOp->p1].pBt;
newMax = 0;
if( pOp->p3 ){
newMax = sqlite3BtreeLastPage(pBt);
if( newMax < (unsigned)pOp->p3 ) newMax = (unsigned)pOp->p3;
@@ -77099,13 +77263,10 @@
*/
case OP_Init: { /* jump */
char *zTrace;
char *z;
- if( pOp->p2 ){
- pc = pOp->p2 - 1;
- }
#ifndef SQLITE_OMIT_TRACE
if( db->xTrace
&& !p->doingRerun
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
@@ -77129,10 +77290,11 @@
){
sqlite3DebugPrintf("SQL-trace: %s\n", zTrace);
}
#endif /* SQLITE_DEBUG */
#endif /* SQLITE_OMIT_TRACE */
+ if( pOp->p2 ) goto jump_to_p2;
break;
}
/* Opcode: Noop * * * * *
@@ -77160,31 +77322,31 @@
}
#ifdef VDBE_PROFILE
{
u64 endTime = sqlite3Hwtime();
- if( endTime>start ) pOp->cycles += endTime - start;
- pOp->cnt++;
+ if( endTime>start ) pOrigOp->cycles += endTime - start;
+ pOrigOp->cnt++;
}
#endif
/* The following code adds nothing to the actual functionality
** of the program. It is only here for testing and debugging.
** On the other hand, it does burn CPU cycles every time through
** the evaluator loop. So we can leave it out when NDEBUG is defined.
*/
#ifndef NDEBUG
- assert( pc>=-1 && pcnOp );
+ assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] );
#ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){
if( rc!=0 ) printf("rc=%d\n",rc);
- if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){
- registerTrace(pOp->p2, &aMem[pOp->p2]);
+ if( pOrigOp->opflags & (OPFLG_OUT2) ){
+ registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
}
- if( pOp->opflags & OPFLG_OUT3 ){
- registerTrace(pOp->p3, &aMem[pOp->p3]);
+ if( pOrigOp->opflags & OPFLG_OUT3 ){
+ registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
}
}
#endif /* SQLITE_DEBUG */
#endif /* NDEBUG */
} /* The end of the for(;;) loop the loops through opcodes */
@@ -77195,11 +77357,11 @@
vdbe_error_halt:
assert( rc );
p->rc = rc;
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
- pc, p->zSql, p->zErrMsg);
+ (int)(pOp - aOp), p->zSql, p->zErrMsg);
sqlite3VdbeHalt(p);
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
rc = SQLITE_ERROR;
if( resetSchemaOnFault>0 ){
sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
@@ -78021,20 +78183,23 @@
**
** In both cases, the effects of the main thread seeing (bDone==0) even
** 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 */
VdbeSorter *pSorter; /* Sorter that owns this sub-task */
UnpackedRecord *pUnpacked; /* Space to unpack a record */
SorterList list; /* List for thread to write to a PMA */
int nPMA; /* Number of PMAs currently in file */
+ SorterCompare xCompare; /* Compare function to use */
SorterFile file; /* Temp file for level-0 PMAs */
SorterFile file2; /* Space for other PMAs */
};
+
/*
** Main sorter structure. A single instance of this is allocated for each
** sorter cursor created by the VDBE.
**
@@ -78058,12 +78223,16 @@
int nMemory; /* Size of list.aMemory allocation in bytes */
u8 bUsePMA; /* True if one or more PMAs created */
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.
** aKey might point into aMap or into aBuffer. If neither of those locations
@@ -78472,35 +78641,165 @@
rc = vdbePmaReaderNext(pReadr);
}
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.
**
-** 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 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.
**
** 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( pKey2 ){
+ if( !*pbKey2Cached ){
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; i7 ){
+ 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)
@@ -78565,13 +78864,17 @@
rc = SQLITE_NOMEM;
}else{
pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
pKeyInfo->db = 0;
- if( nField && nWorker==0 ) pKeyInfo->nField = nField;
+ if( nField && nWorker==0 ){
+ pKeyInfo->nXField += (pKeyInfo->nField - nField);
+ 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; inTask; i++){
SortSubtask *pTask = &pSorter->aTask[i];
pTask->pSorter = pSorter;
@@ -78593,10 +78896,16 @@
pSorter->nMemory = pgsz;
pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
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;
}
#undef nWorker /* Defined at the top of this function */
@@ -78617,34 +78926,28 @@
** Free all resources owned by the object indicated by argument pTask. All
** fields of *pTask are zeroed before returning.
*/
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
static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){
i64 t;
@@ -78820,10 +79123,11 @@
vdbeMergeEngineFree(pSorter->pMerger);
pSorter->pMerger = 0;
for(i=0; inTask; i++){
SortSubtask *pTask = &pSorter->aTask[i];
vdbeSortSubtaskCleanup(db, pTask);
+ pTask->pSorter = pSorter;
}
if( pSorter->list.aMemory==0 ){
vdbeSorterRecordFree(0, pSorter->list.pList);
}
pSorter->list.pList = 0;
@@ -78929,31 +79233,45 @@
SorterRecord *p2, /* Second list to merge */
SorterRecord **ppOut /* OUT: Head of merged list */
){
SorterRecord *pFinal = 0;
SorterRecord **pp = &pFinal;
- void *pVal2 = p2 ? SRVAL(p2) : 0;
+ int bCached = 0;
while( p1 && p2 ){
int res;
- res = vdbeSorterCompare(pTask, SRVAL(p1), p1->nVal, pVal2, p2->nVal);
+ res = pTask->xCompare(
+ pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), 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;
- if( p2==0 ) break;
- pVal2 = SRVAL(p2);
+ bCached = 0;
}
}
*pp = p1 ? p1 : p2;
*ppOut = pFinal;
}
+
+/*
+** 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.
@@ -78965,16 +79283,18 @@
int rc;
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 ){
if( (u8*)p==pList->aMemory ){
pNext = 0;
@@ -79184,28 +79504,27 @@
/* Update contents of aTree[] */
if( rc==SQLITE_OK ){
int i; /* Index of aTree[] to recalculate */
PmaReader *pReadr1; /* First PmaReader to compare */
PmaReader *pReadr2; /* Second PmaReader to compare */
- u8 *pKey2; /* To pReadr2->aKey, or 0 if record cached */
+ int bCached = 0;
/* 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. */
int iRes;
if( pReadr1->pFd==0 ){
iRes = +1;
}else if( pReadr2->pFd==0 ){
iRes = -1;
}else{
- iRes = vdbeSorterCompare(pTask,
- pReadr1->aKey, pReadr1->nKey, pKey2, pReadr2->nKey
+ iRes = pTask->xCompare(pTask, &bCached,
+ pReadr1->aKey, pReadr1->nKey, pReadr2->aKey, pReadr2->nKey
);
}
/* If pReadr1 contained the smaller value, set aTree[i] to its index.
** Then set pReadr2 to the next PmaReader to compare to pReadr1. In this
@@ -79223,13 +79542,13 @@
** is sorted from oldest to newest, so pReadr1 contains older values
** than pReadr2 iff (pReadr1aTree[i] = (int)(pReadr1 - pMerger->aReadr);
pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
- pKey2 = pReadr2->aKey;
+ bCached = 0;
}else{
- if( pReadr1->pFd ) pKey2 = 0;
+ if( pReadr1->pFd ) bCached = 0;
pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr);
pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
}
}
*pbEof = (pMerger->aReadr[pMerger->aTree[1]].pFd==0);
@@ -79332,10 +79651,20 @@
SorterRecord *pNew; /* New list element */
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 );
/* Figure out whether or not the current contents of memory should be
** flushed to a PMA before continuing. If so, do so.
@@ -79597,14 +79926,16 @@
if( p1->pFd==0 ){
iRes = i2;
}else if( p2->pFd==0 ){
iRes = i1;
}else{
+ SortSubtask *pTask = pMerger->pTask;
+ int bCached = 0;
int res;
- assert( pMerger->pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */
- res = vdbeSorterCompare(
- pMerger->pTask, p1->aKey, p1->nKey, p2->aKey, p2->nKey
+ assert( pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */
+ res = pTask->xCompare(
+ pTask, &bCached, p1->aKey, p1->nKey, p2->aKey, p2->nKey
);
if( res<=0 ){
iRes = i1;
}else{
iRes = i2;
@@ -79624,15 +79955,16 @@
*/
#define INCRINIT_NORMAL 0
#define INCRINIT_TASK 1
#define INCRINIT_ROOT 2
-/* Forward reference.
-** The vdbeIncrMergeInit() and vdbePmaReaderIncrMergeInit() routines call each
-** other (when building a merge tree).
+/*
+** Forward reference required as the vdbeIncrMergeInit() and
+** vdbePmaReaderIncrInit() routines are called mutually recursively when
+** building a merge tree.
*/
-static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode);
+static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode);
/*
** Initialize the MergeEngine object passed as the second argument. Once this
** function returns, the first key of merged data may be read from the
** MergeEngine object in the usual fashion.
@@ -79675,11 +80007,11 @@
** the main thread to fill its buffer. So calling PmaReaderNext()
** on this PmaReader before any of the multi-threaded PmaReaders takes
** better advantage of multi-processor hardware. */
rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]);
}else{
- rc = vdbePmaReaderIncrMergeInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
+ rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
}
if( rc!=SQLITE_OK ) return rc;
}
for(i=pMerger->nTree-1; i>0; i--){
@@ -79687,21 +80019,19 @@
}
return pTask->pUnpacked->errCode;
}
/*
-** 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
+** 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
** 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
** background thread. In this case all PmaReaders in the sub-tree are
** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to
@@ -79724,93 +80054,112 @@
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
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 );
- if( pIncr ){
- SortSubtask *pTask = pIncr->pTask;
- sqlite3 *db = pTask->pSorter->db;
-
- 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
-#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 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. 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);
- }
- }
+ 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
+#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 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);
+ }
+#endif
+
+ if( rc==SQLITE_OK && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) ){
+ rc = vdbePmaReaderNext(pReadr);
+ }
+
return rc;
}
#if SQLITE_MAX_WORKER_THREADS>0
/*
** The main routine for vdbePmaReaderIncrMergeInit() operations run in
** background threads.
*/
-static void *vdbePmaReaderBgInit(void *pCtx){
+static void *vdbePmaReaderBgIncrInit(void *pCtx){
PmaReader *pReader = (PmaReader*)pCtx;
void *pRet = SQLITE_INT_TO_PTR(
vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK)
);
pReader->pIncr->pTask->bDone = 1;
return pRet;
}
+#endif
/*
-** 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].
+** 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.
*/
-static int vdbePmaReaderBgIncrInit(PmaReader *pReadr){
- void *pCtx = (void*)pReadr;
- return vdbeSorterCreateThread(pReadr->pIncr->pTask, vdbePmaReaderBgInit, pCtx);
+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;
}
-#endif
/*
** Allocate a new MergeEngine object to merge the contents of nPMA level-0
** PMAs from pTask->file. If no error occurs, set *ppOut to point to
** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut
@@ -80018,10 +80367,15 @@
int rc; /* Return code */
SortSubtask *pTask0 = &pSorter->aTask[0];
MergeEngine *pMain = 0;
#if SQLITE_MAX_WORKER_THREADS
sqlite3 *db = pTask0->pSorter->db;
+ int i;
+ SorterCompare xCompare = vdbeSorterGetCompare(pSorter);
+ for(i=0; inTask; i++){
+ pSorter->aTask[i].xCompare = xCompare;
+ }
#endif
rc = vdbeSorterMergeTreeBuild(pSorter, &pMain);
if( rc==SQLITE_OK ){
#if SQLITE_MAX_WORKER_THREADS
@@ -80046,19 +80400,25 @@
vdbeIncrMergerSetThreads(pIncr);
assert( pIncr->pTask!=pLast );
}
}
for(iTask=0; rc==SQLITE_OK && iTasknTask; 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] );
- if( p->pIncr ){
- if( iTask==pSorter->nTask-1 ){
- rc = vdbePmaReaderIncrMergeInit(p, INCRINIT_TASK);
- }else{
- rc = vdbePmaReaderBgIncrInit(p);
- }
- }
+ 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);
}
}
pMain = 0;
}
if( rc==SQLITE_OK ){
@@ -81009,11 +81369,11 @@
** Should be transformed into:
**
** 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 usually value is
+** alias is removed from the original expression. The usual 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.
*/
static void resolveAlias(
@@ -81029,11 +81389,11 @@
sqlite3 *db; /* The database connection */
assert( iCol>=0 && iColnExpr );
pOrig = pEList->a[iCol].pExpr;
assert( pOrig!=0 );
- assert( pOrig->flags & EP_Resolved );
+ assert( (pOrig->flags & EP_Resolved)!=0 || zType[0]==0 );
db = pParse->db;
pDup = sqlite3ExprDup(db, pOrig, 0);
if( pDup==0 ) return;
if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
incrAggFunctionDepth(pDup, nSubquery);
@@ -81923,13 +82283,15 @@
pNew->flags |= EP_IntValue;
pNew->u.iValue = iCol;
if( pItem->pExpr==pE ){
pItem->pExpr = pNew;
}else{
- assert( pItem->pExpr->op==TK_COLLATE );
- assert( pItem->pExpr->pLeft==pE );
- pItem->pExpr->pLeft = pNew;
+ 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;
}
sqlite3ExprDelete(db, pE);
pItem->u.x.iOrderByCol = (u16)iCol;
pItem->done = 1;
}else{
@@ -82125,11 +82487,11 @@
** 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 && isCompound==0 && p->pOrderBy );
+ assert( p->pSrc->nSrc==1 && p->pOrderBy );
assert( pSub->pPrior && pSub->pOrderBy==0 );
pSub->pOrderBy = p->pOrderBy;
p->pOrderBy = 0;
}
@@ -82227,12 +82589,19 @@
/* 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 && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){
+ if( isCompound<=nCompound /* Defer right-most ORDER BY of a compound */
+ && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER")
+ ){
return WRC_Abort;
}
if( db->mallocFailed ){
return WRC_Abort;
}
@@ -83680,11 +84049,12 @@
SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){
int i;
u32 m = 0;
if( pList ){
for(i=0; inExpr; i++){
- m |= pList->a[i].pExpr->flags;
+ Expr *pExpr = pList->a[i].pExpr;
+ if( ALWAYS(pExpr) ) m |= pExpr->flags;
}
}
return m;
}
@@ -84120,11 +84490,11 @@
/* Check to see if an existing table or index can be used to
** satisfy the query. This is preferable to generating a new
** ephemeral table.
*/
p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
- if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
+ if( pParse->nErr==0 && isCandidateForInOpt(p) ){
sqlite3 *db = pParse->db; /* Database connection */
Table *pTab; /* Table . */
Expr *pExpr; /* Expression */
i16 iCol; /* Index of column */
i16 iDb; /* Database idx for pTab */
@@ -84445,10 +84815,11 @@
}
sqlite3ExprDelete(pParse->db, pSel->pLimit);
pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
&sqlite3IntTokens[1]);
pSel->iLimit = 0;
+ pSel->selFlags &= ~SF_MultiValue;
if( sqlite3Select(pParse, pSel, &dest) ){
return 0;
}
rReg = dest.iSDParm;
ExprSetVVAProperty(pExpr, EP_NoReduce);
@@ -85810,11 +86181,11 @@
sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
break;
}
case TK_ID: {
- sqlite3TreeViewLine(pView,"ID %Q", pExpr->u.zToken);
+ sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
break;
}
#ifndef SQLITE_OMIT_CAST
case TK_CAST: {
/* Expressions of the form: CAST(pLeft AS token) */
@@ -86445,11 +86816,11 @@
if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
if( combinedFlags & EP_xIsSelect ) return 2;
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) ){
+ if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){
if( pA->iColumn!=pB->iColumn ) return 2;
if( pA->iTable!=pB->iTable
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
}
}
@@ -86977,10 +87348,11 @@
do {
z += n;
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);
if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){
char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"",
@@ -89203,18 +89575,21 @@
pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
}
z = argv[2];
if( pIndex ){
+ tRowcnt *aiRowEst = 0;
int nCol = pIndex->nKeyCol+1;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
- tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(
- sizeof(tRowcnt) * nCol
- );
- if( aiRowEst==0 ) pInfo->db->mallocFailed = 1;
-#else
- tRowcnt * const aiRowEst = 0;
+ /* 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;
#endif
pIndex->bUnordered = 0;
decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
}else{
@@ -89873,11 +90248,11 @@
}
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
- sqlite3ResetAllSchemasOfConnection(db);
+ sqlite3CollapseDatabaseArray(db);
return;
detach_error:
sqlite3_result_error(context, zErr, -1);
}
@@ -89907,11 +90282,10 @@
if(
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
){
- pParse->nErr++;
goto attach_end;
}
#ifndef SQLITE_OMIT_AUTHORIZATION
if( pAuthArg ){
@@ -90566,13 +90940,15 @@
sqlite3 *db;
Vdbe *v;
assert( pParse->pToplevel==0 );
db = pParse->db;
- if( db->mallocFailed ) return;
if( pParse->nested ) return;
- if( pParse->nErr ) return;
+ if( db->mallocFailed || pParse->nErr ){
+ if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR;
+ return;
+ }
/* Begin by generating some termination code at the end of the
** vdbe program
*/
v = sqlite3GetVdbe(pParse);
@@ -90650,11 +91026,11 @@
}
/* Get the VDBE program ready for execution
*/
- if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){
+ if( v && 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] */
if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
sqlite3VdbeMakeReady(v, pParse);
@@ -91185,18 +91561,16 @@
sqlite3 *db = pParse->db;
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{
assert( db->init.iDb==0 || db->init.busy );
iDb = db->init.iDb;
@@ -91351,11 +91725,11 @@
pTable = sqlite3FindTable(db, zName, zDb);
if( pTable ){
if( !noErr ){
sqlite3ErrorMsg(pParse, "table %T already exists", pName);
}else{
- assert( !db->init.busy );
+ assert( !db->init.busy || CORRUPT_DB );
sqlite3CodeVerifySchema(pParse, iDb);
}
goto begin_table_error;
}
if( sqlite3FindIndex(db, zName, zDb)!=0 ){
@@ -91640,11 +92014,12 @@
Column *pCol;
p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return;
pCol = &p->aCol[p->nCol-1];
- assert( pCol->zType==0 );
+ assert( pCol->zType==0 || CORRUPT_DB );
+ sqlite3DbFree(pParse->db, pCol->zType);
pCol->zType = sqlite3NameFromToken(pParse->db, pType);
pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst);
}
/*
@@ -92874,10 +93249,11 @@
if( db->mallocFailed ){
goto exit_drop_table;
}
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--;
if( pTab==0 ){
@@ -93187,11 +93563,12 @@
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
}else{
addr2 = sqlite3VdbeCurrentAddr(v);
}
sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
- sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
+ sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1);
+ sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord);
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
@@ -93280,12 +93657,11 @@
int nExtra = 0; /* Space allocated for zExtra[] */
int nExtraCol; /* Number of extra columns needed */
char *zExtra = 0; /* Extra space after the Index object */
Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
- assert( pParse->nErr==0 ); /* Never called with prior errors */
- if( db->mallocFailed || IN_DECLARE_VTAB ){
+ if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){
goto exit_create_index;
}
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto exit_create_index;
}
@@ -94200,11 +94576,10 @@
** operator with A. This routine shifts that operator over to B.
*/
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;
}
p->a[0].jointype = 0;
}
@@ -94447,12 +94822,11 @@
char *zErr;
int j;
StrAccum errMsg;
Table *pTab = pIdx->pTable;
- sqlite3StrAccumInit(&errMsg, 0, 0, 200);
- errMsg.db = pParse->db;
+ sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
for(j=0; jnKeyCol; j++){
char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
sqlite3StrAccumAppendAll(&errMsg, pTab->zName);
sqlite3StrAccumAppend(&errMsg, ".", 1);
@@ -96277,17 +96651,17 @@
){
PrintfArguments x;
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, 0, 0, SQLITE_MAX_LENGTH);
- str.db = sqlite3_context_db_handle(context);
+ sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
n = str.nChar;
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
SQLITE_DYNAMIC);
}
@@ -96433,11 +96807,11 @@
sqlite3_result_double(context, r);
}
#endif
/*
-** Allocate nByte bytes of space using sqlite3_malloc(). If the
+** Allocate nByte bytes of space using sqlite3Malloc(). 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
** raise an SQLITE_TOOBIG exception and return NULL.
*/
@@ -97102,11 +97476,11 @@
int argc,
sqlite3_value **argv
){
unsigned char *z, *zOut;
int i;
- zOut = z = sqlite3_malloc( argc*4+1 );
+ zOut = z = sqlite3_malloc64( argc*4+1 );
if( z==0 ){
sqlite3_result_error_nomem(context);
return;
}
for(i=0; iuseMalloc==0;
- pAccum->useMalloc = 2;
+ int firstTerm = pAccum->mxAlloc==0;
pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
if( !firstTerm ){
if( argc==2 ){
zSep = (char*)sqlite3_value_text(argv[1]);
nSep = sqlite3_value_bytes(argv[1]);
@@ -99033,11 +99406,12 @@
int iFromCol; /* Idx of column in child table */
Expr *pEq; /* tFromCol = OLD.tToCol */
iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iFromCol>=0 );
- tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid";
+ assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKeynCol) );
+ tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName;
tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
tToCol.n = sqlite3Strlen30(tToCol.z);
tFromCol.n = sqlite3Strlen30(tFromCol.z);
@@ -99045,14 +99419,14 @@
** that the "OLD.zToCol" term is on the LHS of the = operator, so
** that the affinity and collation sequence associated with the
** parent table are used for the comparison. */
pEq = sqlite3PExpr(pParse, TK_EQ,
sqlite3PExpr(pParse, TK_DOT,
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
+ sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
, 0),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol)
+ sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
, 0);
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
/* For ON UPDATE, construct the next term of the WHEN clause.
** The final WHEN clause will be like this:
@@ -99060,27 +99434,27 @@
** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
*/
if( pChanges ){
pEq = sqlite3PExpr(pParse, TK_IS,
sqlite3PExpr(pParse, TK_DOT,
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
+ sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
0),
sqlite3PExpr(pParse, TK_DOT,
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
+ sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
0),
0);
pWhen = sqlite3ExprAnd(db, pWhen, pEq);
}
if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
Expr *pNew;
if( action==OE_Cascade ){
pNew = sqlite3PExpr(pParse, TK_DOT,
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
+ sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
, 0);
}else if( action==OE_SetDflt ){
Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
if( pDflt ){
pNew = sqlite3ExprDup(db, pDflt, 0);
@@ -99123,17 +99497,16 @@
db->lookaside.bEnabled = 0;
pTrigger = (Trigger *)sqlite3DbMallocZero(db,
sizeof(Trigger) + /* struct Trigger */
sizeof(TriggerStep) + /* Single step in trigger program */
- nFrom + 1 /* Space for pStep->target.z */
+ nFrom + 1 /* Space for pStep->zTarget */
);
if( pTrigger ){
pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
- pStep->target.z = (char *)&pStep[1];
- pStep->target.n = nFrom;
- memcpy((char *)pStep->target.z, zFrom, nFrom);
+ pStep->zTarget = (char *)&pStep[1];
+ memcpy((char *)pStep->zTarget, zFrom, nFrom);
pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
if( pWhen ){
@@ -99594,24 +99967,27 @@
);
/*
** This routine is called to handle SQL of the following forms:
**
-** insert into TABLE (IDLIST) values(EXPRLIST)
+** insert into TABLE (IDLIST) values(EXPRLIST),(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 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 (non-hidden) columns for the table is substituted.
+** The IDLIST appears in the pColumn parameter. pColumn is NULL if IDLIST
+** is omitted.
**
-** 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.
+** 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 code generated follows one of four templates. For a simple
-** insert with data coming from a VALUES clause, the code executes
+** insert with data coming from a single-row VALUES clause, the code executes
** once straight down through. Pseudo-code follows (we call this
** the "1st template"):
**
** open write cursor to and its indices
** put VALUES clause expressions into registers
@@ -99714,11 +100090,11 @@
int iDb; /* Index of database holding TABLE */
Db *pDb; /* The database containing table being inserted into */
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 = 1; /* True if IDLIST is in table order */
+ u8 bIdListInOrder; /* True if IDLIST is in table order */
ExprList *pList = 0; /* List of VALUES() to be inserted */
/* Register allocations */
int regFromSelect = 0;/* Base register for data coming from SELECT */
int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */
@@ -99739,12 +100115,12 @@
if( pParse->nErr || db->mallocFailed ){
goto insert_cleanup;
}
/* If the Select object is really just a simple VALUES() list with a
- ** single row values (the common case) then keep that one row of values
- ** and go ahead and discard the Select object
+ ** single row (the common case) then keep that one row of values
+ ** and discard the other (unused) parts of the pSelect object
*/
if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){
pList = pSelect->pEList;
pSelect->pEList = 0;
sqlite3SelectDelete(db, pSelect);
@@ -99848,10 +100224,11 @@
** the index into IDLIST of the primary key column. ipkColumn is
** the index of the primary key as it appears in IDLIST, not as
** 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; inId; i++){
pColumn->a[i].idx = -1;
}
for(i=0; inId; i++){
@@ -99883,11 +100260,12 @@
** is coming from a SELECT statement, then generate a co-routine that
** produces a single row of the SELECT on each invocation. The
** co-routine is the common header to the 3rd and 4th templates.
*/
if( pSelect ){
- /* Data is coming from a SELECT. Generate a co-routine to run the SELECT */
+ /* Data is coming from a SELECT or from a multi-row VALUES clause.
+ ** 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 */
regYield = ++pParse->nMem;
@@ -99896,12 +100274,11 @@
sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
dest.iSdst = bIdListInOrder ? regData : 0;
dest.nSdst = pTab->nCol;
rc = sqlite3Select(pParse, pSelect, &dest);
regFromSelect = dest.iSdst;
- assert( pParse->nErr==0 || rc );
- if( rc || db->mallocFailed ) goto insert_cleanup;
+ if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
assert( pSelect->pEList );
nColumn = pSelect->pEList->nExpr;
@@ -99945,12 +100322,12 @@
sqlite3VdbeJumpHere(v, addrL);
sqlite3ReleaseTempReg(pParse, regRec);
sqlite3ReleaseTempReg(pParse, regTempRowid);
}
}else{
- /* This is the case if the data for the INSERT is coming from a VALUES
- ** clause
+ /* This is the case if the data for the INSERT is coming from a
+ ** single-row VALUES clause
*/
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
srcTab = -1;
@@ -101017,10 +101394,11 @@
Table *pDest, /* The table we are inserting into */
Select *pSelect, /* A SELECT statement to use as the data source */
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 */
struct SrcList_item *pItem; /* An element of pSelect->pSrc */
int i; /* Loop counter */
@@ -101164,15 +101542,15 @@
** But the main beneficiary of the transfer optimization is the VACUUM
** command, and the VACUUM command disables foreign key constraints. So
** the extra complication to make this rule less restrictive is probably
** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
*/
- if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
+ if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
return 0;
}
#endif
- if( (pParse->db->flags & SQLITE_CountRows)!=0 ){
+ if( (db->flags & SQLITE_CountRows)!=0 ){
return 0; /* xfer opt does not play well with PRAGMA count_changes */
}
/* If we get this far, it means that the xfer optimization is at
** least a possibility, though it might only work if the destination
@@ -101179,28 +101557,32 @@
** table (tab1) is initially empty.
*/
#ifdef SQLITE_TEST
sqlite3_xferopt_count++;
#endif
- iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema);
+ iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema);
v = sqlite3GetVdbe(pParse);
sqlite3CodeVerifySchema(pParse, iDbSrc);
iSrc = pParse->nTab++;
iDest = pParse->nTab++;
regAutoinc = autoIncBegin(pParse, iDbDest, pDest);
regData = sqlite3GetTempReg(pParse);
regRowid = sqlite3GetTempReg(pParse);
sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
assert( HasRowid(pDest) || destHasUniqueIdx );
- if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
+ if( (db->flags & SQLITE_Vacuum)==0 && (
+ (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. This code makes
- ** that determination. Conditions under which the destination must
- ** be empty:
+ ** 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:
**
** (1) There is no INTEGER PRIMARY KEY but there are indices.
** (If the destination is not initially empty, the rowid fields
** of index entries might need to change.)
**
@@ -101239,10 +101621,11 @@
}else{
sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName);
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;
}
assert( pSrcIdx );
sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc);
@@ -101252,11 +101635,37 @@
sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
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; inColumn; 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);
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}
@@ -102371,11 +102780,11 @@
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
char *zErrmsg = 0;
const char *zEntry;
char *zAltEntry = 0;
void **aHandle;
- int nMsg = 300 + sqlite3Strlen30(zFile);
+ u64 nMsg = 300 + sqlite3Strlen30(zFile);
int ii;
/* Shared library endings to try if zFile cannot be loaded as written */
static const char *azEndings[] = {
#if SQLITE_OS_WIN
@@ -102414,11 +102823,11 @@
sqlite3_free(zAltFile);
}
#endif
if( handle==0 ){
if( pzErrMsg ){
- *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
+ *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
if( zErrmsg ){
sqlite3_snprintf(nMsg, zErrmsg,
"unable to open shared library [%s]", zFile);
sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
}
@@ -102440,11 +102849,11 @@
** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init
*/
if( xInit==0 && zProc==0 ){
int iFile, iEntry, c;
int ncFile = sqlite3Strlen30(zFile);
- zAltEntry = sqlite3_malloc(ncFile+30);
+ zAltEntry = sqlite3_malloc64(ncFile+30);
if( zAltEntry==0 ){
sqlite3OsDlClose(pVfs, handle);
return SQLITE_NOMEM;
}
memcpy(zAltEntry, "sqlite3_", 8);
@@ -102462,11 +102871,11 @@
sqlite3OsDlSym(pVfs, handle, zEntry);
}
if( xInit==0 ){
if( pzErrMsg ){
nMsg += sqlite3Strlen30(zEntry);
- *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
+ *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
if( zErrmsg ){
sqlite3_snprintf(nMsg, zErrmsg,
"no entry point [%s] in shared library [%s]", zEntry, zFile);
sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
}
@@ -102561,11 +102970,11 @@
** This list is shared across threads. The SQLITE_MUTEX_STATIC_MASTER
** mutex must be held while accessing this list.
*/
typedef struct sqlite3AutoExtList sqlite3AutoExtList;
static SQLITE_WSD struct sqlite3AutoExtList {
- int nExt; /* Number of entries in aExt[] */
+ u32 nExt; /* Number of entries in aExt[] */
void (**aExt)(void); /* Pointers to the extension init functions */
} sqlite3Autoext = { 0, 0 };
/* The "wsdAutoext" macro will resolve to the autoextension
** state vector. If writable static data is unsupported on the target,
@@ -102594,23 +103003,23 @@
if( rc ){
return rc;
}else
#endif
{
- int i;
+ u32 i;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
wsdAutoextInit;
sqlite3_mutex_enter(mutex);
for(i=0; i=0; i--){
+ for(i=(int)wsdAutoext.nExt-1; i>=0; i--){
if( wsdAutoext.aExt[i]==xInit ){
wsdAutoext.nExt--;
wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
n++;
break;
@@ -102676,11 +103085,11 @@
** Load all automatic extensions.
**
** If anything goes wrong, set an error in the database connection.
*/
SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
- int i;
+ u32 i;
int go = 1;
int rc;
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
wsdAutoextInit;
@@ -103340,19 +103749,19 @@
/*
** Generate code to return a single integer value.
*/
static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
Vdbe *v = sqlite3GetVdbe(pParse);
- int mem = ++pParse->nMem;
+ int nMem = ++pParse->nMem;
i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value));
if( pI64 ){
memcpy(pI64, &value, sizeof(value));
}
- sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64);
+ sqlite3VdbeAddOp4(v, OP_Int64, 0, nMem, 0, (char*)pI64, P4_INT64);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
}
/*
** Set the safety_level and pager flags for pager iDb. Or if iDb<0
@@ -103513,15 +103922,15 @@
aFcntl[3] = 0;
db->busyHandler.nBusy = 0;
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
if( rc==SQLITE_OK ){
if( aFcntl[0] ){
- int mem = ++pParse->nMem;
- sqlite3VdbeAddOp4(v, OP_String8, 0, mem, 0, aFcntl[0], 0);
+ int nMem = ++pParse->nMem;
+ sqlite3VdbeAddOp4(v, OP_String8, 0, nMem, 0, aFcntl[0], 0);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
sqlite3_free(aFcntl[0]);
}
goto pragma_out;
}
if( rc!=SQLITE_NOTFOUND ){
@@ -104122,11 +104531,13 @@
}else{
if( !db->autoCommit ){
sqlite3ErrorMsg(pParse,
"Safety level may not be changed inside a transaction");
}else{
- pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
+ int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
+ if( iLevel==0 ) iLevel = 1;
+ pDb->safety_level = iLevel;
setAllPagerFlags(db);
}
}
break;
}
@@ -104217,11 +104628,11 @@
if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
k = 0;
}else if( pPk==0 ){
k = 1;
}else{
- for(k=1; ALWAYS(k<=pTab->nCol) && pPk->aiColumn[k-1]!=i; k++){}
+ for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
}
sqlite3VdbeAddOp2(v, OP_Integer, k, 6);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
}
}
@@ -105223,11 +105634,11 @@
assert( iDb>=0 && iDbnDb );
if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
if( argv[1]==0 ){
corruptSchema(pData, argv[0], 0);
- }else if( argv[2] && argv[2][0] ){
+ }else if( sqlite3_strnicmp(argv[2],"create ",7)==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
** structures that describe the table, index, or view.
*/
@@ -105254,12 +105665,12 @@
corruptSchema(pData, argv[0], sqlite3_errmsg(db));
}
}
}
sqlite3_finalize(pStmt);
- }else if( argv[0]==0 ){
- corruptSchema(pData, 0, 0);
+ }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){
+ corruptSchema(pData, argv[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
** constraint for a CREATE TABLE. The index should have already
** been created when we processed the CREATE TABLE. All we have
@@ -106162,11 +106573,10 @@
){
Select *pNew;
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;
memset(pNew, 0, sizeof(*pNew));
}
@@ -106182,11 +106592,11 @@
pNew->pOrderBy = pOrderBy;
pNew->selFlags = selFlags;
pNew->op = TK_SELECT;
pNew->pLimit = pLimit;
pNew->pOffset = pOffset;
- assert( pOffset==0 || pLimit!=0 );
+ assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
if( db->mallocFailed ) {
clearSelect(db, pNew, pNew!=&standin);
pNew = 0;
@@ -107432,11 +107842,11 @@
if( pS ){
/* The "table" is actually a sub-select or a view in the FROM clause
** of the SELECT statement. Return the declaration type and origin
** data for the result-set column of the sub-select.
*/
- if( iCol>=0 && ALWAYS(iColpEList->nExpr) ){
+ if( iCol>=0 && iColpEList->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.
*/
NameContext sNC;
@@ -107752,16 +108162,18 @@
memset(&sNC, 0, sizeof(sNC));
sNC.pSrcList = pSelect->pSrc;
a = pSelect->pEList->a;
for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){
p = a[i].pExpr;
- pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
+ if( pCol->zType==0 ){
+ 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 ){
+ if( pColl && pCol->zColl==0 ){
pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
}
}
pTab->szTabRow = sqlite3LogEst(szAll*4);
}
@@ -108159,12 +108571,11 @@
){
Select *pPrior;
int nExpr = p->pEList->nExpr;
int nRow = 1;
int rc = 0;
- assert( p->pNext==0 );
- assert( p->selFlags & SF_AllValues );
+ assert( p->selFlags & SF_MultiValue );
do{
assert( p->selFlags & SF_Values );
assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
assert( p->pLimit==0 );
assert( p->pOffset==0 );
@@ -108269,11 +108680,11 @@
dest.eDest = SRT_Table;
}
/* Special handling for a compound-select that originates as a VALUES clause.
*/
- if( p->selFlags & SF_AllValues ){
+ if( p->selFlags & SF_MultiValue ){
rc = multiSelectValues(pParse, p, &dest);
goto multi_select_end;
}
/* Make sure all SELECTs in the statement have the same number of elements
@@ -108654,11 +109065,11 @@
** then there should be a single item on the stack. Write this
** item into the set table with bogus data.
*/
case SRT_Set: {
int r1;
- assert( pIn->nSdst==1 );
+ assert( pIn->nSdst==1 || pParse->nErr>0 );
pDest->affSdst =
sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &pDest->affSdst,1);
sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1);
@@ -108680,11 +109091,11 @@
/* If this is a scalar select that is part of an expression, then
** store the results in the appropriate memory cell and break out
** of the scan loop.
*/
case SRT_Mem: {
- assert( pIn->nSdst==1 );
+ assert( pIn->nSdst==1 || pParse->nErr>0 ); testcase( pIn->nSdst!=1 );
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
/* The LIMIT clause will jump out of the loop for us */
break;
}
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
@@ -108695,11 +109106,11 @@
case SRT_Coroutine: {
if( pDest->iSdst==0 ){
pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
pDest->nSdst = pIn->nSdst;
}
- sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst);
+ sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst);
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
break;
}
/* If none of the above, then the result destination must be
@@ -108911,12 +109322,14 @@
*/
aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
if( aPermute ){
struct ExprList_item *pItem;
for(i=0, pItem=pOrderBy->a; iu.x.iOrderByCol>0
- && pItem->u.x.iOrderByCol<=p->pEList->nExpr );
+ 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 );
aPermute[i] = pItem->u.x.iOrderByCol - 1;
}
pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
}else{
pKeyMerge = 0;
@@ -109122,11 +109535,11 @@
pPrior->pNext = p;
/*** TBD: Insert subroutine calls to close cursors on incomplete
**** subqueries ****/
explainComposite(pParse, p->op, iSub1, iSub2, 0);
- return SQLITE_OK;
+ return pParse->nErr!=0;
}
#endif
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/* Forward Declarations */
@@ -109934,10 +110347,11 @@
pNew->pGroupBy = 0;
pNew->pHaving = 0;
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;
@@ -110472,11 +110886,11 @@
if( pParse->hasCompound ){
w.xSelectCallback = convertCompoundSelectToSubquery;
sqlite3WalkSelect(&w, pSelect);
}
w.xSelectCallback = selectExpander;
- if( (pSelect->selFlags & SF_AllValues)==0 ){
+ if( (pSelect->selFlags & SF_MultiValue)==0 ){
w.xSelectCallback2 = selectPopWith;
}
sqlite3WalkSelect(&w, pSelect);
}
@@ -110658,11 +111072,12 @@
nArg = 0;
regAgg = 0;
}
if( pF->iDistinct>=0 ){
addrNext = sqlite3VdbeMakeLabel(v);
- assert( nArg==1 );
+ testcase( nArg==0 ); /* Error condition */
+ testcase( nArg>1 ); /* Also an error */
codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
}
if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
CollSeq *pColl = 0;
struct ExprList_item *pItem;
@@ -111533,14 +111948,13 @@
/* Jump here to skip this query
*/
sqlite3VdbeResolveLabel(v, iEnd);
- /* The SELECT was successfully coded. Set the return code to 0
- ** to indicate no errors.
- */
- rc = 0;
+ /* 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);
/* Control jumps to here if an error is encountered above, or upon
** successful coding of the SELECT.
*/
select_end:
@@ -111587,11 +112001,11 @@
sqlite3TreeViewLine(pView, "FROM");
for(i=0; ipSrc->nSrc; i++){
struct SrcList_item *pItem = &p->pSrc->a[i];
StrAccum x;
char zLine[100];
- sqlite3StrAccumInit(&x, zLine, sizeof(zLine), 0);
+ sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
if( pItem->zDatabase ){
sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
}else if( pItem->zName ){
sqlite3XPrintf(&x, 0, " %s", pItem->zName);
@@ -111746,11 +112160,11 @@
for(i=0; iazResult[p->nData++] = z;
}
@@ -111795,11 +112209,11 @@
res.nRow = 0;
res.nColumn = 0;
res.nData = 1;
res.nAlloc = 20;
res.rc = SQLITE_OK;
- res.azResult = sqlite3_malloc(sizeof(char*)*res.nAlloc );
+ res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc );
if( res.azResult==0 ){
db->errCode = SQLITE_NOMEM;
return SQLITE_NOMEM;
}
res.azResult[0] = 0;
@@ -111823,11 +112237,11 @@
sqlite3_free_table(&res.azResult[1]);
return rc;
}
if( res.nAlloc>res.nData ){
char **azNew;
- azNew = sqlite3_realloc( res.azResult, sizeof(char*)*res.nData );
+ azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData );
if( azNew==0 ){
sqlite3_free_table(&res.azResult[1]);
db->errCode = SQLITE_NOMEM;
return SQLITE_NOMEM;
}
@@ -112051,11 +112465,10 @@
}
/* 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;
}
/* INSTEAD of triggers are only for views and views only support INSTEAD
** of triggers.
@@ -112231,16 +112644,16 @@
u8 op, /* Trigger opcode */
Token *pName /* The target name */
){
TriggerStep *pTriggerStep;
- pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
+ pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
if( pTriggerStep ){
char *z = (char*)&pTriggerStep[1];
memcpy(z, pName->z, pName->n);
- pTriggerStep->target.z = z;
- pTriggerStep->target.n = pName->n;
+ sqlite3Dequote(z);
+ pTriggerStep->zTarget = z;
pTriggerStep->op = op;
}
return pTriggerStep;
}
@@ -112519,11 +112932,11 @@
}
return (mask ? pList : 0);
}
/*
-** Convert the pStep->target token into a SrcList and return a pointer
+** Convert the pStep->zTarget string into a SrcList and return a pointer
** to that SrcList.
**
** This routine adds a specific database name, if needed, to the target when
** forming the SrcList. This prevents a trigger in one database from
** referring to a target in another database. An exception is when the
@@ -112532,21 +112945,21 @@
*/
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(pParse->db, 0, &pStep->target, 0);
+ pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
if( pSrc ){
assert( pSrc->nSrc>0 );
- assert( pSrc->a!=0 );
- iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
+ pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
+ iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
if( iDb==0 || iDb>=2 ){
- sqlite3 *db = pParse->db;
- assert( iDbdb->nDb );
+ assert( iDbnDb );
pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
}
}
return pSrc;
}
@@ -112654,10 +113067,11 @@
assert( pFrom->zErrMsg==0 || pFrom->nErr );
assert( pTo->zErrMsg==0 || pTo->nErr );
if( pTo->nErr==0 ){
pTo->zErrMsg = pFrom->zErrMsg;
pTo->nErr = pFrom->nErr;
+ pTo->rc = pFrom->rc;
}else{
sqlite3DbFree(pFrom->db, pFrom->zErrMsg);
}
}
@@ -114004,17 +114418,21 @@
/* Loop through the tables in the main database. For each, do
** 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) || ';'"
"FROM main.sqlite_master "
"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
*/
rc = execExecSql(db, pzErrMsg,
@@ -114149,10 +114567,12 @@
** are invoked only from within xCreate and xConnect methods.
*/
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 */
};
/*
** The actual function that does the work of creating a new module.
** This function implements the sqlite3_create_module() and
@@ -114595,11 +115015,11 @@
Token *pArg = &pParse->sArg;
if( pArg->z==0 ){
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);
}
}
/*
@@ -114612,19 +115032,31 @@
Table *pTab,
Module *pMod,
int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
char **pzErr
){
- VtabCtx sCtx, *pPriorCtx;
+ VtabCtx sCtx;
VTable *pVTable;
int rc;
const char *const*azArg = (const char *const*)pTab->azModuleArg;
int nArg = pTab->nModuleArg;
char *zErr = 0;
- char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
+ char *zModuleName;
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;
}
pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
@@ -114641,15 +115073,17 @@
/* Invoke the virtual table constructor */
assert( &db->pVtabCtx );
assert( xConstruct );
sCtx.pTab = pTab;
sCtx.pVTable = pVTable;
- pPriorCtx = db->pVtabCtx;
+ sCtx.pPrior = db->pVtabCtx;
+ sCtx.bDeclared = 0;
db->pVtabCtx = &sCtx;
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
- db->pVtabCtx = pPriorCtx;
+ db->pVtabCtx = sCtx.pPrior;
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
+ assert( sCtx.pTab==pTab );
if( SQLITE_OK!=rc ){
if( zErr==0 ){
*pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
}else {
@@ -114661,17 +115095,18 @@
/* Justification of ALWAYS(): A correct vtab constructor must allocate
** the sqlite3_vtab object if successful. */
memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
pVTable->pVtab->pModule = pMod->pModule;
pVTable->nRef = 1;
- if( sCtx.pTab ){
+ if( sCtx.bDeclared==0 ){
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".
** If so, set the Column COLFLAG_HIDDEN flag and remove the token from
** the type string. */
@@ -114680,11 +115115,14 @@
for(iCol=0; iColnCol; iCol++){
char *zType = pTab->aCol[iCol].zType;
int nType;
int i = 0;
- if( !zType ) continue;
+ if( !zType ){
+ pTab->tabFlags |= oooHidden;
+ continue;
+ }
nType = sqlite3Strlen30(zType);
if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
for(i=0; i0 ){
assert(zType[i-1]==' ');
zType[i-1] = '\0';
}
pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
+ oooHidden = TF_OOOHidden;
+ }else{
+ pTab->tabFlags |= oooHidden;
}
}
}
}
@@ -114831,12 +115272,12 @@
** This function is used to set the schema of a virtual table. It is only
** 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;
Parse *pParse;
-
int rc = SQLITE_OK;
Table *pTab;
char *zErr = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -114843,15 +115284,17 @@
if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
sqlite3_mutex_enter(db->mutex);
- if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
+ pCtx = db->pVtabCtx;
+ if( !pCtx || pCtx->bDeclared ){
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));
if( pParse==0 ){
rc = SQLITE_NOMEM;
@@ -114870,11 +115313,11 @@
pTab->aCol = pParse->pNewTable->aCol;
pTab->nCol = pParse->pNewTable->nCol;
pParse->pNewTable->nCol = 0;
pParse->pNewTable->aCol = 0;
}
- db->pVtabCtx->pTab = 0;
+ pCtx->bDeclared = 1;
}else{
sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
rc = SQLITE_ERROR;
}
@@ -115064,11 +115507,11 @@
*/
SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
int rc = SQLITE_OK;
assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN );
- assert( iSavepoint>=0 );
+ assert( iSavepoint>=-1 );
if( db->aVTrans ){
int i;
for(i=0; rc==SQLITE_OK && inVTrans; i++){
VTable *pVTab = db->aVTrans[i];
const sqlite3_module *pMod = pVTab->pMod->pModule;
@@ -115182,11 +115625,11 @@
assert( IsVirtual(pTab) );
for(i=0; inVtabLock; i++){
if( pTab==pToplevel->apVtabLock[i] ) return;
}
n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
- apVtabLock = sqlite3_realloc(pToplevel->apVtabLock, n);
+ apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n);
if( apVtabLock ){
pToplevel->apVtabLock = apVtabLock;
pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
}else{
pToplevel->db->mallocFailed = 1;
@@ -115981,17 +116424,18 @@
** In the previous sentence and in the diagram, "slot[]" refers to
** the WhereClause.a[] array. The slot[] array grows as needed to contain
** all terms of the WHERE clause.
*/
static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
+ Expr *pE2 = sqlite3ExprSkipCollate(pExpr);
pWC->op = op;
- if( pExpr==0 ) return;
- if( pExpr->op!=op ){
+ if( pE2==0 ) return;
+ if( pE2->op!=op ){
whereClauseInsert(pWC, pExpr, 0);
}else{
- whereSplit(pWC, pExpr->pLeft, op);
- whereSplit(pWC, pExpr->pRight, op);
+ whereSplit(pWC, pE2->pLeft, op);
+ whereSplit(pWC, pE2->pRight, op);
}
}
/*
** Initialize a WhereMaskSet object
@@ -117258,11 +117702,11 @@
if( p->op==TK_COLUMN
&& p->iColumn==pIdx->aiColumn[iCol]
&& p->iTable==iBase
){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
- if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
+ if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){
return i;
}
}
}
@@ -117532,11 +117976,11 @@
if( (idxCols & cMask)==0 ){
Expr *pX = pTerm->pExpr;
idxCols |= cMask;
pIdx->aiColumn[n] = pTerm->u.leftColumn;
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
- pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : "BINARY";
+ pIdx->azColl[n] = pColl ? pColl->zName : "BINARY";
n++;
}
}
}
assert( (u32)n==pLoop->u.btree.nEq );
@@ -118828,12 +119272,11 @@
isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
|| ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
|| (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
- sqlite3StrAccumInit(&str, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
- str.db = db;
+ sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
if( pItem->pSelect ){
sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
}else{
sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
@@ -120028,10 +120471,17 @@
/*
** Free a WhereInfo structure
*/
static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
if( ALWAYS(pWInfo) ){
+ int i;
+ for(i=0; inLevel; 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;
pWInfo->pLoops = p->pNextLoop;
whereLoopDelete(db, p);
@@ -120507,11 +120957,11 @@
** changes "x IN (?)" into "x=?". */
}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 && !IsUniqueIndex(pProbe) ){
+ if( iCol>=0 && pProbe->uniqNotNull==0 ){
pNew->wsFlags |= WHERE_UNQ_WANTED;
}else{
pNew->wsFlags |= WHERE_ONEROW;
}
}
@@ -121967,11 +122417,11 @@
pWInfo->nOBSat = pFrom->isOrdered;
if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0;
pWInfo->revMask = pFrom->revLoop;
}
if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
- && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr
+ && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0
){
Bitmask revMask = 0;
int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy,
pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask
);
@@ -122372,11 +122822,10 @@
if( pParse->nErr || NEVER(db->mallocFailed) ){
goto whereBeginError;
}
#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);
}
switch( pWInfo->eDistinct ){
@@ -122625,11 +123074,10 @@
VdbeCoverage(v);
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen);
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
}
- sqlite3DbFree(db, pLevel->u.in.aInLoop);
}
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
if( pLevel->addrSkip ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrSkip);
VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName));
@@ -122836,10 +123284,32 @@
/*
** An instance of this structure holds the ATTACH key and the key type.
*/
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.
*/
@@ -125153,31 +125623,14 @@
sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
}
break;
case 112: /* select ::= with selectnowith */
{
- Select *p = yymsp[0].minor.yy3, *pNext, *pLoop;
+ Select *p = yymsp[0].minor.yy3;
if( p ){
- int cnt = 0, mxSelect;
p->pWith = yymsp[-1].minor.yy59;
- 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");
- }
- }
+ parserDoubleLinkSelect(pParse, p);
}else{
sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy59);
}
yygotominor.yy3 = p;
}
@@ -125191,16 +125644,18 @@
Select *pRhs = yymsp[0].minor.yy3;
if( pRhs && pRhs->pPrior ){
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);
}
yygotominor.yy3 = pRhs;
@@ -125243,17 +125698,20 @@
yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
}
break;
case 121: /* values ::= values COMMA LP exprlist RP */
{
- Select *pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
+ 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;
if( pRight ){
pRight->op = TK_ALL;
- pRight->pPrior = yymsp[-4].minor.yy3;
+ pLeft = yymsp[-4].minor.yy3;
+ pRight->pPrior = pLeft;
yygotominor.yy3 = pRight;
}else{
- yygotominor.yy3 = yymsp[-4].minor.yy3;
+ yygotominor.yy3 = pLeft;
}
}
break;
case 122: /* distinct ::= DISTINCT */
{yygotominor.yy381 = SF_Distinct;}
@@ -127053,14 +127511,12 @@
goto abort_parse;
}
break;
}
case TK_ILLEGAL: {
- sqlite3DbFree(db, *pzErrMsg);
- *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
+ sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"",
&pParse->sLastToken);
- nErr++;
goto abort_parse;
}
case TK_SEMI: {
pParse->zTail = &zSql[i];
/* Fall thru into the default case */
@@ -127074,16 +127530,19 @@
break;
}
}
}
abort_parse:
- if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
+ assert( nErr==0 );
+ if( zSql[i]==0 && pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
if( lastTokenParsed!=TK_SEMI ){
sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
pParse->zTail = &zSql[i];
}
- sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
+ if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
+ sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
+ }
}
#ifdef YYTRACKMAXSTACKDEPTH
sqlite3_mutex_enter(sqlite3MallocMutex());
sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
sqlite3ParserStackPeak(pEngine)
@@ -127140,13 +127599,11 @@
while( pParse->pZombieTab ){
Table *p = pParse->pZombieTab;
pParse->pZombieTab = p->pNextZombie;
sqlite3DeleteTable(db, p);
}
- if( nErr>0 && pParse->rc==SQLITE_OK ){
- pParse->rc = SQLITE_ERROR;
- }
+ assert( nErr==0 || pParse->rc!=SQLITE_OK );
return nErr;
}
/************** End of tokenize.c ********************************************/
/************** Begin file complete.c ****************************************/
@@ -127418,11 +127875,11 @@
** UTF-8.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *zSql){
sqlite3_value *pVal;
char const *zSql8;
- int rc = SQLITE_NOMEM;
+ int rc;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
if( rc ) return rc;
#endif
@@ -127584,10 +128041,22 @@
** 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
+
#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
/*
** If the following function pointer is not NULL and if
** SQLITE_ENABLE_IOTRACE is enabled, then messages describing
** I/O active are written using this function. These messages
@@ -128723,11 +129192,11 @@
/*
** Return a static string containing the name corresponding to the error code
** specified in the argument.
*/
-#if (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) || defined(SQLITE_TEST)
+#if defined(SQLITE_NEED_ERR_NAME)
SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
const char *zName = 0;
int i, origRc = rc;
for(i=0; i<2 && zName==0; i++, rc &= 0xff){
switch( rc ){
@@ -129948,18 +130417,18 @@
){
char *zOpt;
int eState; /* Parser state when parsing URI */
int iIn; /* Input character index */
int iOut = 0; /* Output character index */
- int nByte = nUri+2; /* Bytes of space to allocate */
+ u64 nByte = nUri+2; /* Bytes of space to allocate */
/* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen
** method that there may be extra parameters following the file-name. */
flags |= SQLITE_OPEN_URI;
for(iIn=0; iInmallocFailed && rc==SQLITE_OK){
rc = sqlite3RtreeInit(db);
}
#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.
*/
@@ -132330,10 +132806,15 @@
** false.
*/
#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)
#endif
@@ -132730,10 +133211,11 @@
#define fts3GetVarint32(p, piVal) ( \
(*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \
)
/* 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 *);
SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64);
SQLITE_PRIVATE void sqlite3Fts3Dequote(char *);
@@ -132818,10 +133300,17 @@
static int fts3EvalNext(Fts3Cursor *pCsr);
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.
** The number of bytes written is returned.
@@ -132928,11 +133417,11 @@
int iOut = 0; /* Index of next byte to write to output */
/* If the first byte was a '[', then the close-quote character is a ']' */
if( quote=='[' ) quote = ']';
- while( ALWAYS(z[iIn]) ){
+ while( z[iIn] ){
if( z[iIn]==quote ){
if( z[iIn+1]!=quote ) break;
z[iOut++] = quote;
iIn += 2;
}else{
@@ -133006,10 +133495,21 @@
p->pTokenizer->pModule->xDestroy(p->pTokenizer);
sqlite3_free(p);
return SQLITE_OK;
}
+
+/*
+** 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.
@@ -133525,11 +134025,12 @@
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of db (i.e. "main", "temp" etc.) */
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 */
+ int *pnStr, /* OUT: Bytes of string content */
+ char **pzErr /* OUT: error message */
){
int rc = SQLITE_OK; /* Return code */
char *zSql; /* "SELECT *" statement on zTbl */
sqlite3_stmt *pStmt = 0; /* Compiled version of zSql */
@@ -133536,10 +134037,13 @@
zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", zDb, zTbl);
if( !zSql ){
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);
if( rc==SQLITE_OK ){
const char **azCol; /* Output array */
@@ -133702,17 +134206,17 @@
if( nKey==pOp->nOpt && !sqlite3_strnicmp(z, pOp->zOpt, pOp->nOpt) ){
break;
}
}
if( iOpt==SizeofArray(aFts4Opt) ){
- *pzErr = sqlite3_mprintf("unrecognized parameter: %s", z);
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
rc = SQLITE_ERROR;
}else{
switch( iOpt ){
case 0: /* MATCHINFO */
if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
- *pzErr = sqlite3_mprintf("unrecognized matchinfo: %s", zVal);
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
rc = SQLITE_ERROR;
}
bNoDocsize = 1;
break;
@@ -133736,11 +134240,11 @@
case 4: /* ORDER */
if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
&& (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
){
- *pzErr = sqlite3_mprintf("unrecognized order: %s", zVal);
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
rc = SQLITE_ERROR;
}
bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
break;
@@ -133787,11 +134291,11 @@
zCompress = 0;
zUncompress = 0;
if( nCol==0 ){
sqlite3_free((void*)aCol);
aCol = 0;
- rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
+ rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr);
/* If a languageid= option was specified, remove the language id
** column from the aCol[] array. */
if( rc==SQLITE_OK && zLanguageid ){
int j;
@@ -133822,11 +134326,11 @@
assert( pTokenizer );
rc = fts3PrefixParameter(zPrefix, &nIndex, &aIndex);
if( rc==SQLITE_ERROR ){
assert( zPrefix );
- *pzErr = sqlite3_mprintf("error parsing prefix parameter: %s", zPrefix);
+ sqlite3Fts3ErrMsg(pzErr, "error parsing prefix parameter: %s", zPrefix);
}
if( rc!=SQLITE_OK ) goto fts3_init_out;
/* Allocate and populate the Fts3Table structure. */
nByte = sizeof(Fts3Table) + /* Fts3Table */
@@ -133904,19 +134408,19 @@
}
}
}
for(i=0; izReadExprlist = fts3ReadExprList(p, zUncompress, &rc);
p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc);
if( rc!=SQLITE_OK ) goto fts3_init_out;
@@ -135305,11 +135809,11 @@
** Fts3SegReaderPending might segfault, as the data structures used by
** fts4aux are not completely populated. So it's easiest to filter these
** calls out here. */
if( iLevel<0 && p->aIndex ){
Fts3SegReader *pSeg = 0;
- rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix, &pSeg);
+ rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg);
if( rc==SQLITE_OK && pSeg ){
rc = fts3SegReaderCursorAppend(pCsr, pSeg);
}
}
@@ -135954,15 +136458,35 @@
*/
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--;
}
- if( p>pStart ){ p = &p[2]; }
+ 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
+ */
+ if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; }
while( *p++&0x80 );
*ppPoslist = p;
}
/*
@@ -136029,10 +136553,12 @@
case 3: zEnd = (const char*)sqlite3_value_text(apVal[2]);
case 2: zStart = (const char*)sqlite3_value_text(apVal[1]);
}
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);
}
}
@@ -137090,16 +137616,18 @@
Fts3Expr *pExpr, /* Expression to initialize phrases in */
int *pRc /* IN/OUT: Error code */
){
if( pExpr && SQLITE_OK==*pRc ){
if( pExpr->eType==FTSQUERY_PHRASE ){
- int i;
int nToken = pExpr->pPhrase->nToken;
- for(i=0; ipPhrase->aToken[i].pDeferred==0 ) break;
+ if( nToken ){
+ int i;
+ for(i=0; ipPhrase->aToken[i].pDeferred==0 ) break;
+ }
+ pExpr->bDeferred = (i==nToken);
}
- pExpr->bDeferred = (i==nToken);
*pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase);
}else{
fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc);
fts3EvalStartReaders(pCsr, pExpr->pRight, pRc);
pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred);
@@ -138258,11 +138786,12 @@
if( rc!=SQLITE_OK ) return rc;
pIter = pPhrase->pOrPoslist;
iDocid = pPhrase->iOrDocid;
if( pCsr->bDesc==bDescDoclist ){
- bEof = (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
+ bEof = !pPhrase->doclist.nAll ||
+ (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,
&pIter, &iDocid, &bEof
);
@@ -138470,11 +138999,11 @@
*ppVtab = (sqlite3_vtab *)p;
return SQLITE_OK;
bad_args:
- *pzErr = sqlite3_mprintf("invalid arguments to fts4aux constructor");
+ sqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor");
return SQLITE_ERROR;
}
/*
** This function does the work for both the xDisconnect and xDestroy methods.
@@ -139928,17 +140457,17 @@
if( rc!=SQLITE_OK ){
sqlite3Fts3ExprFree(*ppExpr);
*ppExpr = 0;
if( rc==SQLITE_TOOBIG ){
- *pzErr = sqlite3_mprintf(
+ sqlite3Fts3ErrMsg(pzErr,
"FTS expression tree is too large (maximum depth %d)",
SQLITE_FTS3_MAX_EXPR_DEPTH
);
rc = SQLITE_ERROR;
}else if( rc==SQLITE_ERROR ){
- *pzErr = sqlite3_mprintf("malformed MATCH expression: [%s]", z);
+ sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z);
}
}
return rc;
}
@@ -141410,11 +141939,11 @@
z[n] = '\0';
sqlite3Fts3Dequote(z);
m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1);
if( !m ){
- *pzErr = sqlite3_mprintf("unknown tokenizer: %s", z);
+ sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z);
rc = SQLITE_ERROR;
}else{
char const **aArg = 0;
int iArg = 0;
z = &z[n+1];
@@ -141433,11 +141962,11 @@
z = &z[n+1];
}
rc = m->xCreate(iArg, aArg, ppTok);
assert( rc!=SQLITE_OK || *ppTok );
if( rc!=SQLITE_OK ){
- *pzErr = sqlite3_mprintf("unknown tokenizer");
+ sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer");
}else{
(*ppTok)->pModule = m;
}
sqlite3_free((void *)aArg);
}
@@ -141517,13 +142046,13 @@
pHash = (Fts3Hash *)sqlite3_user_data(context);
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
if( !p ){
- char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
- sqlite3_result_error(context, zErr, -1);
- sqlite3_free(zErr);
+ char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName);
+ sqlite3_result_error(context, zErr2, -1);
+ sqlite3_free(zErr2);
return;
}
pRet = Tcl_NewObj();
Tcl_IncrRefCount(pRet);
@@ -142054,11 +142583,11 @@
sqlite3_tokenizer_module *p;
int nName = (int)strlen(zName);
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
if( !p ){
- *pzErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
+ sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName);
return SQLITE_ERROR;
}
*pp = p;
return SQLITE_OK;
@@ -142751,11 +143280,11 @@
/* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(?,?)",
/* 24 */ "",
/* 25 */ "",
/* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?",
-/* 27 */ "SELECT DISTINCT level / (1024 * ?) FROM %Q.'%q_segdir'",
+/* 27 */ "SELECT ? UNION SELECT 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
** of the oldest level in the db that contains at least ? segments. Or,
** if no level in the FTS index contains more than ? segments, the statement
@@ -145869,11 +146398,12 @@
sqlite3_stmt *pAllLangid = 0;
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
if( rc==SQLITE_OK ){
int rc2;
- sqlite3_bind_int(pAllLangid, 1, p->nIndex);
+ sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
+ sqlite3_bind_int(pAllLangid, 2, p->nIndex);
while( sqlite3_step(pAllLangid)==SQLITE_ROW ){
int i;
int iLangid = sqlite3_column_int(pAllLangid, 0);
for(i=0; rc==SQLITE_OK && inIndex; i++){
rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL);
@@ -147201,11 +147731,11 @@
while( i>0 && (pHint->a[i-1] & 0x80) ) i--;
pHint->n = i;
i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel);
i += fts3GetVarint32(&pHint->a[i], pnInput);
- if( i!=nHint ) return SQLITE_CORRUPT_VTAB;
+ if( i!=nHint ) return FTS_CORRUPT_VTAB;
return SQLITE_OK;
}
@@ -147569,11 +148099,12 @@
/* This block calculates the checksum according to the FTS index. */
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
if( rc==SQLITE_OK ){
int rc2;
- sqlite3_bind_int(pAllLangid, 1, p->nIndex);
+ sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
+ sqlite3_bind_int(pAllLangid, 2, p->nIndex);
while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){
int iLangid = sqlite3_column_int(pAllLangid, 0);
int i;
for(i=0; inIndex; i++){
cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc);
@@ -147582,11 +148113,10 @@
rc2 = sqlite3_reset(pAllLangid);
if( rc==SQLITE_OK ) rc = rc2;
}
/* 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;
char *zSql;
@@ -147679,11 +148209,11 @@
Fts3Table *p /* FTS3 table handle */
){
int rc;
int bOk = 0;
rc = fts3IntegrityCheck(p, &bOk);
- if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_CORRUPT_VTAB;
+ if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB;
return rc;
}
/*
** Handle a 'special' INSERT of the form:
@@ -148117,10 +148647,11 @@
#define FTS3_MATCHINFO_NDOC 'n' /* 1 value */
#define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */
#define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */
#define FTS3_MATCHINFO_LCS 's' /* nCol values */
#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */
+#define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */
/*
** The default value for the second argument to matchinfo().
*/
#define FTS3_MATCHINFO_DEFAULT "pcx"
@@ -148898,10 +149429,55 @@
}
}
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,
char **pzErr
@@ -148911,14 +149487,15 @@
|| (cArg==FTS3_MATCHINFO_NDOC && pTab->bFts4)
|| (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bFts4)
|| (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize)
|| (cArg==FTS3_MATCHINFO_LCS)
|| (cArg==FTS3_MATCHINFO_HITS)
+ || (cArg==FTS3_MATCHINFO_LHITS)
){
return SQLITE_OK;
}
- *pzErr = sqlite3_mprintf("unrecognized matchinfo request: %c", cArg);
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg);
return SQLITE_ERROR;
}
static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
int nVal; /* Number of integers output by cArg */
@@ -148933,10 +149510,14 @@
case FTS3_MATCHINFO_AVGLENGTH:
case FTS3_MATCHINFO_LENGTH:
case FTS3_MATCHINFO_LCS:
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;
break;
@@ -149187,10 +149768,14 @@
rc = fts3ExprLoadDoclists(pCsr, 0, 0);
if( rc==SQLITE_OK ){
rc = fts3MatchinfoLcs(pCsr, pInfo);
}
break;
+
+ case FTS3_MATCHINFO_LHITS:
+ (void)fts3ExprIterate(pCsr->pExpr, fts3ExprLHitsCb, (void*)pInfo);
+ break;
default: {
Fts3Expr *pExpr;
assert( zArg[i]==FTS3_MATCHINFO_HITS );
pExpr = pCsr->pExpr;
@@ -153200,15 +153785,23 @@
** conflict-handling mode specified by the user.
*/
if( nData>1 ){
int ii;
- /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
- assert( nData==(pRtree->nDim*2 + 3) );
+ /* 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) );
+
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+ for(ii=0; iicell.aCoord[ii+1].f ){
rc = SQLITE_CONSTRAINT;
goto constraint;
@@ -153215,11 +153808,11 @@
}
}
}else
#endif
{
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+ for(ii=0; iicell.aCoord[ii+1].i ){
rc = SQLITE_CONSTRAINT;
goto constraint;
@@ -154615,5 +155208,633 @@
#endif /* defined(SQLITE_ENABLE_ICU) */
#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; inCell; 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; iaPage); 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; inCell; 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; jaOvfl[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->iCellnCell ){
+ StatCell *pCell = &p->aCell[p->iCell];
+ if( pCell->iOvflnOvfl ){
+ 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->iOvflnOvfl-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; inCell; 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 **********************************************/
Index: src/sqlite3.h
==================================================================
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -109,13 +109,13 @@
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.8.9"
-#define SQLITE_VERSION_NUMBER 3008009
-#define SQLITE_SOURCE_ID "2015-04-06 11:04:51 3ad829e50faca538db3abb2afb898b5521550c5c"
+#define SQLITE_VERSION "3.8.10"
+#define SQLITE_VERSION_NUMBER 3008010
+#define SQLITE_SOURCE_ID "2015-05-05 18:52:54 04afa3febee32854fbb09ef8d4ffffd432119716"
/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
@@ -268,10 +268,11 @@
# define double sqlite3_int64
#endif
/*
** CAPI3REF: Closing A Database Connection
+** DESTRUCTOR: sqlite3
**
** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
** for the [sqlite3] object.
** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
** the [sqlite3] object is successfully destroyed and all associated
@@ -319,10 +320,11 @@
*/
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()],
** that allows an application to run multiple statements of SQL
** without having to use a lot of C code.
@@ -1376,10 +1378,11 @@
*/
SQLITE_API int SQLITE_CDECL 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
** [sqlite3_config()] except that the changes apply to a single
** [database connection] (specified in the first argument).
@@ -1873,19 +1876,21 @@
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
/*
** 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);
/*
** CAPI3REF: Last Insert Rowid
+** METHOD: sqlite3
**
** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
** has a unique 64-bit signed
** integer key called the [ROWID | "rowid"]. ^The rowid is always available
** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
@@ -1933,10 +1938,11 @@
*/
SQLITE_API sqlite3_int64 SQLITE_STDCALL 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
** statement on the database connection specified by the only parameter.
** ^Executing any other type of SQL statement does not modify the value
@@ -1985,10 +1991,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** since the database connection was opened, including those executed as
** part of trigger programs. ^Executing any other type of SQL statement
@@ -2008,10 +2015,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** called in response to a user action such as pressing "Cancel"
** or Ctrl-C where the user wants a long query operation to halt
@@ -2084,10 +2092,11 @@
SQLITE_API int SQLITE_STDCALL 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
** an attempt is made to access a database table associated with
** [database connection] D when another thread
@@ -2143,10 +2152,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** will sleep multiple times until at least "ms" milliseconds of sleeping
** have accumulated. ^After at least "ms" milliseconds of sleeping,
@@ -2165,10 +2175,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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.
**
** Definition: A result table is memory data structure created by the
@@ -2500,10 +2511,11 @@
*/
SQLITE_API void SQLITE_STDCALL 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.
** ^The authorizer callback is invoked as SQL statements are being compiled
** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
@@ -2656,10 +2668,11 @@
#define SQLITE_COPY 0 /* No longer used */
#define SQLITE_RECURSIVE 33 /* NULL NULL */
/*
** 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.
**
** ^The callback function registered by sqlite3_trace() is invoked at
@@ -2688,10 +2701,11 @@
SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL 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
** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
** database connection D. An example use for this
@@ -2721,10 +2735,11 @@
*/
SQLITE_API void SQLITE_STDCALL 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
** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte
** order for sqlite3_open16(). ^(A [database connection] handle is usually
@@ -3006,10 +3021,11 @@
SQLITE_API sqlite3_int64 SQLITE_STDCALL 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.
@@ -3051,37 +3067,38 @@
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);
/*
-** CAPI3REF: SQL Statement Object
+** CAPI3REF: Prepared Statement Object
** KEYWORDS: {prepared statement} {prepared statements}
**
-** 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".
+** An instance of this object represents a single SQL statement that
+** has been compiled into binary form and is ready to be evaluated.
**
-** The life of a statement object goes something like this:
+** 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:
**
**
-** - Create the object using [sqlite3_prepare_v2()] or a related
-** function.
-**
- Bind values to [host parameters] using the sqlite3_bind_*()
+**
- Create the prepared statement object using [sqlite3_prepare_v2()].
+**
- Bind values to [parameters] using the sqlite3_bind_*()
** interfaces.
**
- Run the SQL by calling [sqlite3_step()] one or more times.
-**
- Reset the statement using [sqlite3_reset()] then go back
+**
- Reset the prepared statement using [sqlite3_reset()] then go back
** to step 2. Do this zero or more times.
**
- Destroy the object using [sqlite3_finalize()].
**
-**
-** 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
** [database connection] whose limit is to be set or queried. The
** second parameter is one of the [limit categories] that define a
@@ -3189,10 +3206,12 @@
#define SQLITE_LIMIT_WORKER_THREADS 11
/*
** 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.
**
** The first argument, "db", is a [database connection] obtained from a
@@ -3296,19 +3315,21 @@
const void **pzTail /* OUT: Pointer to unused portion of zSql */
);
/*
** 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);
/*
** 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
** the content of the database file.
**
@@ -3336,10 +3357,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** [sqlite3_step(S)] but has not run to completion and/or has not
** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S)
@@ -3410,10 +3432,11 @@
/*
** 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
** templates:
**
@@ -3528,10 +3551,11 @@
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);
/*
** 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
** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
** placeholders for values that are [sqlite3_bind_blob | bound]
@@ -3548,10 +3572,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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.
** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA"
** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA"
@@ -3575,10 +3600,11 @@
*/
SQLITE_API const char *SQLITE_STDCALL 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
** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero
** is returned if no matching parameter is found. ^The parameter
@@ -3591,19 +3617,21 @@
*/
SQLITE_API int SQLITE_STDCALL 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*);
/*
** 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
** statement that does not return data (for example an [UPDATE]).
**
@@ -3611,10 +3639,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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()
** interface returns a pointer to a zero-terminated UTF-8 string
** and sqlite3_column_name16() returns a pointer to a zero-terminated
@@ -3640,10 +3669,11 @@
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);
/*
** 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
** [SELECT] statement.
** ^The name of the database or table or column can be returned as
@@ -3692,10 +3722,11 @@
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);
/*
** 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
** returned result set of that [SELECT] is a table column (not an
** expression or subquery) then the declared type of the table
@@ -3724,10 +3755,11 @@
SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int);
SQLITE_API const void *SQLITE_STDCALL 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
** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
** must be called one or more times to evaluate the statement.
@@ -3803,10 +3835,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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.
** ^If prepared statement P does not have results ready to return
** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
@@ -3856,10 +3889,11 @@
#define SQLITE3_TEXT 3
/*
** CAPI3REF: Result Values From A Query
** KEYWORDS: {column access functions}
+** METHOD: sqlite3_stmt
**
** These routines form the "result set" interface.
**
** ^These routines return information about a single column of the current
** result row of a query. ^In every case the first argument is a pointer
@@ -4028,10 +4062,11 @@
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);
/*
** 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
** or if the statement is never been evaluated, then sqlite3_finalize() returns
** SQLITE_OK. ^If the most recent evaluation of statement S failed, then
@@ -4055,10 +4090,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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.
** ^Any SQL statement variables that had values bound to them using
** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values.
@@ -4084,10 +4120,11 @@
/*
** 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
** of existing SQL functions or aggregates. The only differences between
** these routines are the text encoding expected for
@@ -4253,10 +4290,11 @@
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
** the function or aggregate.
**
@@ -4311,10 +4349,11 @@
SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
SQLITE_API int SQLITE_STDCALL 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.
**
** ^The first time the sqlite3_aggregate_context(C,N) routine is called
@@ -4355,10 +4394,11 @@
*/
SQLITE_API void *SQLITE_STDCALL 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)
** of the [sqlite3_create_function()]
** and [sqlite3_create_function16()] routines that originally
@@ -4369,10 +4409,11 @@
*/
SQLITE_API void *SQLITE_STDCALL 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)
** of the [sqlite3_create_function()]
** and [sqlite3_create_function16()] routines that originally
@@ -4380,10 +4421,11 @@
*/
SQLITE_API sqlite3 *SQLITE_STDCALL 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
** multiple invocations of the same SQL function during query execution, under
** some circumstances the associated metadata may be preserved. An example
@@ -4452,10 +4494,11 @@
#define SQLITE_STATIC ((sqlite3_destructor_type)0)
#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1)
/*
** 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
** [sqlite3_create_function()] and [sqlite3_create_function16()]
** for additional information.
@@ -4587,10 +4630,11 @@
SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*);
SQLITE_API void SQLITE_STDCALL 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.
**
** ^The name of the collation is a UTF-8 string
@@ -4689,10 +4733,11 @@
int(*xCompare)(void*,int,const void*,int,const void*)
);
/*
** 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
** [database connection] to be invoked whenever an undefined collation
** sequence is required.
@@ -4896,10 +4941,11 @@
SQLITE_API SQLITE_EXTERN 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,
** respectively. ^Autocommit mode is on by default.
** ^Autocommit mode is disabled by a [BEGIN] statement.
@@ -4918,10 +4964,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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]
** returned by sqlite3_db_handle is the same [database connection]
** that was the first argument
@@ -4930,10 +4977,11 @@
*/
SQLITE_API sqlite3 *SQLITE_STDCALL 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
** has the name "main". If there is no attached database N on the database
** connection D, or if database N is a temporary or in-memory database, then
@@ -4946,19 +4994,21 @@
*/
SQLITE_API const char *SQLITE_STDCALL 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);
/*
** 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
** then this interface returns a pointer to the first prepared statement
** associated with the database connection pDb. ^If no prepared statement
@@ -4970,10 +5020,11 @@
*/
SQLITE_API sqlite3_stmt *SQLITE_STDCALL 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].
** ^Any callback set by a previous call to sqlite3_commit_hook()
** for the same database connection is overridden.
@@ -5019,10 +5070,11 @@
SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
SQLITE_API void *SQLITE_STDCALL 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
** to be invoked whenever a row is updated, inserted or deleted in
** a rowid table.
@@ -5125,10 +5177,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** [sqlite3_release_memory()] interface, this interface is in effect even
** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
@@ -5202,10 +5255,11 @@
SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL 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
** on [database connection] X.)^ ^The sqlite3_table_column_metadata()
** interface returns SQLITE_OK and fills in the non-NULL pointers in
@@ -5280,10 +5334,11 @@
int *pAutoinc /* OUTPUT: True if column is auto-increment */
);
/*
** CAPI3REF: Load An Extension
+** METHOD: sqlite3
**
** ^This interface loads an SQLite extension library from the named file.
**
** ^The sqlite3_load_extension() interface attempts to load an
** [SQLite extension] library contained in the file zFile. If
@@ -5321,10 +5376,11 @@
char **pzErrMsg /* Put error message here if not 0 */
);
/*
** 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
** [extension loading] while evaluating user-entered SQL, the following API
** is provided to turn the [sqlite3_load_extension()] mechanism on and off.
@@ -5570,10 +5626,11 @@
#define SQLITE_INDEX_CONSTRAINT_GE 32
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
/*
** 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
** creating a new [virtual table] using the module and before using a
** preexisting [virtual table] for the module.
@@ -5666,10 +5723,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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].
** But global versions of those functions
** must exist in order to be overloaded.)^
@@ -5708,10 +5766,12 @@
*/
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;
** in other words, the same BLOB that would be selected by:
**
@@ -5789,10 +5849,11 @@
sqlite3_blob **ppBlob
);
/*
** 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
** by the rowid value passed as the second argument. Only the row can be
** changed. ^The database, table and column on which the blob handle is open
@@ -5813,10 +5874,11 @@
*/
SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL 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
** handle is still closed.)^
**
@@ -5835,10 +5897,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** incremental blob I/O routines can only read or overwriting existing
** blob content; they cannot change the size of a blob.
@@ -5850,10 +5913,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** from the open BLOB, starting at offset iOffset.)^
**
@@ -5878,10 +5942,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** into the open BLOB, starting at offset iOffset.)^
**
@@ -6205,10 +6270,11 @@
#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */
#define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */
/*
** 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
** when the [threading mode] is Serialized.
** ^If the [threading mode] is Single-thread or Multi-thread then this
@@ -6216,10 +6282,11 @@
*/
SQLITE_API sqlite3_mutex *SQLITE_STDCALL 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
** with a particular database identified by the second argument. ^The
** name of the database is "main" for the main database or "temp" for the
@@ -6432,10 +6499,11 @@
#define SQLITE_STATUS_SCRATCH_SIZE 8
#define SQLITE_STATUS_MALLOC_COUNT 9
/*
** 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
** database connection object to be interrogated. ^The second argument
** is an integer constant, taken from the set of
@@ -6560,10 +6628,11 @@
#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
/*
** CAPI3REF: Prepared Statement Status
+** METHOD: sqlite3_stmt
**
** ^(Each prepared statement maintains various
** [SQLITE_STMTSTATUS counters] that measure the number
** of times it has performed specific operations.)^ These counters can
** be used to monitor the performance characteristics of the prepared
@@ -7063,10 +7132,11 @@
SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p);
SQLITE_API int SQLITE_STDCALL 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
** individual tables within the shared-cache cannot be obtained. See
** [SQLite Shared-Cache Mode] for a description of shared-cache locking.
@@ -7233,10 +7303,11 @@
*/
SQLITE_API void SQLITE_CDECL 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.
**
** ^(The callback is invoked by SQLite after the commit has taken place and
@@ -7272,10 +7343,11 @@
void*
);
/*
** 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
** to automatically [checkpoint]
** after committing a transaction if there are N or
@@ -7302,10 +7374,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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).)^
**
** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the
@@ -7323,10 +7396,11 @@
*/
SQLITE_API int SQLITE_STDCALL 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
** information is written back into integers pointed to by L and C.)^
** ^(The M parameter must be a valid [checkpoint mode]:)^
@@ -7577,10 +7651,11 @@
#define SQLITE_SCANSTAT_EXPLAIN 4
#define SQLITE_SCANSTAT_SELECTID 5
/*
** 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
** interface to compare the predicted and the measured performance and
** issue warnings and/or rerun [ANALYZE] if discrepancies are found.
@@ -7614,10 +7689,11 @@
void *pOut /* Result written here */
);
/*
** 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.