@@ -1,7 +1,7 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.6.10. By combining all the individual C code files into this
+** version 3.6.12. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a one translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
** of 5% are more are commonly seen when SQLite is compiled as a single
@@ -10,15 +10,15 @@
** This file is all you need to compile SQLite. To use SQLite in other
** programs, you need this file and the "sqlite3.h" header file that defines
** the programming interface to the SQLite library. (If you do not have
** the "sqlite3.h" header file at hand, you will find a copy in the first
-** 6736 lines past this header comment.) Additional code files may be
+** 5487 lines past this header comment.) Additional code files may be
** needed if you want a wrapper to interface SQLite with your choice of
** programming language. The code for the "sqlite3" command-line shell
** is also in a separate file. This file contains only code for the core
** SQLite library.
**
-** This amalgamation was generated on 2009-01-15 16:00:39 UTC.
+** This amalgamation was generated on 2009-03-31 12:19:59 UTC.
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
#ifndef SQLITE_PRIVATE
@@ -40,9 +40,9 @@
**
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.824 2009/01/14 23:03:41 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.848 2009/03/25 16:51:43 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -531,9 +531,9 @@
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
-** @(#) $Id: sqlite.h.in,v 1.421 2008/12/30 06:24:58 danielk1977 Exp $
+** @(#) $Id: sqlite.h.in,v 1.436 2009/03/20 13:15:30 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h> /* Needed for the definition of va_list */
@@ -598,20 +598,12 @@
** each release but resets back to 0 whenever Y is incremented.
**
** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()].
**
-** INVARIANTS:
-**
-** {H10011} The SQLITE_VERSION #define in the sqlite3.h header file shall
-** evaluate to a string literal that is the SQLite version
-** with which the header file is associated.
-**
-** {H10014} The SQLITE_VERSION_NUMBER #define shall resolve to an integer
-** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z
-** are the major version, minor version, and release number.
-*/
-#define SQLITE_VERSION "3.6.10"
-#define SQLITE_VERSION_NUMBER 3006010
+** Requirements: [H10011] [H10014]
+*/
+#define SQLITE_VERSION "3.6.12"
+#define SQLITE_VERSION_NUMBER 3006012
/*
** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
** KEYWORDS: sqlite3_version
@@ -627,18 +619,9 @@
** in the sqlite3_version[] string constant. The function is provided
** for use in DLLs since DLL users usually do not have direct access to string
** constants within the DLL.
**
-** INVARIANTS:
-**
-** {H10021} The [sqlite3_libversion_number()] interface shall return
-** an integer equal to [SQLITE_VERSION_NUMBER].
-**
-** {H10022} The [sqlite3_version] string constant shall contain
-** the text of the [SQLITE_VERSION] string.
-**
-** {H10023} The [sqlite3_libversion()] function shall return
-** a pointer to the [sqlite3_version] string constant.
+** Requirements: [H10021] [H10022] [H10023]
*/
SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
SQLITE_API const char *sqlite3_libversion(void);
SQLITE_API int sqlite3_libversion_number(void);
@@ -672,15 +655,9 @@
** to that setting.
**
** See the [threading mode] documentation for additional information.
**
-** INVARIANTS:
-**
-** {H10101} The [sqlite3_threadsafe()] function shall return zero if
-** and only if SQLite was compiled with mutexing code omitted.
-**
-** {H10102} The value returned by the [sqlite3_threadsafe()] function
-** shall remain the same across calls to [sqlite3_config()].
+** Requirements: [H10101] [H10102]
*/
SQLITE_API int sqlite3_threadsafe(void);
/*
@@ -708,15 +685,9 @@
** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions.
** The sqlite_int64 and sqlite_uint64 types are supported for backwards
** compatibility only.
**
-** INVARIANTS:
-**
-** {H10201} The [sqlite_int64] and [sqlite3_int64] type shall specify
-** a 64-bit signed integer.
-**
-** {H10202} The [sqlite_uint64] and [sqlite3_uint64] type shall specify
-** a 64-bit unsigned integer.
+** Requirements: [H10201] [H10202]
*/
#ifdef SQLITE_INT64_TYPE
typedef SQLITE_INT64_TYPE sqlite_int64;
typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
@@ -759,36 +730,15 @@
**
** If [sqlite3_close()] is invoked while a transaction is open,
** the transaction is automatically rolled back.
**
-** INVARIANTS:
-**
-** {H12011} A successful call to [sqlite3_close(C)] shall destroy the
-** [database connection] object C.
-**
-** {H12012} A successful call to [sqlite3_close(C)] shall return SQLITE_OK.
-**
-** {H12013} A successful call to [sqlite3_close(C)] shall release all
-** memory and system resources associated with [database connection]
-** C.
-**
-** {H12014} A call to [sqlite3_close(C)] on a [database connection] C that
-** has one or more open [prepared statements] shall fail with
-** an [SQLITE_BUSY] error code.
-**
-** {H12015} A call to [sqlite3_close(C)] where C is a NULL pointer shall
-** be a harmless no-op returning SQLITE_OK.
-**
-** {H12019} When [sqlite3_close(C)] is invoked on a [database connection] C
-** that has a pending transaction, the transaction shall be
-** rolled back.
-**
-** ASSUMPTIONS:
-**
-** {A12016} The C parameter to [sqlite3_close(C)] must be either a NULL
-** pointer or an [sqlite3] object pointer obtained
-** from [sqlite3_open()], [sqlite3_open16()], or
-** [sqlite3_open_v2()], and not previously closed.
+** The C parameter to [sqlite3_close(C)] must be either a NULL
+** pointer or an [sqlite3] object pointer obtained
+** from [sqlite3_open()], [sqlite3_open16()], or
+** [sqlite3_open_v2()], and not previously closed.
+**
+** Requirements:
+** [H12011] [H12012] [H12013] [H12014] [H12015] [H12019]
*/
SQLITE_API int sqlite3_close(sqlite3 *);
/*
@@ -824,88 +774,24 @@
** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()].
** The sqlite3_exec() routine does nothing to the database that cannot be done
** by [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()].
**
-** INVARIANTS:
-**
-** {H12101} A successful invocation of [sqlite3_exec(D,S,C,A,E)]
-** shall sequentially evaluate all of the UTF-8 encoded,
-** semicolon-separated SQL statements in the zero-terminated
-** string S within the context of the [database connection] D.
-**
-** {H12102} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL then
-** the actions of the interface shall be the same as if the
-** S parameter were an empty string.
-**
-** {H12104} The return value of [sqlite3_exec()] shall be [SQLITE_OK] if all
-** SQL statements run successfully and to completion.
-**
-** {H12105} The return value of [sqlite3_exec()] shall be an appropriate
-** non-zero [error code] if any SQL statement fails.
-**
-** {H12107} If one or more of the SQL statements handed to [sqlite3_exec()]
-** return results and the 3rd parameter is not NULL, then
-** the callback function specified by the 3rd parameter shall be
-** invoked once for each row of result.
-**
-** {H12110} If the callback returns a non-zero value then [sqlite3_exec()]
-** shall abort the SQL statement it is currently evaluating,
-** skip all subsequent SQL statements, and return [SQLITE_ABORT].
-**
-** {H12113} The [sqlite3_exec()] routine shall pass its 4th parameter through
-** as the 1st parameter of the callback.
-**
-** {H12116} The [sqlite3_exec()] routine shall set the 2nd parameter of its
-** callback to be the number of columns in the current row of
-** result.
-**
-** {H12119} The [sqlite3_exec()] routine shall set the 3rd parameter of its
-** callback to be an array of pointers to strings holding the
-** values for each column in the current result set row as
-** obtained from [sqlite3_column_text()].
-**
-** {H12122} The [sqlite3_exec()] routine shall set the 4th parameter of its
-** callback to be an array of pointers to strings holding the
-** names of result columns as obtained from [sqlite3_column_name()].
-**
-** {H12125} If the 3rd parameter to [sqlite3_exec()] is NULL then
-** [sqlite3_exec()] shall silently discard query results.
-**
-** {H12131} If an error occurs while parsing or evaluating any of the SQL
-** statements in the S parameter of [sqlite3_exec(D,S,C,A,E)] and if
-** the E parameter is not NULL, then [sqlite3_exec()] shall store
-** in *E an appropriate error message written into memory obtained
-** from [sqlite3_malloc()].
-**
-** {H12134} The [sqlite3_exec(D,S,C,A,E)] routine shall set the value of
-** *E to NULL if E is not NULL and there are no errors.
-**
-** {H12137} The [sqlite3_exec(D,S,C,A,E)] function shall set the [error code]
-** and message accessible via [sqlite3_errcode()],
-** [sqlite3_extended_errcode()],
-** [sqlite3_errmsg()], and [sqlite3_errmsg16()].
-**
-** {H12138} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL or an
-** empty string or contains nothing other than whitespace, comments,
-** and/or semicolons, then results of [sqlite3_errcode()],
-** [sqlite3_extended_errcode()],
-** [sqlite3_errmsg()], and [sqlite3_errmsg16()]
-** shall reset to indicate no errors.
-**
-** ASSUMPTIONS:
-**
-** {A12141} The first parameter to [sqlite3_exec()] must be an valid and open
-** [database connection].
-**
-** {A12142} The database connection must not be closed while
-** [sqlite3_exec()] is running.
-**
-** {A12143} The calling function should use [sqlite3_free()] to free
-** the memory that *errmsg is left pointing at once the error
-** message is no longer needed.
-**
-** {A12145} The SQL statement text in the 2nd parameter to [sqlite3_exec()]
-** must remain unchanged while [sqlite3_exec()] is running.
+** The first parameter to [sqlite3_exec()] must be an valid and open
+** [database connection].
+**
+** The database connection must not be closed while
+** [sqlite3_exec()] is running.
+**
+** The calling function should use [sqlite3_free()] to free
+** the memory that *errmsg is left pointing at once the error
+** message is no longer needed.
+**
+** The SQL statement text in the 2nd parameter to [sqlite3_exec()]
+** must remain unchanged while [sqlite3_exec()] is running.
+**
+** Requirements:
+** [H12101] [H12102] [H12104] [H12105] [H12107] [H12110] [H12113] [H12116]
+** [H12119] [H12122] [H12125] [H12131] [H12134] [H12137] [H12138]
*/
SQLITE_API int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
@@ -979,21 +865,8 @@
** to see new result codes in future releases of SQLite.
**
** The SQLITE_OK result code will never be extended. It will always
** be exactly zero.
-**
-** INVARIANTS:
-**
-** {H10223} The symbolic name for an extended result code shall contains
-** a related primary result code as a prefix.
-**
-** {H10224} Primary result code names shall contain a single "_" character.
-**
-** {H10225} Extended result code names shall contain two or more "_" characters.
-**
-** {H10226} The numeric value of an extended result code shall contain the
-** numeric value of its corresponding primary result code in
-** its least significant 8 bits.
*/
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
@@ -1010,8 +883,10 @@
#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8))
#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8))
#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8))
+
+#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8) )
/*
** CAPI3REF: Flags For File Open Operations {H10230} <H11120> <H12700>
**
@@ -1496,96 +1371,12 @@
** When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
** If the option is unknown or SQLite is unable to set the option
** then this routine returns a non-zero [error code].
**
-** INVARIANTS:
-**
-** {H14103} A successful invocation of [sqlite3_config()] shall return
-** [SQLITE_OK].
-**
-** {H14106} The [sqlite3_config()] interface shall return [SQLITE_MISUSE]
-** if it is invoked in between calls to [sqlite3_initialize()] and
-** [sqlite3_shutdown()].
-**
-** {H14120} A successful call to [sqlite3_config]([SQLITE_CONFIG_SINGLETHREAD])
-** shall set the default [threading mode] to Single-thread.
-**
-** {H14123} A successful call to [sqlite3_config]([SQLITE_CONFIG_MULTITHREAD])
-** shall set the default [threading mode] to Multi-thread.
-**
-** {H14126} A successful call to [sqlite3_config]([SQLITE_CONFIG_SERIALIZED])
-** shall set the default [threading mode] to Serialized.
-**
-** {H14129} A successful call to [sqlite3_config]([SQLITE_CONFIG_MUTEX],X)
-** where X is a pointer to an initialized [sqlite3_mutex_methods]
-** object shall cause all subsequent mutex operations performed
-** by SQLite to use the mutex methods that were present in X
-** during the call to [sqlite3_config()].
-**
-** {H14132} A successful call to [sqlite3_config]([SQLITE_CONFIG_GETMUTEX],X)
-** where X is a pointer to an [sqlite3_mutex_methods] object
-** shall overwrite the content of [sqlite3_mutex_methods] object
-** with the mutex methods currently in use by SQLite.
-**
-** {H14135} A successful call to [sqlite3_config]([SQLITE_CONFIG_MALLOC],M)
-** where M is a pointer to an initialized [sqlite3_mem_methods]
-** object shall cause all subsequent memory allocation operations
-** performed by SQLite to use the methods that were present in
-** M during the call to [sqlite3_config()].
-**
-** {H14138} A successful call to [sqlite3_config]([SQLITE_CONFIG_GETMALLOC],M)
-** where M is a pointer to an [sqlite3_mem_methods] object shall
-** overwrite the content of [sqlite3_mem_methods] object with
-** the memory allocation methods currently in use by
-** SQLite.
-**
-** {H14141} A successful call to [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],1)
-** shall enable the memory allocation status collection logic.
-**
-** {H14144} A successful call to [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],0)
-** shall disable the memory allocation status collection logic.
-**
-** {H14147} The memory allocation status collection logic shall be
-** enabled by default.
-**
-** {H14150} A successful call to [sqlite3_config]([SQLITE_CONFIG_SCRATCH],S,Z,N)
-** where Z and N are non-negative integers and
-** S is a pointer to an aligned memory buffer not less than
-** Z*N bytes in size shall cause S to be used by the
-** [scratch memory allocator] for as many as N simulataneous
-** allocations each of size (Z & ~7).
-**
-** {H14153} A successful call to [sqlite3_config]([SQLITE_CONFIG_SCRATCH],S,Z,N)
-** where S is a NULL pointer shall disable the
-** [scratch memory allocator].
-**
-** {H14156} A successful call to
-** [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],S,Z,N)
-** where Z and N are non-negative integers and
-** S is a pointer to an aligned memory buffer not less than
-** Z*N bytes in size shall cause S to be used by the
-** [pagecache memory allocator] for as many as N simulataneous
-** allocations each of size (Z & ~7).
-**
-** {H14159} A successful call to
-** [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],S,Z,N)
-** where S is a NULL pointer shall disable the
-** [pagecache memory allocator].
-**
-** {H14162} A successful call to [sqlite3_config]([SQLITE_CONFIG_HEAP],H,Z,N)
-** where Z and N are non-negative integers and
-** H is a pointer to an aligned memory buffer not less than
-** Z bytes in size shall enable the [memsys5] memory allocator
-** and cause it to use buffer S as its memory source and to use
-** a minimum allocation size of N.
-**
-** {H14165} A successful call to [sqlite3_config]([SQLITE_CONFIG_HEAP],H,Z,N)
-** where H is a NULL pointer shall disable the
-** [memsys5] memory allocator.
-**
-** {H14168} A successful call to [sqlite3_config]([SQLITE_CONFIG_LOOKASIDE],Z,N)
-** shall cause the default [lookaside memory allocator] configuration
-** for new [database connections] to be N slots of Z bytes each.
+** Requirements:
+** [H14103] [H14106] [H14120] [H14123] [H14126] [H14129] [H14132] [H14135]
+** [H14138] [H14141] [H14144] [H14147] [H14150] [H14153] [H14156] [H14159]
+** [H14162] [H14165] [H14168]
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_config(int, ...);
/*
@@ -1606,39 +1397,10 @@
** The only choice for this value is [SQLITE_DBCONFIG_LOOKASIDE].
** New verbs are likely to be added in future releases of SQLite.
** Additional arguments depend on the verb.
**
-** INVARIANTS:
-**
-** {H14203} A call to [sqlite3_db_config(D,V,...)] shall return [SQLITE_OK]
-** if and only if the call is successful.
-**
-** {H14206} If one or more slots of the [lookaside memory allocator] for
-** [database connection] D are in use, then a call to
-** [sqlite3_db_config](D,[SQLITE_DBCONFIG_LOOKASIDE],...) shall
-** fail with an [SQLITE_BUSY] return code.
-**
-** {H14209} A successful call to
-** [sqlite3_db_config](D,[SQLITE_DBCONFIG_LOOKASIDE],B,Z,N) where
-** D is an open [database connection] and Z and N are positive
-** integers and B is an aligned buffer at least Z*N bytes in size
-** shall cause the [lookaside memory allocator] for D to use buffer B
-** with N slots of Z bytes each.
-**
-** {H14212} A successful call to
-** [sqlite3_db_config](D,[SQLITE_DBCONFIG_LOOKASIDE],B,Z,N) where
-** D is an open [database connection] and Z and N are positive
-** integers and B is NULL pointer shall cause the
-** [lookaside memory allocator] for D to a obtain Z*N byte buffer
-** from the primary memory allocator and use that buffer
-** with N lookaside slots of Z bytes each.
-**
-** {H14215} A successful call to
-** [sqlite3_db_config](D,[SQLITE_DBCONFIG_LOOKASIDE],B,Z,N) where
-** D is an open [database connection] and Z and N are zero shall
-** disable the [lookaside memory allocator] for D.
-**
-**
+** Requirements:
+** [H14203] [H14206] [H14209] [H14212] [H14215]
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...);
/*
@@ -1896,16 +1658,10 @@
** 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 considerations.
**
-** INVARIANTS:
-**
-** {H12201} Each new [database connection] shall have the
-** [extended result codes] feature disabled by default.
-**
-** {H12202} The [sqlite3_extended_result_codes(D,F)] interface shall enable
-** [extended result codes] for the [database connection] D
-** if the F parameter is true, or disable them if F is false.
+** Requirements:
+** [H12201] [H12202]
*/
SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
@@ -1940,29 +1696,17 @@
**
** For the purposes of this routine, an [INSERT] is considered to
** be successful even if it is subsequently rolled back.
**
-** INVARIANTS:
-**
-** {H12221} The [sqlite3_last_insert_rowid()] function shall return
-** the [rowid]
-** of the most recent successful [INSERT] performed on the same
-** [database connection] and within the same or higher level
-** trigger context, or zero if there have been no qualifying
-** [INSERT] statements.
-**
-** {H12223} The [sqlite3_last_insert_rowid()] function shall return the
-** same value when called from the same trigger context
-** immediately before and after a [ROLLBACK].
-**
-** ASSUMPTIONS:
-**
-** {A12232} If a separate thread performs a new [INSERT] on the same
-** database connection while the [sqlite3_last_insert_rowid()]
-** function is running and thus changes the last insert [rowid],
-** then the value returned by [sqlite3_last_insert_rowid()] is
-** unpredictable and might not equal either the old or the new
-** last insert [rowid].
+** Requirements:
+** [H12221] [H12223]
+**
+** If a separate thread performs a new [INSERT] on the same
+** database connection while the [sqlite3_last_insert_rowid()]
+** function is running and thus changes the last insert [rowid],
+** then the value returned by [sqlite3_last_insert_rowid()] is
+** unpredictable and might not equal either the old or the new
+** last insert [rowid].
*/
SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
/*
@@ -2015,26 +1759,14 @@
** "DELETE FROM table WHERE 1" instead. Or recompile using the
** [SQLITE_OMIT_TRUNCATE_OPTIMIZATION] compile-time option to disable the
** optimization on all queries.
**
-** INVARIANTS:
-**
-** {H12241} The [sqlite3_changes()] function shall return the number of
-** row changes caused by the most recent INSERT, UPDATE,
-** or DELETE statement on the same database connection and
-** within the same or higher trigger context, or zero if there have
-** not been any qualifying row changes.
-**
-** {H12243} Statements of the form "DELETE FROM tablename" with no
-** WHERE clause shall cause subsequent calls to
-** [sqlite3_changes()] to return zero, regardless of the
-** number of rows originally in the table.
-**
-** ASSUMPTIONS:
-**
-** {A12252} If a separate thread makes changes on the same database connection
-** while [sqlite3_changes()] is running then the value returned
-** is unpredictable and not meaningful.
+** Requirements:
+** [H12241] [H12243]
+**
+** If a separate thread makes changes on the same database connection
+** while [sqlite3_changes()] is running then the value returned
+** is unpredictable and not meaningful.
*/
SQLITE_API int sqlite3_changes(sqlite3*);
/*
@@ -2061,24 +1793,14 @@
** optimization on all queries.
**
** See also the [sqlite3_changes()] interface.
**
-** INVARIANTS:
-**
-** {H12261} The [sqlite3_total_changes()] returns the total number
-** of row changes caused by INSERT, UPDATE, and/or DELETE
-** statements on the same [database connection], in any
-** trigger context, since the database connection was created.
-**
-** {H12263} Statements of the form "DELETE FROM tablename" with no
-** WHERE clause shall not change the value returned
-** by [sqlite3_total_changes()].
-**
-** ASSUMPTIONS:
-**
-** {A12264} If a separate thread makes changes on the same database connection
-** while [sqlite3_total_changes()] is running then the value
-** returned is unpredictable and not meaningful.
+** Requirements:
+** [H12261] [H12263]
+**
+** If a separate thread makes changes on the same database connection
+** while [sqlite3_total_changes()] is running then the value
+** returned is unpredictable and not meaningful.
*/
SQLITE_API int sqlite3_total_changes(sqlite3*);
/*
@@ -2106,21 +1828,13 @@
**
** A call to sqlite3_interrupt() has no effect on SQL statements
** that are started after sqlite3_interrupt() returns.
**
-** INVARIANTS:
-**
-** {H12271} The [sqlite3_interrupt()] interface will force all running
-** SQL statements associated with the same database connection
-** to halt after processing at most one additional row of data.
-**
-** {H12272} Any SQL statement that is interrupted by [sqlite3_interrupt()]
-** will return [SQLITE_INTERRUPT].
-**
-** ASSUMPTIONS:
-**
-** {A12279} If the database connection closes while [sqlite3_interrupt()]
-** is running then bad things will likely happen.
+** Requirements:
+** [H12271] [H12272]
+**
+** If the database connection closes while [sqlite3_interrupt()]
+** is running then bad things will likely happen.
*/
SQLITE_API void sqlite3_interrupt(sqlite3*);
/*
@@ -2139,27 +1853,15 @@
**
** These routines do not parse the SQL statements thus
** will not detect syntactically incorrect SQL.
**
-** INVARIANTS:
-**
-** {H10511} A successful evaluation of [sqlite3_complete()] or
-** [sqlite3_complete16()] functions shall
-** return a numeric 1 if and only if the last non-whitespace
-** token in their input is a semicolon that is not in between
-** the BEGIN and END of a CREATE TRIGGER statement.
-**
-** {H10512} If a memory allocation error occurs during an invocation
-** of [sqlite3_complete()] or [sqlite3_complete16()] then the
-** routine shall return [SQLITE_NOMEM].
-**
-** ASSUMPTIONS:
-**
-** {A10512} The input to [sqlite3_complete()] must be a zero-terminated
-** UTF-8 string.
-**
-** {A10513} The input to [sqlite3_complete16()] must be a zero-terminated
-** UTF-16 string in native byte order.
+** Requirements: [H10511] [H10512]
+**
+** The input to [sqlite3_complete()] must be a zero-terminated
+** UTF-8 string.
+**
+** The input to [sqlite3_complete16()] must be a zero-terminated
+** UTF-16 string in native byte order.
*/
SQLITE_API int sqlite3_complete(const char *sql);
SQLITE_API int sqlite3_complete16(const void *sql);
@@ -2223,34 +1925,13 @@
** The busy callback should not take any actions which modify the
** database connection that invoked the busy handler. Any such actions
** result in undefined behavior.
**
-** INVARIANTS:
-**
-** {H12311} The [sqlite3_busy_handler(D,C,A)] function shall replace
-** busy callback in the [database connection] D with a new
-** a new busy handler C and application data pointer A.
-**
-** {H12312} Newly created [database connections] shall have a busy
-** handler of NULL.
-**
-** {H12314} When two or more [database connections] share a
-** [sqlite3_enable_shared_cache | common cache],
-** the busy handler for the database connection currently using
-** the cache shall be invoked when the cache encounters a lock.
-**
-** {H12316} If a busy handler callback returns zero, then the SQLite interface
-** that provoked the locking event shall return [SQLITE_BUSY].
-**
-** {H12318} SQLite shall invokes the busy handler with two arguments which
-** are a copy of the pointer supplied by the 3rd parameter to
-** [sqlite3_busy_handler()] and a count of the number of prior
-** invocations of the busy handler for the same locking event.
-**
-** ASSUMPTIONS:
-**
-** {A12319} A busy handler must not close the database connection
-** or [prepared statement] that invoked the busy handler.
+** Requirements:
+** [H12311] [H12312] [H12314] [H12316] [H12318]
+**
+** A busy handler must not close the database connection
+** or [prepared statement] that invoked the busy handler.
*/
SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
/*
@@ -2270,23 +1951,10 @@
** [database connection] any any given moment. If another busy handler
** was defined (using [sqlite3_busy_handler()]) prior to calling
** this routine, that other busy handler is cleared.
**
-** INVARIANTS:
-**
-** {H12341} The [sqlite3_busy_timeout()] function shall override any prior
-** [sqlite3_busy_timeout()] or [sqlite3_busy_handler()] setting
-** on the same [database connection].
-**
-** {H12343} If the 2nd parameter to [sqlite3_busy_timeout()] is less than
-** or equal to zero, then the busy handler shall be cleared so that
-** all subsequent locking events immediately return [SQLITE_BUSY].
-**
-** {H12344} If the 2nd parameter to [sqlite3_busy_timeout()] is a positive
-** number N, then a busy handler shall be set that repeatedly calls
-** the xSleep() method in the [sqlite3_vfs | VFS interface] until
-** either the lock clears or until the cumulative sleep time
-** reported back by xSleep() exceeds N milliseconds.
+** Requirements:
+** [H12341] [H12343] [H12344]
*/
SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
/*
@@ -2356,40 +2024,10 @@
** interface defined here. As a consequence, errors that occur in the
** wrapper layer outside of the internal [sqlite3_exec()] call are not
** reflected in subsequent calls to [sqlite3_errcode()] or [sqlite3_errmsg()].
**
-** INVARIANTS:
-**
-** {H12371} If a [sqlite3_get_table()] fails a memory allocation, then
-** it shall free the result table under construction, abort the
-** query in process, skip any subsequent queries, set the
-** *pazResult output pointer to NULL and return [SQLITE_NOMEM].
-**
-** {H12373} If the pnColumn parameter to [sqlite3_get_table()] is not NULL
-** then a successful invocation of [sqlite3_get_table()] shall
-** write the number of columns in the
-** result set of the query into *pnColumn.
-**
-** {H12374} If the pnRow parameter to [sqlite3_get_table()] is not NULL
-** then a successful invocation of [sqlite3_get_table()] shall
-** writes the number of rows in the
-** result set of the query into *pnRow.
-**
-** {H12376} A successful invocation of [sqlite3_get_table()] that computes
-** N rows of result with C columns per row shall make *pazResult
-** point to an array of pointers to (N+1)*C strings where the first
-** C strings are column names as obtained from
-** [sqlite3_column_name()] and the rest are column result values
-** obtained from [sqlite3_column_text()].
-**
-** {H12379} The values in the pazResult array returned by [sqlite3_get_table()]
-** shall remain valid until cleared by [sqlite3_free_table()].
-**
-** {H12382} When an error occurs during evaluation of [sqlite3_get_table()]
-** the function shall set *pazResult to NULL, write an error message
-** into memory obtained from [sqlite3_malloc()], make
-** **pzErrmsg point to that error message, and return a
-** appropriate [error code].
+** Requirements:
+** [H12371] [H12373] [H12374] [H12376] [H12379] [H12382]
*/
SQLITE_API int sqlite3_get_table(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
@@ -2491,24 +2129,10 @@
** The "%z" formatting option works exactly like "%s" with the
** addition that after the string has been read and copied into
** the result, [sqlite3_free()] is called on the input string. {END}
**
-** INVARIANTS:
-**
-** {H17403} The [sqlite3_mprintf()] and [sqlite3_vmprintf()] interfaces
-** return either pointers to zero-terminated UTF-8 strings held in
-** memory obtained from [sqlite3_malloc()] or NULL pointers if
-** a call to [sqlite3_malloc()] fails.
-**
-** {H17406} The [sqlite3_snprintf()] interface writes a zero-terminated
-** UTF-8 string into the buffer pointed to by the second parameter
-** provided that the first parameter is greater than zero.
-**
-** {H17407} The [sqlite3_snprintf()] interface does not write slots of
-** its output buffer (the second parameter) outside the range
-** of 0 through N-1 (where N is the first parameter)
-** regardless of the length of the string
-** requested by the format specification.
+** Requirements:
+** [H17403] [H17406] [H17407]
*/
SQLITE_API char *sqlite3_mprintf(const char*,...);
SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
@@ -2580,59 +2204,20 @@
** installation. Memory allocation errors are detected, but
** they are reported back as [SQLITE_CANTOPEN] or
** [SQLITE_IOERR] rather than [SQLITE_NOMEM].
**
-** INVARIANTS:
-**
-** {H17303} The [sqlite3_malloc(N)] interface returns either a pointer to
-** a newly checked-out block of at least N bytes of memory
-** that is 8-byte aligned, or it returns NULL if it is unable
-** to fulfill the request.
-**
-** {H17304} The [sqlite3_malloc(N)] interface returns a NULL pointer if
-** N is less than or equal to zero.
-**
-** {H17305} The [sqlite3_free(P)] interface releases memory previously
-** returned from [sqlite3_malloc()] or [sqlite3_realloc()],
-** making it available for reuse.
-**
-** {H17306} A call to [sqlite3_free(NULL)] is a harmless no-op.
-**
-** {H17310} A call to [sqlite3_realloc(0,N)] is equivalent to a call
-** to [sqlite3_malloc(N)].
-**
-** {H17312} A call to [sqlite3_realloc(P,0)] is equivalent to a call
-** to [sqlite3_free(P)].
-**
-** {H17315} The SQLite core uses [sqlite3_malloc()], [sqlite3_realloc()],
-** and [sqlite3_free()] for all of its memory allocation and
-** deallocation needs.
-**
-** {H17318} The [sqlite3_realloc(P,N)] interface returns either a pointer
-** to a block of checked-out memory of at least N bytes in size
-** that is 8-byte aligned, or a NULL pointer.
-**
-** {H17321} When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
-** copies the first K bytes of content from P into the newly
-** allocated block, where K is the lesser of N and the size of
-** the buffer P.
-**
-** {H17322} When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
-** releases the buffer P.
-**
-** {H17323} When [sqlite3_realloc(P,N)] returns NULL, the buffer P is
-** not modified or released.
-**
-** ASSUMPTIONS:
-**
-** {A17350} The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
-** must be either NULL or else pointers obtained from a prior
-** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
-** not yet been released.
-**
-** {A17351} The application must not read or write any part of
-** a block of memory after it has been released using
-** [sqlite3_free()] or [sqlite3_realloc()].
+** Requirements:
+** [H17303] [H17304] [H17305] [H17306] [H17310] [H17312] [H17315] [H17318]
+** [H17321] [H17322] [H17323]
+**
+** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
+** must be either NULL or else pointers obtained from a prior
+** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
+** not yet been released.
+**
+** The application must not read or write any part of
+** a block of memory after it has been released using
+** [sqlite3_free()] or [sqlite3_realloc()].
*/
SQLITE_API void *sqlite3_malloc(int);
SQLITE_API void *sqlite3_realloc(void*, int);
SQLITE_API void sqlite3_free(void*);
@@ -2643,28 +2228,10 @@
** SQLite provides these two interfaces for reporting on the status
** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()]
** routines, which form the built-in memory allocation subsystem.
**
-** INVARIANTS:
-**
-** {H17371} The [sqlite3_memory_used()] routine returns the number of bytes
-** of memory currently outstanding (malloced but not freed).
-**
-** {H17373} The [sqlite3_memory_highwater()] routine returns the maximum
-** value of [sqlite3_memory_used()] since the high-water mark
-** was last reset.
-**
-** {H17374} The values returned by [sqlite3_memory_used()] and
-** [sqlite3_memory_highwater()] include any overhead
-** added by SQLite in its implementation of [sqlite3_malloc()],
-** but not overhead added by the any underlying system library
-** routines that [sqlite3_malloc()] may call.
-**
-** {H17375} The memory high-water mark is reset to the current value of
-** [sqlite3_memory_used()] if and only if the parameter to
-** [sqlite3_memory_highwater()] is true. The value returned
-** by [sqlite3_memory_highwater(1)] is the high-water mark
-** prior to the reset.
+** Requirements:
+** [H17371] [H17373] [H17374] [H17375]
*/
SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
@@ -2685,12 +2252,10 @@
** On all subsequent invocations, the pseudo-randomness is generated
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
**
-** INVARIANTS:
-**
-** {H17392} The [sqlite3_randomness(N,P)] interface writes N bytes of
-** high-quality pseudo-randomness into buffer P.
+** Requirements:
+** [H17392]
*/
SQLITE_API void sqlite3_randomness(int N, void *P);
/*
@@ -2765,59 +2330,11 @@
** Note that the authorizer callback is invoked only during
** [sqlite3_prepare()] or its variants. Authorization is not
** performed during statement evaluation in [sqlite3_step()].
**
-** INVARIANTS:
-**
-** {H12501} The [sqlite3_set_authorizer(D,...)] interface registers a
-** authorizer callback with database connection D.
-**
-** {H12502} The authorizer callback is invoked as SQL statements are
-** being parseed and compiled.
-**
-** {H12503} If the authorizer callback returns any value other than
-** [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY], then
-** the application interface call that caused
-** the authorizer callback to run shall fail with an
-** [SQLITE_ERROR] error code and an appropriate error message.
-**
-** {H12504} When the authorizer callback returns [SQLITE_OK], the operation
-** described is processed normally.
-**
-** {H12505} When the authorizer callback returns [SQLITE_DENY], the
-** application interface call that caused the
-** authorizer callback to run shall fail
-** with an [SQLITE_ERROR] error code and an error message
-** explaining that access is denied.
-**
-** {H12506} If the authorizer code (the 2nd parameter to the authorizer
-** callback) is [SQLITE_READ] and the authorizer callback returns
-** [SQLITE_IGNORE], then the prepared statement is constructed to
-** insert a NULL value in place of the table column that would have
-** been read if [SQLITE_OK] had been returned.
-**
-** {H12507} If the authorizer code (the 2nd parameter to the authorizer
-** callback) is anything other than [SQLITE_READ], then
-** a return of [SQLITE_IGNORE] has the same effect as [SQLITE_DENY].
-**
-** {H12510} The first parameter to the authorizer callback is a copy of
-** the third parameter to the [sqlite3_set_authorizer()] interface.
-**
-** {H12511} The second parameter to the callback is an integer
-** [SQLITE_COPY | action code] that specifies the particular action
-** to be authorized.
-**
-** {H12512} The third through sixth parameters to the callback are
-** zero-terminated strings that contain
-** additional details about the action to be authorized.
-**
-** {H12520} Each call to [sqlite3_set_authorizer()] overrides
-** any previously installed authorizer.
-**
-** {H12521} A NULL authorizer means that no authorization
-** callback is invoked.
-**
-** {H12522} The default authorizer is NULL.
+** Requirements:
+** [H12501] [H12502] [H12503] [H12504] [H12505] [H12506] [H12507] [H12510]
+** [H12511] [H12512] [H12520] [H12521] [H12522]
*/
SQLITE_API int sqlite3_set_authorizer(
sqlite3*,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
@@ -2854,29 +2371,10 @@
** is the name of the inner-most trigger or view that is responsible for
** the access attempt or NULL if this access attempt is directly from
** top-level SQL code.
**
-** INVARIANTS:
-**
-** {H12551} The second parameter to an
-** [sqlite3_set_authorizer | authorizer callback] shall be an integer
-** [SQLITE_COPY | authorizer code] that specifies what action
-** is being authorized.
-**
-** {H12552} The 3rd and 4th parameters to the
-** [sqlite3_set_authorizer | authorization callback]
-** shall be parameters or NULL depending on which
-** [SQLITE_COPY | authorizer code] is used as the second parameter.
-**
-** {H12553} The 5th parameter to the
-** [sqlite3_set_authorizer | authorizer callback] shall be the name
-** of the database (example: "main", "temp", etc.) if applicable.
-**
-** {H12554} The 6th parameter to the
-** [sqlite3_set_authorizer | authorizer callback] shall be the name
-** of the inner-most trigger or view that is responsible for
-** the access attempt or NULL if this access attempt is directly from
-** top-level SQL code.
+** Requirements:
+** [H12551] [H12552] [H12553] [H12554]
*/
/******************************************* 3rd ************ 4th ***********/
#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */
#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */
@@ -2930,43 +2428,11 @@
** as each SQL statement finishes. The profile callback contains
** the original statement text and an estimate of wall-clock time
** of how long that statement took to run.
**
-** INVARIANTS:
-**
-** {H12281} The callback function registered by [sqlite3_trace()]
-** shall be invoked
-** whenever an SQL statement first begins to execute and
-** whenever a trigger subprogram first begins to run.
-**
-** {H12282} Each call to [sqlite3_trace()] shall override the previously
-** registered trace callback.
-**
-** {H12283} A NULL trace callback shall disable tracing.
-**
-** {H12284} The first argument to the trace callback shall be a copy of
-** the pointer which was the 3rd argument to [sqlite3_trace()].
-**
-** {H12285} The second argument to the trace callback is a
-** zero-terminated UTF-8 string containing the original text
-** of the SQL statement as it was passed into [sqlite3_prepare_v2()]
-** or the equivalent, or an SQL comment indicating the beginning
-** of a trigger subprogram.
-**
-** {H12287} The callback function registered by [sqlite3_profile()] is invoked
-** as each SQL statement finishes.
-**
-** {H12288} The first parameter to the profile callback is a copy of
-** the 3rd parameter to [sqlite3_profile()].
-**
-** {H12289} The second parameter to the profile callback is a
-** zero-terminated UTF-8 string that contains the complete text of
-** the SQL statement as it was processed by [sqlite3_prepare_v2()]
-** or the equivalent.
-**
-** {H12290} The third parameter to the profile callback is an estimate
-** of the number of nanoseconds of wall-clock time required to
-** run the SQL statement from start to finish.
+** Requirements:
+** [H12281] [H12282] [H12283] [H12284] [H12285] [H12287] [H12288] [H12289]
+** [H12290]
*/
SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
@@ -2988,39 +2454,11 @@
** the database connection that invoked the progress handler.
** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
** database connections for the meaning of "modify" in this paragraph.
**
-** INVARIANTS:
-**
-** {H12911} The callback function registered by sqlite3_progress_handler()
-** is invoked periodically during long running calls to
-** [sqlite3_step()].
-**
-** {H12912} The progress callback is invoked once for every N virtual
-** machine opcodes, where N is the second argument to
-** the [sqlite3_progress_handler()] call that registered
-** the callback. If N is less than 1, sqlite3_progress_handler()
-** acts as if a NULL progress handler had been specified.
-**
-** {H12913} The progress callback itself is identified by the third
-** argument to sqlite3_progress_handler().
-**
-** {H12914} The fourth argument to sqlite3_progress_handler() is a
-** void pointer passed to the progress callback
-** function each time it is invoked.
-**
-** {H12915} If a call to [sqlite3_step()] results in fewer than N opcodes
-** being executed, then the progress callback is never invoked.
-**
-** {H12916} Every call to [sqlite3_progress_handler()]
-** overwrites any previously registered progress handler.
-**
-** {H12917} If the progress handler callback is NULL then no progress
-** handler is invoked.
-**
-** {H12918} If the progress callback returns a result other than 0, then
-** the behavior is a if [sqlite3_interrupt()] had been called.
-** <S30500>
+** Requirements:
+** [H12911] [H12912] [H12913] [H12914] [H12915] [H12916] [H12917] [H12918]
+**
*/
SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
/*
@@ -3102,74 +2540,11 @@
** codepage is currently defined. Filenames containing international
** characters must be converted to UTF-8 prior to passing them into
** sqlite3_open() or sqlite3_open_v2().
**
-** INVARIANTS:
-**
-** {H12701} The [sqlite3_open()], [sqlite3_open16()], and
-** [sqlite3_open_v2()] interfaces create a new
-** [database connection] associated with
-** the database file given in their first parameter.
-**
-** {H12702} 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()].
-**
-** {H12703} A successful invocation of [sqlite3_open()], [sqlite3_open16()],
-** or [sqlite3_open_v2()] writes a pointer to a new
-** [database connection] into *ppDb.
-**
-** {H12704} The [sqlite3_open()], [sqlite3_open16()], and
-** [sqlite3_open_v2()] interfaces return [SQLITE_OK] upon success,
-** or an appropriate [error code] on failure.
-**
-** {H12706} The default text encoding for a new database created using
-** [sqlite3_open()] or [sqlite3_open_v2()] will be UTF-8.
-**
-** {H12707} The default text encoding for a new database created using
-** [sqlite3_open16()] will be UTF-16.
-**
-** {H12709} The [sqlite3_open(F,D)] interface is equivalent to
-** [sqlite3_open_v2(F,D,G,0)] where the G parameter is
-** [SQLITE_OPEN_READWRITE]|[SQLITE_OPEN_CREATE].
-**
-** {H12711} If the G parameter to [sqlite3_open_v2(F,D,G,V)] contains the
-** bit value [SQLITE_OPEN_READONLY] then the database is opened
-** for reading only.
-**
-** {H12712} If the G parameter to [sqlite3_open_v2(F,D,G,V)] contains the
-** bit value [SQLITE_OPEN_READWRITE] then the database is opened
-** reading and writing if possible, or for reading only if the
-** file is write protected by the operating system.
-**
-** {H12713} If the G parameter to [sqlite3_open_v2(F,D,G,V)] omits the
-** bit value [SQLITE_OPEN_CREATE] and the database does not
-** previously exist, an error is returned.
-**
-** {H12714} If the G parameter to [sqlite3_open_v2(F,D,G,V)] contains the
-** bit value [SQLITE_OPEN_CREATE] and the database does not
-** previously exist, then an attempt is made to create and
-** initialize the database.
-**
-** {H12717} If the filename argument to [sqlite3_open()], [sqlite3_open16()],
-** or [sqlite3_open_v2()] is ":memory:", then an private,
-** ephemeral, in-memory database is created for the connection.
-** <todo>Is SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE required
-** in sqlite3_open_v2()?</todo>
-**
-** {H12719} If the filename is NULL or an empty string, then a private,
-** ephemeral on-disk database will be created.
-** <todo>Is SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE required
-** in sqlite3_open_v2()?</todo>
-**
-** {H12721} The [database connection] created by [sqlite3_open_v2(F,D,G,V)]
-** will use the [sqlite3_vfs] object identified by the V parameter,
-** or the default [sqlite3_vfs] object if V is a NULL pointer.
-**
-** {H12723} Two [database connections] will share a common cache if both were
-** opened with the same VFS while [shared cache mode] was enabled and
-** if both filenames compare equal using memcmp() after having been
-** processed by the [sqlite3_vfs | xFullPathname] method of the VFS.
+** Requirements:
+** [H12701] [H12702] [H12703] [H12704] [H12706] [H12707] [H12709] [H12711]
+** [H12712] [H12713] [H12714] [H12717] [H12719] [H12721] [H12723]
*/
SQLITE_API int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
@@ -3217,38 +2592,10 @@
** If an interface fails with SQLITE_MISUSE, that means the interface
** was invoked incorrectly by the application. In that case, the
** error code and message may or may not be set.
**
-** INVARIANTS:
-**
-** {H12801} The [sqlite3_errcode(D)] interface returns the numeric
-** [result code] or [extended result code] for the most recently
-** failed interface call associated with the [database connection] D.
-**
-** {H12802} The [sqlite3_extended_errcode(D)] interface returns the numeric
-** [extended result code] for the most recently
-** failed interface call associated with the [database connection] D.
-**
-** {H12803} The [sqlite3_errmsg(D)] and [sqlite3_errmsg16(D)]
-** interfaces return English-language text that describes
-** the error in the mostly recently failed interface call,
-** encoded as either UTF-8 or UTF-16 respectively.
-**
-** {H12807} The strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]
-** are valid until the next SQLite interface call.
-**
-** {H12808} Calls to API routines that do not return an error code
-** (example: [sqlite3_data_count()]) do not
-** change the error code or message returned by
-** [sqlite3_errcode()], [sqlite3_extended_errcode()],
-** [sqlite3_errmsg()], or [sqlite3_errmsg16()].
-**
-** {H12809} Interfaces that are not associated with a specific
-** [database connection] (examples:
-** [sqlite3_mprintf()] or [sqlite3_enable_shared_cache()]
-** do not change the values returned by
-** [sqlite3_errcode()], [sqlite3_extended_errcode()],
-** [sqlite3_errmsg()], or [sqlite3_errmsg16()].
+** Requirements:
+** [H12801] [H12802] [H12803] [H12807] [H12808] [H12809]
*/
SQLITE_API int sqlite3_errcode(sqlite3 *db);
SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
SQLITE_API const char *sqlite3_errmsg(sqlite3*);
@@ -3290,18 +2637,20 @@
** class of constructs to be size limited. The third parameter is the
** new limit for that construct. The function returns the old limit.
**
** If the new limit is a negative number, the limit is unchanged.
-** For the limit category of SQLITE_LIMIT_XYZ there is a hard upper
-** bound set by a compile-time C preprocessor macro named SQLITE_MAX_XYZ.
+** For the limit category of SQLITE_LIMIT_XYZ there is a
+** [limits | hard upper bound]
+** set by a compile-time C preprocessor macro named
+** [limits | SQLITE_MAX_XYZ].
** (The "_LIMIT_" in the name is changed to "_MAX_".)
** Attempts to increase a limit above its hard upper bound are
** silently truncated to the hard upper limit.
**
** Run time limits are intended for use in applications that manage
** both their own internal database and also databases that are controlled
** by untrusted external sources. An example application might be a
-** webbrowser that has its own databases for storing history and
+** web browser that has its own databases for storing history and
** separate databases controlled by JavaScript applications downloaded
** off the Internet. The internal databases can be given the
** large, default limits. Databases managed by external sources can
** be given much smaller limits designed to prevent a denial of service
@@ -3311,31 +2660,21 @@
** [max_page_count] [PRAGMA].
**
** New run-time limit categories may be added in future releases.
**
-** INVARIANTS:
-**
-** {H12762} A successful call to [sqlite3_limit(D,C,V)] where V is
-** positive changes the limit on the size of construct C in the
-** [database connection] D to the lesser of V and the hard upper
-** bound on the size of C that is set at compile-time.
-**
-** {H12766} A successful call to [sqlite3_limit(D,C,V)] where V is negative
-** leaves the state of the [database connection] D unchanged.
-**
-** {H12769} A successful call to [sqlite3_limit(D,C,V)] returns the
-** value of the limit on the size of construct C in the
-** [database connection] D as it was prior to the call.
+** Requirements:
+** [H12762] [H12766] [H12769]
*/
SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
/*
** CAPI3REF: Run-Time Limit Categories {H12790} <H12760>
** KEYWORDS: {limit category} {limit categories}
**
-** These constants define various aspects of a [database connection]
-** that can be limited in size by calls to [sqlite3_limit()].
-** The meanings of the various limits are as follows:
+** These constants define various performance limits
+** that can be lowered at run-time using [sqlite3_limit()].
+** The synopsis of the meanings of the various limits is shown below.
+** Additional information is available at [limits | Limits in SQLite].
**
** <dl>
** <dt>SQLITE_LIMIT_LENGTH</dt>
** <dd>The maximum size of any string or BLOB or table row.<dd>
@@ -3344,9 +2683,9 @@
** <dd>The maximum length of an SQL statement.</dd>
**
** <dt>SQLITE_LIMIT_COLUMN</dt>
** <dd>The maximum number of columns in a table definition or in the
-** result set of a SELECT or the maximum number of columns in an index
+** result set of a [SELECT] or the maximum number of columns in an index
** or in an ORDER BY or GROUP BY clause.</dd>
**
** <dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
** <dd>The maximum depth of the parse tree on any expression.</dd>
@@ -3361,13 +2700,13 @@
** <dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
** <dd>The maximum number of arguments on a function.</dd>
**
** <dt>SQLITE_LIMIT_ATTACHED</dt>
-** <dd>The maximum number of attached databases.</dd>
+** <dd>The maximum number of [ATTACH | attached databases].</dd>
**
** <dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt>
-** <dd>The maximum length of the pattern argument to the LIKE or
-** GLOB operators.</dd>
+** <dd>The maximum length of the pattern argument to the [LIKE] or
+** [GLOB] operators.</dd>
**
** <dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
** <dd>The maximum number of variables in an SQL statement that can
** be bound.</dd>
@@ -3452,43 +2791,11 @@
** interfaces, the underlying reason for the error is returned immediately.
** </li>
** </ol>
**
-** INVARIANTS:
-**
-** {H13011} The [sqlite3_prepare(db,zSql,...)] and
-** [sqlite3_prepare_v2(db,zSql,...)] interfaces interpret the
-** text in their zSql parameter as UTF-8.
-**
-** {H13012} The [sqlite3_prepare16(db,zSql,...)] and
-** [sqlite3_prepare16_v2(db,zSql,...)] interfaces interpret the
-** text in their zSql parameter as UTF-16 in the native byte order.
-**
-** {H13013} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
-** and its variants is less than zero, the SQL text is
-** read from zSql is read up to the first zero terminator.
-**
-** {H13014} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
-** and its variants is non-negative, then at most nBytes bytes of
-** SQL text is read from zSql.
-**
-** {H13015} In [sqlite3_prepare_v2(db,zSql,N,P,pzTail)] and its variants
-** if the zSql input text contains more than one SQL statement
-** and pzTail is not NULL, then *pzTail is made to point to the
-** first byte past the end of the first SQL statement in zSql.
-** <todo>What does *pzTail point to if there is one statement?</todo>
-**
-** {H13016} A successful call to [sqlite3_prepare_v2(db,zSql,N,ppStmt,...)]
-** or one of its variants writes into *ppStmt a pointer to a new
-** [prepared statement] or a pointer to NULL if zSql contains
-** nothing other than whitespace or comments.
-**
-** {H13019} The [sqlite3_prepare_v2()] interface and its variants return
-** [SQLITE_OK] or an appropriate [error code] upon failure.
-**
-** {H13021} Before [sqlite3_prepare(db,zSql,nByte,ppStmt,pzTail)] or its
-** variants returns an error (any value other than [SQLITE_OK]),
-** they first set *ppStmt to NULL.
+** Requirements:
+** [H13011] [H13012] [H13013] [H13014] [H13015] [H13016] [H13019] [H13021]
+**
*/
SQLITE_API int sqlite3_prepare(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
@@ -3524,22 +2831,10 @@
** 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()].
**
-** INVARIANTS:
-**
-** {H13101} If the [prepared statement] passed as the argument to
-** [sqlite3_sql()] was compiled using either [sqlite3_prepare_v2()] or
-** [sqlite3_prepare16_v2()], then [sqlite3_sql()] returns
-** a pointer to a zero-terminated string containing a UTF-8 rendering
-** of the original SQL statement.
-**
-** {H13102} If the [prepared statement] passed as the argument to
-** [sqlite3_sql()] was compiled using either [sqlite3_prepare()] or
-** [sqlite3_prepare16()], then [sqlite3_sql()] returns a NULL pointer.
-**
-** {H13103} The string returned by [sqlite3_sql(S)] is valid until the
-** [prepared statement] S is deleted using [sqlite3_finalize(S)].
+** Requirements:
+** [H13101] [H13102] [H13103]
*/
SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
/*
@@ -3600,9 +2895,9 @@
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
**
** In the SQL strings input to [sqlite3_prepare_v2()] and its variants,
-** literals may be replaced by a parameter in one of these forms:
+** literals may be replaced by a [parameter] in one of these forms:
**
** <ul>
** <li> ?
** <li> ?NNN
@@ -3673,81 +2968,12 @@
**
** See also: [sqlite3_bind_parameter_count()],
** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
**
-** INVARIANTS:
-**
-** {H13506} The [SQL statement compiler] recognizes tokens of the forms
-** "?", "?NNN", "$VVV", ":VVV", and "@VVV" as SQL parameters,
-** where NNN is any sequence of one or more digits
-** and where VVV is any sequence of one or more alphanumeric
-** characters or "::" optionally followed by a string containing
-** no spaces and contained within parentheses.
-**
-** {H13509} The initial value of an SQL parameter is NULL.
-**
-** {H13512} The index of an "?" SQL parameter is one larger than the
-** largest index of SQL parameter to the left, or 1 if
-** the "?" is the leftmost SQL parameter.
-**
-** {H13515} The index of an "?NNN" SQL parameter is the integer NNN.
-**
-** {H13518} The index of an ":VVV", "$VVV", or "@VVV" SQL parameter is
-** the same as the index of leftmost occurrences of the same
-** parameter, or one more than the largest index over all
-** parameters to the left if this is the first occurrence
-** of this parameter, or 1 if this is the leftmost parameter.
-**
-** {H13521} The [SQL statement compiler] fails with an [SQLITE_RANGE]
-** error if the index of an SQL parameter is less than 1
-** or greater than the compile-time SQLITE_MAX_VARIABLE_NUMBER
-** parameter.
-**
-** {H13524} Calls to [sqlite3_bind_text | sqlite3_bind(S,N,V,...)]
-** associate the value V with all SQL parameters having an
-** index of N in the [prepared statement] S.
-**
-** {H13527} Calls to [sqlite3_bind_text | sqlite3_bind(S,N,...)]
-** override prior calls with the same values of S and N.
-**
-** {H13530} Bindings established by [sqlite3_bind_text | sqlite3_bind(S,...)]
-** persist across calls to [sqlite3_reset(S)].
-**
-** {H13533} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
-** [sqlite3_bind_text(S,N,V,L,D)], or
-** [sqlite3_bind_text16(S,N,V,L,D)] SQLite binds the first L
-** bytes of the BLOB or string pointed to by V, when L
-** is non-negative.
-**
-** {H13536} In calls to [sqlite3_bind_text(S,N,V,L,D)] or
-** [sqlite3_bind_text16(S,N,V,L,D)] SQLite binds characters
-** from V through the first zero character when L is negative.
-**
-** {H13539} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
-** [sqlite3_bind_text(S,N,V,L,D)], or
-** [sqlite3_bind_text16(S,N,V,L,D)] when D is the special
-** constant [SQLITE_STATIC], SQLite assumes that the value V
-** is held in static unmanaged space that will not change
-** during the lifetime of the binding.
-**
-** {H13542} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
-** [sqlite3_bind_text(S,N,V,L,D)], or
-** [sqlite3_bind_text16(S,N,V,L,D)] when D is the special
-** constant [SQLITE_TRANSIENT], the routine makes a
-** private copy of the value V before it returns.
-**
-** {H13545} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
-** [sqlite3_bind_text(S,N,V,L,D)], or
-** [sqlite3_bind_text16(S,N,V,L,D)] when D is a pointer to
-** a function, SQLite invokes that function to destroy the
-** value V after it has finished using the value V.
-**
-** {H13548} In calls to [sqlite3_bind_zeroblob(S,N,V,L)] the value bound
-** is a BLOB of L bytes, or a zero-length BLOB if L is negative.
-**
-** {H13551} In calls to [sqlite3_bind_value(S,N,V)] the V argument may
-** be either a [protected sqlite3_value] object or an
-** [unprotected sqlite3_value] object.
+** Requirements:
+** [H13506] [H13509] [H13512] [H13515] [H13518] [H13521] [H13524] [H13527]
+** [H13530] [H13533] [H13536] [H13539] [H13542] [H13545] [H13548] [H13551]
+**
*/
SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
@@ -3775,13 +3001,10 @@
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_name()], and
** [sqlite3_bind_parameter_index()].
**
-** INVARIANTS:
-**
-** {H13601} The [sqlite3_bind_parameter_count(S)] interface returns
-** the largest index of all SQL parameters in the
-** [prepared statement] S, or 0 if S contains no SQL parameters.
+** Requirements:
+** [H13601]
*/
SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
/*
@@ -3808,15 +3031,10 @@
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_index()].
**
-** INVARIANTS:
-**
-** {H13621} The [sqlite3_bind_parameter_name(S,N)] interface returns
-** a UTF-8 rendering of the name of the SQL parameter in
-** the [prepared statement] S having index N, or
-** NULL if there is no SQL parameter with index N or if the
-** parameter with index N is an anonymous parameter "?".
+** Requirements:
+** [H13621]
*/
SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
/*
@@ -3832,14 +3050,10 @@
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_index()].
**
-** INVARIANTS:
-**
-** {H13641} The [sqlite3_bind_parameter_index(S,N)] interface returns
-** the index of SQL parameter in the [prepared statement]
-** S whose name matches the UTF-8 string N, or 0 if there is
-** no match.
+** Requirements:
+** [H13641]
*/
SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
/*
@@ -3848,12 +3062,10 @@
** 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.
**
-** INVARIANTS:
-**
-** {H13661} The [sqlite3_clear_bindings(S)] interface resets all SQL
-** parameter bindings in the [prepared statement] S back to NULL.
+** Requirements:
+** [H13661]
*/
SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
/*
@@ -3862,13 +3074,10 @@
** 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]).
**
-** INVARIANTS:
-**
-** {H13711} The [sqlite3_column_count(S)] interface returns the number of
-** columns in the result set generated by the [prepared statement] S,
-** or 0 if S does not generate a result set.
+** Requirements:
+** [H13711]
*/
SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
/*
@@ -3894,37 +3103,10 @@
** that column, if there is an AS clause. If there is no AS clause
** then the name of the column is unspecified and may change from
** one release of SQLite to the next.
**
-** INVARIANTS:
-**
-** {H13721} A successful invocation of the [sqlite3_column_name(S,N)]
-** interface returns the name of the Nth column (where 0 is
-** the leftmost column) for the result set of the
-** [prepared statement] S as a zero-terminated UTF-8 string.
-**
-** {H13723} A successful invocation of the [sqlite3_column_name16(S,N)]
-** interface returns the name of the Nth column (where 0 is
-** the leftmost column) for the result set of the
-** [prepared statement] S as a zero-terminated UTF-16 string
-** in the native byte order.
-**
-** {H13724} The [sqlite3_column_name()] and [sqlite3_column_name16()]
-** interfaces return a NULL pointer if they are unable to
-** allocate memory to hold their normal return strings.
-**
-** {H13725} If the N parameter to [sqlite3_column_name(S,N)] or
-** [sqlite3_column_name16(S,N)] is out of range, then the
-** interfaces return a NULL pointer.
-**
-** {H13726} The strings returned by [sqlite3_column_name(S,N)] and
-** [sqlite3_column_name16(S,N)] are valid until the next
-** call to either routine with the same S and N parameters
-** or until [sqlite3_finalize(S)] is called.
-**
-** {H13727} When a result column of a [SELECT] statement contains
-** an AS clause, the name of that column is the identifier
-** to the right of the AS keyword.
+** Requirements:
+** [H13721] [H13723] [H13724] [H13725] [H13726] [H13727]
*/
SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
@@ -3964,59 +3146,15 @@
** If two or more threads call one or more of these routines against the same
** prepared statement and column at the same time then the results are
** undefined.
**
-** INVARIANTS:
-**
-** {H13741} The [sqlite3_column_database_name(S,N)] interface returns either
-** the UTF-8 zero-terminated name of the database from which the
-** Nth result column of the [prepared statement] S is extracted,
-** or NULL if the Nth column of S is a general expression
-** or if unable to allocate memory to store the name.
-**
-** {H13742} The [sqlite3_column_database_name16(S,N)] interface returns either
-** the UTF-16 native byte order zero-terminated name of the database
-** from which the Nth result column of the [prepared statement] S is
-** extracted, or NULL if the Nth column of S is a general expression
-** or if unable to allocate memory to store the name.
-**
-** {H13743} The [sqlite3_column_table_name(S,N)] interface returns either
-** the UTF-8 zero-terminated name of the table from which the
-** Nth result column of the [prepared statement] S is extracted,
-** or NULL if the Nth column of S is a general expression
-** or if unable to allocate memory to store the name.
-**
-** {H13744} The [sqlite3_column_table_name16(S,N)] interface returns either
-** the UTF-16 native byte order zero-terminated name of the table
-** from which the Nth result column of the [prepared statement] S is
-** extracted, or NULL if the Nth column of S is a general expression
-** or if unable to allocate memory to store the name.
-**
-** {H13745} The [sqlite3_column_origin_name(S,N)] interface returns either
-** the UTF-8 zero-terminated name of the table column from which the
-** Nth result column of the [prepared statement] S is extracted,
-** or NULL if the Nth column of S is a general expression
-** or if unable to allocate memory to store the name.
-**
-** {H13746} The [sqlite3_column_origin_name16(S,N)] interface returns either
-** the UTF-16 native byte order zero-terminated name of the table
-** column from which the Nth result column of the
-** [prepared statement] S is extracted, or NULL if the Nth column
-** of S is a general expression or if unable to allocate memory
-** to store the name.
-**
-** {H13748} The return values from
-** [sqlite3_column_database_name | column metadata interfaces]
-** are valid for the lifetime of the [prepared statement]
-** or until the encoding is changed by another metadata
-** interface call for the same prepared statement and column.
-**
-** ASSUMPTIONS:
-**
-** {A13751} If two or more threads call one or more
-** [sqlite3_column_database_name | column metadata interfaces]
-** for the same [prepared statement] and result column
-** at the same time then the results are undefined.
+** Requirements:
+** [H13741] [H13742] [H13743] [H13744] [H13745] [H13746] [H13748]
+**
+** If two or more threads call one or more
+** [sqlite3_column_database_name | column metadata interfaces]
+** for the same [prepared statement] and result column
+** at the same time then the results are undefined.
*/
SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
@@ -4052,28 +3190,10 @@
** strongly typed, but the typing is dynamic not static. Type
** is associated with individual values, not with the containers
** used to hold those values.
**
-** INVARIANTS:
-**
-** {H13761} A successful call to [sqlite3_column_decltype(S,N)] returns a
-** zero-terminated UTF-8 string containing the declared datatype
-** of the table column that appears as the Nth column (numbered
-** from 0) of the result set to the [prepared statement] S.
-**
-** {H13762} A successful call to [sqlite3_column_decltype16(S,N)]
-** returns a zero-terminated UTF-16 native byte order string
-** containing the declared datatype of the table column that appears
-** as the Nth column (numbered from 0) of the result set to the
-** [prepared statement] S.
-**
-** {H13763} If N is less than 0 or N is greater than or equal to
-** the number of columns in the [prepared statement] S,
-** or if the Nth column of S is an expression or subquery rather
-** than a table column, or if a memory allocation failure
-** occurs during encoding conversions, then
-** calls to [sqlite3_column_decltype(S,N)] or
-** [sqlite3_column_decltype16(S,N)] return NULL.
+** Requirements:
+** [H13761] [H13762] [H13763]
*/
SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
@@ -4141,33 +3261,10 @@
** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
** then the more specific [error codes] are returned directly
** by sqlite3_step(). The use of the "v2" interface is recommended.
**
-** INVARIANTS:
-**
-** {H13202} If the [prepared statement] S is ready to be run, then
-** [sqlite3_step(S)] advances that prepared statement until
-** completion or until it is ready to return another row of the
-** result set, or until an [sqlite3_interrupt | interrupt]
-** or a run-time error occurs.
-**
-** {H15304} When a call to [sqlite3_step(S)] causes the [prepared statement]
-** S to run to completion, the function returns [SQLITE_DONE].
-**
-** {H15306} When a call to [sqlite3_step(S)] stops because it is ready to
-** return another row of the result set, it returns [SQLITE_ROW].
-**
-** {H15308} If a call to [sqlite3_step(S)] encounters an
-** [sqlite3_interrupt | interrupt] or a run-time error,
-** it returns an appropriate error code that is not one of
-** [SQLITE_OK], [SQLITE_ROW], or [SQLITE_DONE].
-**
-** {H15310} If an [sqlite3_interrupt | interrupt] or a run-time error
-** occurs during a call to [sqlite3_step(S)]
-** for a [prepared statement] S created using
-** legacy interfaces [sqlite3_prepare()] or
-** [sqlite3_prepare16()], then the function returns either
-** [SQLITE_ERROR], [SQLITE_BUSY], or [SQLITE_MISUSE].
+** Requirements:
+** [H13202] [H15304] [H15306] [H15308] [H15310]
*/
SQLITE_API int sqlite3_step(sqlite3_stmt*);
/*
@@ -4174,19 +3271,10 @@
** CAPI3REF: Number of columns in a result set {H13770} <S10700>
**
** Returns the number of values in the current row of the result set.
**
-** INVARIANTS:
-**
-** {H13771} After a call to [sqlite3_step(S)] that returns [SQLITE_ROW],
-** the [sqlite3_data_count(S)] routine will return the same value
-** as the [sqlite3_column_count(S)] function.
-**
-** {H13772} After [sqlite3_step(S)] has returned any value other than
-** [SQLITE_ROW] or before [sqlite3_step(S)] has been called on the
-** [prepared statement] for the first time since it was
-** [sqlite3_prepare | prepared] or [sqlite3_reset | reset],
-** the [sqlite3_data_count(S)] routine returns zero.
+** Requirements:
+** [H13771] [H13772]
*/
SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
/*
@@ -4372,62 +3460,11 @@
** is either the integer 0, the floating point number 0.0, or a NULL
** pointer. Subsequent calls to [sqlite3_errcode()] will return
** [SQLITE_NOMEM].
**
-** INVARIANTS:
-**
-** {H13803} The [sqlite3_column_blob(S,N)] interface converts the
-** Nth column in the current row of the result set for
-** the [prepared statement] S into a BLOB and then returns a
-** pointer to the converted value.
-**
-** {H13806} The [sqlite3_column_bytes(S,N)] interface returns the
-** number of bytes in the BLOB or string (exclusive of the
-** zero terminator on the string) that was returned by the
-** most recent call to [sqlite3_column_blob(S,N)] or
-** [sqlite3_column_text(S,N)].
-**
-** {H13809} The [sqlite3_column_bytes16(S,N)] interface returns the
-** number of bytes in the string (exclusive of the
-** zero terminator on the string) that was returned by the
-** most recent call to [sqlite3_column_text16(S,N)].
-**
-** {H13812} The [sqlite3_column_double(S,N)] interface converts the
-** Nth column in the current row of the result set for the
-** [prepared statement] S into a floating point value and
-** returns a copy of that value.
-**
-** {H13815} The [sqlite3_column_int(S,N)] interface converts the
-** Nth column in the current row of the result set for the
-** [prepared statement] S into a 64-bit signed integer and
-** returns the lower 32 bits of that integer.
-**
-** {H13818} The [sqlite3_column_int64(S,N)] interface converts the
-** Nth column in the current row of the result set for the
-** [prepared statement] S into a 64-bit signed integer and
-** returns a copy of that integer.
-**
-** {H13821} The [sqlite3_column_text(S,N)] interface converts the
-** Nth column in the current row of the result set for
-** the [prepared statement] S into a zero-terminated UTF-8
-** string and returns a pointer to that string.
-**
-** {H13824} The [sqlite3_column_text16(S,N)] interface converts the
-** Nth column in the current row of the result set for the
-** [prepared statement] S into a zero-terminated 2-byte
-** aligned UTF-16 native byte order string and returns
-** a pointer to that string.
-**
-** {H13827} The [sqlite3_column_type(S,N)] interface returns
-** one of [SQLITE_NULL], [SQLITE_INTEGER], [SQLITE_FLOAT],
-** [SQLITE_TEXT], or [SQLITE_BLOB] as appropriate for
-** the Nth column in the current row of the result set for
-** the [prepared statement] S.
-**
-** {H13830} The [sqlite3_column_value(S,N)] interface returns a
-** pointer to an [unprotected sqlite3_value] object for the
-** Nth column in the current row of the result set for
-** the [prepared statement] S.
+** Requirements:
+** [H13803] [H13806] [H13809] [H13812] [H13815] [H13818] [H13821] [H13824]
+** [H13827] [H13830]
*/
SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
@@ -4454,17 +3491,10 @@
** Incomplete updates may be rolled back and transactions canceled,
** depending on the circumstances, and the
** [error code] returned will be [SQLITE_ABORT].
**
-** INVARIANTS:
-**
-** {H11302} The [sqlite3_finalize(S)] interface destroys the
-** [prepared statement] S and releases all
-** memory and file resources held by that object.
-**
-** {H11304} If the most recent call to [sqlite3_step(S)] for the
-** [prepared statement] S returned an error,
-** then [sqlite3_finalize(S)] returns that same error.
+** Requirements:
+** [H11302] [H11304]
*/
SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
/*
@@ -4569,72 +3599,11 @@
** SQLite interfaces. However, such calls must not
** close the database connection nor finalize or reset the prepared
** statement in which the function is running.
**
-** INVARIANTS:
-**
-** {H16103} The [sqlite3_create_function16(D,X,...)] interface shall behave
-** as [sqlite3_create_function(D,X,...)] in every way except that it
-** interprets the X argument as zero-terminated UTF-16
-** native byte order instead of as zero-terminated UTF-8.
-**
-** {H16106} A successful invocation of the
-** [sqlite3_create_function(D,X,N,E,...)] interface shall register
-** or replaces callback functions in the [database connection] D
-** used to implement the SQL function named X with N parameters
-** and having a preferred text encoding of E.
-**
-** {H16109} A successful call to [sqlite3_create_function(D,X,N,E,P,F,S,L)]
-** shall replace the P, F, S, and L values from any prior calls with
-** the same D, X, N, and E values.
-**
-** {H16112} The [sqlite3_create_function(D,X,...)] interface shall fail
-** if the SQL function name X is
-** longer than 255 bytes exclusive of the zero terminator.
-**
-** {H16118} The [sqlite3_create_function(D,X,N,E,P,F,S,L)] interface
-** shall fail unless either F is NULL and S and L are non-NULL or
-*** F is non-NULL and S and L are NULL.
-**
-** {H16121} The [sqlite3_create_function(D,...)] interface shall fails with an
-** error code of [SQLITE_BUSY] if there exist [prepared statements]
-** associated with the [database connection] D.
-**
-** {H16124} The [sqlite3_create_function(D,X,N,...)] interface shall fail with
-** an error code of [SQLITE_ERROR] if parameter N is less
-** than -1 or greater than 127.
-**
-** {H16127} When N is non-negative, the [sqlite3_create_function(D,X,N,...)]
-** interface shall register callbacks to be invoked for the
-** SQL function
-** named X when the number of arguments to the SQL function is
-** exactly N.
-**
-** {H16130} When N is -1, the [sqlite3_create_function(D,X,N,...)]
-** interface shall register callbacks to be invoked for the SQL
-** function named X with any number of arguments.
-**
-** {H16133} When calls to [sqlite3_create_function(D,X,N,...)]
-** specify multiple implementations of the same function X
-** and when one implementation has N>=0 and the other has N=(-1)
-** the implementation with a non-zero N shall be preferred.
-**
-** {H16136} When calls to [sqlite3_create_function(D,X,N,E,...)]
-** specify multiple implementations of the same function X with
-** the same number of arguments N but with different
-** encodings E, then the implementation where E matches the
-** database encoding shall preferred.
-**
-** {H16139} For an aggregate SQL function created using
-** [sqlite3_create_function(D,X,N,E,P,0,S,L)] the finalizer
-** function L shall always be invoked exactly once if the
-** step function S is called one or more times.
-**
-** {H16142} When SQLite invokes either the xFunc or xStep function of
-** an application-defined SQL function or aggregate created
-** by [sqlite3_create_function()] or [sqlite3_create_function16()],
-** then the array of [sqlite3_value] objects passed as the
-** third parameter shall be [protected sqlite3_value] objects.
+** Requirements:
+** [H16103] [H16106] [H16109] [H16112] [H16118] [H16121] [H16124] [H16127]
+** [H16130] [H16133] [H16136] [H16139] [H16142]
*/
SQLITE_API int sqlite3_create_function(
sqlite3 *db,
const char *zFunctionName,
@@ -4732,69 +3701,11 @@
**
** These routines must be called from the same thread as
** the SQL function that supplied the [sqlite3_value*] parameters.
**
-** INVARIANTS:
-**
-** {H15103} The [sqlite3_value_blob(V)] interface converts the
-** [protected sqlite3_value] object V into a BLOB and then
-** returns a pointer to the converted value.
-**
-** {H15106} The [sqlite3_value_bytes(V)] interface returns the
-** number of bytes in the BLOB or string (exclusive of the
-** zero terminator on the string) that was returned by the
-** most recent call to [sqlite3_value_blob(V)] or
-** [sqlite3_value_text(V)].
-**
-** {H15109} The [sqlite3_value_bytes16(V)] interface returns the
-** number of bytes in the string (exclusive of the
-** zero terminator on the string) that was returned by the
-** most recent call to [sqlite3_value_text16(V)],
-** [sqlite3_value_text16be(V)], or [sqlite3_value_text16le(V)].
-**
-** {H15112} The [sqlite3_value_double(V)] interface converts the
-** [protected sqlite3_value] object V into a floating point value and
-** returns a copy of that value.
-**
-** {H15115} The [sqlite3_value_int(V)] interface converts the
-** [protected sqlite3_value] object V into a 64-bit signed integer and
-** returns the lower 32 bits of that integer.
-**
-** {H15118} The [sqlite3_value_int64(V)] interface converts the
-** [protected sqlite3_value] object V into a 64-bit signed integer and
-** returns a copy of that integer.
-**
-** {H15121} The [sqlite3_value_text(V)] interface converts the
-** [protected sqlite3_value] object V into a zero-terminated UTF-8
-** string and returns a pointer to that string.
-**
-** {H15124} The [sqlite3_value_text16(V)] interface converts the
-** [protected sqlite3_value] object V into a zero-terminated 2-byte
-** aligned UTF-16 native byte order
-** string and returns a pointer to that string.
-**
-** {H15127} The [sqlite3_value_text16be(V)] interface converts the
-** [protected sqlite3_value] object V into a zero-terminated 2-byte
-** aligned UTF-16 big-endian
-** string and returns a pointer to that string.
-**
-** {H15130} The [sqlite3_value_text16le(V)] interface converts the
-** [protected sqlite3_value] object V into a zero-terminated 2-byte
-** aligned UTF-16 little-endian
-** string and returns a pointer to that string.
-**
-** {H15133} The [sqlite3_value_type(V)] interface returns
-** one of [SQLITE_NULL], [SQLITE_INTEGER], [SQLITE_FLOAT],
-** [SQLITE_TEXT], or [SQLITE_BLOB] as appropriate for
-** the [sqlite3_value] object V.
-**
-** {H15136} The [sqlite3_value_numeric_type(V)] interface converts
-** the [protected sqlite3_value] object V into either an integer or
-** a floating point value if it can do so without loss of
-** information, and returns one of [SQLITE_NULL],
-** [SQLITE_INTEGER], [SQLITE_FLOAT], [SQLITE_TEXT], or
-** [SQLITE_BLOB] as appropriate for the
-** [protected sqlite3_value] object V after the conversion attempt.
+** Requirements:
+** [H15103] [H15106] [H15109] [H15112] [H15115] [H15118] [H15121] [H15124]
+** [H15127] [H15130] [H15133] [H15136]
*/
SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
@@ -4830,27 +3741,10 @@
**
** This routine must be called from the same thread in which
** the aggregate SQL function is running.
**
-** INVARIANTS:
-**
-** {H16211} The first invocation of [sqlite3_aggregate_context(C,N)] for
-** a particular instance of an aggregate function (for a particular
-** context C) causes SQLite to allocate N bytes of memory,
-** zero that memory, and return a pointer to the allocated memory.
-**
-** {H16213} If a memory allocation error occurs during
-** [sqlite3_aggregate_context(C,N)] then the function returns 0.
-**
-** {H16215} Second and subsequent invocations of
-** [sqlite3_aggregate_context(C,N)] for the same context pointer C
-** ignore the N parameter and return a pointer to the same
-** block of memory returned by the first invocation.
-**
-** {H16217} The memory allocated by [sqlite3_aggregate_context(C,N)] is
-** automatically freed on the next call to [sqlite3_reset()]
-** or [sqlite3_finalize()] for the [prepared statement] containing
-** the aggregate function associated with context C.
+** Requirements:
+** [H16211] [H16213] [H16215] [H16217]
*/
SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
/*
@@ -4864,14 +3758,10 @@
**
** This routine must be called from the same thread in which
** the application-defined function is running.
**
-** INVARIANTS:
-**
-** {H16243} The [sqlite3_user_data(C)] interface returns a copy of the
-** P pointer from the [sqlite3_create_function(D,X,N,E,P,F,S,L)]
-** or [sqlite3_create_function16(D,X,N,E,P,F,S,L)] call that
-** registered the SQL function associated with [sqlite3_context] C.
+** Requirements:
+** [H16243]
*/
SQLITE_API void *sqlite3_user_data(sqlite3_context*);
/*
@@ -4882,14 +3772,10 @@
** of the [sqlite3_create_function()]
** and [sqlite3_create_function16()] routines that originally
** registered the application defined function.
**
-** INVARIANTS:
-**
-** {H16253} The [sqlite3_context_db_handle(C)] interface returns a copy of the
-** D pointer from the [sqlite3_create_function(D,X,N,E,P,F,S,L)]
-** or [sqlite3_create_function16(D,X,N,E,P,F,S,L)] call that
-** registered the SQL function associated with [sqlite3_context] C.
+** Requirements:
+** [H16253]
*/
SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
/*
@@ -4933,33 +3819,10 @@
**
** These routines must be called from the same thread in which
** the SQL function is running.
**
-** INVARIANTS:
-**
-** {H16272} The [sqlite3_get_auxdata(C,N)] interface returns a pointer
-** to metadata associated with the Nth parameter of the SQL function
-** whose context is C, or NULL if there is no metadata associated
-** with that parameter.
-**
-** {H16274} The [sqlite3_set_auxdata(C,N,P,D)] interface assigns a metadata
-** pointer P to the Nth parameter of the SQL function with context C.
-**
-** {H16276} SQLite will invoke the destructor D with a single argument
-** which is the metadata pointer P following a call to
-** [sqlite3_set_auxdata(C,N,P,D)] when SQLite ceases to hold
-** the metadata.
-**
-** {H16277} SQLite ceases to hold metadata for an SQL function parameter
-** when the value of that parameter changes.
-**
-** {H16278} When [sqlite3_set_auxdata(C,N,P,D)] is invoked, the destructor
-** is called for any prior metadata associated with the same function
-** context C and parameter N.
-**
-** {H16279} SQLite will call destructors for any metadata it is holding
-** in a particular [prepared statement] S when either
-** [sqlite3_reset(S)] or [sqlite3_finalize(S)] is called.
+** Requirements:
+** [H16272] [H16274] [H16276] [H16277] [H16278] [H16279]
*/
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
@@ -5085,103 +3948,12 @@
** If these routines are called from within the different thread
** than the one containing the application-defined function that received
** the [sqlite3_context] pointer, the results are undefined.
**
-** INVARIANTS:
-**
-** {H16403} The default return value from any SQL function is NULL.
-**
-** {H16406} The [sqlite3_result_blob(C,V,N,D)] interface changes the
-** return value of function C to be a BLOB that is N bytes
-** in length and with content pointed to by V.
-**
-** {H16409} The [sqlite3_result_double(C,V)] interface changes the
-** return value of function C to be the floating point value V.
-**
-** {H16412} The [sqlite3_result_error(C,V,N)] interface changes the return
-** value of function C to be an exception with error code
-** [SQLITE_ERROR] and a UTF-8 error message copied from V up to the
-** first zero byte or until N bytes are read if N is positive.
-**
-** {H16415} The [sqlite3_result_error16(C,V,N)] interface changes the return
-** value of function C to be an exception with error code
-** [SQLITE_ERROR] and a UTF-16 native byte order error message
-** copied from V up to the first zero terminator or until N bytes
-** are read if N is positive.
-**
-** {H16418} The [sqlite3_result_error_toobig(C)] interface changes the return
-** value of the function C to be an exception with error code
-** [SQLITE_TOOBIG] and an appropriate error message.
-**
-** {H16421} The [sqlite3_result_error_nomem(C)] interface changes the return
-** value of the function C to be an exception with error code
-** [SQLITE_NOMEM] and an appropriate error message.
-**
-** {H16424} The [sqlite3_result_error_code(C,E)] interface changes the return
-** value of the function C to be an exception with error code E.
-** The error message text is unchanged.
-**
-** {H16427} The [sqlite3_result_int(C,V)] interface changes the
-** return value of function C to be the 32-bit integer value V.
-**
-** {H16430} The [sqlite3_result_int64(C,V)] interface changes the
-** return value of function C to be the 64-bit integer value V.
-**
-** {H16433} The [sqlite3_result_null(C)] interface changes the
-** return value of function C to be NULL.
-**
-** {H16436} The [sqlite3_result_text(C,V,N,D)] interface changes the
-** return value of function C to be the UTF-8 string
-** V up to the first zero if N is negative
-** or the first N bytes of V if N is non-negative.
-**
-** {H16439} The [sqlite3_result_text16(C,V,N,D)] interface changes the
-** return value of function C to be the UTF-16 native byte order
-** string V up to the first zero if N is negative
-** or the first N bytes of V if N is non-negative.
-**
-** {H16442} The [sqlite3_result_text16be(C,V,N,D)] interface changes the
-** return value of function C to be the UTF-16 big-endian
-** string V up to the first zero if N is negative
-** or the first N bytes or V if N is non-negative.
-**
-** {H16445} The [sqlite3_result_text16le(C,V,N,D)] interface changes the
-** return value of function C to be the UTF-16 little-endian
-** string V up to the first zero if N is negative
-** or the first N bytes of V if N is non-negative.
-**
-** {H16448} The [sqlite3_result_value(C,V)] interface changes the
-** return value of function C to be the [unprotected sqlite3_value]
-** object V.
-**
-** {H16451} The [sqlite3_result_zeroblob(C,N)] interface changes the
-** return value of function C to be an N-byte BLOB of all zeros.
-**
-** {H16454} The [sqlite3_result_error()] and [sqlite3_result_error16()]
-** interfaces make a copy of their error message strings before
-** returning.
-**
-** {H16457} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
-** [sqlite3_result_text(C,V,N,D)], [sqlite3_result_text16(C,V,N,D)],
-** [sqlite3_result_text16be(C,V,N,D)], or
-** [sqlite3_result_text16le(C,V,N,D)] is the constant [SQLITE_STATIC]
-** then no destructor is ever called on the pointer V and SQLite
-** assumes that V is immutable.
-**
-** {H16460} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
-** [sqlite3_result_text(C,V,N,D)], [sqlite3_result_text16(C,V,N,D)],
-** [sqlite3_result_text16be(C,V,N,D)], or
-** [sqlite3_result_text16le(C,V,N,D)] is the constant
-** [SQLITE_TRANSIENT] then the interfaces makes a copy of the
-** content of V and retains the copy.
-**
-** {H16463} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
-** [sqlite3_result_text(C,V,N,D)], [sqlite3_result_text16(C,V,N,D)],
-** [sqlite3_result_text16be(C,V,N,D)], or
-** [sqlite3_result_text16le(C,V,N,D)] is some value other than
-** the constants [SQLITE_STATIC] and [SQLITE_TRANSIENT] then
-** SQLite will invoke the destructor D with V as its only argument
-** when it has finished with the V value.
+** Requirements:
+** [H16403] [H16406] [H16409] [H16412] [H16415] [H16418] [H16421] [H16424]
+** [H16427] [H16430] [H16433] [H16436] [H16439] [H16442] [H16445] [H16448]
+** [H16451] [H16454] [H16457] [H16460] [H16463]
*/
SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
@@ -5240,56 +4012,11 @@
** Collations are destroyed when they are overridden by later calls to the
** collation creation functions or when the [database connection] is closed
** using [sqlite3_close()].
**
-** INVARIANTS:
-**
-** {H16603} A successful call to the
-** [sqlite3_create_collation_v2(B,X,E,P,F,D)] interface
-** registers function F as the comparison function used to
-** implement collation X on the [database connection] B for
-** databases having encoding E.
-**
-** {H16604} SQLite understands the X parameter to
-** [sqlite3_create_collation_v2(B,X,E,P,F,D)] as a zero-terminated
-** UTF-8 string in which case is ignored for ASCII characters and
-** is significant for non-ASCII characters.
-**
-** {H16606} Successive calls to [sqlite3_create_collation_v2(B,X,E,P,F,D)]
-** with the same values for B, X, and E, override prior values
-** of P, F, and D.
-**
-** {H16609} If the destructor D in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
-** is not NULL then it is called with argument P when the
-** collating function is dropped by SQLite.
-**
-** {H16612} A collating function is dropped when it is overloaded.
-**
-** {H16615} A collating function is dropped when the database connection
-** is closed using [sqlite3_close()].
-**
-** {H16618} The pointer P in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
-** is passed through as the first parameter to the comparison
-** function F for all subsequent invocations of F.
-**
-** {H16621} A call to [sqlite3_create_collation(B,X,E,P,F)] is exactly
-** the same as a call to [sqlite3_create_collation_v2()] with
-** the same parameters and a NULL destructor.
-**
-** {H16624} Following a [sqlite3_create_collation_v2(B,X,E,P,F,D)],
-** SQLite uses the comparison function F for all text comparison
-** operations on the [database connection] B on text values that
-** use the collating sequence named X.
-**
-** {H16627} The [sqlite3_create_collation16(B,X,E,P,F)] works the same
-** as [sqlite3_create_collation(B,X,E,P,F)] except that the
-** collation name X is understood as UTF-16 in native byte order
-** instead of UTF-8.
-**
-** {H16630} When multiple comparison functions are available for the same
-** collating sequence, SQLite chooses the one whose text encoding
-** requires the least amount of conversion from the default
-** text encoding of the database.
+** Requirements:
+** [H16603] [H16604] [H16606] [H16609] [H16612] [H16615] [H16618] [H16621]
+** [H16624] [H16627] [H16630]
*/
SQLITE_API int sqlite3_create_collation(
sqlite3*,
const char *zName,
@@ -5338,26 +4065,10 @@
** The callback function should register the desired collation using
** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
** [sqlite3_create_collation_v2()].
**
-** INVARIANTS:
-**
-** {H16702} A successful call to [sqlite3_collation_needed(D,P,F)]
-** or [sqlite3_collation_needed16(D,P,F)] causes
-** the [database connection] D to invoke callback F with first
-** parameter P whenever it needs a comparison function for a
-** collating sequence that it does not know about.
-**
-** {H16704} Each successful call to [sqlite3_collation_needed()] or
-** [sqlite3_collation_needed16()] overrides the callback registered
-** on the same [database connection] by prior calls to either
-** interface.
-**
-** {H16706} The name of the requested collating function passed in the
-** 4th parameter to the callback is in UTF-8 if the callback
-** was registered using [sqlite3_collation_needed()] and
-** is in UTF-16 native byte order if the callback was
-** registered using [sqlite3_collation_needed16()].
+** Requirements:
+** [H16702] [H16704] [H16706]
*/
SQLITE_API int sqlite3_collation_needed(
sqlite3*,
void*,
@@ -5407,18 +4118,9 @@
**
** SQLite implements this interface by calling the xSleep()
** method of the default [sqlite3_vfs] object.
**
-** INVARIANTS:
-**
-** {H10533} The [sqlite3_sleep(M)] interface invokes the xSleep
-** method of the default [sqlite3_vfs|VFS] in order to
-** suspend execution of the current thread for at least
-** M milliseconds.
-**
-** {H10536} The [sqlite3_sleep(M)] interface returns the number of
-** milliseconds of sleep actually requested of the operating
-** system, which might be larger than the parameter M.
+** Requirements: [H10533] [H10536]
*/
SQLITE_API int sqlite3_sleep(int);
/*
@@ -5453,43 +4155,26 @@
** transaction might be rolled back automatically. The only way to
** find out whether SQLite automatically rolled back the transaction after
** an error is to use this function.
**
-** INVARIANTS:
-**
-** {H12931} The [sqlite3_get_autocommit(D)] interface returns non-zero or
-** zero if the [database connection] D is or is not in autocommit
-** mode, respectively.
-**
-** {H12932} Autocommit mode is on by default.
-**
-** {H12933} Autocommit mode is disabled by a successful [BEGIN] statement.
-**
-** {H12934} Autocommit mode is enabled by a successful [COMMIT] or [ROLLBACK]
-** statement.
-**
-** ASSUMPTIONS:
-**
-** {A12936} If another thread changes the autocommit status of the database
-** connection while this routine is running, then the return value
-** is undefined.
+** If another thread changes the autocommit status of the database
+** connection while this routine is running, then the return value
+** is undefined.
+**
+** Requirements: [H12931] [H12932] [H12933] [H12934]
*/
SQLITE_API int sqlite3_get_autocommit(sqlite3*);
/*
** CAPI3REF: Find The Database Handle Of A Prepared Statement {H13120} <S60600>
**
** The sqlite3_db_handle interface returns the [database connection] handle
-** to which a [prepared statement] belongs. The database handle returned by
-** sqlite3_db_handle is the same database handle that was the first argument
+** to which a [prepared statement] belongs. The [database connection]
+** returned by sqlite3_db_handle is the same [database connection] that was the first argument
** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
** create the statement in the first place.
**
-** INVARIANTS:
-**
-** {H13123} The [sqlite3_db_handle(S)] interface returns a pointer
-** to the [database connection] associated with the
-** [prepared statement] S.
+** Requirements: [H13123]
*/
SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
/*
@@ -5500,33 +4185,13 @@
** then this interface returns a pointer to the first prepared statement
** associated with the database connection pDb. If no prepared statement
** satisfies the conditions of this routine, it returns NULL.
**
-** INVARIANTS:
-**
-** {H13143} If D is a [database connection] that holds one or more
-** unfinalized [prepared statements] and S is a NULL pointer,
-** then [sqlite3_next_stmt(D, S)] routine shall return a pointer
-** to one of the prepared statements associated with D.
-**
-** {H13146} If D is a [database connection] that holds no unfinalized
-** [prepared statements] and S is a NULL pointer, then
-** [sqlite3_next_stmt(D, S)] routine shall return a NULL pointer.
-**
-** {H13149} If S is a [prepared statement] in the [database connection] D
-** and S is not the last prepared statement in D, then
-** [sqlite3_next_stmt(D, S)] routine shall return a pointer
-** to the next prepared statement in D after S.
-**
-** {H13152} If S is the last [prepared statement] in the
-** [database connection] D then the [sqlite3_next_stmt(D, S)]
-** routine shall return a NULL pointer.
-**
-** ASSUMPTIONS:
-**
-** {A13154} The [database connection] pointer D in a call to
-** [sqlite3_next_stmt(D,S)] must refer to an open database
-** connection and in particular must not be a NULL pointer.
+** The [database connection] pointer D in a call to
+** [sqlite3_next_stmt(D,S)] must refer to an open database
+** connection and in particular must not be a NULL pointer.
+**
+** Requirements: [H13143] [H13146] [H13149] [H13152]
*/
SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
/*
@@ -5565,43 +4230,11 @@
** The rollback callback is not invoked if a transaction is
** rolled back because a commit callback returned non-zero.
** <todo> Check on this </todo>
**
-** INVARIANTS:
-**
-** {H12951} The [sqlite3_commit_hook(D,F,P)] interface registers the
-** callback function F to be invoked with argument P whenever
-** a transaction commits on the [database connection] D.
-**
-** {H12952} The [sqlite3_commit_hook(D,F,P)] interface returns the P argument
-** from the previous call with the same [database connection] D,
-** or NULL on the first call for a particular database connection D.
-**
-** {H12953} Each call to [sqlite3_commit_hook()] overwrites the callback
-** registered by prior calls.
-**
-** {H12954} If the F argument to [sqlite3_commit_hook(D,F,P)] is NULL
-** then the commit hook callback is canceled and no callback
-** is invoked when a transaction commits.
-**
-** {H12955} If the commit callback returns non-zero then the commit is
-** converted into a rollback.
-**
-** {H12961} The [sqlite3_rollback_hook(D,F,P)] interface registers the
-** callback function F to be invoked with argument P whenever
-** a transaction rolls back on the [database connection] D.
-**
-** {H12962} The [sqlite3_rollback_hook(D,F,P)] interface returns the P
-** argument from the previous call with the same
-** [database connection] D, or NULL on the first call
-** for a particular database connection D.
-**
-** {H12963} Each call to [sqlite3_rollback_hook()] overwrites the callback
-** registered by prior calls.
-**
-** {H12964} If the F argument to [sqlite3_rollback_hook(D,F,P)] is NULL
-** then the rollback hook callback is canceled and no callback
-** is invoked when a transaction rolls back.
+** Requirements:
+** [H12951] [H12952] [H12953] [H12954] [H12955]
+** [H12961] [H12962] [H12963] [H12964]
*/
SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
@@ -5638,38 +4271,10 @@
**
** If another function was previously registered, its pArg value
** is returned. Otherwise NULL is returned.
**
-** INVARIANTS:
-**
-** {H12971} The [sqlite3_update_hook(D,F,P)] interface causes the callback
-** function F to be invoked with first parameter P whenever
-** a table row is modified, inserted, or deleted on
-** the [database connection] D.
-**
-** {H12973} The [sqlite3_update_hook(D,F,P)] interface returns the value
-** of P for the previous call on the same [database connection] D,
-** or NULL for the first call.
-**
-** {H12975} If the update hook callback F in [sqlite3_update_hook(D,F,P)]
-** is NULL then the no update callbacks are made.
-**
-** {H12977} Each call to [sqlite3_update_hook(D,F,P)] overrides prior calls
-** to the same interface on the same [database connection] D.
-**
-** {H12979} The update hook callback is not invoked when internal system
-** tables such as sqlite_master and sqlite_sequence are modified.
-**
-** {H12981} The second parameter to the update callback
-** is one of [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE],
-** depending on the operation that caused the callback to be invoked.
-**
-** {H12983} The third and fourth arguments to the callback contain pointers
-** to zero-terminated UTF-8 strings which are the names of the
-** database and table that is being updated.
-
-** {H12985} The final callback parameter is the [rowid] of the row after
-** the change occurs.
+** Requirements:
+** [H12971] [H12973] [H12975] [H12977] [H12979] [H12981] [H12983] [H12986]
*/
SQLITE_API void *sqlite3_update_hook(
sqlite3*,
void(*)(void *,int ,char const *,char const *,sqlite3_int64),
@@ -5684,9 +4289,9 @@
** and schema data structures between [database connection | connections]
** to the same database. Sharing is enabled if the argument is true
** and disabled if the argument is false.
**
-** Cache sharing is enabled and disabled for an entire process. {END}
+** Cache sharing is enabled and disabled for an entire process.
** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
** sharing was enabled or disabled for each thread separately.
**
** The cache sharing mode set by this interface effects all subsequent
@@ -5704,21 +4309,11 @@
** Shared cache is disabled by default. But this might change in
** future releases of SQLite. Applications that care about shared
** cache setting should set it explicitly.
**
-** INVARIANTS:
-**
-** {H10331} A successful invocation of [sqlite3_enable_shared_cache(B)]
-** will enable or disable shared cache mode for any subsequently
-** created [database connection] in the same process.
-**
-** {H10336} When shared cache is enabled, the [sqlite3_create_module()]
-** interface will always return an error.
-**
-** {H10337} The [sqlite3_enable_shared_cache(B)] interface returns
-** [SQLITE_OK] if shared cache was enabled or disabled successfully.
-**
-** {H10339} Shared cache is disabled by default.
+** See Also: [SQLite Shared-Cache Mode]
+**
+** Requirements: [H10331] [H10336] [H10337] [H10339]
*/
SQLITE_API int sqlite3_enable_shared_cache(int);
/*
@@ -5730,17 +4325,9 @@
** pages to improve performance is an example of non-essential memory.
** sqlite3_release_memory() returns the number of bytes actually freed,
** which might be more or less than the amount requested.
**
-** INVARIANTS:
-**
-** {H17341} The [sqlite3_release_memory(N)] interface attempts to
-** free N bytes of heap memory by deallocating non-essential
-** memory allocations held by the database library.
-**
-** {H16342} The [sqlite3_release_memory(N)] returns the number
-** of bytes actually freed, which might be more or less
-** than the amount requested.
+** Requirements: [H17341] [H17342]
*/
SQLITE_API int sqlite3_release_memory(int);
/*
@@ -5772,35 +4359,10 @@
** is an upper bound on the total memory allocation for all threads. In
** version 3.5.0 there is no mechanism for limiting the heap usage for
** individual threads.
**
-** INVARIANTS:
-**
-** {H16351} The [sqlite3_soft_heap_limit(N)] interface places a soft limit
-** of N bytes on the amount of heap memory that may be allocated
-** using [sqlite3_malloc()] or [sqlite3_realloc()] at any point
-** in time.
-**
-** {H16352} If a call to [sqlite3_malloc()] or [sqlite3_realloc()] would
-** cause the total amount of allocated memory to exceed the
-** soft heap limit, then [sqlite3_release_memory()] is invoked
-** in an attempt to reduce the memory usage prior to proceeding
-** with the memory allocation attempt.
-**
-** {H16353} Calls to [sqlite3_malloc()] or [sqlite3_realloc()] that trigger
-** attempts to reduce memory usage through the soft heap limit
-** mechanism continue even if the attempt to reduce memory
-** usage is unsuccessful.
-**
-** {H16354} A negative or zero value for N in a call to
-** [sqlite3_soft_heap_limit(N)] means that there is no soft
-** heap limit and [sqlite3_release_memory()] will only be
-** called when memory is completely exhausted.
-**
-** {H16355} The default value for the soft heap limit is zero.
-**
-** {H16358} Each call to [sqlite3_soft_heap_limit(N)] overrides the
-** values set by all prior calls.
+** Requirements:
+** [H16351] [H16352] [H16353] [H16354] [H16355] [H16358]
*/
SQLITE_API void sqlite3_soft_heap_limit(int);
/*
@@ -6298,36 +4860,10 @@
** Changes written into a BLOB prior to the BLOB expiring are not
** rollback by the expiration of the BLOB. Such changes will eventually
** commit if the transaction continues to completion.
**
-** INVARIANTS:
-**
-** {H17813} A successful invocation of the [sqlite3_blob_open(D,B,T,C,R,F,P)]
-** interface shall open an [sqlite3_blob] object P on the BLOB
-** in column C of the table T in the database B on
-** the [database connection] D.
-**
-** {H17814} A successful invocation of [sqlite3_blob_open(D,...)] shall start
-** a new transaction on the [database connection] D if that
-** connection is not already in a transaction.
-**
-** {H17816} The [sqlite3_blob_open(D,B,T,C,R,F,P)] interface shall open
-** the BLOB for read and write access if and only if the F
-** parameter is non-zero.
-**
-** {H17819} The [sqlite3_blob_open()] interface shall return [SQLITE_OK] on
-** success and an appropriate [error code] on failure.
-**
-** {H17821} If an error occurs during evaluation of [sqlite3_blob_open(D,...)]
-** then subsequent calls to [sqlite3_errcode(D)],
-** [sqlite3_extended_errcode()],
-** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
-** information appropriate for that error.
-**
-** {H17824} If any column in the row that a [sqlite3_blob] has open is
-** changed by a separate [UPDATE] or [DELETE] statement or by
-** an [ON CONFLICT] side effect, then the [sqlite3_blob] shall
-** be marked as invalid.
+** Requirements:
+** [H17813] [H17814] [H17816] [H17819] [H17821] [H17824]
*/
SQLITE_API int sqlite3_blob_open(
sqlite3*,
const char *zDb,
@@ -6356,22 +4892,10 @@
**
** The BLOB is closed unconditionally. Even if this routine returns
** an error code, the BLOB is still closed.
**
-** INVARIANTS:
-**
-** {H17833} The [sqlite3_blob_close(P)] interface closes an [sqlite3_blob]
-** object P previously opened using [sqlite3_blob_open()].
-**
-** {H17836} Closing an [sqlite3_blob] object using
-** [sqlite3_blob_close()] shall cause the current transaction to
-** commit if there are no other open [sqlite3_blob] objects
-** or [prepared statements] on the same [database connection] and
-** the database connection is in [autocommit mode].
-**
-** {H17839} The [sqlite3_blob_close(P)] interfaces shall close the
-** [sqlite3_blob] object P unconditionally, even if
-** [sqlite3_blob_close(P)] returns something other than [SQLITE_OK].
+** Requirements:
+** [H17833] [H17836] [H17839]
*/
SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
/*
@@ -6379,13 +4903,10 @@
**
** Returns the size in bytes of the BLOB accessible via the open
** []BLOB handle] in its only argument.
**
-** INVARIANTS:
-**
-** {H17843} The [sqlite3_blob_bytes(P)] interface returns the size
-** in bytes of the BLOB that the [sqlite3_blob] object P
-** refers to.
+** Requirements:
+** [H17843]
*/
SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
/*
@@ -6404,40 +4925,10 @@
**
** On success, SQLITE_OK is returned.
** Otherwise, an [error code] or an [extended error code] is returned.
**
-** INVARIANTS:
-**
-** {H17853} A successful invocation of [sqlite3_blob_read(P,Z,N,X)]
-** shall reads N bytes of data out of the BLOB referenced by
-** [BLOB handle] P beginning at offset X and store those bytes
-** into buffer Z.
-**
-** {H17856} In [sqlite3_blob_read(P,Z,N,X)] if the size of the BLOB
-** is less than N+X bytes, then the function shall leave the
-** Z buffer unchanged and return [SQLITE_ERROR].
-**
-** {H17859} In [sqlite3_blob_read(P,Z,N,X)] if X or N is less than zero
-** then the function shall leave the Z buffer unchanged
-** and return [SQLITE_ERROR].
-**
-** {H17862} The [sqlite3_blob_read(P,Z,N,X)] interface shall return [SQLITE_OK]
-** if N bytes are successfully read into buffer Z.
-**
-** {H17863} If the [BLOB handle] P is expired and X and N are within bounds
-** then [sqlite3_blob_read(P,Z,N,X)] shall leave the Z buffer
-** unchanged and return [SQLITE_ABORT].
-**
-** {H17865} If the requested read could not be completed,
-** the [sqlite3_blob_read(P,Z,N,X)] interface shall return an
-** appropriate [error code] or [extended error code].
-**
-** {H17868} If an error occurs during evaluation of [sqlite3_blob_read(P,...)]
-** then subsequent calls to [sqlite3_errcode(D)],
-** [sqlite3_extended_errcode()],
-** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
-** information appropriate for that error, where D is the
-** [database connection] that was used to open the [BLOB handle] P.
+** Requirements:
+** [H17853] [H17856] [H17859] [H17862] [H17863] [H17865] [H17868]
*/
SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
/*
@@ -6466,47 +4957,11 @@
**
** On success, SQLITE_OK is returned.
** Otherwise, an [error code] or an [extended error code] is returned.
**
-** INVARIANTS:
-**
-** {H17873} A successful invocation of [sqlite3_blob_write(P,Z,N,X)]
-** shall write N bytes of data from buffer Z into the BLOB
-** referenced by [BLOB handle] P beginning at offset X into
-** the BLOB.
-**
-** {H17874} In the absence of other overridding changes, the changes
-** written to a BLOB by [sqlite3_blob_write()] shall
-** remain in effect after the associated [BLOB handle] expires.
-**
-** {H17875} If the [BLOB handle] P was opened for reading only then
-** an invocation of [sqlite3_blob_write(P,Z,N,X)] shall leave
-** the referenced BLOB unchanged and return [SQLITE_READONLY].
-**
-** {H17876} If the size of the BLOB referenced by [BLOB handle] P is
-** less than N+X bytes then [sqlite3_blob_write(P,Z,N,X)] shall
-** leave the BLOB unchanged and return [SQLITE_ERROR].
-**
-** {H17877} If the [BLOB handle] P is expired and X and N are within bounds
-** then [sqlite3_blob_read(P,Z,N,X)] shall leave the BLOB
-** unchanged and return [SQLITE_ABORT].
-**
-** {H17879} If X or N are less than zero then [sqlite3_blob_write(P,Z,N,X)]
-** shall leave the BLOB referenced by [BLOB handle] P unchanged
-** and return [SQLITE_ERROR].
-**
-** {H17882} The [sqlite3_blob_write(P,Z,N,X)] interface shall return
-** [SQLITE_OK] if N bytes where successfully written into the BLOB.
-**
-** {H17885} If the requested write could not be completed,
-** the [sqlite3_blob_write(P,Z,N,X)] interface shall return an
-** appropriate [error code] or [extended error code].
-**
-** {H17888} If an error occurs during evaluation of [sqlite3_blob_write(D,...)]
-** then subsequent calls to [sqlite3_errcode(D)],
-** [sqlite3_extended_errcode()],
-** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
-** information appropriate for that error.
+** Requirements:
+** [H17873] [H17874] [H17875] [H17876] [H17877] [H17879] [H17882] [H17885]
+** [H17888]
*/
SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
/*
@@ -6537,33 +4992,10 @@
** Unregister a VFS with the sqlite3_vfs_unregister() interface.
** If the default VFS is unregistered, another VFS is chosen as
** the default. The choice for the new VFS is arbitrary.
**
-** INVARIANTS:
-**
-** {H11203} The [sqlite3_vfs_find(N)] interface returns a pointer to the
-** registered [sqlite3_vfs] object whose name exactly matches
-** the zero-terminated UTF-8 string N, or it returns NULL if
-** there is no match.
-**
-** {H11206} If the N parameter to [sqlite3_vfs_find(N)] is NULL then
-** the function returns a pointer to the default [sqlite3_vfs]
-** object if there is one, or NULL if there is no default
-** [sqlite3_vfs] object.
-**
-** {H11209} The [sqlite3_vfs_register(P,F)] interface registers the
-** well-formed [sqlite3_vfs] object P using the name given
-** by the zName field of the object.
-**
-** {H11212} Using the [sqlite3_vfs_register(P,F)] interface to register
-** the same [sqlite3_vfs] object multiple times is a harmless no-op.
-**
-** {H11215} The [sqlite3_vfs_register(P,F)] interface makes the [sqlite3_vfs]
-** object P the default [sqlite3_vfs] object if F is non-zero.
-**
-** {H11218} The [sqlite3_vfs_unregister(P)] interface unregisters the
-** [sqlite3_vfs] object P so that it is no longer returned by
-** subsequent calls to [sqlite3_vfs_find()].
+** Requirements:
+** [H11203] [H11206] [H11209] [H11212] [H11215] [H11218]
*/
SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
@@ -6795,9 +5227,10 @@
#define SQLITE_MUTEX_FAST 0
#define SQLITE_MUTEX_RECURSIVE 1
#define SQLITE_MUTEX_STATIC_MASTER 2
#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */
-#define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */
+#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */
+#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */
#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
#define SQLITE_MUTEX_STATIC_LRU2 7 /* lru page list */
@@ -6873,8 +5306,9 @@
#define SQLITE_TESTCTRL_PRNG_RESET 7
#define SQLITE_TESTCTRL_BITVEC_TEST 8
#define SQLITE_TESTCTRL_FAULT_INSTALL 9
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
+#define SQLITE_TESTCTRL_PENDING_BYTE 11
/*
** CAPI3REF: SQLite Runtime Status {H17200} <S60200>
** EXPERIMENTAL
@@ -7162,19 +5596,19 @@
** cache implementation has two choices: it can return NULL,
** in which case SQLite will attempt to unpin one or more
** pages before re-requesting the same page, or it can
** allocate a new page and return a pointer to it. If a new
-** page is allocated, then it must be completely zeroed before
-** it is returned.
+** page is allocated, then the first sizeof(void*) bytes of
+** it (at least) must be zeroed before it is returned.
** <tr><td>2<td>If createFlag is set to 2, then SQLite is not holding any
** pinned pages associated with the specific cache passed
** as the first argument to xFetch() that can be unpinned. The
** cache implementation should attempt to allocate a new
-** cache entry and return a pointer to it. Again, the new
-** page should be zeroed before it is returned. If the xFetch()
-** method returns NULL when createFlag==2, SQLite assumes that
-** a memory allocation failed and returns SQLITE_NOMEM to the
-** user.
+** cache entry and return a pointer to it. Again, the first
+** sizeof(void*) bytes of the page should be zeroed before
+** it is returned. If the xFetch() method returns NULL when
+** createFlag==2, SQLite assumes that a memory allocation
+** failed and returns SQLITE_NOMEM to the user.
** </table>
**
** xUnpin() is called by SQLite with a pointer to a currently pinned page
** as its second argument. If the third parameter, discard, is non-zero,
@@ -7222,8 +5656,325 @@
void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey);
void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
void (*xDestroy)(sqlite3_pcache*);
};
+
+/*
+** CAPI3REF: Online Backup Object
+** EXPERIMENTAL
+**
+** The sqlite3_backup object records state information about an ongoing
+** online backup operation. The sqlite3_backup object is created by
+** a call to [sqlite3_backup_init()] and is destroyed by a call to
+** [sqlite3_backup_finish()].
+**
+** See Also: [Using the SQLite Online Backup API]
+*/
+typedef struct sqlite3_backup sqlite3_backup;
+
+/*
+** CAPI3REF: Online Backup API.
+** EXPERIMENTAL
+**
+** This API is used to overwrite the contents of one database with that
+** of another. It is useful either for creating backups of databases or
+** for copying in-memory databases to or from persistent files.
+**
+** See Also: [Using the SQLite Online Backup API]
+**
+** Exclusive access is required to the destination database for the
+** duration of the operation. However the source database is only
+** read-locked while it is actually being read, it is not locked
+** continuously for the entire operation. Thus, the backup may be
+** performed on a live database without preventing other users from
+** writing to the database for an extended period of time.
+**
+** To perform a backup operation:
+** <ol>
+** <li><b>sqlite3_backup_init()</b> is called once to initialize the
+** backup,
+** <li><b>sqlite3_backup_step()</b> is called one or more times to transfer
+** the data between the two databases, and finally
+** <li><b>sqlite3_backup_finish()</b> is called to release all resources
+** associated with the backup operation.
+** </ol>
+** There should be exactly one call to sqlite3_backup_finish() for each
+** successful call to sqlite3_backup_init().
+**
+** <b>sqlite3_backup_init()</b>
+**
+** The first two arguments passed to [sqlite3_backup_init()] are the database
+** handle associated with the destination database and the database name
+** used to attach the destination database to the handle. The database name
+** is "main" for the main database, "temp" for the temporary database, or
+** the name specified as part of the [ATTACH] statement if the destination is
+** an attached database. The third and fourth arguments passed to
+** sqlite3_backup_init() identify the [database connection]
+** and database name used
+** to access the source database. The values passed for the source and
+** destination [database connection] parameters must not be the same.
+**
+** If an error occurs within sqlite3_backup_init(), then NULL is returned
+** and an error code and error message written into the [database connection]
+** passed as the first argument. They may be retrieved using the
+** [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()] functions.
+** Otherwise, if successful, a pointer to an [sqlite3_backup] object is
+** returned. This pointer may be used with the sqlite3_backup_step() and
+** sqlite3_backup_finish() functions to perform the specified backup
+** operation.
+**
+** <b>sqlite3_backup_step()</b>
+**
+** Function [sqlite3_backup_step()] is used to copy up to nPage pages between
+** the source and destination databases, where nPage is the value of the
+** second parameter passed to sqlite3_backup_step(). If nPage is a negative
+** value, all remaining source pages are copied. If the required pages are
+** succesfully copied, but there are still more pages to copy before the
+** backup is complete, it returns [SQLITE_OK]. If no error occured and there
+** are no more pages to copy, then [SQLITE_DONE] is returned. If an error
+** occurs, then an SQLite error code is returned. As well as [SQLITE_OK] and
+** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY],
+** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an
+** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code.
+**
+** As well as the case where the destination database file was opened for
+** read-only access, sqlite3_backup_step() may return [SQLITE_READONLY] if
+** the destination is an in-memory database with a different page size
+** from the source database.
+**
+** If sqlite3_backup_step() cannot obtain a required file-system lock, then
+** the [sqlite3_busy_handler | busy-handler function]
+** is invoked (if one is specified). If the
+** busy-handler returns non-zero before the lock is available, then
+** [SQLITE_BUSY] is returned to the caller. In this case the call to
+** sqlite3_backup_step() can be retried later. If the source
+** [database connection]
+** is being used to write to the source database when sqlite3_backup_step()
+** is called, then [SQLITE_LOCKED] is returned immediately. Again, in this
+** case the call to sqlite3_backup_step() can be retried later on. If
+** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or
+** [SQLITE_READONLY] is returned, then
+** there is no point in retrying the call to sqlite3_backup_step(). These
+** errors are considered fatal. At this point the application must accept
+** that the backup operation has failed and pass the backup operation handle
+** to the sqlite3_backup_finish() to release associated resources.
+**
+** Following the first call to sqlite3_backup_step(), an exclusive lock is
+** obtained on the destination file. It is not released until either
+** sqlite3_backup_finish() is called or the backup operation is complete
+** and sqlite3_backup_step() returns [SQLITE_DONE]. Additionally, each time
+** a call to sqlite3_backup_step() is made a [shared lock] is obtained on
+** the source database file. This lock is released before the
+** sqlite3_backup_step() call returns. Because the source database is not
+** locked between calls to sqlite3_backup_step(), it may be modified mid-way
+** through the backup procedure. If the source database is modified by an
+** external process or via a database connection other than the one being
+** used by the backup operation, then the backup will be transparently
+** restarted by the next call to sqlite3_backup_step(). If the source
+** database is modified by the using the same database connection as is used
+** by the backup operation, then the backup database is transparently
+** updated at the same time.
+**
+** <b>sqlite3_backup_finish()</b>
+**
+** Once sqlite3_backup_step() has returned [SQLITE_DONE], or when the
+** application wishes to abandon the backup operation, the [sqlite3_backup]
+** object should be passed to sqlite3_backup_finish(). This releases all
+** resources associated with the backup operation. If sqlite3_backup_step()
+** has not yet returned [SQLITE_DONE], then any active write-transaction on the
+** destination database is rolled back. The [sqlite3_backup] object is invalid
+** and may not be used following a call to sqlite3_backup_finish().
+**
+** The value returned by sqlite3_backup_finish is [SQLITE_OK] if no error
+** occurred, regardless or whether or not sqlite3_backup_step() was called
+** a sufficient number of times to complete the backup operation. Or, if
+** an out-of-memory condition or IO error occured during a call to
+** sqlite3_backup_step() then [SQLITE_NOMEM] or an
+** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] error code
+** is returned. In this case the error code and an error message are
+** written to the destination [database connection].
+**
+** A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() is
+** not a permanent error and does not affect the return value of
+** sqlite3_backup_finish().
+**
+** <b>sqlite3_backup_remaining(), sqlite3_backup_pagecount()</b>
+**
+** Each call to sqlite3_backup_step() sets two values stored internally
+** by an [sqlite3_backup] object. The number of pages still to be backed
+** up, which may be queried by sqlite3_backup_remaining(), and the total
+** number of pages in the source database file, which may be queried by
+** sqlite3_backup_pagecount().
+**
+** The values returned by these functions are only updated by
+** sqlite3_backup_step(). If the source database is modified during a backup
+** operation, then the values are not updated to account for any extra
+** pages that need to be updated or the size of the source database file
+** changing.
+**
+** <b>Concurrent Usage of Database Handles</b>
+**
+** The source [database connection] may be used by the application for other
+** purposes while a backup operation is underway or being initialized.
+** If SQLite is compiled and configured to support threadsafe database
+** connections, then the source database connection may be used concurrently
+** from within other threads.
+**
+** However, the application must guarantee that the destination database
+** connection handle is not passed to any other API (by any thread) after
+** sqlite3_backup_init() is called and before the corresponding call to
+** sqlite3_backup_finish(). Unfortunately SQLite does not currently check
+** for this, if the application does use the destination [database connection]
+** for some other purpose during a backup operation, things may appear to
+** work correctly but in fact be subtly malfunctioning. Use of the
+** destination database connection while a backup is in progress might
+** also cause a mutex deadlock.
+**
+** Furthermore, if running in [shared cache mode], the application must
+** guarantee that the shared cache used by the destination database
+** is not accessed while the backup is running. In practice this means
+** that the application must guarantee that the file-system file being
+** backed up to is not accessed by any connection within the process,
+** not just the specific connection that was passed to sqlite3_backup_init().
+**
+** The [sqlite3_backup] object itself is partially threadsafe. Multiple
+** threads may safely make multiple concurrent calls to sqlite3_backup_step().
+** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount()
+** APIs are not strictly speaking threadsafe. If they are invoked at the
+** same time as another thread is invoking sqlite3_backup_step() it is
+** possible that they return invalid values.
+*/
+SQLITE_API sqlite3_backup *sqlite3_backup_init(
+ sqlite3 *pDest, /* Destination database handle */
+ const char *zDestName, /* Destination database name */
+ sqlite3 *pSource, /* Source database handle */
+ const char *zSourceName /* Source database name */
+);
+SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
+SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
+
+/*
+** CAPI3REF: Unlock Notification
+** EXPERIMENTAL
+**
+** When running in shared-cache mode, a database operation may fail with
+** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
+** individual tables within the shared-cache cannot be obtained. See
+** [SQLite Shared-Cache Mode] for a description of shared-cache locking.
+** This API may be used to register a callback that SQLite will invoke
+** when the connection currently holding the required lock relinquishes it.
+** This API is only available if the library was compiled with the
+** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined.
+**
+** See Also: [Using the SQLite Unlock Notification Feature].
+**
+** Shared-cache locks are released when a database connection concludes
+** its current transaction, either by committing it or rolling it back.
+**
+** When a connection (known as the blocked connection) fails to obtain a
+** shared-cache lock and SQLITE_LOCKED is returned to the caller, the
+** identity of the database connection (the blocking connection) that
+** has locked the required resource is stored internally. After an
+** application receives an SQLITE_LOCKED error, it may call the
+** sqlite3_unlock_notify() method with the blocked connection handle as
+** the first argument to register for a callback that will be invoked
+** when the blocking connections current transaction is concluded. The
+** callback is invoked from within the [sqlite3_step] or [sqlite3_close]
+** call that concludes the blocking connections transaction.
+**
+** If sqlite3_unlock_notify() is called in a multi-threaded application,
+** there is a chance that the blocking connection will have already
+** concluded its transaction by the time sqlite3_unlock_notify() is invoked.
+** If this happens, then the specified callback is invoked immediately,
+** from within the call to sqlite3_unlock_notify().
+**
+** If the blocked connection is attempting to obtain a write-lock on a
+** shared-cache table, and more than one other connection currently holds
+** a read-lock on the same table, then SQLite arbitrarily selects one of
+** the other connections to use as the blocking connection.
+**
+** There may be at most one unlock-notify callback registered by a
+** blocked connection. If sqlite3_unlock_notify() is called when the
+** blocked connection already has a registered unlock-notify callback,
+** then the new callback replaces the old. If sqlite3_unlock_notify() is
+** called with a NULL pointer as its second argument, then any existing
+** unlock-notify callback is cancelled. The blocked connections
+** unlock-notify callback may also be canceled by closing the blocked
+** connection using [sqlite3_close()].
+**
+** The unlock-notify callback is not reentrant. If an application invokes
+** any sqlite3_xxx API functions from within an unlock-notify callback, a
+** crash or deadlock may be the result.
+**
+** Unless deadlock is detected (see below), sqlite3_unlock_notify() always
+** returns SQLITE_OK.
+**
+** <b>Callback Invocation Details</b>
+**
+** When an unlock-notify callback is registered, the application provides a
+** single void* pointer that is passed to the callback when it is invoked.
+** However, the signature of the callback function allows SQLite to pass
+** it an array of void* context pointers. The first argument passed to
+** an unlock-notify callback is a pointer to an array of void* pointers,
+** and the second is the number of entries in the array.
+**
+** When a blocking connections transaction is concluded, there may be
+** more than one blocked connection that has registered for an unlock-notify
+** callback. If two or more such blocked connections have specified the
+** same callback function, then instead of invoking the callback function
+** multiple times, it is invoked once with the set of void* context pointers
+** specified by the blocked connections bundled together into an array.
+** This gives the application an opportunity to prioritize any actions
+** related to the set of unblocked database connections.
+**
+** <b>Deadlock Detection</b>
+**
+** Assuming that after registering for an unlock-notify callback a
+** database waits for the callback to be issued before taking any further
+** action (a reasonable assumption), then using this API may cause the
+** application to deadlock. For example, if connection X is waiting for
+** connection Y's transaction to be concluded, and similarly connection
+** Y is waiting on connection X's transaction, then neither connection
+** will proceed and the system may remain deadlocked indefinitely.
+**
+** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock
+** detection. If a given call to sqlite3_unlock_notify() would put the
+** system in a deadlocked state, then SQLITE_LOCKED is returned and no
+** unlock-notify callback is registered. The system is said to be in
+** a deadlocked state if connection A has registered for an unlock-notify
+** callback on the conclusion of connection B's transaction, and connection
+** B has itself registered for an unlock-notify callback when connection
+** A's transaction is concluded. Indirect deadlock is also detected, so
+** the system is also considered to be deadlocked if connection B has
+** registered for an unlock-notify callback on the conclusion of connection
+** C's transaction, where connection C is waiting on connection A. Any
+** number of levels of indirection are allowed.
+**
+** <b>The "DROP TABLE" Exception</b>
+**
+** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost
+** always appropriate to call sqlite3_unlock_notify(). There is however,
+** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement,
+** SQLite checks if there are any currently executing SELECT statements
+** that belong to the same connection. If there are, SQLITE_LOCKED is
+** returned. In this case there is no "blocking connection", so invoking
+** sqlite3_unlock_notify() results in the unlock-notify callback being
+** invoked immediately. If the application then re-attempts the "DROP TABLE"
+** or "DROP INDEX" query, an infinite loop might be the result.
+**
+** One way around this problem is to check the extended error code returned
+** by an sqlite3_step() call. If there is a blocking connection, then the
+** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in
+** the special "DROP TABLE/INDEX" case, the extended error code is just
+** SQLITE_LOCKED.
+*/
+SQLITE_API int sqlite3_unlock_notify(
+ sqlite3 *pBlocked, /* Waiting connection */
+ void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */
+ void *pNotifyArg /* Argument to pass to xNotify */
+);
/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
@@ -7347,10 +6098,10 @@
#define TK_ROLLBACK 12
#define TK_SAVEPOINT 13
#define TK_RELEASE 14
#define TK_TO 15
-#define TK_CREATE 16
-#define TK_TABLE 17
+#define TK_TABLE 16
+#define TK_CREATE 17
#define TK_IF 18
#define TK_NOT 19
#define TK_EXISTS 20
#define TK_TEMP 21
@@ -7358,122 +6109,122 @@
#define TK_RP 23
#define TK_AS 24
#define TK_COMMA 25
#define TK_ID 26
-#define TK_ABORT 27
-#define TK_AFTER 28
-#define TK_ANALYZE 29
-#define TK_ASC 30
-#define TK_ATTACH 31
-#define TK_BEFORE 32
-#define TK_CASCADE 33
-#define TK_CAST 34
-#define TK_CONFLICT 35
-#define TK_DATABASE 36
-#define TK_DESC 37
-#define TK_DETACH 38
-#define TK_EACH 39
-#define TK_FAIL 40
-#define TK_FOR 41
-#define TK_IGNORE 42
-#define TK_INITIALLY 43
-#define TK_INSTEAD 44
-#define TK_LIKE_KW 45
-#define TK_MATCH 46
-#define TK_KEY 47
-#define TK_OF 48
-#define TK_OFFSET 49
-#define TK_PRAGMA 50
-#define TK_RAISE 51
-#define TK_REPLACE 52
-#define TK_RESTRICT 53
-#define TK_ROW 54
-#define TK_TRIGGER 55
-#define TK_VACUUM 56
-#define TK_VIEW 57
-#define TK_VIRTUAL 58
-#define TK_REINDEX 59
-#define TK_RENAME 60
-#define TK_CTIME_KW 61
-#define TK_ANY 62
-#define TK_OR 63
-#define TK_AND 64
-#define TK_IS 65
-#define TK_BETWEEN 66
-#define TK_IN 67
-#define TK_ISNULL 68
-#define TK_NOTNULL 69
-#define TK_NE 70
-#define TK_EQ 71
-#define TK_GT 72
-#define TK_LE 73
-#define TK_LT 74
-#define TK_GE 75
-#define TK_ESCAPE 76
-#define TK_BITAND 77
-#define TK_BITOR 78
-#define TK_LSHIFT 79
-#define TK_RSHIFT 80
-#define TK_PLUS 81
-#define TK_MINUS 82
-#define TK_STAR 83
-#define TK_SLASH 84
-#define TK_REM 85
-#define TK_CONCAT 86
-#define TK_COLLATE 87
-#define TK_UMINUS 88
-#define TK_UPLUS 89
-#define TK_BITNOT 90
-#define TK_STRING 91
-#define TK_JOIN_KW 92
-#define TK_CONSTRAINT 93
-#define TK_DEFAULT 94
-#define TK_NULL 95
-#define TK_PRIMARY 96
-#define TK_UNIQUE 97
-#define TK_CHECK 98
-#define TK_REFERENCES 99
-#define TK_AUTOINCR 100
-#define TK_ON 101
-#define TK_DELETE 102
-#define TK_UPDATE 103
-#define TK_INSERT 104
-#define TK_SET 105
-#define TK_DEFERRABLE 106
-#define TK_FOREIGN 107
-#define TK_DROP 108
-#define TK_UNION 109
-#define TK_ALL 110
-#define TK_EXCEPT 111
-#define TK_INTERSECT 112
-#define TK_SELECT 113
-#define TK_DISTINCT 114
-#define TK_DOT 115
-#define TK_FROM 116
-#define TK_JOIN 117
-#define TK_INDEXED 118
-#define TK_BY 119
-#define TK_USING 120
-#define TK_ORDER 121
-#define TK_GROUP 122
-#define TK_HAVING 123
-#define TK_LIMIT 124
-#define TK_WHERE 125
-#define TK_INTO 126
-#define TK_VALUES 127
-#define TK_INTEGER 128
-#define TK_FLOAT 129
-#define TK_BLOB 130
-#define TK_REGISTER 131
-#define TK_VARIABLE 132
-#define TK_CASE 133
-#define TK_WHEN 134
-#define TK_THEN 135
-#define TK_ELSE 136
-#define TK_INDEX 137
-#define TK_ALTER 138
-#define TK_ADD 139
-#define TK_COLUMNKW 140
+#define TK_INDEXED 27
+#define TK_ABORT 28
+#define TK_AFTER 29
+#define TK_ANALYZE 30
+#define TK_ASC 31
+#define TK_ATTACH 32
+#define TK_BEFORE 33
+#define TK_BY 34
+#define TK_CASCADE 35
+#define TK_CAST 36
+#define TK_COLUMNKW 37
+#define TK_CONFLICT 38
+#define TK_DATABASE 39
+#define TK_DESC 40
+#define TK_DETACH 41
+#define TK_EACH 42
+#define TK_FAIL 43
+#define TK_FOR 44
+#define TK_IGNORE 45
+#define TK_INITIALLY 46
+#define TK_INSTEAD 47
+#define TK_LIKE_KW 48
+#define TK_MATCH 49
+#define TK_KEY 50
+#define TK_OF 51
+#define TK_OFFSET 52
+#define TK_PRAGMA 53
+#define TK_RAISE 54
+#define TK_REPLACE 55
+#define TK_RESTRICT 56
+#define TK_ROW 57
+#define TK_TRIGGER 58
+#define TK_VACUUM 59
+#define TK_VIEW 60
+#define TK_VIRTUAL 61
+#define TK_REINDEX 62
+#define TK_RENAME 63
+#define TK_CTIME_KW 64
+#define TK_ANY 65
+#define TK_OR 66
+#define TK_AND 67
+#define TK_IS 68
+#define TK_BETWEEN 69
+#define TK_IN 70
+#define TK_ISNULL 71
+#define TK_NOTNULL 72
+#define TK_NE 73
+#define TK_EQ 74
+#define TK_GT 75
+#define TK_LE 76
+#define TK_LT 77
+#define TK_GE 78
+#define TK_ESCAPE 79
+#define TK_BITAND 80
+#define TK_BITOR 81
+#define TK_LSHIFT 82
+#define TK_RSHIFT 83
+#define TK_PLUS 84
+#define TK_MINUS 85
+#define TK_STAR 86
+#define TK_SLASH 87
+#define TK_REM 88
+#define TK_CONCAT 89
+#define TK_COLLATE 90
+#define TK_UMINUS 91
+#define TK_UPLUS 92
+#define TK_BITNOT 93
+#define TK_STRING 94
+#define TK_JOIN_KW 95
+#define TK_CONSTRAINT 96
+#define TK_DEFAULT 97
+#define TK_NULL 98
+#define TK_PRIMARY 99
+#define TK_UNIQUE 100
+#define TK_CHECK 101
+#define TK_REFERENCES 102
+#define TK_AUTOINCR 103
+#define TK_ON 104
+#define TK_DELETE 105
+#define TK_UPDATE 106
+#define TK_INSERT 107
+#define TK_SET 108
+#define TK_DEFERRABLE 109
+#define TK_FOREIGN 110
+#define TK_DROP 111
+#define TK_UNION 112
+#define TK_ALL 113
+#define TK_EXCEPT 114
+#define TK_INTERSECT 115
+#define TK_SELECT 116
+#define TK_DISTINCT 117
+#define TK_DOT 118
+#define TK_FROM 119
+#define TK_JOIN 120
+#define TK_USING 121
+#define TK_ORDER 122
+#define TK_GROUP 123
+#define TK_HAVING 124
+#define TK_LIMIT 125
+#define TK_WHERE 126
+#define TK_INTO 127
+#define TK_VALUES 128
+#define TK_INTEGER 129
+#define TK_FLOAT 130
+#define TK_BLOB 131
+#define TK_REGISTER 132
+#define TK_VARIABLE 133
+#define TK_CASE 134
+#define TK_WHEN 135
+#define TK_THEN 136
+#define TK_ELSE 137
+#define TK_INDEX 138
+#define TK_ALTER 139
+#define TK_ADD 140
#define TK_TO_TEXT 141
#define TK_TO_BLOB 142
#define TK_TO_NUMERIC 143
#define TK_TO_INT 144
@@ -7657,8 +6408,19 @@
#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
/*
+** Round up a number to the next larger multiple of 8. This is used
+** to force 8-byte alignment on 64-bit architectures.
+*/
+#define ROUND8(x) (((x)+7)&~7)
+
+/*
+** Round down to the nearest multiple of 8
+*/
+#define ROUNDDOWN8(x) ((x)&~7)
+
+/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle.
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
@@ -7810,9 +6572,9 @@
** This header file defines the interface that the sqlite B-Tree file
** subsystem. See comments in the source code for a detailed description
** of what each interface routine does.
**
-** @(#) $Id: btree.h,v 1.106 2008/12/17 17:30:26 danielk1977 Exp $
+** @(#) $Id: btree.h,v 1.111 2009/03/18 10:33:01 danielk1977 Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_
@@ -7888,22 +6650,19 @@
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*);
SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeCommitStmt(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeRollbackStmt(Btree*);
+SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags);
SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeIsInStmt(Btree*);
SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*);
+SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*);
SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *);
SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *, int, u8);
SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int);
SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *);
-SQLITE_PRIVATE const char *sqlite3BtreeGetDirname(Btree *);
SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *);
SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *);
SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *);
@@ -7962,15 +6721,21 @@
SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
SQLITE_PRIVATE int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
+SQLITE_PRIVATE void sqlite3BtreeSetCachedRowid(BtCursor*, sqlite3_int64);
+SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor*);
SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *);
SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
+
+#ifndef SQLITE_OMIT_BTREECOUNT
+SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *);
+#endif
#ifdef SQLITE_TEST
SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*);
@@ -8042,9 +6807,9 @@
** This header defines the interface to the virtual database engine
** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
-** $Id: vdbe.h,v 1.139 2008/10/31 10:53:23 danielk1977 Exp $
+** $Id: vdbe.h,v 1.140 2009/02/19 14:39:25 danielk1977 Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
@@ -8179,40 +6944,40 @@
#define OP_Affinity 2
#define OP_Column 3
#define OP_SetCookie 4
#define OP_Seek 5
-#define OP_Real 129 /* same as TK_FLOAT */
+#define OP_Real 130 /* same as TK_FLOAT */
#define OP_Sequence 6
#define OP_Savepoint 7
-#define OP_Ge 75 /* same as TK_GE */
+#define OP_Ge 78 /* same as TK_GE */
#define OP_RowKey 8
#define OP_SCopy 9
-#define OP_Eq 71 /* same as TK_EQ */
+#define OP_Eq 74 /* same as TK_EQ */
#define OP_OpenWrite 10
-#define OP_NotNull 69 /* same as TK_NOTNULL */
+#define OP_NotNull 72 /* same as TK_NOTNULL */
#define OP_If 11
#define OP_ToInt 144 /* same as TK_TO_INT */
-#define OP_String8 91 /* same as TK_STRING */
+#define OP_String8 94 /* same as TK_STRING */
#define OP_VRowid 12
#define OP_CollSeq 13
#define OP_OpenRead 14
#define OP_Expire 15
#define OP_AutoCommit 16
-#define OP_Gt 72 /* same as TK_GT */
+#define OP_Gt 75 /* same as TK_GT */
#define OP_Pagecount 17
#define OP_IntegrityCk 18
#define OP_Sort 20
#define OP_Copy 21
#define OP_Trace 22
#define OP_Function 23
#define OP_IfNeg 24
-#define OP_And 64 /* same as TK_AND */
-#define OP_Subtract 82 /* same as TK_MINUS */
+#define OP_And 67 /* same as TK_AND */
+#define OP_Subtract 85 /* same as TK_MINUS */
#define OP_Noop 25
#define OP_Return 26
-#define OP_Remainder 85 /* same as TK_REM */
+#define OP_Remainder 88 /* same as TK_REM */
#define OP_NewRowid 27
-#define OP_Multiply 83 /* same as TK_STAR */
+#define OP_Multiply 86 /* same as TK_STAR */
#define OP_Variable 28
#define OP_String 29
#define OP_RealAffinity 30
#define OP_VRename 31
@@ -8230,49 +6995,49 @@
#define OP_AddImm 43
#define OP_Statement 44
#define OP_RowData 45
#define OP_MemMax 46
-#define OP_Or 63 /* same as TK_OR */
+#define OP_Or 66 /* same as TK_OR */
#define OP_NotExists 47
#define OP_Gosub 48
-#define OP_Divide 84 /* same as TK_SLASH */
+#define OP_Divide 87 /* same as TK_SLASH */
#define OP_Integer 49
#define OP_ToNumeric 143 /* same as TK_TO_NUMERIC*/
#define OP_Prev 50
#define OP_RowSetRead 51
-#define OP_Concat 86 /* same as TK_CONCAT */
+#define OP_Concat 89 /* same as TK_CONCAT */
#define OP_RowSetAdd 52
-#define OP_BitAnd 77 /* same as TK_BITAND */
+#define OP_BitAnd 80 /* same as TK_BITAND */
#define OP_VColumn 53
#define OP_CreateTable 54
#define OP_Last 55
#define OP_SeekLe 56
-#define OP_IsNull 68 /* same as TK_ISNULL */
+#define OP_IsNull 71 /* same as TK_ISNULL */
#define OP_IncrVacuum 57
#define OP_IdxRowid 58
-#define OP_ShiftRight 80 /* same as TK_RSHIFT */
+#define OP_ShiftRight 83 /* same as TK_RSHIFT */
#define OP_ResetCount 59
#define OP_ContextPush 60
#define OP_Yield 61
#define OP_DropTrigger 62
-#define OP_DropIndex 65
-#define OP_IdxGE 66
-#define OP_IdxDelete 67
-#define OP_Vacuum 76
-#define OP_IfNot 87
-#define OP_DropTable 88
-#define OP_SeekLt 89
-#define OP_MakeRecord 92
+#define OP_DropIndex 63
+#define OP_IdxGE 64
+#define OP_IdxDelete 65
+#define OP_Vacuum 68
+#define OP_IfNot 69
+#define OP_DropTable 70
+#define OP_SeekLt 79
+#define OP_MakeRecord 90
#define OP_ToBlob 142 /* same as TK_TO_BLOB */
-#define OP_ResultRow 93
-#define OP_Delete 94
+#define OP_ResultRow 91
+#define OP_Delete 92
#define OP_AggFinal 95
#define OP_Compare 96
-#define OP_ShiftLeft 79 /* same as TK_LSHIFT */
+#define OP_ShiftLeft 82 /* same as TK_LSHIFT */
#define OP_Goto 97
#define OP_TableLock 98
#define OP_Clear 99
-#define OP_Le 73 /* same as TK_LE */
+#define OP_Le 76 /* same as TK_LE */
#define OP_VerifyCookie 100
#define OP_AggStep 101
#define OP_ToText 141 /* same as TK_TO_TEXT */
#define OP_Not 19 /* same as TK_NOT */
@@ -8279,43 +7044,43 @@
#define OP_ToReal 145 /* same as TK_TO_REAL */
#define OP_SetNumColumns 102
#define OP_Transaction 103
#define OP_VFilter 104
-#define OP_Ne 70 /* same as TK_NE */
+#define OP_Ne 73 /* same as TK_NE */
#define OP_VDestroy 105
#define OP_ContextPop 106
-#define OP_BitOr 78 /* same as TK_BITOR */
+#define OP_BitOr 81 /* same as TK_BITOR */
#define OP_Next 107
-#define OP_IdxInsert 108
-#define OP_Lt 74 /* same as TK_LT */
-#define OP_SeekGe 109
-#define OP_Insert 110
-#define OP_Destroy 111
-#define OP_ReadCookie 112
-#define OP_LoadAnalysis 113
-#define OP_Explain 114
-#define OP_OpenPseudo 115
-#define OP_OpenEphemeral 116
-#define OP_Null 117
-#define OP_Move 118
-#define OP_Blob 119
-#define OP_Add 81 /* same as TK_PLUS */
-#define OP_Rewind 120
-#define OP_SeekGt 121
-#define OP_VBegin 122
-#define OP_VUpdate 123
-#define OP_IfZero 124
-#define OP_BitNot 90 /* same as TK_BITNOT */
-#define OP_VCreate 125
-#define OP_Found 126
-#define OP_IfPos 127
-#define OP_NullRow 128
-#define OP_Jump 130
-#define OP_Permutation 131
-
-/* The following opcode values are never used */
-#define OP_NotUsed_132 132
-#define OP_NotUsed_133 133
+#define OP_Count 108
+#define OP_IdxInsert 109
+#define OP_Lt 77 /* same as TK_LT */
+#define OP_SeekGe 110
+#define OP_Insert 111
+#define OP_Destroy 112
+#define OP_ReadCookie 113
+#define OP_LoadAnalysis 114
+#define OP_Explain 115
+#define OP_HaltIfNull 116
+#define OP_OpenPseudo 117
+#define OP_OpenEphemeral 118
+#define OP_Null 119
+#define OP_Move 120
+#define OP_Blob 121
+#define OP_Add 84 /* same as TK_PLUS */
+#define OP_Rewind 122
+#define OP_SeekGt 123
+#define OP_VBegin 124
+#define OP_VUpdate 125
+#define OP_IfZero 126
+#define OP_BitNot 93 /* same as TK_BITNOT */
+#define OP_VCreate 127
+#define OP_Found 128
+#define OP_IfPos 129
+#define OP_NullRow 131
+#define OP_Jump 132
+#define OP_Permutation 133
+
+/* The following opcode values are never used */
#define OP_NotUsed_134 134
#define OP_NotUsed_135 135
#define OP_NotUsed_136 136
#define OP_NotUsed_137 137
@@ -8337,22 +7102,22 @@
#define OPFLG_INITIALIZER {\
/* 0 */ 0x00, 0x01, 0x00, 0x00, 0x10, 0x08, 0x02, 0x00,\
/* 8 */ 0x00, 0x04, 0x00, 0x05, 0x02, 0x00, 0x00, 0x00,\
/* 16 */ 0x00, 0x02, 0x00, 0x04, 0x01, 0x04, 0x00, 0x00,\
-/* 24 */ 0x05, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00,\
+/* 24 */ 0x05, 0x00, 0x04, 0x02, 0x00, 0x02, 0x04, 0x00,\
/* 32 */ 0x00, 0x00, 0x00, 0x02, 0x11, 0x11, 0x02, 0x05,\
/* 40 */ 0x00, 0x02, 0x11, 0x04, 0x00, 0x00, 0x0c, 0x11,\
/* 48 */ 0x01, 0x02, 0x01, 0x21, 0x08, 0x00, 0x02, 0x01,\
-/* 56 */ 0x11, 0x01, 0x02, 0x00, 0x00, 0x04, 0x00, 0x2c,\
-/* 64 */ 0x2c, 0x00, 0x11, 0x00, 0x05, 0x05, 0x15, 0x15,\
-/* 72 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x2c, 0x2c, 0x2c,\
-/* 80 */ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x05,\
-/* 88 */ 0x00, 0x11, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00,\
+/* 56 */ 0x11, 0x01, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00,\
+/* 64 */ 0x11, 0x00, 0x2c, 0x2c, 0x00, 0x05, 0x00, 0x05,\
+/* 72 */ 0x05, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x11,\
+/* 80 */ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,\
+/* 88 */ 0x2c, 0x2c, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00,\
/* 96 */ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 104 */ 0x01, 0x00, 0x00, 0x01, 0x08, 0x11, 0x00, 0x02,\
-/* 112 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02,\
-/* 120 */ 0x01, 0x11, 0x00, 0x00, 0x05, 0x00, 0x11, 0x05,\
-/* 128 */ 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 104 */ 0x01, 0x00, 0x00, 0x01, 0x02, 0x08, 0x11, 0x00,\
+/* 112 */ 0x02, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02,\
+/* 120 */ 0x00, 0x02, 0x01, 0x11, 0x00, 0x00, 0x05, 0x00,\
+/* 128 */ 0x11, 0x05, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,\
/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04,\
/* 144 */ 0x04, 0x04,}
/************** End of opcodes.h *********************************************/
@@ -8392,9 +7157,9 @@
SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n);
+SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int);
SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
SQLITE_PRIVATE int sqlite3VdbeReleaseMemory(int);
@@ -8435,17 +7200,18 @@
** This header file defines the interface that the sqlite page cache
** subsystem. The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
-** @(#) $Id: pager.h,v 1.93 2009/01/07 15:18:21 danielk1977 Exp $
+** @(#) $Id: pager.h,v 1.100 2009/02/03 16:51:25 danielk1977 Exp $
*/
#ifndef _PAGER_H_
#define _PAGER_H_
/*
-** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
-** it must be turned on for each database using "PRAGMA auto_vacuum = 1".
+** Default maximum size for persistent journal files. A negative
+** value means no limit. This value may be overridden using the
+** sqlite3PagerJournalSizeLimit() API. See also "PRAGMA journal_size_limit".
*/
#ifndef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT
#define SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT -1
#endif
@@ -8466,11 +7232,21 @@
*/
typedef struct PgHdr DbPage;
/*
+** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
+** reserved for working around a windows/posix incompatibility). It is
+** used in the journal to signify that the remainder of the journal file
+** is devoted to storing a master journal name - there are no more pages to
+** roll back. See comments for function writeMasterJournal() in pager.c
+** for details.
+*/
+#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
+
+/*
** Allowed values for the flags parameter to sqlite3PagerOpen().
**
-** NOTE: This values must match the corresponding BTREE_ values in btree.h.
+** NOTE: These values must match the corresponding BTREE_ values in btree.h.
*/
#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */
#define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */
@@ -8491,77 +7267,84 @@
#define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */
#define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */
/*
-** See source code comments for a detailed description of the following
-** routines:
-*/
+** The remainder of this file contains the declarations of the functions
+** that make up the Pager sub-system API. See source code comments for
+** a detailed description of each routine.
+*/
+
+/* Open and close a Pager connection. */
SQLITE_PRIVATE int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char*, int,int,int);
+SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager);
+SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
+
+/* Functions used to configure a Pager object. */
SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
SQLITE_PRIVATE void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*));
SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u16*);
SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
-SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
-SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager);
+SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int);
+SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
+SQLITE_PRIVATE int sqlite3PagerJournalMode(Pager *, int);
+SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
+SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*);
+
+/* Functions used to obtain and release page references. */
SQLITE_PRIVATE int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
#define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0)
SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
-SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage*);
-SQLITE_PRIVATE int sqlite3PagerRef(DbPage*);
-SQLITE_PRIVATE int sqlite3PagerUnref(DbPage*);
+SQLITE_PRIVATE void sqlite3PagerRef(DbPage*);
+SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*);
+
+/* Operations on page references. */
SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*);
+SQLITE_PRIVATE void sqlite3PagerDontWrite(DbPage*);
+SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int);
+SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage*);
+SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *);
+SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *);
+
+/* Functions used to manage pager transactions and savepoints. */
SQLITE_PRIVATE int sqlite3PagerPagecount(Pager*, int*);
-SQLITE_PRIVATE int sqlite3PagerBegin(DbPage*, int exFlag);
+SQLITE_PRIVATE int sqlite3PagerBegin(Pager*, int exFlag);
SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int);
+SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*);
SQLITE_PRIVATE int sqlite3PagerRollback(Pager*);
+SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
+SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
+
+/* Functions used to query pager state and configuration. */
SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
-SQLITE_PRIVATE void sqlite3PagerDontRollback(DbPage*);
-SQLITE_PRIVATE int sqlite3PagerDontWrite(DbPage*);
-SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
-SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int);
+SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*);
SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*);
SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
-SQLITE_PRIVATE const char *sqlite3PagerDirname(Pager*);
SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
SQLITE_PRIVATE int sqlite3PagerNosync(Pager*);
-SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int);
-SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *);
-SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *);
-SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
-SQLITE_PRIVATE int sqlite3PagerJournalMode(Pager *, int);
-SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
-SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager);
-
-SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
-SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
-SQLITE_PRIVATE Pgno sqlite3PagerImageSize(Pager *);
-#endif
-
+SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
+
+/* Functions used to truncate the database file. */
+SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
+
+/* Used by encryption extensions. */
#ifdef SQLITE_HAS_CODEC
SQLITE_PRIVATE void sqlite3PagerSetCodec(Pager*,void*(*)(void*,void*,Pgno,int),void*);
#endif
+/* Functions to support testing and debugging. */
#if !defined(NDEBUG) || defined(SQLITE_TEST)
SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage*);
SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage*);
#endif
-
#ifdef SQLITE_TEST
SQLITE_PRIVATE int *sqlite3PagerStats(Pager*);
SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*);
-SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
-#endif
-
-#ifdef SQLITE_TEST
-void disable_simulated_io_errors(void);
-void enable_simulated_io_errors(void);
+ void disable_simulated_io_errors(void);
+ void enable_simulated_io_errors(void);
#else
# define disable_simulated_io_errors()
# define enable_simulated_io_errors()
#endif
@@ -8585,9 +7368,9 @@
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem.
**
-** @(#) $Id: pcache.h,v 1.16 2008/11/19 16:52:44 danielk1977 Exp $
+** @(#) $Id: pcache.h,v 1.19 2009/01/20 17:06:27 danielk1977 Exp $
*/
#ifndef _PCACHE_H_
@@ -8684,9 +7467,9 @@
/* Clear flags from pages of the page cache */
SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *);
/* Discard the contents of the cache */
-SQLITE_PRIVATE int sqlite3PcacheClear(PCache*);
+SQLITE_PRIVATE void sqlite3PcacheClear(PCache*);
/* Return the total number of outstanding page references */
SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache*);
@@ -8753,9 +7536,9 @@
**
** This header file is #include-ed by sqliteInt.h and thus ends up
** being included by every source file.
**
-** $Id: os.h,v 1.107 2009/01/14 23:03:41 drh Exp $
+** $Id: os.h,v 1.108 2009/02/05 16:31:46 drh Exp $
*/
#ifndef _SQLITE_OS_H_
#define _SQLITE_OS_H_
@@ -8931,11 +7714,9 @@
** SHARED_SIZE is the number of bytes available in the pool from which
** a random byte is selected for a shared lock. The pool of bytes for
** shared locks begins at SHARED_FIRST.
**
-** These #defines are available in sqlite_aux.h so that adaptors for
-** connecting SQLite to other operating systems can use the same byte
-** ranges for locking. In particular, the same locking strategy and
+** The same locking strategy and
** byte ranges are used for Unix. This leaves open the possiblity of having
** clients on win95, winNT, and unix all talking to the same shared file
** and all locking correctly. To do so would require that samba (or whatever
** tool is being used for file sharing) implements locks correctly between
@@ -8957,15 +7738,9 @@
** The default location of PENDING_BYTE is the first byte past the
** 1GB boundary.
**
*/
-#ifndef SQLITE_TEST
-#define PENDING_BYTE 0x40000000 /* First byte past the 1GB boundary */
-#else
-SQLITE_API extern unsigned int sqlite3_pending_byte;
-#define PENDING_BYTE sqlite3_pending_byte
-#endif
-
+#define PENDING_BYTE sqlite3PendingByte
#define RESERVED_BYTE (PENDING_BYTE+1)
#define SHARED_FIRST (PENDING_BYTE+2)
#define SHARED_SIZE 510
@@ -8995,9 +7770,9 @@
SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *);
#ifndef SQLITE_OMIT_LOAD_EXTENSION
SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *);
SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *);
-void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void);
+SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void);
SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *);
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *);
SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int);
@@ -9178,12 +7953,19 @@
** The Lookaside structure holds configuration information about the
** lookaside malloc subsystem. Each available memory allocation in
** the lookaside subsystem is stored on a linked list of LookasideSlot
** objects.
+**
+** Lookaside allocations are only allowed for objects that are associated
+** with a particular database connection. Hence, schema information cannot
+** be stored in lookaside because in shared cache mode the schema information
+** is shared by multiple database connections. Therefore, while parsing
+** schema information, the Lookaside.bEnabled flag is cleared so that
+** lookaside allocations are not used to construct the schema objects.
*/
struct Lookaside {
u16 sz; /* Size of each buffer in bytes */
- u8 bEnabled; /* True if use lookaside. False to ignore it */
+ u8 bEnabled; /* False to disable new lookaside allocations */
u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */
int nOut; /* Number of buffers currently checked out */
int mxOut; /* Highwater mark for nOut */
LookasideSlot *pFree; /* List of available buffers */
@@ -9310,9 +8092,21 @@
sqlite3_stmt *pFetch; /* Used by SSE to fetch stored statements */
#endif
Savepoint *pSavepoint; /* List of active savepoints */
int nSavepoint; /* Number of non-transaction savepoints */
+ int nStatement; /* Number of nested statement-transactions */
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
+
+#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
+ /* The following variables are all protected by the STATIC_MASTER
+ ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
+ */
+ sqlite3 *pBlockingConnection; /* Connection that caused SQLITE_LOCKED */
+ sqlite3 *pUnlockConnection; /* Connection to watch for unlock */
+ void *pUnlockArg; /* Argument to xUnlockNotify */
+ void (*xUnlockNotify)(void **, int); /* Unlock notify callback */
+ sqlite3 *pNextBlocked; /* Next in list of all blocked connections */
+#endif
};
/*
** A macro to discover the encoding of a database.
@@ -9350,8 +8144,9 @@
#define SQLITE_RecoveryMode 0x00040000 /* Ignore schema errors */
#define SQLITE_SharedCache 0x00080000 /* Cache sharing is enabled */
#define SQLITE_Vtab 0x00100000 /* There exists a virtual table */
#define SQLITE_CommitBusy 0x00200000 /* In the process of committing */
+#define SQLITE_ReverseOrder 0x00400000 /* Reverse unordered SELECTs */
/*
** Possible values for the sqlite.magic field.
** The numbers are obtained at random and have no special meaning, other
@@ -9389,8 +8184,9 @@
#define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */
#define SQLITE_FUNC_EPHEM 0x04 /* Ephemeral. Delete with VDBE */
#define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite3GetFuncCollSeq() might be called */
#define SQLITE_FUNC_PRIVATE 0x10 /* Allowed for internal use only */
+#define SQLITE_FUNC_COUNT 0x20 /* Built-in count(*) aggregate */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
** used to create the initializers for the FuncDef structures.
@@ -9583,9 +8379,9 @@
** sub-query that appears instead of a real table name in the FROM clause
** of a SELECT statement.
*/
struct Table {
- sqlite3 *db; /* Associated database connection. Might be NULL. */
+ sqlite3 *dbMem; /* DB connection used for lookaside allocations. */
char *zName; /* Name of the table or view */
int iPKey; /* If not negative, use aCol[iPKey] as the primary key */
int nCol; /* Number of columns in this table */
Column *aCol; /* Information about each column */
@@ -9594,9 +8390,8 @@
Select *pSelect; /* NULL for tables. Points to definition if a view. */
u16 nRef; /* Number of pointers to this Table */
u8 tabFlags; /* Mask of TF_* values */
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
- Trigger *pTrigger; /* List of SQL triggers on this table */
FKey *pFKey; /* Linked list of all foreign keys in this table */
char *zColAff; /* String defining the affinity of each column */
#ifndef SQLITE_OMIT_CHECK
Expr *pCheck; /* The AND of all CHECK constraints */
@@ -9609,8 +8404,9 @@
sqlite3_vtab *pVtab; /* Pointer to the module instance */
int nModuleArg; /* Number of arguments to the module */
char **azModuleArg; /* Text of all module args. [0] is module name */
#endif
+ Trigger *pTrigger; /* List of triggers stored in pSchema */
Schema *pSchema; /* Schema that contains this table */
Table *pNextZombie; /* Next on the Parse.pZombieTab list */
};
@@ -9866,21 +8662,29 @@
/*
** Each node of an expression in the parse tree is an instance
** of this structure.
**
-** Expr.op is the opcode. The integer parser token codes are reused
-** as opcodes here. For example, the parser defines TK_GE to be an integer
-** code representing the ">=" operator. This same integer code is reused
+** Expr.op is the opcode. The integer parser token codes are reused
+** as opcodes here. For example, the parser defines TK_GE to be an integer
+** code representing the ">=" operator. This same integer code is reused
** to represent the greater-than-or-equal-to operator in the expression
** tree.
**
-** Expr.pRight and Expr.pLeft are subexpressions. Expr.pList is a list
-** of argument if the expression is a function.
-**
-** Expr.token is the operator token for this node. For some expressions
-** that have subexpressions, Expr.token can be the complete text that gave
-** rise to the Expr. In the latter case, the token is marked as being
-** a compound token.
+** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
+** or TK_STRING), then Expr.token contains the text of the SQL literal. If
+** the expression is a variable (TK_VARIABLE), then Expr.token contains the
+** variable name. Finally, if the expression is an SQL function (TK_FUNCTION),
+** then Expr.token contains the name of the function.
+**
+** Expr.pRight and Expr.pLeft are the left and right subexpressions of a
+** binary operator. Either or both may be NULL.
+**
+** Expr.x.pList is a list of arguments if the expression is an SQL function,
+** a CASE expression or an IN expression of the form "<lhs> IN (<y>, <z>...)".
+** Expr.x.pSelect is used if the expression is a sub-select or an expression of
+** the form "<lhs> IN (SELECT ...)". If the EP_xIsSelect bit is set in the
+** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is
+** valid.
**
** An expression of the form ID or ID.ID refers to a column in a table.
** For such expressions, Expr.op is set to TK_COLUMN and Expr.iTable is
** the integer cursor number of a VDBE cursor pointing to that table and
@@ -9888,45 +8692,75 @@
** expression is used as a result in an aggregate SELECT, then the
** value is also stored in the Expr.iAgg column in the aggregate so that
** it can be accessed after all aggregates are computed.
**
-** If the expression is a function, the Expr.iTable is an integer code
-** representing which function. If the expression is an unbound variable
-** marker (a question mark character '?' in the original SQL) then the
-** Expr.iTable holds the index number for that variable.
+** If the expression is an unbound variable marker (a question mark
+** character '?' in the original SQL) then the Expr.iTable holds the index
+** number for that variable.
**
** If the expression is a subquery then Expr.iColumn holds an integer
** register number containing the result of the subquery. If the
** subquery gives a constant result, then iTable is -1. If the subquery
** gives a different answer at different times during statement processing
** then iTable is the address of a subroutine that computes the subquery.
**
-** The Expr.pSelect field points to a SELECT statement. The SELECT might
-** be the right operand of an IN operator. Or, if a scalar SELECT appears
-** in an expression the opcode is TK_SELECT and Expr.pSelect is the only
-** operand.
-**
** If the Expr is of type OP_Column, and the table it is selecting from
** is a disk table or the "old.*" pseudo-table, then pTab points to the
** corresponding table definition.
+**
+** ALLOCATION NOTES:
+**
+** Expr structures may be stored as part of the in-memory database schema,
+** for example as part of trigger, view or table definitions. In this case,
+** the amount of memory consumed by complex expressions may be significant.
+** For this reason, less than sizeof(Expr) bytes may be allocated for some
+** Expr structs stored as part of the in-memory database schema.
+**
+** If the EP_Reduced flag is set in Expr.flags, then only EXPR_REDUCEDSIZE
+** bytes of space are allocated for the expression structure. This is enough
+** space to store all fields up to and including the "Token span;" field.
+**
+** If the EP_TokenOnly flag is set in Expr.flags, then only EXPR_TOKENONLYSIZE
+** bytes of space are allocated for the expression structure. This is enough
+** space to store all fields up to and including the "Token token;" field.
*/
struct Expr {
u8 op; /* Operation performed by this node */
char affinity; /* The affinity of the column or 0 if not a column */
- u16 flags; /* Various flags. See below */
- CollSeq *pColl; /* The collation type of the column or 0 */
- Expr *pLeft, *pRight; /* Left and right subnodes */
- ExprList *pList; /* A list of expressions used as function arguments
- ** or in "<expr> IN (<expr-list)" */
+ VVA_ONLY(u8 vvaFlags;) /* Flags used for VV&A only. EVVA_* below. */
+ u16 flags; /* Various flags. EP_* See below */
Token token; /* An operand token */
+
+ /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
+ ** space is allocated for the fields below this point. An attempt to
+ ** access them will result in a segfault or malfunction.
+ *********************************************************************/
+
Token span; /* Complete text of the expression */
+
+ /* If the EP_SpanOnly flag is set in the Expr.flags mask, then no
+ ** space is allocated for the fields below this point. An attempt to
+ ** access them will result in a segfault or malfunction.
+ *********************************************************************/
+
+ Expr *pLeft; /* Left subnode */
+ Expr *pRight; /* Right subnode */
+ union {
+ ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
+ Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
+ } x;
+ CollSeq *pColl; /* The collation type of the column or 0 */
+
+ /* If the EP_Reduced flag is set in the Expr.flags mask, then no
+ ** space is allocated for the fields below this point. An attempt to
+ ** access them will result in a segfault or malfunction.
+ *********************************************************************/
+
int iTable, iColumn; /* When op==TK_COLUMN, then this expr node means the
** iColumn-th field of the iTable-th table. */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
int iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
- Select *pSelect; /* When the expression is a sub-select. Also the
- ** right side of "<expr> IN (<select>)" */
Table *pTab; /* Table for TK_COLUMN expressions. */
#if SQLITE_MAX_EXPR_DEPTH>0
int nHeight; /* Height of the tree headed by this node */
#endif
@@ -9946,8 +8780,23 @@
#define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */
#define EP_AnyAff 0x0200 /* Can take a cached column of any affinity */
#define EP_FixedDest 0x0400 /* Result needed in a specific register */
#define EP_IntValue 0x0800 /* Integer value contained in iTable */
+#define EP_xIsSelect 0x1000 /* x.pSelect is valid (otherwise x.pList is) */
+
+#define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
+#define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */
+#define EP_SpanOnly 0x8000 /* Expr struct is EXPR_SPANONLYSIZE bytes only */
+
+/*
+** The following are the meanings of bits in the Expr.vvaFlags field.
+** This information is only used when SQLite is compiled with
+** SQLITE_DEBUG defined.
+*/
+#ifndef NDEBUG
+#define EVVA_ReadOnlyToken 0x01 /* Expr.token.z is read-only */
+#endif
+
/*
** These macros can be used to test, set, or clear bits in the
** Expr.flags field.
*/
@@ -9954,8 +8803,26 @@
#define ExprHasProperty(E,P) (((E)->flags&(P))==(P))
#define ExprHasAnyProperty(E,P) (((E)->flags&(P))!=0)
#define ExprSetProperty(E,P) (E)->flags|=(P)
#define ExprClearProperty(E,P) (E)->flags&=~(P)
+
+/*
+** Macros to determine the number of bytes required by a normal Expr
+** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
+** and an Expr struct with the EP_TokenOnly flag set.
+*/
+#define EXPR_FULLSIZE sizeof(Expr)
+#define EXPR_REDUCEDSIZE offsetof(Expr,iTable)
+#define EXPR_TOKENONLYSIZE offsetof(Expr,span)
+#define EXPR_SPANONLYSIZE offsetof(Expr,pLeft)
+
+/*
+** Flags passed to the sqlite3ExprDup() function. See the header comment
+** above sqlite3ExprDup() for details.
+*/
+#define EXPRDUP_REDUCE 0x0001
+#define EXPRDUP_SPAN 0x0002
+#define EXPRDUP_DISTINCTSPAN 0x0004
/*
** A list of expressions. Each expression may optionally have a
** name. An expr/name combination can be used in several ways, such
@@ -10121,11 +8988,8 @@
int iCur; /* The VDBE cursor used by this IN operator */
int addrInTop; /* Top of the IN loop */
} *aInLoop; /* Information about each nested IN operator */
} in; /* Used when plan.wsFlags&WHERE_IN_ABLE */
- struct {
- WherePlan *aPlan; /* Plans for each term of the WHERE clause */
- } or; /* Used when plan.wsFlags&WHERE_MULTI_OR */
} u;
/* The following field is really not part of the current level. But
** we need a place to cache virtual table index information for each
@@ -10654,8 +9518,32 @@
# define SQLITE_CORRUPT_BKPT SQLITE_CORRUPT
#endif
/*
+** The following macros mimic the standard library functions toupper(),
+** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The
+** sqlite versions only work for ASCII characters, regardless of locale.
+*/
+#ifdef SQLITE_ASCII
+# define sqlite3Toupper(x) ((x)&~(sqlite3CtypeMap[(unsigned char)(x)]&0x20))
+# define sqlite3Isspace(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x01)
+# define sqlite3Isalnum(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x06)
+# define sqlite3Isalpha(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x02)
+# define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04)
+# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
+# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)])
+#else
+# include <ctype.h>
+# define sqlite3Toupper(x) toupper((unsigned char)(x))
+# define sqlite3Isspace(x) isspace((unsigned char)(x))
+# define sqlite3Isalnum(x) isalnum((unsigned char)(x))
+# define sqlite3Isalpha(x) isalpha((unsigned char)(x))
+# define sqlite3Isdigit(x) isdigit((unsigned char)(x))
+# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
+# define sqlite3Tolower(x) tolower((unsigned char)(x))
+#endif
+
+/*
** Internal function prototypes
*/
SQLITE_PRIVATE int sqlite3StrICmp(const char *, const char *);
SQLITE_PRIVATE int sqlite3StrNICmp(const char *, const char *, int);
@@ -10719,9 +9607,9 @@
SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
SQLITE_PRIVATE void sqlite3ErrorClear(Parse*);
SQLITE_PRIVATE void sqlite3Dequote(char*);
-SQLITE_PRIVATE void sqlite3DequoteExpr(sqlite3*, Expr*);
+SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*);
SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **);
SQLITE_PRIVATE void sqlite3FinishCoding(Parse*);
SQLITE_PRIVATE int sqlite3GetTempReg(Parse*);
@@ -10761,8 +9649,9 @@
SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32);
SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32);
SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32);
SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*);
+SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*);
SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int);
SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*);
@@ -10860,14 +9749,14 @@
int*,int,int,int,int);
SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
-SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*);
-SQLITE_PRIVATE void sqlite3TokenCopy(sqlite3*,Token*, Token*);
-SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*);
-SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*);
+SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
+SQLITE_PRIVATE void sqlite3TokenCopy(sqlite3*,Token*,const Token*);
+SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
+SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
-SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*);
+SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*);
SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
@@ -10892,11 +9781,12 @@
Expr*,int, int);
SQLITE_PRIVATE void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*);
SQLITE_PRIVATE void sqlite3DropTrigger(Parse*, SrcList*, int);
SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse*, Trigger*);
-SQLITE_PRIVATE int sqlite3TriggersExist(Table*, int, ExprList*);
-SQLITE_PRIVATE int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int,
- int, int, u32*, u32*);
+SQLITE_PRIVATE Trigger *sqlite3TriggersExist(Parse *, Table*, int, ExprList*, int *pMask);
+SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *, Table *);
+SQLITE_PRIVATE int sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *,
+ int, int, int, int, u32*, u32*);
void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
@@ -10909,9 +9799,9 @@
# define sqlite3TriggersExist(B,C,D,E,F) 0
# define sqlite3DeleteTrigger(A,B)
# define sqlite3DropTriggerPtr(A,B)
# define sqlite3UnlinkAndDeleteTrigger(A,B,C)
-# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I,J,K) 0
+# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I,J,K,L) 0
#endif
SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*);
SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
@@ -11009,10 +9899,12 @@
SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
#ifndef SQLITE_AMALGAMATION
SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[];
+SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[];
SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config;
SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
+SQLITE_PRIVATE int sqlite3PendingByte;
#endif
SQLITE_PRIVATE void sqlite3RootPageMoved(Db*, int, int);
SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
SQLITE_PRIVATE void sqlite3AlterFunctions(sqlite3*);
@@ -11032,8 +9924,9 @@
SQLITE_PRIVATE char sqlite3AffinityType(const Token*);
SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
+SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*);
SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int);
SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
@@ -11052,8 +9945,11 @@
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
+
+SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
+SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
/*
** The interface to the LEMON-generated parser
*/
@@ -11161,8 +10057,19 @@
SQLITE_PRIVATE u32 sqlite3Get4byte(const u8*);
SQLITE_PRIVATE void sqlite3Put4byte(u8*, u32);
+#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
+SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *, sqlite3 *);
+SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db);
+SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db);
+#else
+ #define sqlite3ConnectionBlocked(x,y)
+ #define sqlite3ConnectionUnlocked(x)
+ #define sqlite3ConnectionClosed(x)
+#endif
+
+
#ifdef SQLITE_SSE
#include "sseInt.h"
#endif
@@ -11201,9 +10108,9 @@
*************************************************************************
**
** This file contains definitions of global variables and contants.
**
-** $Id: global.c,v 1.9 2008/12/08 18:19:18 drh Exp $
+** $Id: global.c,v 1.12 2009/02/05 16:31:46 drh Exp $
*/
/* An array to map all upper-case characters into their corresponding
@@ -11251,8 +10158,74 @@
#endif
};
/*
+** The following 256 byte lookup table is used to support SQLites built-in
+** equivalents to the following standard library functions:
+**
+** isspace() 0x01
+** isalpha() 0x02
+** isdigit() 0x04
+** isalnum() 0x06
+** isxdigit() 0x08
+** toupper() 0x20
+**
+** Bit 0x20 is set if the mapped character requires translation to upper
+** case. i.e. if the character is a lower-case ASCII character.
+** If x is a lower-case ASCII character, then its upper-case equivalent
+** is (x - 0x20). Therefore toupper() can be implemented as:
+**
+** (x & ~(map[x]&0x20))
+**
+** Standard function tolower() is implemented using the sqlite3UpperToLower[]
+** array. tolower() is used more often than toupper() by SQLite.
+**
+** SQLite's versions are identical to the standard versions assuming a
+** locale of "C". They are implemented as macros in sqliteInt.h.
+*/
+#ifdef SQLITE_ASCII
+SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */
+ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 20..27 !"#$%&' */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */
+ 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */
+
+ 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */
+ 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* 58..5f XYZ[\]^_ */
+ 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */
+ 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 80..87 ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 88..8f ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 90..97 ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 98..9f ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a0..a7 ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a8..af ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b0..b7 ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b8..bf ........ */
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c0..c7 ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c8..cf ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d0..d7 ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d8..df ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e0..e7 ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e8..ef ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f0..f7 ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* f8..ff ........ */
+};
+#endif
+
+
+
+/*
** The following singleton contains the global configuration for
** the SQLite library.
*/
SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
@@ -11290,8 +10263,28 @@
** database connections. After initialization, this table is
** read-only.
*/
SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
+
+/*
+** The value of the "pending" byte must be 0x40000000 (1 byte past the
+** 1-gibabyte boundary) in a compatible database. SQLite never uses
+** the database page that contains the pending byte. It never attempts
+** to read or write that page. The pending byte page is set assign
+** for use by the VFS layers as space for managing file locks.
+**
+** During testing, it is often desirable to move the pending byte to
+** a different position in the file. This allows code that has to
+** deal with the pending byte to run on files that are much smaller
+** than 1 GiB. The sqlite3_test_control() interface can be used to
+** move the pending byte.
+**
+** IMPORTANT: Changing the pending byte to any value other than
+** 0x40000000 results in an incompatible database file format!
+** Changing the pending byte during operating results in undefined
+** and dileterious behavior.
+*/
+SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
/************** End of global.c **********************************************/
/************** Begin file status.c ******************************************/
/*
@@ -11435,9 +10428,9 @@
** There is only one exported symbol in this file - the function
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: date.c,v 1.99 2008/12/20 13:18:50 drh Exp $
+** $Id: date.c,v 1.103 2009/02/04 03:59:25 shane Exp $
**
** SQLite processes all times and dates as Julian Day numbers. The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
@@ -11464,9 +10457,8 @@
** ISBM 0-943396-61-1
** Willmann-Bell, Inc
** Richmond, Virginia (USA)
*/
-#include <ctype.h>
#include <time.h>
#ifndef SQLITE_OMIT_DATETIME_FUNCS
@@ -11534,9 +10526,9 @@
nextC = va_arg(ap, int);
pVal = va_arg(ap, int*);
val = 0;
while( N-- ){
- if( !isdigit(*(u8*)zDate) ){
+ if( !sqlite3Isdigit(*zDate) ){
goto end_getDigits;
}
val = val*10 + *zDate - '0';
zDate++;
@@ -11578,9 +10570,9 @@
static int parseTimezone(const char *zDate, DateTime *p){
int sgn = 0;
int nHr, nMn;
int c;
- while( isspace(*(u8*)zDate) ){ zDate++; }
+ while( sqlite3Isspace(*zDate) ){ zDate++; }
p->tz = 0;
c = *zDate;
if( c=='-' ){
sgn = -1;
@@ -11598,9 +10590,9 @@
}
zDate += 5;
p->tz = sgn*(nMn + nHr*60);
zulu_time:
- while( isspace(*(u8*)zDate) ){ zDate++; }
+ while( sqlite3Isspace(*zDate) ){ zDate++; }
return *zDate!=0;
}
/*
@@ -11622,12 +10614,12 @@
if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
return 1;
}
zDate += 2;
- if( *zDate=='.' && isdigit((u8)zDate[1]) ){
+ if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){
double rScale = 1.0;
zDate++;
- while( isdigit(*(u8*)zDate) ){
+ while( sqlite3Isdigit(*zDate) ){
ms = ms*10.0 + *zDate - '0';
rScale *= 10.0;
zDate++;
}
@@ -11710,9 +10702,9 @@
if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
return 1;
}
zDate += 10;
- while( isspace(*(u8*)zDate) || 'T'==*(u8*)zDate ){ zDate++; }
+ while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; }
if( parseHhMmSs(zDate, p)==0 ){
/* We got the time */
}else if( *zDate==0 ){
p->validHMS = 0;
@@ -12046,8 +11038,9 @@
case '6':
case '7':
case '8':
case '9': {
+ double rRounder;
n = getValue(z, &r);
assert( n>=1 );
if( z[n]==':' ){
/* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
@@ -12057,9 +11050,9 @@
*/
const char *z2 = z;
DateTime tx;
sqlite3_int64 day;
- if( !isdigit(*(u8*)z2) ) z2++;
+ if( !sqlite3Isdigit(*z2) ) z2++;
memset(&tx, 0, sizeof(tx));
if( parseHhMmSs(z2, &tx) ) break;
computeJD(&tx);
tx.iJD -= 43200000;
@@ -12072,22 +11065,23 @@
rc = 0;
break;
}
z += n;
- while( isspace(*(u8*)z) ) z++;
+ while( sqlite3Isspace(*z) ) z++;
n = sqlite3Strlen30(z);
if( n>10 || n<3 ) break;
if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
computeJD(p);
rc = 0;
+ rRounder = r<0 ? -0.5 : +0.5;
if( n==3 && strcmp(z,"day")==0 ){
- p->iJD += (sqlite3_int64)(r*86400000.0 + 0.5);
+ p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder);
}else if( n==4 && strcmp(z,"hour")==0 ){
- p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + 0.5);
+ p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder);
}else if( n==6 && strcmp(z,"minute")==0 ){
- p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + 0.5);
+ p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder);
}else if( n==6 && strcmp(z,"second")==0 ){
- p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + 0.5);
+ p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder);
}else if( n==5 && strcmp(z,"month")==0 ){
int x, y;
computeYMD_HMS(p);
p->M += (int)r;
@@ -12097,15 +11091,19 @@
p->validJD = 0;
computeJD(p);
y = (int)r;
if( y!=r ){
- p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + 0.5);
+ p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder);
}
}else if( n==4 && strcmp(z,"year")==0 ){
+ int y = (int)r;
computeYMD_HMS(p);
- p->Y += (int)r;
+ p->Y += y;
p->validJD = 0;
computeJD(p);
+ if( y!=r ){
+ p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder);
+ }
}else{
rc = 1;
}
clearYMD_HMS_TZ(p);
@@ -12303,8 +11301,12 @@
}
i++;
}
}
+ testcase( n==sizeof(zBuf)-1 );
+ testcase( n==sizeof(zBuf) );
+ testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
+ testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] );
if( n<sizeof(zBuf) ){
z = zBuf;
}else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){
sqlite3_result_error_toobig(context);
@@ -12449,11 +11451,21 @@
sqlite3 *db;
double rT;
char zBuf[20];
+ UNUSED_PARAMETER(argc);
+ UNUSED_PARAMETER(argv);
+
db = sqlite3_context_db_handle(context);
sqlite3OsCurrentTime(db->pVfs, &rT);
+#ifndef SQLITE_OMIT_FLOATING_POINT
t = 86400.0*(rT - 2440587.5) + 0.5;
+#else
+ /* without floating point support, rT will have
+ ** already lost fractional day precision.
+ */
+ t = 86400 * (rT - 2440587) - 43200;
+#endif
#ifdef HAVE_GMTIME_R
{
struct tm sNow;
gmtime_r(&t, &sNow);
@@ -12520,9 +11532,9 @@
**
** This file contains OS interface code that is common to all
** architectures.
**
-** $Id: os.c,v 1.125 2008/12/08 18:19:18 drh Exp $
+** $Id: os.c,v 1.126 2009/03/25 14:24:42 drh Exp $
*/
#define _SQLITE_OS_C_ 1
#undef _SQLITE_OS_C_
@@ -12618,10 +11630,13 @@
sqlite3_file *pFile,
int flags,
int *pFlagsOut
){
+ int rc;
DO_OS_MALLOC_TEST;
- return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
+ rc = pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
+ assert( rc==SQLITE_OK || pFile->pMethods==0 );
+ return rc;
}
SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
return pVfs->xDelete(pVfs, zPath, dirSync);
}
@@ -12648,9 +11663,9 @@
}
SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
pVfs->xDlError(pVfs, nByte, zBufOut);
}
-void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
+SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
return pVfs->xDlSym(pVfs, pHdle, zSym);
}
SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
pVfs->xDlClose(pVfs, pHandle);
@@ -12960,9 +11975,9 @@
**
** This file contains implementations of the low-level memory allocation
** routines specified in the sqlite3_mem_methods object.
**
-** $Id: mem1.c,v 1.29 2008/12/10 21:19:57 drh Exp $
+** $Id: mem1.c,v 1.30 2009/03/23 04:33:33 danielk1977 Exp $
*/
/*
** This version of the memory allocator is the default. It is
@@ -12981,9 +11996,9 @@
*/
static void *sqlite3MemMalloc(int nByte){
sqlite3_int64 *p;
assert( nByte>0 );
- nByte = (nByte+7)&~7;
+ nByte = ROUND8(nByte);
p = malloc( nByte+8 );
if( p ){
p[0] = nByte;
p++;
@@ -13018,9 +12033,9 @@
*/
static void *sqlite3MemRealloc(void *pPrior, int nByte){
sqlite3_int64 *p = (sqlite3_int64*)pPrior;
assert( pPrior!=0 && nByte>0 );
- nByte = (nByte+7)&~7;
+ nByte = ROUND8(nByte);
p = (sqlite3_int64*)pPrior;
p--;
p = realloc(p, nByte+8 );
if( p ){
@@ -13045,9 +12060,9 @@
/*
** Round up a request size to the next valid allocation size.
*/
static int sqlite3MemRoundup(int n){
- return (n+7) & ~7;
+ return ROUND8(n);
}
/*
** Initialize this module.
@@ -13109,9 +12124,9 @@
**
** This file contains implementations of the low-level memory allocation
** routines specified in the sqlite3_mem_methods object.
**
-** $Id: mem2.c,v 1.42 2008/12/10 19:26:24 drh Exp $
+** $Id: mem2.c,v 1.45 2009/03/23 04:33:33 danielk1977 Exp $
*/
/*
** This version of the memory allocator is used only if the
@@ -13216,9 +12231,9 @@
/*
** Adjust memory usage statistics
*/
static void adjustStats(int iSize, int increment){
- int i = ((iSize+7)&~7)/8;
+ int i = ROUND8(iSize)/8;
if( i>NCSIZE-1 ){
i = NCSIZE - 1;
}
if( increment>0 ){
@@ -13247,15 +12262,17 @@
p = (struct MemBlockHdr*)pAllocation;
p--;
assert( p->iForeGuard==(int)FOREGUARD );
- nReserve = (p->iSize+7)&~7;
+ nReserve = ROUND8(p->iSize);
pInt = (int*)pAllocation;
pU8 = (u8*)pAllocation;
assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD );
- assert( (nReserve-0)<=p->iSize || pU8[nReserve-1]==0x65 );
- assert( (nReserve-1)<=p->iSize || pU8[nReserve-2]==0x65 );
- assert( (nReserve-2)<=p->iSize || pU8[nReserve-3]==0x65 );
+ /* This checks any of the "extra" bytes allocated due
+ ** to rounding up to an 8 byte boundary to ensure
+ ** they haven't been overwritten.
+ */
+ while( nReserve-- > p->iSize ) assert( pU8[nReserve]==0x65 );
return p;
}
/*
@@ -13274,8 +12291,9 @@
** Initialize the memory allocation subsystem.
*/
static int sqlite3MemInit(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
+ assert( (sizeof(struct MemBlockHdr)&7) == 0 );
if( !sqlite3GlobalConfig.bMemstat ){
/* If memory status is enabled, then the malloc.c wrapper will already
** hold the STATIC_MEM mutex when the routines here are invoked. */
mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
@@ -13294,9 +12312,9 @@
/*
** Round up a request size to the next valid allocation size.
*/
static int sqlite3MemRoundup(int n){
- return (n+7) & ~7;
+ return ROUND8(n);
}
/*
** Allocate nByte bytes of memory.
@@ -13310,9 +12328,9 @@
int totalSize;
int nReserve;
sqlite3_mutex_enter(mem.mutex);
assert( mem.disallow==0 );
- nReserve = (nByte+7)&~7;
+ nReserve = ROUND8(nByte);
totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
mem.nBacktrace*sizeof(void*) + mem.nTitle;
p = malloc(totalSize);
if( p ){
@@ -13333,8 +12351,9 @@
if( mem.nBacktrace ){
void *aAddr[40];
pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
+ assert(pBt[0]);
if( mem.xBacktrace ){
mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]);
}
}else{
@@ -13456,9 +12475,9 @@
sqlite3_mutex_enter(mem.mutex);
if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
memcpy(mem.zTitle, zTitle, n);
mem.zTitle[n] = 0;
- mem.nTitle = (n+7)&~7;
+ mem.nTitle = ROUND8(n);
sqlite3_mutex_leave(mem.mutex);
}
SQLITE_PRIVATE void sqlite3MemdebugSync(){
@@ -14725,9 +13744,9 @@
**
** This file contains code that is common across all mutex implementations.
**
-** $Id: mutex.c,v 1.29 2008/10/07 15:25:48 drh Exp $
+** $Id: mutex.c,v 1.30 2009/02/17 16:29:11 danielk1977 Exp $
*/
#ifndef SQLITE_MUTEX_OMIT
/*
@@ -14777,9 +13796,11 @@
** sqlite3MutexInit().
*/
SQLITE_PRIVATE int sqlite3MutexEnd(void){
int rc = SQLITE_OK;
- rc = sqlite3GlobalConfig.mutex.xMutexEnd();
+ if( sqlite3GlobalConfig.mutex.xMutexEnd ){
+ rc = sqlite3GlobalConfig.mutex.xMutexEnd();
+ }
return rc;
}
/*
@@ -15664,9 +14685,9 @@
**
*************************************************************************
** This file contains the C functions that implement mutexes for win32
**
-** $Id: mutex_w32.c,v 1.13 2008/12/08 18:19:18 drh Exp $
+** $Id: mutex_w32.c,v 1.15 2009/01/30 16:09:23 shane Exp $
*/
/*
** The code in this file is only used if we are compiling multithreaded
@@ -15865,8 +14886,10 @@
p->owner = GetCurrentThreadId();
p->nRef++;
rc = SQLITE_OK;
}
+#else
+ UNUSED_PARAMETER(p);
#endif
return rc;
}
@@ -15921,9 +14944,9 @@
*************************************************************************
**
** Memory allocation functions used throughout sqlite.
**
-** $Id: malloc.c,v 1.53 2008/12/16 17:20:38 shane Exp $
+** $Id: malloc.c,v 1.61 2009/03/24 15:08:10 drh Exp $
*/
/*
** This routine runs when the memory allocator sees that the
@@ -16028,9 +15051,9 @@
}
if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100
&& sqlite3GlobalConfig.nScratch>=0 ){
int i;
- sqlite3GlobalConfig.szScratch = (sqlite3GlobalConfig.szScratch - 4) & ~7;
+ sqlite3GlobalConfig.szScratch = ROUNDDOWN8(sqlite3GlobalConfig.szScratch-4);
mem0.aScratchFree = (u32*)&((char*)sqlite3GlobalConfig.pScratch)
[sqlite3GlobalConfig.szScratch*sqlite3GlobalConfig.nScratch];
for(i=0; i<sqlite3GlobalConfig.nScratch; i++){ mem0.aScratchFree[i] = i; }
mem0.nScratchFree = sqlite3GlobalConfig.nScratch;
@@ -16041,9 +15064,9 @@
if( sqlite3GlobalConfig.pPage && sqlite3GlobalConfig.szPage>=512
&& sqlite3GlobalConfig.nPage>=1 ){
int i;
int overhead;
- int sz = sqlite3GlobalConfig.szPage & ~7;
+ int sz = ROUNDDOWN8(sqlite3GlobalConfig.szPage);
int n = sqlite3GlobalConfig.nPage;
overhead = (4*n + sz - 1)/sz;
sqlite3GlobalConfig.nPage -= overhead;
mem0.aPageFree = (u32*)&((char*)sqlite3GlobalConfig.pPage)
@@ -16060,9 +15083,11 @@
/*
** Deinitialize the memory allocation subsystem.
*/
SQLITE_PRIVATE void sqlite3MallocEnd(void){
- sqlite3GlobalConfig.m.xShutdown(sqlite3GlobalConfig.m.pAppData);
+ if( sqlite3GlobalConfig.m.xShutdown ){
+ sqlite3GlobalConfig.m.xShutdown(sqlite3GlobalConfig.m.pAppData);
+ }
memset(&mem0, 0, sizeof(mem0));
}
/*
@@ -16171,9 +15196,17 @@
** assumes the memory subsystem has already been initialized.
*/
SQLITE_PRIVATE void *sqlite3Malloc(int n){
void *p;
- if( n<=0 ){
+ if( n<=0 || NEVER(n>=0x7fffff00) ){
+ /* The NEVER(n>=0x7fffff00) term is added out of paranoia. We want to make
+ ** absolutely sure that there is nothing within SQLite that can cause a
+ ** memory allocation of a number of bytes which is near the maximum signed
+ ** integer value and thus cause an integer overflow inside of the xMalloc()
+ ** implementation. The n>=0x7fffff00 gives us 255 bytes of headroom. The
+ ** test should never be true because SQLITE_MAX_LENGTH should be much
+ ** less than 0x7fffff00 and it should catch large memory allocations
+ ** before they reach this point. */
p = 0;
}else if( sqlite3GlobalConfig.bMemstat ){
sqlite3_mutex_enter(mem0.mutex);
mallocWithAlarm(n, &p);
@@ -16305,97 +15338,8 @@
}
}
/*
-** Allocate memory to be used by the page cache. Make use of the
-** memory buffer provided by SQLITE_CONFIG_PAGECACHE if there is one
-** and that memory is of the right size and is not completely
-** consumed. Otherwise, failover to sqlite3Malloc().
-*/
-#if 0
-SQLITE_PRIVATE void *sqlite3PageMalloc(int n){
- void *p;
- assert( n>0 );
- assert( (n & (n-1))==0 );
- assert( n>=512 && n<=32768 );
-
- if( sqlite3GlobalConfig.szPage<n ){
- goto page_overflow;
- }else{
- sqlite3_mutex_enter(mem0.mutex);
- if( mem0.nPageFree==0 ){
- sqlite3_mutex_leave(mem0.mutex);
- goto page_overflow;
- }else{
- int i;
- i = mem0.aPageFree[--mem0.nPageFree];
- sqlite3_mutex_leave(mem0.mutex);
- i *= sqlite3GlobalConfig.szPage;
- sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, n);
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
- p = (void*)&((char*)sqlite3GlobalConfig.pPage)[i];
- }
- }
- return p;
-
-page_overflow:
- if( sqlite3GlobalConfig.bMemstat ){
- sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, n);
- n = mallocWithAlarm(n, &p);
- if( p ) sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, n);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- p = sqlite3GlobalConfig.m.xMalloc(n);
- }
- return p;
-}
-SQLITE_PRIVATE void sqlite3PageFree(void *p){
- if( p ){
- if( sqlite3GlobalConfig.pPage==0
- || p<sqlite3GlobalConfig.pPage
- || p>=(void*)mem0.aPageFree ){
- /* In this case, the page allocation was obtained from a regular
- ** call to sqlite3_mem_methods.xMalloc() (a page-cache-memory
- ** "overflow"). Free the block with sqlite3_mem_methods.xFree().
- */
- if( sqlite3GlobalConfig.bMemstat ){
- int iSize = sqlite3MallocSize(p);
- sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize);
- sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize);
- sqlite3GlobalConfig.m.xFree(p);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- sqlite3GlobalConfig.m.xFree(p);
- }
- }else{
- /* The page allocation was allocated from the sqlite3GlobalConfig.pPage
- ** buffer. In this case all that is add the index of the page in
- ** the sqlite3GlobalConfig.pPage array to the set of free indexes stored
- ** in the mem0.aPageFree[] array.
- */
- int i;
- i = (u8 *)p - (u8 *)sqlite3GlobalConfig.pPage;
- i /= sqlite3GlobalConfig.szPage;
- assert( i>=0 && i<sqlite3GlobalConfig.nPage );
- sqlite3_mutex_enter(mem0.mutex);
- assert( mem0.nPageFree<sqlite3GlobalConfig.nPage );
- mem0.aPageFree[mem0.nPageFree++] = i;
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
- sqlite3_mutex_leave(mem0.mutex);
-#if !defined(NDEBUG) && 0
- /* Assert that a duplicate was not just inserted into aPageFree[]. */
- for(i=0; i<mem0.nPageFree-1; i++){
- assert( mem0.aPageFree[i]!=mem0.aPageFree[mem0.nPageFree-1] );
- }
-#endif
- }
- }
-}
-#endif
-
-/*
** TRUE if p is a lookaside memory allocation from db
*/
#ifndef SQLITE_OMIT_LOOKASIDE
static int isLookaside(sqlite3 *db, void *p){
@@ -16412,8 +15356,9 @@
SQLITE_PRIVATE int sqlite3MallocSize(void *p){
return sqlite3GlobalConfig.m.xSize(p);
}
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
+ assert( db==0 || sqlite3_mutex_held(db->mutex) );
if( p==0 ){
return 0;
}else if( isLookaside(db, p) ){
return db->lookaside.sz;
@@ -16441,8 +15386,9 @@
** Free memory that might be associated with a particular database
** connection.
*/
SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
+ assert( db==0 || sqlite3_mutex_held(db->mutex) );
if( isLookaside(db, p) ){
LookasideSlot *pBuf = (LookasideSlot*)p;
pBuf->pNext = db->lookaside.pFree;
db->lookaside.pFree = pBuf;
@@ -16460,9 +15406,10 @@
void *pNew;
if( pOld==0 ){
return sqlite3Malloc(nBytes);
}
- if( nBytes<=0 ){
+ if( nBytes<=0 || NEVER(nBytes>=0x7fffff00) ){
+ /* The NEVER(...) term is explained in comments on sqlite3Malloc() */
sqlite3_free(pOld);
return 0;
}
nOld = sqlite3MallocSize(pOld);
@@ -16548,8 +15495,9 @@
** that all prior mallocs (ex: "a") worked too.
*/
SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){
void *p;
+ assert( db==0 || sqlite3_mutex_held(db->mutex) );
#ifndef SQLITE_OMIT_LOOKASIDE
if( db ){
LookasideSlot *pBuf;
if( db->mallocFailed ){
@@ -16582,8 +15530,10 @@
** resize fails, set the mallocFailed flag in the connection object.
*/
SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){
void *pNew = 0;
+ assert( db!=0 );
+ assert( sqlite3_mutex_held(db->mutex) );
if( db->mallocFailed==0 ){
if( p==0 ){
return sqlite3DbMallocRaw(db, n);
}
@@ -16676,12 +15626,12 @@
** returning control to the user) that has called sqlite3_malloc or
** sqlite3_realloc.
**
** The returned value is normally a copy of the second argument to this
-** function. However, if a malloc() failure has occured since the previous
+** function. However, if a malloc() failure has occurred since the previous
** invocation SQLITE_NOMEM is returned instead.
**
-** If the first argument, db, is not NULL and a malloc() error has occured,
+** If the first argument, db, is not NULL and a malloc() error has occurred,
** then the connection error-code (the value returned by sqlite3_errcode())
** is set to SQLITE_NOMEM.
*/
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
@@ -17800,9 +16750,9 @@
*************************************************************************
** This file contains routines used to translate between UTF-8,
** UTF-16, UTF-16BE, and UTF-16LE.
**
-** $Id: utf.c,v 1.70 2008/12/10 22:30:25 shane Exp $
+** $Id: utf.c,v 1.71 2009/03/31 03:41:57 shane Exp $
**
** Notes on UTF-8:
**
** Byte-0 Byte-1 Byte-2 Byte-3 Value
@@ -17842,9 +16792,9 @@
** source code file "vdbe.c". When that file became too big (over
** 6000 lines long) it was split up into several smaller files and
** this header information was factored out.
**
-** $Id: vdbeInt.h,v 1.161 2009/01/05 18:02:27 drh Exp $
+** $Id: vdbeInt.h,v 1.166 2009/03/18 10:33:02 danielk1977 Exp $
*/
#ifndef _VDBEINT_H_
#define _VDBEINT_H_
@@ -17886,15 +16836,13 @@
struct VdbeCursor {
BtCursor *pCursor; /* The cursor structure of the backend */
int iDb; /* Index of cursor database in db->aDb[] (or -1) */
i64 lastRowid; /* Last rowid from a Next or NextIdx operation */
- i64 nextRowid; /* Next rowid returned by OP_NewRowid */
Bool zeroed; /* True if zeroed out and ready for reuse */
Bool rowidIsValid; /* True if lastRowid is valid */
Bool atFirst; /* True if pointing to first entry */
Bool useRandomRowid; /* Generate new record numbers semi-randomly */
Bool nullRow; /* True if pointing to a row with no data */
- Bool nextRowidValid; /* True if the nextRowid field is valid */
Bool pseudoTable; /* This is a NEW or OLD pseudo-tables of a trigger */
Bool ephemPseudoTable;
Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
Bool isTable; /* True if a table requiring integer keys */
@@ -18106,18 +17054,15 @@
int okVar; /* True if azVar[] has been initialized */
u32 magic; /* Magic number for sanity checking */
int nMem; /* Number of memory locations currently allocated */
Mem *aMem; /* The memory locations */
- int nCallback; /* Number of callbacks invoked so far */
int cacheCtr; /* VdbeCursor row cache generation counter */
int contextStackTop; /* Index of top element in the context stack */
int contextStackDepth; /* The size of the "context" stack */
Context *contextStack; /* Stack used by opcodes ContextPush & ContextPop*/
int pc; /* The program counter */
int rc; /* Value to return */
- unsigned uniqueCnt; /* Used by OP_MakeRecord when P2!=0 */
- int errorAction; /* Recovery action to do in case of an error */
- int inTempTrans; /* True if temp database is transactioned */
+ int errorAction; /* Recovery action to do in case of an error */
int nResColumn; /* Number of columns in one row of the result set */
char **azResColumn; /* Values for one row of result */
char *zErrMsg; /* Error message written here */
Mem *pResultSet; /* Pointer to an array of results */
@@ -18127,19 +17072,20 @@
u8 minWriteFileFormat; /* Minimum file format for writable database files */
u8 inVtabMethod; /* See comments above */
u8 usesStmtJournal; /* True if uses a statement journal */
u8 readOnly; /* True for read-only statements */
+ u8 isPrepareV2; /* True if prepared with prepare_v2() */
int nChange; /* Number of db changes made since last reset */
i64 startTime; /* Time when query started - used for profiling */
int btreeMask; /* Bitmask of db->aDb[] entries referenced */
BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
int aCounter[2]; /* Counters used by sqlite3_stmt_status() */
- int nSql; /* Number of bytes in zSql */
char *zSql; /* Text of the SQL statement that generated this */
+ void *pFree; /* Free this when deleting the vdbe */
#ifdef SQLITE_DEBUG
FILE *trace; /* Write an execution trace here, if not NULL */
#endif
- int openedStatement; /* True if this VM has opened a statement journal */
+ int iStatement; /* Statement number (or 0 if has not opened stmt) */
#ifdef SQLITE_SSE
int fetchId; /* Statement number used by sqlite3_fetch_statement */
int lru; /* Counter used for LRU cache replacement */
#endif
@@ -18205,15 +17151,13 @@
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
SQLITE_PRIVATE int sqlite3VdbeOpcodeHasProperty(int, int);
SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
+SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
SQLITE_PRIVATE int sqlite3VdbeReleaseBuffers(Vdbe *p);
#endif
-#ifndef NDEBUG
-SQLITE_PRIVATE void sqlite3VdbeMemSanity(Mem*);
-#endif
SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
@@ -18608,9 +17552,9 @@
WRITE_UTF8(zOut, c);
}
}
*zOut = 0;
- return zOut - zStart;
+ return (int)(zOut - zStart);
}
#endif
#ifndef SQLITE_OMIT_UTF16
@@ -18744,11 +17688,10 @@
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.246 2009/01/10 16:15:22 drh Exp $
-*/
-
+** $Id: util.c,v 1.249 2009/03/01 22:29:20 drh Exp $
+*/
/*
** Routine needed to support the testcase() macro.
*/
@@ -18983,25 +17926,25 @@
SQLITE_PRIVATE int sqlite3IsNumber(const char *z, int *realnum, u8 enc){
int incr = (enc==SQLITE_UTF8?1:2);
if( enc==SQLITE_UTF16BE ) z++;
if( *z=='-' || *z=='+' ) z += incr;
- if( !isdigit(*(u8*)z) ){
+ if( !sqlite3Isdigit(*z) ){
return 0;
}
z += incr;
if( realnum ) *realnum = 0;
- while( isdigit(*(u8*)z) ){ z += incr; }
+ while( sqlite3Isdigit(*z) ){ z += incr; }
if( *z=='.' ){
z += incr;
- if( !isdigit(*(u8*)z) ) return 0;
- while( isdigit(*(u8*)z) ){ z += incr; }
+ if( !sqlite3Isdigit(*z) ) return 0;
+ while( sqlite3Isdigit(*z) ){ z += incr; }
if( realnum ) *realnum = 1;
}
if( *z=='e' || *z=='E' ){
z += incr;
if( *z=='+' || *z=='-' ) z += incr;
- if( !isdigit(*(u8*)z) ) return 0;
- while( isdigit(*(u8*)z) ){ z += incr; }
+ if( !sqlite3Isdigit(*z) ) return 0;
+ while( sqlite3Isdigit(*z) ){ z += incr; }
if( realnum ) *realnum = 1;
}
return *z==0;
}
@@ -19023,9 +17966,9 @@
int sign = 1;
const char *zBegin = z;
LONGDOUBLE_TYPE v1 = 0.0;
int nSignificant = 0;
- while( isspace(*(u8*)z) ) z++;
+ while( sqlite3Isspace(*z) ) z++;
if( *z=='-' ){
sign = -1;
z++;
}else if( *z=='+' ){
@@ -19033,9 +17976,9 @@
}
while( z[0]=='0' ){
z++;
}
- while( isdigit(*(u8*)z) ){
+ while( sqlite3Isdigit(*z) ){
v1 = v1*10.0 + (*z - '0');
z++;
nSignificant++;
}
@@ -19047,9 +17990,9 @@
divisor *= 10.0;
z++;
}
}
- while( isdigit(*(u8*)z) ){
+ while( sqlite3Isdigit(*z) ){
if( nSignificant<18 ){
v1 = v1*10.0 + (*z - '0');
divisor *= 10.0;
nSignificant++;
@@ -19068,9 +18011,9 @@
z++;
}else if( *z=='+' ){
z++;
}
- while( isdigit(*(u8*)z) ){
+ while( sqlite3Isdigit(*z) ){
eval = eval*10 + *z - '0';
z++;
}
while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; }
@@ -19127,9 +18070,9 @@
i64 v = 0;
int neg;
int i, c;
const char *zStart;
- while( isspace(*(u8*)zNum) ) zNum++;
+ while( sqlite3Isspace(*zNum) ) zNum++;
if( *zNum=='-' ){
neg = 1;
zNum++;
}else if( *zNum=='+' ){
@@ -19423,9 +18366,9 @@
a |= *p;
/* a: p2<<28 | p4<<14 | p6 (unmasked) */
if (!(a&0x80))
{
- a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ a &= (0x1f<<28)|(0x7f<<14)|(0x7f);
b &= (0x7f<<14)|(0x7f);
b = b<<7;
a |= b;
s = s>>11;
@@ -19440,9 +18383,9 @@
b |= *p;
/* b: p3<<28 | p5<<14 | p7 (unmasked) */
if (!(b&0x80))
{
- b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ b &= (0x1f<<28)|(0x7f<<14)|(0x7f);
/* moved CSE2 up */
/* a &= (0x7f<<14)|(0x7f); */
a = a<<7;
a |= b;
@@ -19535,10 +18478,10 @@
a |= *p;
/* a: p0<<28 | p2<<14 | p4 (unmasked) */
if (!(a&0x80))
{
- a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
- b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ a &= (0x1f<<28)|(0x7f<<14)|(0x7f);
+ b &= (0x1f<<28)|(0x7f<<14)|(0x7f);
b = b<<7;
*v = a | b;
return 5;
}
@@ -20092,40 +19035,40 @@
/* 59 */ "ResetCount",
/* 60 */ "ContextPush",
/* 61 */ "Yield",
/* 62 */ "DropTrigger",
- /* 63 */ "Or",
- /* 64 */ "And",
- /* 65 */ "DropIndex",
- /* 66 */ "IdxGE",
- /* 67 */ "IdxDelete",
- /* 68 */ "IsNull",
- /* 69 */ "NotNull",
- /* 70 */ "Ne",
- /* 71 */ "Eq",
- /* 72 */ "Gt",
- /* 73 */ "Le",
- /* 74 */ "Lt",
- /* 75 */ "Ge",
- /* 76 */ "Vacuum",
- /* 77 */ "BitAnd",
- /* 78 */ "BitOr",
- /* 79 */ "ShiftLeft",
- /* 80 */ "ShiftRight",
- /* 81 */ "Add",
- /* 82 */ "Subtract",
- /* 83 */ "Multiply",
- /* 84 */ "Divide",
- /* 85 */ "Remainder",
- /* 86 */ "Concat",
- /* 87 */ "IfNot",
- /* 88 */ "DropTable",
- /* 89 */ "SeekLt",
- /* 90 */ "BitNot",
- /* 91 */ "String8",
- /* 92 */ "MakeRecord",
- /* 93 */ "ResultRow",
- /* 94 */ "Delete",
+ /* 63 */ "DropIndex",
+ /* 64 */ "IdxGE",
+ /* 65 */ "IdxDelete",
+ /* 66 */ "Or",
+ /* 67 */ "And",
+ /* 68 */ "Vacuum",
+ /* 69 */ "IfNot",
+ /* 70 */ "DropTable",
+ /* 71 */ "IsNull",
+ /* 72 */ "NotNull",
+ /* 73 */ "Ne",
+ /* 74 */ "Eq",
+ /* 75 */ "Gt",
+ /* 76 */ "Le",
+ /* 77 */ "Lt",
+ /* 78 */ "Ge",
+ /* 79 */ "SeekLt",
+ /* 80 */ "BitAnd",
+ /* 81 */ "BitOr",
+ /* 82 */ "ShiftLeft",
+ /* 83 */ "ShiftRight",
+ /* 84 */ "Add",
+ /* 85 */ "Subtract",
+ /* 86 */ "Multiply",
+ /* 87 */ "Divide",
+ /* 88 */ "Remainder",
+ /* 89 */ "Concat",
+ /* 90 */ "MakeRecord",
+ /* 91 */ "ResultRow",
+ /* 92 */ "Delete",
+ /* 93 */ "BitNot",
+ /* 94 */ "String8",
/* 95 */ "AggFinal",
/* 96 */ "Compare",
/* 97 */ "Goto",
/* 98 */ "TableLock",
@@ -20137,34 +19080,34 @@
/* 104 */ "VFilter",
/* 105 */ "VDestroy",
/* 106 */ "ContextPop",
/* 107 */ "Next",
- /* 108 */ "IdxInsert",
- /* 109 */ "SeekGe",
- /* 110 */ "Insert",
- /* 111 */ "Destroy",
- /* 112 */ "ReadCookie",
- /* 113 */ "LoadAnalysis",
- /* 114 */ "Explain",
- /* 115 */ "OpenPseudo",
- /* 116 */ "OpenEphemeral",
- /* 117 */ "Null",
- /* 118 */ "Move",
- /* 119 */ "Blob",
- /* 120 */ "Rewind",
- /* 121 */ "SeekGt",
- /* 122 */ "VBegin",
- /* 123 */ "VUpdate",
- /* 124 */ "IfZero",
- /* 125 */ "VCreate",
- /* 126 */ "Found",
- /* 127 */ "IfPos",
- /* 128 */ "NullRow",
- /* 129 */ "Real",
- /* 130 */ "Jump",
- /* 131 */ "Permutation",
- /* 132 */ "NotUsed_132",
- /* 133 */ "NotUsed_133",
+ /* 108 */ "Count",
+ /* 109 */ "IdxInsert",
+ /* 110 */ "SeekGe",
+ /* 111 */ "Insert",
+ /* 112 */ "Destroy",
+ /* 113 */ "ReadCookie",
+ /* 114 */ "LoadAnalysis",
+ /* 115 */ "Explain",
+ /* 116 */ "HaltIfNull",
+ /* 117 */ "OpenPseudo",
+ /* 118 */ "OpenEphemeral",
+ /* 119 */ "Null",
+ /* 120 */ "Move",
+ /* 121 */ "Blob",
+ /* 122 */ "Rewind",
+ /* 123 */ "SeekGt",
+ /* 124 */ "VBegin",
+ /* 125 */ "VUpdate",
+ /* 126 */ "IfZero",
+ /* 127 */ "VCreate",
+ /* 128 */ "Found",
+ /* 129 */ "IfPos",
+ /* 130 */ "Real",
+ /* 131 */ "NullRow",
+ /* 132 */ "Jump",
+ /* 133 */ "Permutation",
/* 134 */ "NotUsed_134",
/* 135 */ "NotUsed_135",
/* 136 */ "NotUsed_136",
/* 137 */ "NotUsed_137",
@@ -20259,9 +19202,9 @@
**
** This file should be #included by the os_*.c files only. It is not a
** general purpose header file.
**
-** $Id: os_common.h,v 1.37 2008/05/29 20:22:37 shane Exp $
+** $Id: os_common.h,v 1.38 2009/02/24 18:40:50 danielk1977 Exp $
*/
#ifndef _OS_COMMON_H_
#define _OS_COMMON_H_
@@ -20271,17 +19214,8 @@
** switch. The following code should catch this problem at compile-time.
*/
#ifdef MEMORY_DEBUG
# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
-#endif
-
-
-/*
- * When testing, this global variable stores the location of the
- * pending-byte in the database file.
- */
-#ifdef SQLITE_TEST
-SQLITE_API unsigned int sqlite3_pending_byte = 0x40000000;
#endif
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3OSTrace = 0;
@@ -21588,9 +20522,9 @@
** * Locking primitives for the proxy uber-locking-method. (MacOSX only)
** * Definitions of sqlite3_vfs objects for all locking methods
** plus implementations of sqlite3_os_init() and sqlite3_os_end().
**
-** $Id: os_unix.c,v 1.237 2009/01/15 04:30:03 drh Exp $
+** $Id: os_unix.c,v 1.248 2009/03/30 07:39:35 danielk1977 Exp $
*/
#if SQLITE_OS_UNIX /* This file is used on unix only */
/*
@@ -21725,9 +20659,11 @@
int dirfd; /* File descriptor for the directory */
unsigned char locktype; /* The type of lock held on this fd */
int lastErrno; /* The unix errno from the last I/O error */
void *lockingContext; /* Locking style specific state */
- int openFlags; /* The flags specified at open */
+#if SQLITE_ENABLE_LOCKING_STYLE
+ int openFlags; /* The flags specified at open() */
+#endif
#if SQLITE_THREADSAFE && defined(__linux__)
pthread_t tid; /* The thread that "owns" this unixFile */
#endif
#if OS_VXWORKS
@@ -21744,8 +20680,13 @@
*/
unsigned char transCntrChng; /* True if the transaction counter changed */
unsigned char dbUpdate; /* True if any part of database file changed */
unsigned char inNormalWrite; /* True if in a normal write operation */
+
+ /* If true, that means we are dealing with a database file that has
+ ** a range of locking bytes from PENDING_BYTE through PENDING_BYTE+511
+ ** which should never be read or written. Asserts() will verify this */
+ unsigned char isLockable; /* True if file might be locked */
#endif
#ifdef SQLITE_TEST
/* In test mode, increase the size of this structure a bit so that
** it is larger than the struct CrashFile defined in test6.c.
@@ -21777,9 +20718,9 @@
**
** This file should be #included by the os_*.c files only. It is not a
** general purpose header file.
**
-** $Id: os_common.h,v 1.37 2008/05/29 20:22:37 shane Exp $
+** $Id: os_common.h,v 1.38 2009/02/24 18:40:50 danielk1977 Exp $
*/
#ifndef _OS_COMMON_H_
#define _OS_COMMON_H_
@@ -21789,17 +20730,8 @@
** switch. The following code should catch this problem at compile-time.
*/
#ifdef MEMORY_DEBUG
# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
-#endif
-
-
-/*
- * When testing, this global variable stores the location of the
- * pending-byte in the database file.
- */
-#ifdef SQLITE_TEST
-SQLITE_API unsigned int sqlite3_pending_byte = 0x40000000;
#endif
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3OSTrace = 0;
@@ -22694,8 +21626,9 @@
#endif
return SQLITE_IOERR;
}
+#ifdef __APPLE__
/* On OS X on an msdos filesystem, the inode number is reported
** incorrectly for zero-size files. See ticket #3260. To work
** around this problem (we consider it a bug in OS X, not SQLite)
** we always increase the file size to 1 by writing a single byte
@@ -22705,15 +21638,19 @@
** is a race condition such that another thread has already populated
** the first page of the database, no damage is done.
*/
if( statbuf.st_size==0 ){
- write(fd, "S", 1);
+ rc = write(fd, "S", 1);
+ if( rc!=1 ){
+ return SQLITE_IOERR;
+ }
rc = fstat(fd, &statbuf);
if( rc!=0 ){
pFile->lastErrno = errno;
return SQLITE_IOERR;
}
}
+#endif
memset(&lockKey, 0, sizeof(lockKey));
lockKey.fid.dev = statbuf.st_dev;
#if OS_VXWORKS
@@ -22858,8 +21795,9 @@
}
/* Otherwise see if some other process holds it.
*/
+#ifndef __DJGPP__
if( !reserved ){
struct flock lock;
lock.l_whence = SEEK_SET;
lock.l_start = RESERVED_BYTE;
@@ -22872,8 +21810,9 @@
} else if( lock.l_type!=F_UNLCK ){
reserved = 1;
}
}
+#endif
unixLeaveMutex();
OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
@@ -23199,9 +22138,9 @@
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
if( IS_LOCK_ERROR(rc) ){
pFile->lastErrno = tErrno;
}
- goto end_unlock;
+ goto end_unlock;
}
}
lock.l_type = F_UNLCK;
lock.l_whence = SEEK_SET;
@@ -23214,13 +22153,14 @@
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
if( IS_LOCK_ERROR(rc) ){
pFile->lastErrno = tErrno;
}
- goto end_unlock;
+ goto end_unlock;
}
}
if( locktype==NO_LOCK ){
struct unixOpenCnt *pOpen;
+ int rc2 = SQLITE_OK;
/* Decrement the shared lock counter. Release the lock using an
** OS call only when all threads in this same process have released
** the lock.
@@ -23240,41 +22180,42 @@
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
if( IS_LOCK_ERROR(rc) ){
pFile->lastErrno = tErrno;
}
- pLock->cnt = 1;
- goto end_unlock;
+ pLock->locktype = NO_LOCK;
+ pFile->locktype = NO_LOCK;
}
}
/* Decrement the count of locks against this same file. When the
** count reaches zero, close any other file descriptors whose close
** was deferred because of outstanding locks.
*/
- if( rc==SQLITE_OK ){
- pOpen = pFile->pOpen;
- pOpen->nLock--;
- assert( pOpen->nLock>=0 );
- if( pOpen->nLock==0 && pOpen->nPending>0 ){
- int i;
- for(i=0; i<pOpen->nPending; i++){
- /* close pending fds, but if closing fails don't free the array
- ** assign -1 to the successfully closed descriptors and record the
- ** error. The next attempt to unlock will try again. */
- if( pOpen->aPending[i] < 0 ) continue;
- if( close(pOpen->aPending[i]) ){
- pFile->lastErrno = errno;
- rc = SQLITE_IOERR_CLOSE;
- }else{
- pOpen->aPending[i] = -1;
- }
- }
- if( rc==SQLITE_OK ){
- sqlite3_free(pOpen->aPending);
- pOpen->nPending = 0;
- pOpen->aPending = 0;
- }
- }
+ pOpen = pFile->pOpen;
+ pOpen->nLock--;
+ assert( pOpen->nLock>=0 );
+ if( pOpen->nLock==0 && pOpen->nPending>0 ){
+ int i;
+ for(i=0; i<pOpen->nPending; i++){
+ /* close pending fds, but if closing fails don't free the array
+ ** assign -1 to the successfully closed descriptors and record the
+ ** error. The next attempt to unlock will try again. */
+ if( pOpen->aPending[i] < 0 ) continue;
+ if( close(pOpen->aPending[i]) ){
+ pFile->lastErrno = errno;
+ rc2 = SQLITE_IOERR_CLOSE;
+ }else{
+ pOpen->aPending[i] = -1;
+ }
+ }
+ if( rc2==SQLITE_OK ){
+ sqlite3_free(pOpen->aPending);
+ pOpen->nPending = 0;
+ pOpen->aPending = 0;
+ }
+ }
+ if( rc==SQLITE_OK ){
+ rc = rc2;
}
}
end_unlock:
@@ -24456,8 +23397,14 @@
sqlite3_int64 offset
){
int got;
assert( id );
+
+ /* Never read or write any of the bytes in the locking range */
+ assert( ((unixFile*)id)->isLockable==0
+ || offset>=PENDING_BYTE+512
+ || offset+amt<=PENDING_BYTE );
+
got = seekAndRead((unixFile*)id, offset, pBuf, amt);
if( got==amt ){
return SQLITE_OK;
}else if( got<0 ){
@@ -24521,8 +23468,13 @@
int wrote = 0;
assert( id );
assert( amt>0 );
+ /* Never read or write any of the bytes in the locking range */
+ assert( ((unixFile*)id)->isLockable==0
+ || offset>=PENDING_BYTE+512
+ || offset+amt<=PENDING_BYTE );
+
#ifndef NDEBUG
/* If we are doing a normal write to a database file (as opposed to
** doing a hot-journal rollback or a write to some file other than a
** normal database file) then record the fact that the database
@@ -24532,13 +23484,14 @@
if( ((unixFile*)id)->inNormalWrite ){
unixFile *pFile = (unixFile*)id;
pFile->dbUpdate = 1; /* The database has been modified */
if( offset<=24 && offset+amt>=27 ){
+ int rc;
char oldCntr[4];
SimulateIOErrorBenign(1);
- seekAndRead(pFile, 24, oldCntr, 4);
+ rc = seekAndRead(pFile, 24, oldCntr, 4);
SimulateIOErrorBenign(0);
- if( memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){
+ if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){
pFile->transCntrChng = 1; /* The transaction counter has changed */
}
}
}
@@ -24572,12 +23525,14 @@
SQLITE_API int sqlite3_fullsync_count = 0;
#endif
/*
-** Use the fdatasync() API only if the HAVE_FDATASYNC macro is defined.
-** Otherwise use fsync() in its place.
-*/
-#ifndef HAVE_FDATASYNC
+** We do not trust systems to provide a working fdatasync(). Some do.
+** Others do no. To be safe, we will stick with the (slower) fsync().
+** If you know that your system does support fdatasync() correctly,
+** then simply compile with -Dfdatasync=fdatasync
+*/
+#if !defined(fdatasync) && !defined(__linux__)
# define fdatasync fsync
#endif
/*
@@ -24601,8 +23556,21 @@
** for testing when we want to run through the test suite quickly.
** You are strongly advised *not* to deploy with SQLITE_NO_SYNC
** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash
** or power failure will likely corrupt the database file.
+**
+** SQLite sets the dataOnly flag if the size of the file is unchanged.
+** The idea behind dataOnly is that it should only write the file content
+** to disk, not the inode. We only set dataOnly if the file size is
+** unchanged since the file size is part of the inode. However,
+** Ted Ts'o tells us that fdatasync() will also write the inode if the
+** file size has changed. The only real difference between fdatasync()
+** and fsync(), Ted tells us, is that fdatasync() will not flush the
+** inode if the mtime or owner or other inode attributes have changed.
+** We only care about the file size, not the other file attributes, so
+** as far as SQLite is concerned, an fdatasync() is always adequate.
+** So, we always use fdatasync() if it is available, regardless of
+** the value of the dataOnly flag.
*/
static int full_fsync(int fd, int fullSync, int dataOnly){
int rc;
@@ -24617,8 +23585,9 @@
#elif HAVE_FULLFSYNC
UNUSED_PARAMETER(dataOnly);
#else
UNUSED_PARAMETER(fullSync);
+ UNUSED_PARAMETER(dataOnly);
#endif
/* Record the number of times that we do a normal fsync() and
** FULLSYNC. This is used during testing to verify that this procedure
@@ -24650,18 +23619,14 @@
*/
if( rc ) rc = fsync(fd);
#else
- if( dataOnly ){
- rc = fdatasync(fd);
+ rc = fdatasync(fd);
#if OS_VXWORKS
- if( rc==-1 && errno==ENOTSUP ){
- rc = fsync(fd);
- }
-#endif
- }else{
+ if( rc==-1 && errno==ENOTSUP ){
rc = fsync(fd);
}
+#endif /* OS_VXWORKS */
#endif /* ifdef SQLITE_NO_SYNC elif HAVE_FULLFSYNC */
if( OS_VXWORKS && rc!= -1 ){
rc = 0;
@@ -25444,8 +24409,14 @@
if( pOutFlags ){
*pOutFlags = flags;
}
+#ifndef NDEBUG
+ if( (flags & SQLITE_OPEN_MAIN_DB)!=0 ){
+ ((unixFile*)pFile)->isLockable = 1;
+ }
+#endif
+
assert(fd!=0);
if( isOpenDirectory ){
rc = openDirectory(zPath, &dirfd);
if( rc!=SQLITE_OK ){
@@ -25726,18 +24697,20 @@
sp.tv_sec = microseconds / 1000000;
sp.tv_nsec = (microseconds % 1000000) * 1000;
nanosleep(&sp, NULL);
+ UNUSED_PARAMETER(NotUsed);
return microseconds;
#elif defined(HAVE_USLEEP) && HAVE_USLEEP
usleep(microseconds);
+ UNUSED_PARAMETER(NotUsed);
return microseconds;
#else
int seconds = (microseconds+999999)/1000000;
sleep(seconds);
+ UNUSED_PARAMETER(NotUsed);
return seconds*1000000;
#endif
- UNUSED_PARAMETER(NotUsed);
}
/*
** The following variable, if set to a non-zero value, is interpreted as
@@ -26844,9 +25817,9 @@
******************************************************************************
**
** This file contains code that is specific to windows.
**
-** $Id: os_win.c,v 1.145 2008/12/11 02:58:27 shane Exp $
+** $Id: os_win.c,v 1.153 2009/03/31 03:41:57 shane Exp $
*/
#if SQLITE_OS_WIN /* This file is used for windows only */
@@ -26912,9 +25885,9 @@
**
** This file should be #included by the os_*.c files only. It is not a
** general purpose header file.
**
-** $Id: os_common.h,v 1.37 2008/05/29 20:22:37 shane Exp $
+** $Id: os_common.h,v 1.38 2009/02/24 18:40:50 danielk1977 Exp $
*/
#ifndef _OS_COMMON_H_
#define _OS_COMMON_H_
@@ -26924,17 +25897,8 @@
** switch. The following code should catch this problem at compile-time.
*/
#ifdef MEMORY_DEBUG
# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
-#endif
-
-
-/*
- * When testing, this global variable stores the location of the
- * pending-byte in the database file.
- */
-#ifdef SQLITE_TEST
-SQLITE_API unsigned int sqlite3_pending_byte = 0x40000000;
#endif
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3OSTrace = 0;
@@ -27138,8 +26102,9 @@
** reduced API.
*/
#if SQLITE_OS_WINCE
# define AreFileApisANSI() 1
+# define GetDiskFreeSpaceW() 0
#endif
/*
** WinCE lacks native support for file locking so we have to fake it
@@ -27163,8 +26128,10 @@
const sqlite3_io_methods *pMethod;/* Must be first */
HANDLE h; /* Handle for accessing the file */
unsigned char locktype; /* Type of lock currently held on this file */
short sharedLockByte; /* Randomly chosen byte used as a shared lock */
+ DWORD lastErrno; /* The Windows errno from the last I/O error */
+ DWORD sectorSize; /* Sector size of the device file is on */
#if SQLITE_OS_WINCE
WCHAR *zDeleteOnClose; /* Name of file to delete when closing */
HANDLE hMutex; /* Mutex used to control access to shared lock */
HANDLE hShared; /* Shared memory segment used for locking */
@@ -27172,8 +26139,15 @@
winceLock *shared; /* Global shared lock memory for the file */
#endif
};
+/*
+** Forward prototypes.
+*/
+static int getSectorSize(
+ sqlite3_vfs *pVfs,
+ const char *zRelative /* UTF-8 file name */
+);
/*
** The following variable is (normally) set once and never changes
** thereafter. It records whether the operating system is Win95
@@ -27197,9 +26171,9 @@
** or WinCE. Return false (zero) for Win95, Win98, or WinME.
**
** Here is an interesting observation: Win95, Win98, and WinME lack
** the LockFileEx() API. But we can still statically link against that
-** API as long as we don't call it win running Win95/98/ME. A call to
+** API as long as we don't call it when running Win95/98/ME. A call to
** this routine is used to determine if the host is Win95/98/ME or
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/
@@ -27420,8 +26394,9 @@
/* Create/open the named mutex */
pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
if (!pFile->hMutex){
+ pFile->lastErrno = GetLastError();
free(zName);
return FALSE;
}
@@ -27450,8 +26425,9 @@
pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared,
FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
/* If mapping failed, close the shared memory handle and erase it */
if (!pFile->shared){
+ pFile->lastErrno = GetLastError();
CloseHandle(pFile->hShared);
pFile->hShared = NULL;
}
}
@@ -27669,8 +26645,10 @@
#define MX_CLOSE_ATTEMPT 3
static int winClose(sqlite3_file *id){
int rc, cnt = 0;
winFile *pFile = (winFile*)id;
+
+ assert( id!=0 );
OSTRACE2("CLOSE %d\n", pFile->h);
do{
rc = CloseHandle(pFile->h);
}while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
@@ -27713,18 +26691,22 @@
){
LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
LONG lowerBits = (LONG)(offset & 0xffffffff);
DWORD rc;
- DWORD got;
winFile *pFile = (winFile*)id;
+ DWORD error;
+ DWORD got;
+
assert( id!=0 );
SimulateIOError(return SQLITE_IOERR_READ);
OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype);
rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
- if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
+ if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
+ pFile->lastErrno = error;
return SQLITE_FULL;
}
if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){
+ pFile->lastErrno = GetLastError();
return SQLITE_IOERR_READ;
}
if( got==(DWORD)amt ){
return SQLITE_OK;
@@ -27747,16 +26729,19 @@
){
LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
LONG lowerBits = (LONG)(offset & 0xffffffff);
DWORD rc;
- DWORD wrote = 0;
winFile *pFile = (winFile*)id;
+ DWORD error;
+ DWORD wrote = 0;
+
assert( id!=0 );
SimulateIOError(return SQLITE_IOERR_WRITE);
SimulateDiskfullError(return SQLITE_FULL);
OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype);
rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
- if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
+ if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
+ pFile->lastErrno = error;
return SQLITE_FULL;
}
assert( amt>0 );
while(
@@ -27767,8 +26752,9 @@
amt -= wrote;
pBuf = &((char*)pBuf)[wrote];
}
if( !rc || amt>(int)wrote ){
+ pFile->lastErrno = GetLastError();
return SQLITE_FULL;
}
return SQLITE_OK;
}
@@ -27776,22 +26762,28 @@
/*
** Truncate an open file to a specified size
*/
static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
- DWORD rc;
LONG upperBits = (LONG)((nByte>>32) & 0x7fffffff);
LONG lowerBits = (LONG)(nByte & 0xffffffff);
+ DWORD rc;
winFile *pFile = (winFile*)id;
+ DWORD error;
+
+ assert( id!=0 );
OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte);
SimulateIOError(return SQLITE_IOERR_TRUNCATE);
rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
- if( INVALID_SET_FILE_POINTER != rc ){
- /* SetEndOfFile will fail if nByte is negative */
- if( SetEndOfFile(pFile->h) ){
- return SQLITE_OK;
- }
- }
- return SQLITE_IOERR_TRUNCATE;
+ if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
+ pFile->lastErrno = error;
+ return SQLITE_IOERR_TRUNCATE;
+ }
+ /* SetEndOfFile will fail if nByte is negative */
+ if( !SetEndOfFile(pFile->h) ){
+ pFile->lastErrno = GetLastError();
+ return SQLITE_IOERR_TRUNCATE;
+ }
+ return SQLITE_OK;
}
#ifdef SQLITE_TEST
/*
@@ -27807,12 +26799,14 @@
*/
static int winSync(sqlite3_file *id, int flags){
#ifndef SQLITE_NO_SYNC
winFile *pFile = (winFile*)id;
+
+ assert( id!=0 );
+ OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);
#else
UNUSED_PARAMETER(id);
#endif
- OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);
#ifndef SQLITE_TEST
UNUSED_PARAMETER(flags);
#else
if( flags & SQLITE_SYNC_FULL ){
@@ -27828,8 +26822,9 @@
#else
if( FlushFileBuffers(pFile->h) ){
return SQLITE_OK;
}else{
+ pFile->lastErrno = GetLastError();
return SQLITE_IOERR;
}
#endif
}
@@ -27837,12 +26832,22 @@
/*
** Determine the current size of a file in bytes
*/
static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
+ DWORD upperBits;
+ DWORD lowerBits;
winFile *pFile = (winFile*)id;
- DWORD upperBits, lowerBits;
+ DWORD error;
+
+ assert( id!=0 );
SimulateIOError(return SQLITE_IOERR_FSTAT);
lowerBits = GetFileSize(pFile->h, &upperBits);
+ if( (lowerBits == INVALID_FILE_SIZE)
+ && ((error = GetLastError()) != NO_ERROR) )
+ {
+ pFile->lastErrno = error;
+ return SQLITE_IOERR_FSTAT;
+ }
*pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
return SQLITE_OK;
}
@@ -27876,8 +26881,11 @@
pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
#endif
}
+ if( res == 0 ){
+ pFile->lastErrno = GetLastError();
+ }
return res;
}
/*
@@ -27892,8 +26900,11 @@
#if SQLITE_OS_WINCE==0
}else{
res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
#endif
+ }
+ if( res == 0 ){
+ pFile->lastErrno = GetLastError();
}
return res;
}
@@ -27928,10 +26939,11 @@
int res = 1; /* Result of a windows lock call */
int newLocktype; /* Set pFile->locktype to this value before exiting */
int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
winFile *pFile = (winFile*)id;
-
- assert( pFile!=0 );
+ DWORD error = NO_ERROR;
+
+ assert( id!=0 );
OSTRACE5("LOCK %d %d was %d(%d)\n",
pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
/* If there is already a lock of this type or more restrictive on the
@@ -27952,10 +26964,11 @@
** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
** the PENDING_LOCK byte is temporary.
*/
newLocktype = pFile->locktype;
- if( pFile->locktype==NO_LOCK
- || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
+ if( (pFile->locktype==NO_LOCK)
+ || ( (locktype==EXCLUSIVE_LOCK)
+ && (pFile->locktype==RESERVED_LOCK))
){
int cnt = 3;
while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
/* Try 3 times to get the pending lock. The pending lock might be
@@ -27964,8 +26977,11 @@
OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
Sleep(1);
}
gotPendingLock = res;
+ if( !res ){
+ error = GetLastError();
+ }
}
/* Acquire a shared lock
*/
@@ -27973,8 +26989,10 @@
assert( pFile->locktype==NO_LOCK );
res = getReadLock(pFile);
if( res ){
newLocktype = SHARED_LOCK;
+ }else{
+ error = GetLastError();
}
}
/* Acquire a RESERVED lock
@@ -27983,8 +27001,10 @@
assert( pFile->locktype==SHARED_LOCK );
res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
if( res ){
newLocktype = RESERVED_LOCK;
+ }else{
+ error = GetLastError();
}
}
/* Acquire a PENDING lock
@@ -28003,9 +27023,10 @@
res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
if( res ){
newLocktype = EXCLUSIVE_LOCK;
}else{
- OSTRACE2("error-code = %d\n", GetLastError());
+ error = GetLastError();
+ OSTRACE2("error-code = %d\n", error);
getReadLock(pFile);
}
}
@@ -28023,8 +27044,9 @@
rc = SQLITE_OK;
}else{
OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
locktype, newLocktype);
+ pFile->lastErrno = error;
rc = SQLITE_BUSY;
}
pFile->locktype = (u8)newLocktype;
return rc;
@@ -28037,9 +27059,10 @@
*/
static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
int rc;
winFile *pFile = (winFile*)id;
- assert( pFile!=0 );
+
+ assert( id!=0 );
if( pFile->locktype>=RESERVED_LOCK ){
rc = 1;
OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
}else{
@@ -28103,8 +27126,12 @@
case SQLITE_FCNTL_LOCKSTATE: {
*(int*)pArg = ((winFile*)id)->locktype;
return SQLITE_OK;
}
+ case SQLITE_LAST_ERRNO: {
+ *(int*)pArg = (int)((winFile*)id)->lastErrno;
+ return SQLITE_OK;
+ }
}
return SQLITE_ERROR;
}
@@ -28118,10 +27145,10 @@
** a database and its journal file) that the sector size will be the
** same for both.
*/
static int winSectorSize(sqlite3_file *id){
- UNUSED_PARAMETER(id);
- return SQLITE_DEFAULT_SECTOR_SIZE;
+ assert( id!=0 );
+ return (int)(((winFile*)id)->sectorSize);
}
/*
** Return a vector of device characteristics.
@@ -28263,9 +27290,8 @@
return 0;
}
-
/*
** Open a file.
*/
static int winOpen(
@@ -28287,8 +27313,9 @@
void *zConverted; /* Filename in OS encoding */
const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
char zTmpname[MAX_PATH+1]; /* Buffer used to create temp filename */
+ assert( id!=0 );
UNUSED_PARAMETER(pVfs);
/* If the second argument to this function is NULL, generate a
** temporary file name to use
@@ -28366,9 +27393,9 @@
}
if( h==INVALID_HANDLE_VALUE ){
free(zConverted);
if( flags & SQLITE_OPEN_READWRITE ){
- return winOpen(0, zName, id,
+ return winOpen(pVfs, zName, id,
((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
}else{
return SQLITE_CANTOPEN;
}
@@ -28382,8 +27409,10 @@
}
memset(pFile, 0, sizeof(*pFile));
pFile->pMethod = &winIoMethod;
pFile->h = h;
+ pFile->lastErrno = NO_ERROR;
+ pFile->sectorSize = getSectorSize(pVfs, zUtf8Name);
#if SQLITE_OS_WINCE
if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
(SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
&& !winceCreateLock(zName, pFile)
@@ -28573,8 +27602,75 @@
}
#endif
}
+/*
+** Get the sector size of the device used to store
+** file.
+*/
+static int getSectorSize(
+ sqlite3_vfs *pVfs,
+ const char *zRelative /* UTF-8 file name */
+){
+ DWORD bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
+ char zFullpath[MAX_PATH+1];
+ int rc;
+ DWORD dwRet = 0;
+
+ /*
+ ** We need to get the full path name of the file
+ ** to get the drive letter to look up the sector
+ ** size.
+ */
+ rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath);
+ if( rc == SQLITE_OK )
+ {
+ void *zConverted = convertUtf8Filename(zFullpath);
+ if( zConverted ){
+ if( isNT() ){
+ int i;
+ /* trim path to just drive reference */
+ WCHAR *p = zConverted;
+ for(i=0;i<MAX_PATH;i++){
+ if( p[i] == '\\' ){
+ i++;
+ p[i] = '\0';
+ break;
+ }
+ }
+ dwRet = GetDiskFreeSpaceW((WCHAR*)zConverted,
+ NULL,
+ &bytesPerSector,
+ NULL,
+ NULL);
+#if SQLITE_OS_WINCE==0
+ }else{
+ int i;
+ /* trim path to just drive reference */
+ CHAR *p = (CHAR *)zConverted;
+ for(i=0;i<MAX_PATH;i++){
+ if( p[i] == '\\' ){
+ i++;
+ p[i] = '\0';
+ break;
+ }
+ }
+ dwRet = GetDiskFreeSpaceA((CHAR*)zConverted,
+ NULL,
+ &bytesPerSector,
+ NULL,
+ NULL);
+#endif
+ }
+ free(zConverted);
+ }
+ if( !dwRet ){
+ bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
+ }
+ }
+ return (int) bytesPerSector;
+}
+
#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.
@@ -28694,9 +27790,23 @@
FILETIME ft;
/* FILETIME structure is a 64-bit value representing the number of
100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
*/
- double now;
+ sqlite3_int64 timeW; /* Whole days */
+ sqlite3_int64 timeF; /* Fractional Days */
+
+ /* Number of 100-nanosecond intervals in a single day */
+ static const sqlite3_int64 ntuPerDay =
+ 10000000*(sqlite3_int64)86400;
+
+ /* Number of 100-nanosecond intervals in half of a day */
+ static const sqlite3_int64 ntuPerHalfDay =
+ 10000000*(sqlite3_int64)43200;
+
+ /* 2^32 - to avoid use of LL and warnings in gcc */
+ static const sqlite3_int64 max32BitValue =
+ (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
+
#if SQLITE_OS_WINCE
SYSTEMTIME time;
GetSystemTime(&time);
/* if SystemTimeToFileTime() fails, it returns zero. */
@@ -28706,13 +27816,19 @@
#else
GetSystemTimeAsFileTime( &ft );
#endif
UNUSED_PARAMETER(pVfs);
- now = ((double)ft.dwHighDateTime) * 4294967296.0;
- *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
+ timeW = (((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + (sqlite3_int64)ft.dwLowDateTime;
+ timeF = timeW % ntuPerDay; /* fractional days (100-nanoseconds) */
+ timeW = timeW / ntuPerDay; /* whole days */
+ timeW = timeW + 2305813; /* add whole days (from 2305813.5) */
+ timeF = timeF + ntuPerHalfDay; /* add half a day (from 2305813.5) */
+ timeW = timeW + (timeF/ntuPerDay); /* add whole day if half day made one */
+ timeF = timeF % ntuPerDay; /* compute new fractional days */
+ *prNow = (double)timeW + ((double)timeF / (double)ntuPerDay);
#ifdef SQLITE_TEST
if( sqlite3_current_time ){
- *prNow = sqlite3_current_time/86400.0 + 2440587.5;
+ *prNow = ((double)sqlite3_current_time + (double)43200) / (double)86400 + (double)2440587;
}
#endif
return 0;
}
@@ -28723,9 +27839,9 @@
** strerror_r() on unix). After an error is returned by an OS
** function, SQLite calls this function with zBuf pointing to
** a buffer of nBuf bytes. The OS layer should populate the
** buffer with a nul-terminated UTF-8 encoded error message
-** describing the last IO error to have occured within the calling
+** describing the last IO error to have occurred within the calling
** thread.
**
** If the error message is too large for the supplied buffer,
** it should be truncated. The return value of xGetLastError
@@ -28823,9 +27939,9 @@
** Bitvec object is the number of pages in the database file at the
** start of a transaction, and is thus usually less than a few thousand,
** but can be as large as 2 billion for a really big database.
**
-** @(#) $Id: bitvec.c,v 1.10 2009/01/02 21:39:39 drh Exp $
+** @(#) $Id: bitvec.c,v 1.13 2009/01/20 17:06:27 danielk1977 Exp $
*/
/* Size of the Bitvec structure in bytes. */
#define BITVEC_SZ 512
@@ -29063,8 +28179,16 @@
}
sqlite3_free(p);
}
+/*
+** Return the value of the iSize parameter specified when Bitvec *p
+** was created.
+*/
+SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){
+ return p->iSize;
+}
+
#ifndef SQLITE_OMIT_BUILTIN_TEST
/*
** Let V[] be an array of unsigned characters sufficient to hold
** up to N bits. Let I be an integer between 0 and N. 0<=I<N.
@@ -29188,9 +28312,9 @@
**
*************************************************************************
** This file implements that page cache.
**
-** @(#) $Id: pcache.c,v 1.39 2008/12/04 20:40:10 drh Exp $
+** @(#) $Id: pcache.c,v 1.44 2009/03/31 01:32:18 drh Exp $
*/
/*
** A complete page cache is an instance of this structure.
@@ -29199,16 +28323,15 @@
PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */
PgHdr *pSynced; /* Last synced page in dirty page list */
int nRef; /* Number of referenced pages */
int nMax; /* Configured cache size */
- int nMin; /* Configured minimum cache size */
int szPage; /* Size of every page in this cache */
int szExtra; /* Size of extra space for each page */
int bPurgeable; /* True if pages are on backing store */
int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */
void *pStress; /* Argument to xStress */
sqlite3_pcache *pCache; /* Pluggable cache module */
- PgHdr *pPage1;
+ PgHdr *pPage1; /* Reference to page 1 */
};
/*
** Some of the assert() macros in this code are too expensive to run
@@ -29357,9 +28480,8 @@
p->bPurgeable = bPurgeable;
p->xStress = xStress;
p->pStress = pStress;
p->nMax = 100;
- p->nMin = 10;
}
/*
** Change the page size for PCache object. The caller must ensure that there
@@ -29439,16 +28561,23 @@
pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, 2);
}
if( pPage ){
+ if( !pPage->pData ){
+ memset(pPage, 0, sizeof(PgHdr) + pCache->szExtra);
+ pPage->pExtra = (void*)&pPage[1];
+ pPage->pData = (void *)&((char *)pPage)[sizeof(PgHdr) + pCache->szExtra];
+ pPage->pCache = pCache;
+ pPage->pgno = pgno;
+ }
+ assert( pPage->pCache==pCache );
+ assert( pPage->pgno==pgno );
+ assert( pPage->pExtra==(void *)&pPage[1] );
+
if( 0==pPage->nRef ){
pCache->nRef++;
}
pPage->nRef++;
- pPage->pData = (void*)&pPage[1];
- pPage->pExtra = (void*)&((char*)pPage->pData)[pCache->szPage];
- pPage->pCache = pCache;
- pPage->pgno = pgno;
if( pgno==1 ){
pCache->pPage1 = pPage;
}
}
@@ -29507,13 +28636,11 @@
** Make sure the page is marked as dirty. If it isn't dirty already,
** make it so.
*/
SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
- PCache *pCache;
p->flags &= ~PGHDR_DONT_WRITE;
assert( p->nRef>0 );
if( 0==(p->flags & PGHDR_DIRTY) ){
- pCache = p->pCache;
p->flags |= PGHDR_DIRTY;
pcacheAddToDirtyList( p);
}
}
@@ -29607,11 +28734,10 @@
/*
** Discard the contents of the cache.
*/
-SQLITE_PRIVATE int sqlite3PcacheClear(PCache *pCache){
- sqlite3PcacheTruncate(pCache, 0);
- return SQLITE_OK;
+SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){
+ sqlite3PcacheTruncate(pCache, 0);
}
/*
** Merge two lists of pages connected by pDirty and in pgno order.
@@ -29775,9 +28901,9 @@
** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features.
** If the default page cache implementation is overriden, then neither of
** these two features are available.
**
-** @(#) $Id: pcache1.c,v 1.7 2009/01/07 15:18:21 danielk1977 Exp $
+** @(#) $Id: pcache1.c,v 1.10 2009/03/23 04:33:33 danielk1977 Exp $
*/
typedef struct PCache1 PCache1;
@@ -29887,9 +29013,9 @@
** enough to contain 'n' buffers of 'sz' bytes each.
*/
SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
PgFreeslot *p;
- sz &= ~7;
+ sz = ROUNDDOWN8(sz);
pcache1.szSlot = sz;
pcache1.pStart = pBuf;
pcache1.pFree = 0;
while( n-- ){
@@ -29959,9 +29085,8 @@
static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
int nByte = sizeof(PgHdr1) + pCache->szPage;
PgHdr1 *p = (PgHdr1 *)pcache1Alloc(nByte);
if( p ){
- memset(p, 0, nByte);
if( pCache->bPurgeable ){
pcache1.nCurrentPage++;
}
}
@@ -30275,9 +29400,9 @@
/* Step 3 of header comment. */
nPinned = pCache->nPage - pCache->nRecyclable;
if( createFlag==1 && pCache->bPurgeable && (
nPinned>=(pcache1.nMaxPage+pCache->nMin-pcache1.nMinPage)
- || nPinned>=(pCache->nMax)
+ || nPinned>=(pCache->nMax * 9 / 10)
)){
goto fetch_out;
}
@@ -30308,13 +29433,15 @@
}
if( pPage ){
unsigned int h = iKey % pCache->nHash;
- memset(pPage, 0, pCache->szPage + sizeof(PgHdr1));
+ *(void **)(PGHDR1_TO_PAGE(pPage)) = 0;
pCache->nPage++;
pPage->iKey = iKey;
pPage->pNext = pCache->apHash[h];
pPage->pCache = pCache;
+ pPage->pLruPrev = 0;
+ pPage->pLruNext = 0;
pCache->apHash[h] = pPage;
}
fetch_out:
@@ -30770,9 +29897,9 @@
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.551 2009/01/14 23:03:41 drh Exp $
+** @(#) $Id: pager.c,v 1.576 2009/03/31 02:54:40 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
/*
@@ -30851,14 +29978,8 @@
#define PAGER_EXCLUSIVE 4 /* same as EXCLUSIVE_LOCK */
#define PAGER_SYNCED 5
/*
-** This macro rounds values up so that if the value is an address it
-** is guaranteed to be an address that is aligned to an 8-byte boundary.
-*/
-#define FORCE_ALIGNMENT(X) (((X)+7)&~7)
-
-/*
** A macro used for invoking the codec if there is one
*/
#ifdef SQLITE_HAS_CODEC
# define CODEC1(P,D,N,X) if( P->xCodec!=0 ){ P->xCodec(P->pCodecArg,D,N,X); }
@@ -30900,75 +30021,153 @@
/*
** A open page cache is an instance of the following structure.
**
-** Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, or
-** or SQLITE_FULL. Once one of the first three errors occurs, it persists
-** and is returned as the result of every major pager API call. The
-** SQLITE_FULL return code is slightly different. It persists only until the
-** next successful rollback is performed on the pager cache. Also,
-** SQLITE_FULL does not affect the sqlite3PagerGet() and sqlite3PagerLookup()
-** APIs, they may still be used successfully.
-**
-** Managing the size of the database file in pages is a little complicated.
-** The variable Pager.dbSize contains the number of pages that the database
-** image currently contains. As the database image grows or shrinks this
-** variable is updated. The variable Pager.dbFileSize contains the number
-** of pages in the database file. This may be different from Pager.dbSize
-** if some pages have been appended to the database image but not yet written
-** out from the cache to the actual file on disk. Or if the image has been
-** truncated by an incremental-vacuum operation. The Pager.dbOrigSize variable
-** contains the number of pages in the database image when the current
-** transaction was opened. The contents of all three of these variables is
-** only guaranteed to be correct if the boolean Pager.dbSizeValid is true.
+** errCode
+**
+** Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, or
+** or SQLITE_FULL. Once one of the first three errors occurs, it persists
+** and is returned as the result of every major pager API call. The
+** SQLITE_FULL return code is slightly different. It persists only until the
+** next successful rollback is performed on the pager cache. Also,
+** SQLITE_FULL does not affect the sqlite3PagerGet() and sqlite3PagerLookup()
+** APIs, they may still be used successfully.
+**
+** dbSizeValid, dbSize, dbOrigSize, dbFileSize
+**
+** Managing the size of the database file in pages is a little complicated.
+** The variable Pager.dbSize contains the number of pages that the database
+** image currently contains. As the database image grows or shrinks this
+** variable is updated. The variable Pager.dbFileSize contains the number
+** of pages in the database file. This may be different from Pager.dbSize
+** if some pages have been appended to the database image but not yet written
+** out from the cache to the actual file on disk. Or if the image has been
+** truncated by an incremental-vacuum operation. The Pager.dbOrigSize variable
+** contains the number of pages in the database image when the current
+** transaction was opened. The contents of all three of these variables is
+** only guaranteed to be correct if the boolean Pager.dbSizeValid is true.
+**
+** TODO: Under what conditions is dbSizeValid set? Cleared?
+**
+** changeCountDone
+**
+** This boolean variable is used to make sure that the change-counter
+** (the 4-byte header field at byte offset 24 of the database file) is
+** not updated more often than necessary.
+**
+** It is set to true when the change-counter field is updated, which
+** can only happen if an exclusive lock is held on the database file.
+** It is cleared (set to false) whenever an exclusive lock is
+** relinquished on the database file. Each time a transaction is committed,
+** The changeCountDone flag is inspected. If it is true, the work of
+** updating the change-counter is omitted for the current transaction.
+**
+** This mechanism means that when running in exclusive mode, a connection
+** need only update the change-counter once, for the first transaction
+** committed.
+**
+** dbModified
+**
+** The dbModified flag is set whenever a database page is dirtied.
+** It is cleared at the end of each transaction.
+**
+** It is used when committing or otherwise ending a transaction. If
+** the dbModified flag is clear then less work has to be done.
+**
+** journalStarted
+**
+** This flag is set whenever the the main journal is synced.
+**
+** The point of this flag is that it must be set after the
+** first journal header in a journal file has been synced to disk.
+** After this has happened, new pages appended to the database
+** do not need the PGHDR_NEED_SYNC flag set, as they do not need
+** to wait for a journal sync before they can be written out to
+** the database file (see function pager_write()).
+**
+** setMaster
+**
+** This variable is used to ensure that the master journal file name
+** (if any) is only written into the journal file once.
+**
+** When committing a transaction, the master journal file name (if any)
+** may be written into the journal file while the pager is still in
+** PAGER_RESERVED state (see CommitPhaseOne() for the action). It
+** then attempts to upgrade to an exclusive lock. If this attempt
+** fails, then SQLITE_BUSY may be returned to the user and the user
+** may attempt to commit the transaction again later (calling
+** CommitPhaseOne() again). This flag is used to ensure that the
+** master journal name is only written to the journal file the first
+** time CommitPhaseOne() is called.
+**
+** doNotSync
+**
+** This variable is set and cleared by sqlite3PagerWrite().
+**
+** needSync
+**
+** TODO: It might be easier to set this variable in writeJournalHdr()
+** and writeMasterJournal() only. Change its meaning to "unsynced data
+** has been written to the journal".
*/
struct Pager {
sqlite3_vfs *pVfs; /* OS functions to use for IO */
- u8 journalOpen; /* True if journal file descriptors is valid */
- u8 journalStarted; /* True if header of journal is synced */
+ u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */
+ u8 journalMode; /* On of the PAGER_JOURNALMODE_* values */
u8 useJournal; /* Use a rollback journal on this file */
u8 noReadlock; /* Do not bother to obtain readlocks */
u8 noSync; /* Do not sync the journal if true */
u8 fullSync; /* Do extra syncs of the journal for robustness */
u8 sync_flags; /* One of SYNC_NORMAL or SYNC_FULL */
- u8 state; /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
u8 tempFile; /* zFilename is a temporary file */
u8 readOnly; /* True for a read-only database */
- u8 needSync; /* True if an fsync() is needed on the journal */
- u8 dirtyCache; /* True if cached pages have changed */
u8 memDb; /* True to inhibit all file I/O */
+
+ /* The following block contains those class members that are dynamically
+ ** modified during normal operations. The other variables in this structure
+ ** are either constant throughout the lifetime of the pager, or else
+ ** used to store configuration parameters that affect the way the pager
+ ** operates.
+ **
+ ** The 'state' variable is described in more detail along with the
+ ** descriptions of the values it may take - PAGER_UNLOCK etc. Many of the
+ ** other variables in this block are described in the comment directly
+ ** above this class definition.
+ */
+ u8 state; /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
+ u8 dbModified; /* True if there are any changes to the Db */
+ u8 needSync; /* True if an fsync() is needed on the journal */
+ u8 journalStarted; /* True if header of journal is synced */
+ u8 changeCountDone; /* Set after incrementing the change-counter */
u8 setMaster; /* True if a m-j name has been written to jrnl */
u8 doNotSync; /* Boolean. While true, do not spill the cache */
- u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */
- u8 journalMode; /* On of the PAGER_JOURNALMODE_* values */
- u8 dbModified; /* True if there are any changes to the Db */
- u8 changeCountDone; /* Set after incrementing the change-counter */
u8 dbSizeValid; /* Set when dbSize is correct */
Pgno dbSize; /* Number of pages in the database */
Pgno dbOrigSize; /* dbSize before the current transaction */
Pgno dbFileSize; /* Number of pages in the database file */
- u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */
int errCode; /* One of several kinds of errors */
- int nRec; /* Number of pages written to the journal */
+ int nRec; /* Pages journalled since last j-header written */
u32 cksumInit; /* Quasi-random value added to every checksum */
- int stmtNRec; /* Number of records in stmt subjournal */
- int nExtra; /* Add this many bytes to each in-memory page */
- int pageSize; /* Number of bytes in a page */
- int nPage; /* Total number of in-memory pages */
- int mxPage; /* Maximum number of pages to hold in cache */
- Pgno mxPgno; /* Maximum allowed size of the database */
+ u32 nSubRec; /* Number of records written to sub-journal */
Bitvec *pInJournal; /* One bit for each page in the database file */
- Bitvec *pAlwaysRollback; /* One bit for each page marked always-rollback */
+ sqlite3_file *fd; /* File descriptor for database */
+ sqlite3_file *jfd; /* File descriptor for main journal */
+ sqlite3_file *sjfd; /* File descriptor for sub-journal */
+ i64 journalOff; /* Current write offset in the journal file */
+ i64 journalHdr; /* Byte offset to previous journal header */
+ PagerSavepoint *aSavepoint; /* Array of active savepoints */
+ int nSavepoint; /* Number of elements in aSavepoint[] */
+ char dbFileVers[16]; /* Changes whenever database file changes */
+ u32 sectorSize; /* Assumed sector size during rollback */
+
+ int nExtra; /* Add this many bytes to each in-memory page */
+ u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */
+ int pageSize; /* Number of bytes in a page */
+ Pgno mxPgno; /* Maximum allowed size of the database */
char *zFilename; /* Name of the database file */
char *zJournal; /* Name of the journal file */
- char *zDirectory; /* Directory hold database and journal files */
- sqlite3_file *fd, *jfd; /* File descriptors for database and journal */
- sqlite3_file *sjfd; /* File descriptor for the sub-journal*/
int (*xBusyHandler)(void*); /* Function to call when busy */
void *pBusyHandlerArg; /* Context argument for xBusyHandler */
- i64 journalOff; /* Current byte offset in the journal file */
- i64 journalHdr; /* Byte offset to previous journal header */
- u32 sectorSize; /* Assumed sector size during rollback */
#ifdef SQLITE_TEST
int nHit, nMiss; /* Cache hits and missing */
int nRead, nWrite; /* Database pages read/written */
#endif
@@ -30977,13 +30176,11 @@
void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
void *pCodecArg; /* First argument to xCodec() */
#endif
char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */
- char dbFileVers[16]; /* Changes whenever database file changes */
i64 journalSizeLimit; /* Size limit for persistent journal files */
PCache *pPCache; /* Pointer to page cache object */
- PagerSavepoint *aSavepoint; /* Array of active savepoints */
- int nSavepoint; /* Number of elements in aSavepoint[] */
+ sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */
};
/*
** The following global variables hold counters used for
@@ -31028,17 +30225,16 @@
0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7,
};
/*
-** The size of the header and of each page in the journal is determined
-** by the following macros.
+** The size of the of each page record in the journal is given by
+** the following macro.
*/
#define JOURNAL_PG_SZ(pPager) ((pPager->pageSize) + 8)
/*
-** The journal header size for this pager. In the future, this could be
-** set to some value read from the disk controller. The important
-** characteristic is that it is the same size as a disk sector.
+** The journal header size for this pager. This is usually the same
+** size as a single disk sector. See also setSectorSize().
*/
#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize)
/*
@@ -31053,21 +30249,29 @@
# define MEMDB pPager->memDb
#endif
/*
-** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
-** reserved for working around a windows/posix incompatibility). It is
-** used in the journal to signify that the remainder of the journal file
-** is devoted to storing a master journal name - there are no more pages to
-** roll back. See comments for function writeMasterJournal() for details.
-*/
-/* #define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) */
-#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
-
-/*
** The maximum legal page number is (2^31 - 1).
*/
#define PAGER_MAX_PGNO 2147483647
+
+#ifndef NDEBUG
+/*
+** Usage:
+**
+** assert( assert_pager_state(pPager) );
+*/
+static int assert_pager_state(Pager *pPager){
+
+ /* A temp-file is always in PAGER_EXCLUSIVE or PAGER_SYNCED state. */
+ assert( pPager->tempFile==0 || pPager->state>=PAGER_EXCLUSIVE );
+
+ /* The changeCountDone flag is always set for temp-files */
+ assert( pPager->tempFile==0 || pPager->changeCountDone );
+
+ return 1;
+}
+#endif
/*
** Return true if it is necessary to write page *pPg into the sub-journal.
** A page needs to be written into the sub-journal if there exists one
@@ -31128,12 +30332,26 @@
return sqlite3OsWrite(fd, ac, 4, offset);
}
/*
+** The argument to this macro is a file descriptor (type sqlite3_file*).
+** Return 0 if it is not open, or non-zero (but not 1) if it is.
+**
+** This is so that expressions can be written as:
+**
+** if( isOpen(pPager->jfd) ){ ...
+**
+** instead of
+**
+** if( pPager->jfd->pMethods ){ ...
+*/
+#define isOpen(pFd) ((pFd)->pMethods)
+
+/*
** If file pFd is open, call sqlite3OsUnlock() on it.
*/
static int osUnlock(sqlite3_file *pFd, int eLock){
- if( !pFd->pMethods ){
+ if( !isOpen(pFd) ){
return SQLITE_OK;
}
return sqlite3OsUnlock(pFd, eLock);
}
@@ -31146,79 +30364,39 @@
** a database page may be written atomically, and
** (b) the value returned by OsSectorSize() is less than or equal
** to the page size.
**
+** The optimization is also always enabled for temporary files. It is
+** an error to call this function if pPager is opened on an in-memory
+** database.
+**
** If the optimization cannot be used, 0 is returned. If it can be used,
** then the value returned is the size of the journal file when it
** contains rollback data for exactly one page.
*/
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
static int jrnlBufferSize(Pager *pPager){
- int dc; /* Device characteristics */
- int nSector; /* Sector size */
- int szPage; /* Page size */
- sqlite3_file *fd = pPager->fd;
-
- if( fd->pMethods ){
- dc = sqlite3OsDeviceCharacteristics(fd);
+ assert( !MEMDB );
+ if( !pPager->tempFile ){
+ int dc; /* Device characteristics */
+ int nSector; /* Sector size */
+ int szPage; /* Page size */
+
+ assert( isOpen(pPager->fd) );
+ dc = sqlite3OsDeviceCharacteristics(pPager->fd);
nSector = pPager->sectorSize;
szPage = pPager->pageSize;
- }
-
- assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
- assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
-
- if( !fd->pMethods ||
- (dc & (SQLITE_IOCAP_ATOMIC|(szPage>>8)) && nSector<=szPage) ){
- return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
- }
- return 0;
-}
-#endif
-
-/*
-** This function should be called when an error occurs within the pager
-** code. The first argument is a pointer to the pager structure, the
-** second the error-code about to be returned by a pager API function.
-** The value returned is a copy of the second argument to this function.
-**
-** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_FULL
-** the error becomes persistent. Until the persisten error is cleared,
-** subsequent API calls on this Pager will immediately return the same
-** error code.
-**
-** A persistent error indicates that the contents of the pager-cache
-** cannot be trusted. This state can be cleared by completely discarding
-** the contents of the pager-cache. If a transaction was active when
-** the persistent error occured, then the rollback journal may need
-** to be replayed.
-*/
-static void pager_unlock(Pager *pPager);
-static int pager_error(Pager *pPager, int rc){
- int rc2 = rc & 0xff;
- assert(
- pPager->errCode==SQLITE_FULL ||
- pPager->errCode==SQLITE_OK ||
- (pPager->errCode & 0xff)==SQLITE_IOERR
- );
- if(
- rc2==SQLITE_FULL ||
- rc2==SQLITE_IOERR ||
- rc2==SQLITE_CORRUPT
- ){
- pPager->errCode = rc;
- if( pPager->state==PAGER_UNLOCK
- && sqlite3PcacheRefCount(pPager->pPCache)==0
- ){
- /* If the pager is already unlocked, call pager_unlock() now to
- ** clear the error state and ensure that the pager-cache is
- ** completely empty.
- */
- pager_unlock(pPager);
- }
- }
- return rc;
-}
+
+ assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
+ assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
+ if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){
+ return 0;
+ }
+ }
+
+ return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
+}
+#endif
/*
** If SQLITE_CHECK_PAGES is defined then we do some sanity checking
** on the cache using a hash function. This is used for testing
@@ -31262,10 +30440,12 @@
#endif /* SQLITE_CHECK_PAGES */
/*
** When this is called the journal file for pager pPager must be open.
-** The master journal file name is read from the end of the file and
-** written into memory supplied by the caller.
+** This function attempts to read a master journal file name from the
+** end of the file and, if successful, copies it into memory supplied
+** by the caller. See comments above writeMasterJournal() for the format
+** used to store a master journal file name at the end of a journal file.
**
** zMaster must point to a buffer of at least nMaster bytes allocated by
** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is
** enough space to write the master journal name). If the master journal
@@ -31272,72 +30452,70 @@
** name in the journal is longer than nMaster bytes (including a
** nul-terminator), then this is handled as if no master journal name
** were present in the journal.
**
-** If no master journal file name is present zMaster[0] is set to 0 and
-** SQLITE_OK returned.
+** If a master journal file name is present at the end of the journal
+** file, then it is copied into the buffer pointed to by zMaster. A
+** nul-terminator byte is appended to the buffer following the master
+** journal file name.
+**
+** If it is determined that no master journal file name is present
+** zMaster[0] is set to 0 and SQLITE_OK returned.
+**
+** If an error occurs while reading from the journal file, an SQLite
+** error code is returned.
*/
static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){
- int rc;
- u32 len;
- i64 szJ;
- u32 cksum;
- u32 u; /* Unsigned loop counter */
- unsigned char aMagic[8]; /* A buffer to hold the magic header */
-
+ int rc; /* Return code */
+ u32 len; /* Length in bytes of master journal name */
+ i64 szJ; /* Total size in bytes of journal file pJrnl */
+ u32 cksum; /* MJ checksum value read from journal */
+ u32 u; /* Unsigned loop counter */
+ unsigned char aMagic[8]; /* A buffer to hold the magic header */
zMaster[0] = '\0';
- rc = sqlite3OsFileSize(pJrnl, &szJ);
- if( rc!=SQLITE_OK || szJ<16 ) return rc;
-
- rc = read32bits(pJrnl, szJ-16, &len);
- if( rc!=SQLITE_OK ) return rc;
-
- if( len>=nMaster ){
- return SQLITE_OK;
- }
-
- rc = read32bits(pJrnl, szJ-12, &cksum);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8);
- if( rc!=SQLITE_OK || memcmp(aMagic, aJournalMagic, 8) ) return rc;
-
- rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- zMaster[len] = '\0';
+ if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ))
+ || szJ<16
+ || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
+ || len>=nMaster
+ || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
+ || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
+ || memcmp(aMagic, aJournalMagic, 8)
+ || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len))
+ ){
+ return rc;
+ }
/* See if the checksum matches the master journal name */
for(u=0; u<len; u++){
cksum -= zMaster[u];
- }
+ }
if( cksum ){
/* If the checksum doesn't add up, then one or more of the disk sectors
** containing the master journal filename is corrupted. This means
** definitely roll back, so just return SQLITE_OK and report a (nul)
** master-journal filename.
*/
- zMaster[0] = '\0';
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Seek the journal file descriptor to the next sector boundary where a
-** journal header may be read or written. Pager.journalOff is updated with
-** the new seek offset.
+ len = 0;
+ }
+ zMaster[len] = '\0';
+
+ return SQLITE_OK;
+}
+
+/*
+** Return the offset of the sector boundary at or immediately
+** following the value in pPager->journalOff, assuming a sector
+** size of pPager->sectorSize bytes.
**
** i.e for a sector size of 512:
**
-** Input Offset Output Offset
-** ---------------------------------------
-** 0 0
-** 512 512
-** 100 512
-** 2000 2048
+** Pager.journalOff Return value
+** ---------------------------------------
+** 0 0
+** 512 512
+** 100 512
+** 2000 2048
**
*/
static i64 journalHdrOffset(Pager *pPager){
i64 offset = 0;
@@ -31349,28 +30527,41 @@
assert( offset>=c );
assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
return offset;
}
-static void seekJournalHdr(Pager *pPager){
- pPager->journalOff = journalHdrOffset(pPager);
-}
-
-/*
-** Write zeros over the header of the journal file. This has the
-** effect of invalidating the journal file and committing the
-** transaction.
+
+/*
+** The journal file must be open when this function is called.
+**
+** This function is a no-op if the journal file has not been written to
+** within the current transaction (i.e. if Pager.journalOff==0).
+**
+** If doTruncate is non-zero or the Pager.journalSizeLimit variable is
+** set to 0, then truncate the journal file to zero bytes in size. Otherwise,
+** zero the 28-byte header at the start of the journal file. In either case,
+** if the pager is not in no-sync mode, sync the journal file immediately
+** after writing or truncating it.
+**
+** If Pager.journalSizeLimit is set to a positive, non-zero value, and
+** following the truncation or zeroing described above the size of the
+** journal file in bytes is larger than this value, then truncate the
+** journal file to Pager.journalSizeLimit bytes. The journal file does
+** not need to be synced following this operation.
+**
+** If an IO error occurs, abandon processing and return the IO error code.
+** Otherwise, return SQLITE_OK.
*/
static int zeroJournalHdr(Pager *pPager, int doTruncate){
- int rc = SQLITE_OK;
- static const char zeroHdr[28] = {0};
-
+ int rc = SQLITE_OK; /* Return code */
+ assert( isOpen(pPager->jfd) );
if( pPager->journalOff ){
- i64 iLimit = pPager->journalSizeLimit;
+ const i64 iLimit = pPager->journalSizeLimit; /* Local cache of jsl */
IOTRACE(("JZEROHDR %p\n", pPager))
if( doTruncate || iLimit==0 ){
rc = sqlite3OsTruncate(pPager->jfd, 0);
}else{
+ static const char zeroHdr[28] = {0};
rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0);
}
if( rc==SQLITE_OK && !pPager->noSync ){
rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->sync_flags);
@@ -31408,31 +30599,31 @@
**
** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space.
*/
static int writeJournalHdr(Pager *pPager){
- int rc = SQLITE_OK;
- char *zHeader = pPager->pTmpSpace;
- u32 nHeader = pPager->pageSize;
- u32 nWrite;
- int ii;
+ int rc = SQLITE_OK; /* Return code */
+ char *zHeader = pPager->pTmpSpace; /* Temporary space used to build header */
+ u32 nHeader = pPager->pageSize; /* Size of buffer pointed to by zHeader */
+ u32 nWrite; /* Bytes of header sector written */
+ int ii; /* Loop counter */
+
+ assert( isOpen(pPager->jfd) ); /* Journal file must be open. */
if( nHeader>JOURNAL_HDR_SZ(pPager) ){
nHeader = JOURNAL_HDR_SZ(pPager);
}
- /* If there are active savepoints and any of them were created since the
- ** most recent journal header was written, update the PagerSavepoint.iHdrOff
- ** fields now.
+ /* If there are active savepoints and any of them were created
+ ** since the most recent journal header was written, update the
+ ** PagerSavepoint.iHdrOffset fields now.
*/
for(ii=0; ii<pPager->nSavepoint; ii++){
if( pPager->aSavepoint[ii].iHdrOffset==0 ){
pPager->aSavepoint[ii].iHdrOffset = pPager->journalOff;
}
}
- seekJournalHdr(pPager);
- pPager->journalHdr = pPager->journalOff;
-
+ pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager);
memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
/*
** Write the nRec Field - the number of page records that follow this
@@ -31443,9 +30634,9 @@
**
** A faster alternative is to write 0xFFFFFFFF to the nRec field. When
** reading the journal this value tells SQLite to assume that the
** rest of the journal file contains valid page records. This assumption
- ** is dangerous, as if a failure occured whilst writing to the journal
+ ** is dangerous, as if a failure occurred whilst writing to the journal
** file it may contain some garbage data. There are two scenarios
** where this risk can be ignored:
**
** * When the pager is in no-sync mode. Corruption can follow a
@@ -31453,9 +30644,9 @@
**
** * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees
** that garbage data is never appended to the journal file.
*/
- assert(pPager->fd->pMethods||pPager->noSync);
+ assert( isOpen(pPager->fd) || pPager->noSync );
if( (pPager->noSync) || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY)
|| (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
){
put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
@@ -31470,21 +30661,36 @@
put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize);
/* The assumed sector size for this process */
put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
+ /* The page size */
+ put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize);
+
/* Initializing the tail of the buffer is not necessary. Everything
** works find if the following memset() is omitted. But initializing
** the memory prevents valgrind from complaining, so we are willing to
** take the performance hit.
*/
- memset(&zHeader[sizeof(aJournalMagic)+16], 0,
- nHeader-(sizeof(aJournalMagic)+16));
-
- if( pPager->journalHdr==0 ){
- /* The page size */
- put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize);
- }
-
+ memset(&zHeader[sizeof(aJournalMagic)+20], 0,
+ nHeader-(sizeof(aJournalMagic)+20));
+
+ /* In theory, it is only necessary to write the 28 bytes that the
+ ** journal header consumes to the journal file here. Then increment the
+ ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next
+ ** record is written to the following sector (leaving a gap in the file
+ ** that will be implicitly filled in by the OS).
+ **
+ ** However it has been discovered that on some systems this pattern can
+ ** be significantly slower than contiguously writing data to the file,
+ ** even if that means explicitly writing data to the block of
+ ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what
+ ** is done.
+ **
+ ** The loop is required here in case the sector-size is larger than the
+ ** database page size. Since the zHeader buffer is only Pager.pageSize
+ ** bytes in size, more than one call to sqlite3OsWrite() may be required
+ ** to populate the entire journal header sector.
+ */
for(nWrite=0; rc==SQLITE_OK&&nWrite<JOURNAL_HDR_SZ(pPager); nWrite+=nHeader){
IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, nHeader))
rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff);
pPager->journalOff += nHeader;
@@ -31496,95 +30702,116 @@
/*
** The journal file must be open when this is called. A journal header file
** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal
** file. The current location in the journal file is given by
-** pPager->journalOff. See comments above function writeJournalHdr() for
+** pPager->journalOff. See comments above function writeJournalHdr() for
** a description of the journal header format.
**
-** If the header is read successfully, *nRec is set to the number of
-** page records following this header and *dbSize is set to the size of the
+** If the header is read successfully, *pNRec is set to the number of
+** page records following this header and *pDbSize is set to the size of the
** database before the transaction began, in pages. Also, pPager->cksumInit
** is set to the value read from the journal header. SQLITE_OK is returned
** in this case.
**
** If the journal header file appears to be corrupted, SQLITE_DONE is
-** returned and *nRec and *dbSize are undefined. If JOURNAL_HDR_SZ bytes
+** returned and *pNRec and *PDbSize are undefined. If JOURNAL_HDR_SZ bytes
** cannot be read from the journal file an error code is returned.
*/
static int readJournalHdr(
- Pager *pPager,
- i64 journalSize,
- u32 *pNRec,
- u32 *pDbSize
-){
- int rc;
- unsigned char aMagic[8]; /* A buffer to hold the magic header */
- i64 jrnlOff;
- u32 iPageSize;
- u32 iSectorSize;
-
- seekJournalHdr(pPager);
+ Pager *pPager, /* Pager object */
+ i64 journalSize, /* Size of the open journal file in bytes */
+ u32 *pNRec, /* OUT: Value read from the nRec field */
+ u32 *pDbSize /* OUT: Value of original database size field */
+){
+ int rc; /* Return code */
+ unsigned char aMagic[8]; /* A buffer to hold the magic header */
+ i64 iHdrOff; /* Offset of journal header being read */
+
+ assert( isOpen(pPager->jfd) ); /* Journal file must be open. */
+
+ /* Advance Pager.journalOff to the start of the next sector. If the
+ ** journal file is too small for there to be a header stored at this
+ ** point, return SQLITE_DONE.
+ */
+ pPager->journalOff = journalHdrOffset(pPager);
if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
return SQLITE_DONE;
}
- jrnlOff = pPager->journalOff;
-
- rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), jrnlOff);
- if( rc ) return rc;
- jrnlOff += sizeof(aMagic);
-
+ iHdrOff = pPager->journalOff;
+
+ /* Read in the first 8 bytes of the journal header. If they do not match
+ ** the magic string found at the start of each journal header, return
+ ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise,
+ ** proceed.
+ */
+ rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff);
+ if( rc ){
+ return rc;
+ }
if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
return SQLITE_DONE;
}
- rc = read32bits(pPager->jfd, jrnlOff, pNRec);
- if( rc ) return rc;
-
- rc = read32bits(pPager->jfd, jrnlOff+4, &pPager->cksumInit);
- if( rc ) return rc;
-
- rc = read32bits(pPager->jfd, jrnlOff+8, pDbSize);
- if( rc ) return rc;
+ /* Read the first three 32-bit fields of the journal header: The nRec
+ ** field, the checksum-initializer and the database size at the start
+ ** of the transaction. Return an error code if anything goes wrong.
+ */
+ if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+8, pNRec))
+ || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+12, &pPager->cksumInit))
+ || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+16, pDbSize))
+ ){
+ return rc;
+ }
if( pPager->journalOff==0 ){
- rc = read32bits(pPager->jfd, jrnlOff+16, &iPageSize);
- if( rc ) return rc;
-
- if( iPageSize<512
- || iPageSize>SQLITE_MAX_PAGE_SIZE
- || ((iPageSize-1)&iPageSize)!=0
- ){
- /* If the page-size in the journal-header is invalid, then the process
- ** that wrote the journal-header must have crashed before the header
- ** was synced. In this case stop reading the journal file here.
- */
- rc = SQLITE_DONE;
- }else{
- u16 pagesize = (u16)iPageSize;
- rc = sqlite3PagerSetPagesize(pPager, &pagesize);
- assert( rc!=SQLITE_OK || pagesize==(u16)iPageSize );
- }
- if( rc ) return rc;
+ u32 iPageSize; /* Page-size field of journal header */
+ u32 iSectorSize; /* Sector-size field of journal header */
+ u16 iPageSize16; /* Copy of iPageSize in 16-bit variable */
+
+ /* Read the page-size and sector-size journal header fields. */
+ if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize))
+ || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize))
+ ){
+ return rc;
+ }
+
+ /* Check that the values read from the page-size and sector-size fields
+ ** are within range. To be 'in range', both values need to be a power
+ ** of two greater than or equal to 512, and not greater than their
+ ** respective compile time maximum limits.
+ */
+ if( iPageSize<512 || iSectorSize<512
+ || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE
+ || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0
+ ){
+ /* If the either the page-size or sector-size in the journal-header is
+ ** invalid, then the process that wrote the journal-header must have
+ ** crashed before the header was synced. In this case stop reading
+ ** the journal file here.
+ */
+ return SQLITE_DONE;
+ }
+
+ /* Update the page-size to match the value read from the journal.
+ ** Use a testcase() macro to make sure that malloc failure within
+ ** PagerSetPagesize() is tested.
+ */
+ iPageSize16 = (u16)iPageSize;
+ rc = sqlite3PagerSetPagesize(pPager, &iPageSize16);
+ testcase( rc!=SQLITE_OK );
+ assert( rc!=SQLITE_OK || iPageSize16==(u16)iPageSize );
/* Update the assumed sector-size to match the value used by
** the process that created this journal. If this journal was
** created by a process other than this one, then this routine
** is being called from within pager_playback(). The local value
** of Pager.sectorSize is restored at the end of that routine.
*/
- rc = read32bits(pPager->jfd, jrnlOff+12, &iSectorSize);
- if( rc ) return rc;
- if( (iSectorSize&(iSectorSize-1))
- || iSectorSize<512
- || iSectorSize>MAX_SECTOR_SIZE
- ){
- return SQLITE_DONE;
- }
pPager->sectorSize = iSectorSize;
}
pPager->journalOff += JOURNAL_HDR_SZ(pPager);
- return SQLITE_OK;
+ return rc;
}
/*
@@ -31593,61 +30820,62 @@
** thing written to a journal file. If the pager is in full-sync mode, the
** journal file descriptor is advanced to the next sector boundary before
** anything is written. The format is:
**
-** + 4 bytes: PAGER_MJ_PGNO.
-** + N bytes: length of master journal name.
-** + 4 bytes: N
-** + 4 bytes: Master journal name checksum.
-** + 8 bytes: aJournalMagic[].
+** + 4 bytes: PAGER_MJ_PGNO.
+** + N bytes: Master journal filename in utf-8.
+** + 4 bytes: N (length of master journal name in bytes, no nul-terminator).
+** + 4 bytes: Master journal name checksum.
+** + 8 bytes: aJournalMagic[].
**
** The master journal page checksum is the sum of the bytes in the master
-** journal name.
+** journal name, where each byte is interpreted as a signed 8-bit integer.
**
** If zMaster is a NULL pointer (occurs for a single database transaction),
** this call is a no-op.
*/
static int writeMasterJournal(Pager *pPager, const char *zMaster){
- int rc;
- int len;
- int i;
- i64 jrnlOff;
- i64 jrnlSize;
- u32 cksum = 0;
- char zBuf[sizeof(aJournalMagic)+2*4];
-
- if( !zMaster || pPager->setMaster ) return SQLITE_OK;
- if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ) return SQLITE_OK;
+ int rc; /* Return code */
+ int nMaster; /* Length of string zMaster */
+ i64 iHdrOff; /* Offset of header in journal file */
+ i64 jrnlSize; /* Size of journal file on disk */
+ u32 cksum = 0; /* Checksum of string zMaster */
+
+ if( !zMaster || pPager->setMaster
+ || pPager->journalMode==PAGER_JOURNALMODE_MEMORY
+ || pPager->journalMode==PAGER_JOURNALMODE_OFF
+ ){
+ return SQLITE_OK;
+ }
pPager->setMaster = 1;
-
- len = sqlite3Strlen30(zMaster);
- for(i=0; i<len; i++){
- cksum += zMaster[i];
+ assert( isOpen(pPager->jfd) );
+
+ /* Calculate the length in bytes and the checksum of zMaster */
+ for(nMaster=0; zMaster[nMaster]; nMaster++){
+ cksum += zMaster[nMaster];
}
/* If in full-sync mode, advance to the next disk sector before writing
** the master journal name. This is in case the previous page written to
** the journal has already been synced.
*/
if( pPager->fullSync ){
- seekJournalHdr(pPager);
- }
- jrnlOff = pPager->journalOff;
- pPager->journalOff += (len+20);
-
- rc = write32bits(pPager->jfd, jrnlOff, PAGER_MJ_PGNO(pPager));
- if( rc!=SQLITE_OK ) return rc;
- jrnlOff += 4;
-
- rc = sqlite3OsWrite(pPager->jfd, zMaster, len, jrnlOff);
- if( rc!=SQLITE_OK ) return rc;
- jrnlOff += len;
-
- put32bits(zBuf, len);
- put32bits(&zBuf[4], cksum);
- memcpy(&zBuf[8], aJournalMagic, sizeof(aJournalMagic));
- rc = sqlite3OsWrite(pPager->jfd, zBuf, 8+sizeof(aJournalMagic), jrnlOff);
- jrnlOff += 8+sizeof(aJournalMagic);
+ pPager->journalOff = journalHdrOffset(pPager);
+ }
+ iHdrOff = pPager->journalOff;
+
+ /* Write the master journal data to the end of the journal file. If
+ ** an error occurs, return the error code to the caller.
+ */
+ if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager))))
+ || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4)))
+ || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster)))
+ || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum)))
+ || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaster+8)))
+ ){
+ return rc;
+ }
+ pPager->journalOff += (nMaster+20);
pPager->needSync = !pPager->noSync;
/* If the pager is in peristent-journal mode, then the physical
** journal-file may extend past the end of the master-journal name
@@ -31658,45 +30886,51 @@
**
** Easiest thing to do in this scenario is to truncate the journal
** file to the required size.
*/
- if( (rc==SQLITE_OK)
- && (rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize))==SQLITE_OK
- && jrnlSize>jrnlOff
- ){
- rc = sqlite3OsTruncate(pPager->jfd, jrnlOff);
- }
- return rc;
-}
-
-/*
-** Find a page in the hash table given its page number. Return
-** a pointer to the page or NULL if not found.
+ if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize))
+ && jrnlSize>pPager->journalOff
+ ){
+ rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff);
+ }
+ return rc;
+}
+
+/*
+** Find a page in the hash table given its page number. Return
+** a pointer to the page or NULL if the requested page is not
+** already in memory.
*/
static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
- PgHdr *p;
- sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &p);
- return p;
-}
-
-/*
-** Clear the in-memory cache. This routine
-** sets the state of the pager back to what it was when it was first
-** opened. Any outstanding pages are invalidated and subsequent attempts
-** to access those pages will likely result in a coredump.
+ PgHdr *p; /* Return value */
+
+ /* It is not possible for a call to PcacheFetch() with createFlag==0 to
+ ** fail, since no attempt to allocate dynamic memory will be made.
+ */
+ (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &p);
+ return p;
+}
+
+/*
+** Unless the pager is in error-state, discard all in-memory pages. If
+** the pager is in error-state, then this call is a no-op.
+**
+** TODO: Why can we not reset the pager while in error state?
*/
static void pager_reset(Pager *pPager){
- if( pPager->errCode ) return;
- sqlite3PcacheClear(pPager->pPCache);
+ if( SQLITE_OK==pPager->errCode ){
+ sqlite3BackupRestart(pPager->pBackup);
+ sqlite3PcacheClear(pPager->pPCache);
+ }
}
/*
** Free all structures in the Pager.aSavepoint[] array and set both
** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal
** if it is open and the pager is not in exclusive mode.
*/
-static void releaseAllSavepoint(Pager *pPager){
- int ii;
+static void releaseAllSavepoints(Pager *pPager){
+ int ii; /* Iterator for looping through Pager.aSavepoint */
for(ii=0; ii<pPager->nSavepoint; ii++){
sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
}
if( !pPager->exclusiveMode ){
@@ -31704,14 +30938,15 @@
}
sqlite3_free(pPager->aSavepoint);
pPager->aSavepoint = 0;
pPager->nSavepoint = 0;
- pPager->stmtNRec = 0;
-}
-
-/*
-** Set the bit number pgno in the PagerSavepoint.pInSavepoint bitvecs of
-** all open savepoints.
+ pPager->nSubRec = 0;
+}
+
+/*
+** Set the bit number pgno in the PagerSavepoint.pInSavepoint
+** bitvecs of all open savepoints. Return SQLITE_OK if successful
+** or SQLITE_NOMEM if a malloc failure occurs.
*/
static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){
int ii; /* Loop counter */
int rc = SQLITE_OK; /* Result code */
@@ -31719,16 +30954,18 @@
for(ii=0; ii<pPager->nSavepoint; ii++){
PagerSavepoint *p = &pPager->aSavepoint[ii];
if( pgno<=p->nOrig ){
rc |= sqlite3BitvecSet(p->pInSavepoint, pgno);
+ testcase( rc==SQLITE_NOMEM );
assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
}
}
return rc;
}
/*
-** Unlock the database file.
+** Unlock the database file. This function is a no-op if the pager
+** is in exclusive mode.
**
** If the pager is currently in error state, discard the contents of
** the cache and reset the Pager structure internal state. If there is
** an open journal-file, then the next time a shared-lock is obtained
@@ -31736,94 +30973,204 @@
** treated as a hot-journal and rolled back.
*/
static void pager_unlock(Pager *pPager){
if( !pPager->exclusiveMode ){
- int rc;
+ int rc; /* Return code */
/* Always close the journal file when dropping the database lock.
** Otherwise, another connection with journal_mode=delete might
** delete the file out from under us.
*/
- if( pPager->journalOpen ){
- sqlite3OsClose(pPager->jfd);
- pPager->journalOpen = 0;
- sqlite3BitvecDestroy(pPager->pInJournal);
- pPager->pInJournal = 0;
- sqlite3BitvecDestroy(pPager->pAlwaysRollback);
- pPager->pAlwaysRollback = 0;
- }
+ sqlite3OsClose(pPager->jfd);
+ sqlite3BitvecDestroy(pPager->pInJournal);
+ pPager->pInJournal = 0;
+ releaseAllSavepoints(pPager);
+
+ /* If the file is unlocked, somebody else might change it. The
+ ** values stored in Pager.dbSize etc. might become invalid if
+ ** this happens. TODO: Really, this doesn't need to be cleared
+ ** until the change-counter check fails in pagerSharedLock().
+ */
+ pPager->dbSizeValid = 0;
rc = osUnlock(pPager->fd, NO_LOCK);
- if( rc ) pPager->errCode = rc;
- pPager->dbSizeValid = 0;
+ if( rc ){
+ pPager->errCode = rc;
+ }
IOTRACE(("UNLOCK %p\n", pPager))
/* If Pager.errCode is set, the contents of the pager cache cannot be
** trusted. Now that the pager file is unlocked, the contents of the
** cache can be discarded and the error code safely cleared.
*/
if( pPager->errCode ){
- if( rc==SQLITE_OK ) pPager->errCode = SQLITE_OK;
+ if( rc==SQLITE_OK ){
+ pPager->errCode = SQLITE_OK;
+ }
pager_reset(pPager);
- releaseAllSavepoint(pPager);
- pPager->journalOff = 0;
- pPager->journalStarted = 0;
- pPager->dbOrigSize = 0;
- }
-
+ }
+
+ pPager->changeCountDone = 0;
pPager->state = PAGER_UNLOCK;
- pPager->changeCountDone = 0;
- }
+ }
+}
+
+/*
+** This function should be called when an IOERR, CORRUPT or FULL error
+** may have occurred. The first argument is a pointer to the pager
+** structure, the second the error-code about to be returned by a pager
+** API function. The value returned is a copy of the second argument
+** to this function.
+**
+** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_FULL
+** the error becomes persistent. Until the persisten error is cleared,
+** subsequent API calls on this Pager will immediately return the same
+** error code.
+**
+** A persistent error indicates that the contents of the pager-cache
+** cannot be trusted. This state can be cleared by completely discarding
+** the contents of the pager-cache. If a transaction was active when
+** the persistent error occurred, then the rollback journal may need
+** to be replayed to restore the contents of the database file (as if
+** it were a hot-journal).
+*/
+static int pager_error(Pager *pPager, int rc){
+ int rc2 = rc & 0xff;
+ assert(
+ pPager->errCode==SQLITE_FULL ||
+ pPager->errCode==SQLITE_OK ||
+ (pPager->errCode & 0xff)==SQLITE_IOERR
+ );
+ if(
+ rc2==SQLITE_FULL ||
+ rc2==SQLITE_IOERR ||
+ rc2==SQLITE_CORRUPT
+ ){
+ pPager->errCode = rc;
+ if( pPager->state==PAGER_UNLOCK
+ && sqlite3PcacheRefCount(pPager->pPCache)==0
+ ){
+ /* If the pager is already unlocked, call pager_unlock() now to
+ ** clear the error state and ensure that the pager-cache is
+ ** completely empty.
+ */
+ pager_unlock(pPager);
+ }
+ }
+ return rc;
}
/*
** Execute a rollback if a transaction is active and unlock the
-** database file. If the pager has already entered the error state,
-** do not attempt the rollback.
-*/
-static void pagerUnlockAndRollback(Pager *p){
- if( p->errCode==SQLITE_OK && p->state>=PAGER_RESERVED ){
+** database file.
+**
+** If the pager has already entered the error state, do not attempt
+** the rollback at this time. Instead, pager_unlock() is called. The
+** call to pager_unlock() will discard all in-memory pages, unlock
+** the database file and clear the error state. If this means that
+** there is a hot-journal left in the file-system, the next connection
+** to obtain a shared lock on the pager (which may be this one) will
+** roll it back.
+**
+** If the pager has not already entered the error state, but an IO or
+** malloc error occurs during a rollback, then this will itself cause
+** the pager to enter the error state. Which will be cleared by the
+** call to pager_unlock(), as described above.
+*/
+static void pagerUnlockAndRollback(Pager *pPager){
+ if( pPager->errCode==SQLITE_OK && pPager->state>=PAGER_RESERVED ){
sqlite3BeginBenignMalloc();
- sqlite3PagerRollback(p);
+ sqlite3PagerRollback(pPager);
sqlite3EndBenignMalloc();
}
- pager_unlock(p);
-}
-
-/*
-** This routine ends a transaction. A transaction is ended by either
-** a COMMIT or a ROLLBACK.
-**
-** When this routine is called, the pager has the journal file open and
-** a RESERVED or EXCLUSIVE lock on the database. This routine will release
-** the database lock and acquires a SHARED lock in its place if that is
-** the appropriate thing to do. Release locks usually is appropriate,
-** unless we are in exclusive access mode or unless this is a
-** COMMIT AND BEGIN or ROLLBACK AND BEGIN operation.
-**
-** The journal file is either deleted or truncated.
-**
-** TODO: Consider keeping the journal file open for temporary databases.
-** This might give a performance improvement on windows where opening
-** a file is an expensive operation.
+ pager_unlock(pPager);
+}
+
+/*
+** This routine ends a transaction. A transaction is usually ended by
+** either a COMMIT or a ROLLBACK operation. This routine may be called
+** after rollback of a hot-journal, or if an error occurs while opening
+** the journal file or writing the very first journal-header of a
+** database transaction.
+**
+** If the pager is in PAGER_SHARED or PAGER_UNLOCK state when this
+** routine is called, it is a no-op (returns SQLITE_OK).
+**
+** Otherwise, any active savepoints are released.
+**
+** If the journal file is open, then it is "finalized". Once a journal
+** file has been finalized it is not possible to use it to roll back a
+** transaction. Nor will it be considered to be a hot-journal by this
+** or any other database connection. Exactly how a journal is finalized
+** depends on whether or not the pager is running in exclusive mode and
+** the current journal-mode (Pager.journalMode value), as follows:
+**
+** journalMode==MEMORY
+** Journal file descriptor is simply closed. This destroys an
+** in-memory journal.
+**
+** journalMode==TRUNCATE
+** Journal file is truncated to zero bytes in size.
+**
+** journalMode==PERSIST
+** The first 28 bytes of the journal file are zeroed. This invalidates
+** the first journal header in the file, and hence the entire journal
+** file. An invalid journal file cannot be rolled back.
+**
+** journalMode==DELETE
+** The journal file is closed and deleted using sqlite3OsDelete().
+**
+** If the pager is running in exclusive mode, this method of finalizing
+** the journal file is never used. Instead, if the journalMode is
+** DELETE and the pager is in exclusive mode, the method described under
+** journalMode==PERSIST is used instead.
+**
+** After the journal is finalized, if running in non-exclusive mode, the
+** pager moves to PAGER_SHARED state (and downgrades the lock on the
+** database file accordingly).
+**
+** If the pager is running in exclusive mode and is in PAGER_SYNCED state,
+** it moves to PAGER_EXCLUSIVE. No locks are downgraded when running in
+** exclusive mode.
+**
+** SQLITE_OK is returned if no error occurs. If an error occurs during
+** any of the IO operations to finalize the journal file or unlock the
+** database then the IO error code is returned to the user. If the
+** operation to finalize the journal file fails, then the code still
+** tries to unlock the database file if not in exclusive mode. If the
+** unlock operation fails as well, then the first error code related
+** to the first error encountered (the journal finalization one) is
+** returned.
*/
static int pager_end_transaction(Pager *pPager, int hasMaster){
- int rc = SQLITE_OK;
- int rc2 = SQLITE_OK;
+ int rc = SQLITE_OK; /* Error code from journal finalization operation */
+ int rc2 = SQLITE_OK; /* Error code from db file unlock operation */
+
if( pPager->state<PAGER_RESERVED ){
return SQLITE_OK;
}
- releaseAllSavepoint(pPager);
- if( pPager->journalOpen ){
+ releaseAllSavepoints(pPager);
+
+ assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
+ if( isOpen(pPager->jfd) ){
+
+ /* TODO: There's a problem here if a journal-file was opened in MEMORY
+ ** mode and then the journal-mode is changed to TRUNCATE or PERSIST
+ ** during the transaction. This code should be changed to assume
+ ** that the journal mode has not changed since the transaction was
+ ** started. And the sqlite3PagerJournalMode() function should be
+ ** changed to make sure that this is the case too.
+ */
+
+ /* Finalize the journal file. */
if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
int isMemoryJournal = sqlite3IsMemJournal(pPager->jfd);
sqlite3OsClose(pPager->jfd);
- pPager->journalOpen = 0;
if( !isMemoryJournal ){
rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
}
- }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE
- && (rc = sqlite3OsTruncate(pPager->jfd, 0))==SQLITE_OK ){
+ }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
+ rc = sqlite3OsTruncate(pPager->jfd, 0);
pPager->journalOff = 0;
pPager->journalStarted = 0;
}else if( pPager->exclusiveMode
|| pPager->journalMode==PAGER_JOURNALMODE_PERSIST
@@ -31834,25 +31181,21 @@
pPager->journalStarted = 0;
}else{
assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE || rc );
sqlite3OsClose(pPager->jfd);
- pPager->journalOpen = 0;
if( rc==SQLITE_OK && !pPager->tempFile ){
rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
}
}
- sqlite3BitvecDestroy(pPager->pInJournal);
- pPager->pInJournal = 0;
- sqlite3BitvecDestroy(pPager->pAlwaysRollback);
- pPager->pAlwaysRollback = 0;
+
#ifdef SQLITE_CHECK_PAGES
sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
#endif
+
sqlite3PcacheCleanAll(pPager->pPCache);
- pPager->dirtyCache = 0;
- pPager->nRec = 0;
- }else{
- assert( pPager->pInJournal==0 );
+ sqlite3BitvecDestroy(pPager->pInJournal);
+ pPager->pInJournal = 0;
+ pPager->nRec = 0;
}
if( !pPager->exclusiveMode ){
rc2 = osUnlock(pPager->fd, SHARED_LOCK);
@@ -31860,44 +31203,45 @@
pPager->changeCountDone = 0;
}else if( pPager->state==PAGER_SYNCED ){
pPager->state = PAGER_EXCLUSIVE;
}
- pPager->dbOrigSize = 0;
pPager->setMaster = 0;
pPager->needSync = 0;
- /* lruListSetFirstSynced(pPager); */
+ pPager->dbModified = 0;
+
+ /* TODO: Is this optimal? Why is the db size invalidated here
+ ** when the database file is not unlocked? */
+ pPager->dbOrigSize = 0;
sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
if( !MEMDB ){
pPager->dbSizeValid = 0;
}
- pPager->dbModified = 0;
return (rc==SQLITE_OK?rc2:rc);
}
/*
-** Compute and return a checksum for the page of data.
-**
-** This is not a real checksum. It is really just the sum of the
-** random initial value and the page number. We experimented with
-** a checksum of the entire data, but that was found to be too slow.
-**
-** Note that the page number is stored at the beginning of data and
-** the checksum is stored at the end. This is important. If journal
-** corruption occurs due to a power failure, the most likely scenario
-** is that one end or the other of the record will be changed. It is
-** much less likely that the two ends of the journal record will be
+** Parameter aData must point to a buffer of pPager->pageSize bytes
+** of data. Compute and return a checksum based ont the contents of the
+** page of data and the current value of pPager->cksumInit.
+**
+** This is not a real checksum. It is really just the sum of the
+** random initial value (pPager->cksumInit) and every 200th byte
+** of the page data, starting with byte offset (pPager->pageSize%200).
+** Each byte is interpreted as an 8-bit unsigned integer.
+**
+** Changing the formula used to compute this checksum results in an
+** incompatible journal file format.
+**
+** If journal corruption occurs due to a power failure, the most likely
+** scenario is that one end or the other of the record will be changed.
+** It is much less likely that the two ends of the journal record will be
** correct and the middle be corrupt. Thus, this "checksum" scheme,
** though fast and simple, catches the mostly likely kind of corruption.
-**
-** FIX ME: Consider adding every 200th (or so) byte of the data to the
-** checksum. That way if a single page spans 3 or more disk sectors and
-** only the middle sector is corrupt, we will still have a reasonable
-** chance of failing the checksum and thus detecting the problem.
*/
static u32 pager_cksum(Pager *pPager, const u8 *aData){
- u32 cksum = pPager->cksumInit;
- int i = pPager->pageSize-200;
+ u32 cksum = pPager->cksumInit; /* Checksum value to return */
+ int i = pPager->pageSize-200; /* Loop counter */
while( i>0 ){
cksum += aData[i];
i -= 200;
}
@@ -31906,24 +31250,47 @@
/*
** Read a single page from either the journal file (if isMainJrnl==1) or
** from the sub-journal (if isMainJrnl==0) and playback that page.
-** The page begins at offset *pOffset into the file. The *pOffset
+** The page begins at offset *pOffset into the file. The *pOffset
** value is increased to the start of the next page in the journal.
**
** The isMainJrnl flag is true if this is the main rollback journal and
** false for the statement journal. The main rollback journal uses
** checksums - the statement journal does not.
**
+** If the page number of the page record read from the (sub-)journal file
+** is greater than the current value of Pager.dbSize, then playback is
+** skipped and SQLITE_OK is returned.
+**
** If pDone is not NULL, then it is a record of pages that have already
** been played back. If the page at *pOffset has already been played back
** (if the corresponding pDone bit is set) then skip the playback.
** Make sure the pDone bit corresponding to the *pOffset page is set
** prior to returning.
+**
+** If the page record is successfully read from the (sub-)journal file
+** and played back, then SQLITE_OK is returned. If an IO error occurs
+** while reading the record from the (sub-)journal file or while writing
+** to the database file, then the IO error code is returned. If data
+** is successfully read from the (sub-)journal file but appears to be
+** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
+** two circumstances:
+**
+** * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or
+** * If the record is being rolled back from the main journal file
+** and the checksum field does not match the record content.
+**
+** Neither of these two scenarios are possible during a savepoint rollback.
+**
+** If this is a savepoint rollback, then memory may have to be dynamically
+** allocated by this function. If this is the case and an allocation fails,
+** SQLITE_NOMEM is returned.
*/
static int pager_playback_one_page(
Pager *pPager, /* The pager being played back */
int isMainJrnl, /* 1 -> main journal. 0 -> sub-journal. */
+ int isUnsync, /* True if reading from unsynced main journal */
i64 *pOffset, /* Offset of record to playback */
int isSavepnt, /* True for a savepoint rollback */
Bitvec *pDone /* Bitvec of pages already played back */
){
@@ -31941,10 +31308,12 @@
aData = (u8*)pPager->pTmpSpace;
assert( aData ); /* Temp storage must have already been allocated */
- jfd = isMainJrnl ? pPager->jfd : pPager->sjfd;
-
+ /* Read the page number and page data from the journal or sub-journal
+ ** file. Return an error code to the caller if an IO error occurs.
+ */
+ jfd = isMainJrnl ? pPager->jfd : pPager->sjfd;
rc = read32bits(jfd, *pOffset, &pgno);
if( rc!=SQLITE_OK ) return rc;
rc = sqlite3OsRead(jfd, aData, pPager->pageSize, (*pOffset)+4);
if( rc!=SQLITE_OK ) return rc;
@@ -31955,8 +31324,9 @@
** it could cause invalid data to be written into the journal. We need to
** detect this invalid data (with high probability) and ignore it.
*/
if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
+ assert( !isSavepnt );
return SQLITE_DONE;
}
if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){
return SQLITE_OK;
@@ -31967,9 +31337,10 @@
if( !isSavepnt && pager_cksum(pPager, aData)!=cksum ){
return SQLITE_DONE;
}
}
- if( pDone && (rc = sqlite3BitvecSet(pDone, pgno)) ){
+
+ if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
return rc;
}
assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE );
@@ -32006,21 +31377,24 @@
** is possible to fail a statement on a database that does not yet exist.
** Do not attempt to write if database file has never been opened.
*/
pPg = pager_lookup(pPager, pgno);
+ assert( pPg || !MEMDB );
PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, aData),
(isMainJrnl?"main-journal":"sub-journal")
));
if( (pPager->state>=PAGER_EXCLUSIVE)
&& (pPg==0 || 0==(pPg->flags&PGHDR_NEED_SYNC))
- && (pPager->fd->pMethods)
+ && isOpen(pPager->fd)
+ && !isUnsync
){
i64 ofst = (pgno-1)*(i64)pPager->pageSize;
rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize, ofst);
if( pgno>pPager->dbFileSize ){
pPager->dbFileSize = pgno;
}
+ sqlite3BackupUpdate(pPager->pBackup, pgno, aData);
}else if( !isMainJrnl && pPg==0 ){
/* If this is a rollback of a savepoint and data was not written to
** the database and the page is not in-memory, there is a potential
** problem. When the page is next fetched by the b-tree layer, it
@@ -32037,9 +31411,9 @@
** and if the pager requires a journal-sync, then mark the page as
** requiring a journal-sync before it is written.
*/
assert( isSavepnt );
- if( (rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1)) ){
+ if( (rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1))!=SQLITE_OK ){
return rc;
}
pPg->flags &= ~PGHDR_NEED_READ;
sqlite3PcacheMakeDirty(pPg);
@@ -32056,9 +31430,9 @@
memcpy(pData, aData, pPager->pageSize);
if( pPager->xReiniter ){
pPager->xReiniter(pPg);
}
- if( isMainJrnl && (!isSavepnt || pPager->journalOff<=pPager->journalHdr) ){
+ if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){
/* If the contents of this page were just restored from the main
** journal file, then its content must be as they were when the
** transaction was first opened. In this case we can mark the page
** as clean, since there will be no need to write it out to the.
@@ -32142,44 +31516,70 @@
**
** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not
** available for use within this function.
**
-**
-** The master journal file contains the names of all child journals.
-** To tell if a master journal can be deleted, check to each of the
-** children. If all children are either missing or do not refer to
-** a different master journal, then this master journal can be deleted.
+** When a master journal file is created, it is populated with the names
+** of all of its child journals, one after another, formatted as utf-8
+** encoded text. The end of each child journal file is marked with a
+** nul-terminator byte (0x00). i.e. the entire contents of a master journal
+** file for a transaction involving two databases might be:
+**
+** "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00"
+**
+** A master journal file may only be deleted once all of its child
+** journals have been rolled back.
+**
+** This function reads the contents of the master-journal file into
+** memory and loops through each of the child journal names. For
+** each child journal, it checks if:
+**
+** * if the child journal exists, and if so
+** * if the child journal contains a reference to master journal
+** file zMaster
+**
+** If a child journal can be found that matches both of the criteria
+** above, this function returns without doing anything. Otherwise, if
+** no such child journal can be found, file zMaster is deleted from
+** the file-system using sqlite3OsDelete().
+**
+** If an IO error within this function, an error code is returned. This
+** function allocates memory by calling sqlite3Malloc(). If an allocation
+** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors
+** occur, SQLITE_OK is returned.
+**
+** TODO: This function allocates a single block of memory to load
+** the entire contents of the master journal file. This could be
+** a couple of kilobytes or so - potentially larger than the page
+** size.
*/
static int pager_delmaster(Pager *pPager, const char *zMaster){
sqlite3_vfs *pVfs = pPager->pVfs;
- int rc;
- int master_open = 0;
- sqlite3_file *pMaster;
- sqlite3_file *pJournal;
+ int rc; /* Return code */
+ sqlite3_file *pMaster; /* Malloc'd master-journal file descriptor */
+ sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */
char *zMasterJournal = 0; /* Contents of master journal file */
i64 nMasterJournal; /* Size of master journal file */
- /* Open the master journal file exclusively in case some other process
- ** is running this routine also. Not that it makes too much difference.
- */
- pMaster = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile * 2);
+ /* Allocate space for both the pJournal and pMaster file descriptors.
+ ** If successful, open the master journal file for reading.
+ */
+ pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
if( !pMaster ){
rc = SQLITE_NOMEM;
}else{
- int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
+ const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
}
if( rc!=SQLITE_OK ) goto delmaster_out;
- master_open = 1;
rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
if( rc!=SQLITE_OK ) goto delmaster_out;
if( nMasterJournal>0 ){
char *zJournal;
char *zMasterPtr = 0;
- int nMasterPtr = pPager->pVfs->mxPathname+1;
+ int nMasterPtr = pVfs->mxPathname+1;
/* Load the entire master journal file into space obtained from
** sqlite3_malloc() and pointed to by zMasterJournal.
*/
@@ -32232,34 +31632,42 @@
delmaster_out:
if( zMasterJournal ){
sqlite3_free(zMasterJournal);
}
- if( master_open ){
+ if( pMaster ){
sqlite3OsClose(pMaster);
+ assert( !isOpen(pJournal) );
}
sqlite3_free(pMaster);
return rc;
}
/*
-** If the main database file is open and an exclusive lock is held,
-** truncate the main file of the given pager to the specified number
-** of pages.
-**
-** It might might be the case that the file on disk is smaller than nPage.
-** This can happen, for example, if we are in the middle of a transaction
-** which has extended the file size and the new pages are still all held
-** in cache, then an INSERT or UPDATE does a statement rollback. Some
-** operating system implementations can get confused if you try to
-** truncate a file to some size that is larger than it currently is,
-** so detect this case and write a single zero byte to the end of the new
-** file instead.
+** This function is used to change the actual size of the database
+** file in the file-system. This only happens when committing a transaction,
+** or rolling back a transaction (including rolling back a hot-journal).
+**
+** If the main database file is not open, or an exclusive lock is not
+** held, this function is a no-op. Otherwise, the size of the file is
+** changed to nPage pages (nPage*pPager->pageSize bytes). If the file
+** on disk is currently larger than nPage pages, then use the VFS
+** xTruncate() method to truncate it.
+**
+** Or, it might might be the case that the file on disk is smaller than
+** nPage pages. Some operating system implementations can get confused if
+** you try to truncate a file to some size that is larger than it
+** currently is, so detect this case and write a single zero byte to
+** the end of the new file instead.
+**
+** If successful, return SQLITE_OK. If an IO error occurs while modifying
+** the database file, return the error code to the caller.
*/
static int pager_truncate(Pager *pPager, Pgno nPage){
int rc = SQLITE_OK;
- if( pPager->state>=PAGER_EXCLUSIVE && pPager->fd->pMethods ){
+ if( pPager->state>=PAGER_EXCLUSIVE && isOpen(pPager->fd) ){
i64 currentSize, newSize;
+ /* TODO: Is it safe to use Pager.dbFileSize here? */
rc = sqlite3OsFileSize(pPager->fd, ¤tSize);
newSize = pPager->pageSize*(i64)nPage;
if( rc==SQLITE_OK && currentSize!=newSize ){
if( currentSize>newSize ){
@@ -32275,18 +31683,27 @@
return rc;
}
/*
-** Set the sectorSize for the given pager.
-**
-** The sector size is at least as big as the sector size reported
-** by sqlite3OsSectorSize(). The minimum sector size is 512.
+** Set the value of the Pager.sectorSize variable for the given
+** pager based on the value returned by the xSectorSize method
+** of the open database file. The sector size will be used used
+** to determine the size and alignment of journal header and
+** master journal pointers within created journal files.
+**
+** For temporary files the effective sector size is always 512 bytes.
+**
+** Otherwise, for non-temporary files, the effective sector size is
+** the value returned by the xSectorSize() method rounded up to 512 if
+** it is less than 512, or rounded down to MAX_SECTOR_SIZE if it
+** is greater than MAX_SECTOR_SIZE.
*/
static void setSectorSize(Pager *pPager){
- assert(pPager->fd->pMethods||pPager->tempFile);
+ assert( isOpen(pPager->fd) || pPager->tempFile );
+
if( !pPager->tempFile ){
/* Sector size doesn't matter for temporary files. Also, the file
- ** may not have been opened yet, in whcih case the OsSectorSize()
+ ** may not have been opened yet, in which case the OsSectorSize()
** call will segfault.
*/
pPager->sectorSize = sqlite3OsSectorSize(pPager->fd);
}
@@ -32293,8 +31710,9 @@
if( pPager->sectorSize<512 ){
pPager->sectorSize = 512;
}
if( pPager->sectorSize>MAX_SECTOR_SIZE ){
+ assert( MAX_SECTOR_SIZE>=512 );
pPager->sectorSize = MAX_SECTOR_SIZE;
}
}
@@ -32352,8 +31770,15 @@
** been encountered.
**
** If an I/O or malloc() error occurs, the journal-file is not deleted
** and an error code is returned.
+**
+** The isHot parameter indicates that we are trying to rollback a journal
+** that might be a hot journal. Or, it could be that the journal is
+** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE.
+** If the journal really is hot, reset the pager cache prior rolling
+** back any content. If the journal is merely persistent, no reset is
+** needed.
*/
static int pager_playback(Pager *pPager, int isHot){
sqlite3_vfs *pVfs = pPager->pVfs;
i64 szJ; /* Size of the journal file in bytes */
@@ -32362,13 +31787,14 @@
Pgno mxPg = 0; /* Size of the original file in pages */
int rc; /* Result code of a subroutine */
int res = 1; /* Value returned by sqlite3OsAccess() */
char *zMaster = 0; /* Name of master journal file if any */
+ int needPagerReset; /* True to reset page prior to first page rollback */
/* Figure out how many records are in the journal. Abort early if
** the journal is empty.
*/
- assert( pPager->journalOpen );
+ assert( isOpen(pPager->jfd) );
rc = sqlite3OsFileSize(pPager->jfd, &szJ);
if( rc!=SQLITE_OK || szJ==0 ){
goto end_playback;
}
@@ -32376,8 +31802,14 @@
/* Read the master journal name from the journal, if it is present.
** If a master journal file name is specified, but the file is not
** present on disk, then the journal is not hot and does not need to be
** played back.
+ **
+ ** TODO: Technically the following is an error because it assumes that
+ ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
+ ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
+ ** mxPathname is 512, which is the same as the minimum allowable value
+ ** for pageSize.
*/
zMaster = pPager->pTmpSpace;
rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
if( rc==SQLITE_OK && zMaster[0] ){
@@ -32387,12 +31819,16 @@
if( rc!=SQLITE_OK || !res ){
goto end_playback;
}
pPager->journalOff = 0;
-
- /* This loop terminates either when the readJournalHdr() call returns
- ** SQLITE_DONE or an IO error occurs. */
+ needPagerReset = isHot;
+
+ /* This loop terminates either when a readJournalHdr() or
+ ** pager_playback_one_page() call returns SQLITE_DONE or an IO error
+ ** occurs.
+ */
while( 1 ){
+ int isUnsync = 0;
/* Read the next journal header from the journal file. If there are
** not enough bytes left in the journal file for a complete header, or
** it is corrupted, then a process must of failed while writing it.
@@ -32437,8 +31873,9 @@
);
if( nRec==0 && !isHot &&
pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){
nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager));
+ isUnsync = 1;
}
/* If this is the first header read from the journal, truncate the
** database file back to its original size.
@@ -32450,12 +31887,17 @@
}
pPager->dbSize = mxPg;
}
- /* Copy original pages out of the journal and back into the database file.
+ /* Copy original pages out of the journal and back into the
+ ** database file and/or page cache.
*/
for(u=0; u<nRec; u++){
- rc = pager_playback_one_page(pPager, 1, &pPager->journalOff, 0, 0);
+ if( needPagerReset ){
+ pager_reset(pPager);
+ needPagerReset = 0;
+ }
+ rc = pager_playback_one_page(pPager,1,isUnsync,&pPager->journalOff,0,0);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_DONE ){
rc = SQLITE_OK;
pPager->journalOff = szJ;
@@ -32484,20 +31926,34 @@
pPager->fd->pMethods==0 ||
sqlite3OsFileControl(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0)>=SQLITE_OK
);
+ /* If this playback is happening automatically as a result of an IO or
+ ** malloc error that occurred after the change-counter was updated but
+ ** before the transaction was committed, then the change-counter
+ ** modification may just have been reverted. If this happens in exclusive
+ ** mode, then subsequent transactions performed by the connection will not
+ ** update the change-counter at all. This may lead to cache inconsistency
+ ** problems for other processes at some point in the future. So, just
+ ** in case this has happened, clear the changeCountDone flag now.
+ */
+ pPager->changeCountDone = pPager->tempFile;
+
if( rc==SQLITE_OK ){
zMaster = pPager->pTmpSpace;
rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
+ testcase( rc!=SQLITE_OK );
}
if( rc==SQLITE_OK ){
rc = pager_end_transaction(pPager, zMaster[0]!='\0');
+ testcase( rc!=SQLITE_OK );
}
if( rc==SQLITE_OK && zMaster[0] && res ){
/* If there was a master journal and this routine will return success,
** see if it is possible to delete the master journal.
*/
rc = pager_delmaster(pPager, zMaster);
+ testcase( rc!=SQLITE_OK );
}
/* The Pager.sectorSize variable may have been updated while rolling
** back a journal created by a process with a different sector size
@@ -32507,20 +31963,50 @@
return rc;
}
/*
-** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback
-** the entire master journal file.
-**
-** The case pSavepoint==NULL occurs when a ROLLBACK TO command is invoked
-** on a SAVEPOINT that is a transaction savepoint.
+** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback
+** the entire master journal file. The case pSavepoint==NULL occurs when
+** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction
+** savepoint.
+**
+** When pSavepoint is not NULL (meaning a non-transaction savepoint is
+** being rolled back), then the rollback consists of up to three stages,
+** performed in the order specified:
+**
+** * Pages are played back from the main journal starting at byte
+** offset PagerSavepoint.iOffset and continuing to
+** PagerSavepoint.iHdrOffset, or to the end of the main journal
+** file if PagerSavepoint.iHdrOffset is zero.
+**
+** * If PagerSavepoint.iHdrOffset is not zero, then pages are played
+** back starting from the journal header immediately following
+** PagerSavepoint.iHdrOffset to the end of the main journal file.
+**
+** * Pages are then played back from the sub-journal file, starting
+** with the PagerSavepoint.iSubRec and continuing to the end of
+** the journal file.
+**
+** Throughout the rollback process, each time a page is rolled back, the
+** corresponding bit is set in a bitvec structure (variable pDone in the
+** implementation below). This is used to ensure that a page is only
+** rolled back the first time it is encountered in either journal.
+**
+** If pSavepoint is NULL, then pages are only played back from the main
+** journal file. There is no need for a bitvec in this case.
+**
+** In either case, before playback commences the Pager.dbSize variable
+** is reset to the value that it held at the start of the savepoint
+** (or transaction). No page with a page-number greater than this value
+** is played back. If one is encountered it is simply skipped.
*/
static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
i64 szJ; /* Effective size of the main journal */
i64 iHdrOff; /* End of first segment of main-journal records */
- Pgno ii; /* Loop counter */
int rc = SQLITE_OK; /* Return code */
Bitvec *pDone = 0; /* Bitvec to ensure pages played back only once */
+
+ assert( pPager->state>=PAGER_SHARED );
/* Allocate a bitvec to use to store the set of pages rolled back */
if( pSavepoint ){
pDone = sqlite3BitvecCreate(pSavepoint->nOrig);
@@ -32528,13 +32014,12 @@
return SQLITE_NOMEM;
}
}
- /* Truncate the database back to the size it was before the
- ** savepoint being reverted was opened.
- */
- pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize;
- assert( pPager->state>=PAGER_SHARED );
+ /* Set the database size back to the value it was before the savepoint
+ ** being reverted was opened.
+ */
+ pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize;
/* Use pPager->journalOff as the effective size of the main rollback
** journal. The actual file might be larger than this in
** PAGER_JOURNALMODE_TRUNCATE or PAGER_JOURNALMODE_PERSIST. But anything
@@ -32552,11 +32037,11 @@
if( pSavepoint ){
iHdrOff = pSavepoint->iHdrOffset ? pSavepoint->iHdrOffset : szJ;
pPager->journalOff = pSavepoint->iOffset;
while( rc==SQLITE_OK && pPager->journalOff<iHdrOff ){
- rc = pager_playback_one_page(pPager, 1, &pPager->journalOff, 1, pDone);
- assert( rc!=SQLITE_DONE );
- }
+ rc = pager_playback_one_page(pPager, 1, 0, &pPager->journalOff, 1, pDone);
+ }
+ assert( rc!=SQLITE_DONE );
}else{
pPager->journalOff = 0;
}
@@ -32565,8 +32050,9 @@
** of the main journal file. Continue to skip out-of-range pages and
** continue adding pages rolled back to pDone.
*/
while( rc==SQLITE_OK && pPager->journalOff<szJ ){
+ u32 ii; /* Loop counter */
u32 nJRec = 0; /* Number of Journal Records */
u32 dummy;
rc = readJournalHdr(pPager, szJ, &nJRec, &dummy);
assert( rc!=SQLITE_DONE );
@@ -32583,14 +32069,14 @@
);
if( nJRec==0
&& pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff
){
- nJRec = (szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager);
+ nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager));
}
for(ii=0; rc==SQLITE_OK && ii<nJRec && pPager->journalOff<szJ; ii++){
- rc = pager_playback_one_page(pPager, 1, &pPager->journalOff, 1, pDone);
- assert( rc!=SQLITE_DONE );
- }
+ rc = pager_playback_one_page(pPager, 1, 0, &pPager->journalOff, 1, pDone);
+ }
+ assert( rc!=SQLITE_DONE );
}
assert( rc!=SQLITE_OK || pPager->journalOff==szJ );
/* Finally, rollback pages from the sub-journal. Page that were
@@ -32597,14 +32083,15 @@
** previously rolled back out of the main journal (and are hence in pDone)
** will be skipped. Out-of-range pages are also skipped.
*/
if( pSavepoint ){
+ u32 ii; /* Loop counter */
i64 offset = pSavepoint->iSubRec*(4+pPager->pageSize);
- for(ii=pSavepoint->iSubRec; rc==SQLITE_OK&&ii<(u32)pPager->stmtNRec; ii++){
- assert( offset == ii*(4+pPager->pageSize) );
- rc = pager_playback_one_page(pPager, 0, &offset, 1, pDone);
- assert( rc!=SQLITE_DONE );
- }
+ for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && ii<pPager->nSubRec; ii++){
+ assert( offset==ii*(4+pPager->pageSize) );
+ rc = pager_playback_one_page(pPager, 0, 0, &offset, 1, pDone);
+ }
+ assert( rc!=SQLITE_DONE );
}
sqlite3BitvecDestroy(pDone);
if( rc==SQLITE_OK ){
@@ -32666,18 +32153,26 @@
/*
** Open a temporary file.
**
-** Write the file descriptor into *fd. Return SQLITE_OK on success or some
-** other error code if we fail. The OS will automatically delete the temporary
-** file when it is closed.
-*/
-static int sqlite3PagerOpentemp(
+** Write the file descriptor into *pFile. Return SQLITE_OK on success
+** or some other error code if we fail. The OS will automatically
+** delete the temporary file when it is closed.
+**
+** The flags passed to the VFS layer xOpen() call are those specified
+** by parameter vfsFlags ORed with the following:
+**
+** SQLITE_OPEN_READWRITE
+** SQLITE_OPEN_CREATE
+** SQLITE_OPEN_EXCLUSIVE
+** SQLITE_OPEN_DELETEONCLOSE
+*/
+static int pagerOpentemp(
Pager *pPager, /* The pager object */
sqlite3_file *pFile, /* Write the file descriptor here */
int vfsFlags /* Flags passed through to the VFS */
){
- int rc;
+ int rc; /* Return code */
#ifdef SQLITE_TEST
sqlite3_opentemp_count++; /* Used for testing and analysis only */
#endif
@@ -32684,274 +32179,82 @@
vfsFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0);
- assert( rc!=SQLITE_OK || pFile->pMethods );
- return rc;
-}
-
-static int pagerStress(void *,PgHdr *);
-
-/*
-** Create a new page cache and put a pointer to the page cache in *ppPager.
-** The file to be cached need not exist. The file is not locked until
-** the first call to sqlite3PagerGet() and is only held open until the
-** last page is released using sqlite3PagerUnref().
-**
-** If zFilename is NULL then a randomly-named temporary file is created
-** and used as the file to be cached. The file will be deleted
-** automatically when it is closed.
-**
-** If zFilename is ":memory:" then all information is held in cache.
-** It is never written to disk. This can be used to implement an
-** in-memory database.
-*/
-SQLITE_PRIVATE int sqlite3PagerOpen(
- sqlite3_vfs *pVfs, /* The virtual file system to use */
- Pager **ppPager, /* Return the Pager structure here */
- const char *zFilename, /* Name of the database file to open */
- int nExtra, /* Extra bytes append to each in-memory page */
- int flags, /* flags controlling this file */
- int vfsFlags /* flags passed through to sqlite3_vfs.xOpen() */
-){
- u8 *pPtr;
- Pager *pPager = 0;
- int rc = SQLITE_OK;
- int i;
- int tempFile = 0;
- int memDb = 0;
- int readOnly = 0;
- int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
- int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
- int journalFileSize;
- int pcacheSize = sqlite3PcacheSize();
- int szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;
- char *zPathname = 0;
- int nPathname = 0;
-
- if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
- journalFileSize = sqlite3JournalSize(pVfs);
- }else{
- journalFileSize = sqlite3MemJournalSize();
- }
-
- /* The default return is a NULL pointer */
- *ppPager = 0;
-
- /* Compute and store the full pathname in an allocated buffer pointed
- ** to by zPathname, length nPathname. Or, if this is a temporary file,
- ** leave both nPathname and zPathname set to 0.
- */
- if( zFilename && zFilename[0] ){
- nPathname = pVfs->mxPathname+1;
- zPathname = sqlite3Malloc(nPathname*2);
- if( zPathname==0 ){
- return SQLITE_NOMEM;
- }
-#ifndef SQLITE_OMIT_MEMORYDB
- if( strcmp(zFilename,":memory:")==0 ){
- memDb = 1;
- zPathname[0] = 0;
- }else
-#endif
- {
- rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
- }
- if( rc!=SQLITE_OK ){
- sqlite3_free(zPathname);
- return rc;
- }
- nPathname = sqlite3Strlen30(zPathname);
- }
-
- /* Allocate memory for the pager structure */
- pPager = sqlite3MallocZero(
- sizeof(*pPager) + /* Pager structure */
- pcacheSize + /* PCache object */
- journalFileSize + /* The journal file structure */
- pVfs->szOsFile + /* The main db file */
- journalFileSize * 2 + /* The two journal files */
- 3*nPathname + 40 /* zFilename, zDirectory, zJournal */
- );
- if( !pPager ){
- sqlite3_free(zPathname);
- return SQLITE_NOMEM;
- }
- pPager->pPCache = (PCache *)&pPager[1];
- pPtr = ((u8 *)&pPager[1]) + pcacheSize;
- pPager->vfsFlags = vfsFlags;
- pPager->fd = (sqlite3_file*)&pPtr[pVfs->szOsFile*0];
- pPager->sjfd = (sqlite3_file*)&pPtr[pVfs->szOsFile];
- pPager->jfd = (sqlite3_file*)&pPtr[pVfs->szOsFile+journalFileSize];
- pPager->zFilename = (char*)&pPtr[pVfs->szOsFile+2*journalFileSize];
- pPager->zDirectory = &pPager->zFilename[nPathname+1];
- pPager->zJournal = &pPager->zDirectory[nPathname+1];
- pPager->pVfs = pVfs;
- if( zPathname ){
- memcpy(pPager->zFilename, zPathname, nPathname+1);
- sqlite3_free(zPathname);
- }
-
- /* Open the pager file.
- */
- if( zFilename && zFilename[0] && !memDb ){
- if( nPathname>(pVfs->mxPathname - (int)sizeof("-journal")) ){
- rc = SQLITE_CANTOPEN;
- }else{
- int fout = 0;
- rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd,
- pPager->vfsFlags, &fout);
- readOnly = (fout&SQLITE_OPEN_READONLY);
-
- /* If the file was successfully opened for read/write access,
- ** choose a default page size in case we have to create the
- ** database file. The default page size is the maximum of:
- **
- ** + SQLITE_DEFAULT_PAGE_SIZE,
- ** + The value returned by sqlite3OsSectorSize()
- ** + The largest page size that can be written atomically.
- */
- if( rc==SQLITE_OK && !readOnly ){
- setSectorSize(pPager);
- if( szPageDflt<pPager->sectorSize ){
- szPageDflt = pPager->sectorSize;
- }
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
- {
- int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
- int ii;
- assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
- assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
- assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536);
- for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){
- if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ) szPageDflt = ii;
- }
- }
-#endif
- if( szPageDflt>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
- szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE;
- }
- }
- }
- }else{
- /* If a temporary file is requested, it is not opened immediately.
- ** In this case we accept the default page size and delay actually
- ** opening the file until the first call to OsWrite().
- **
- ** This branch is also run for an in-memory database. An in-memory
- ** database is the same as a temp-file that is never written out to
- ** disk and uses an in-memory rollback journal.
- */
- tempFile = 1;
- pPager->state = PAGER_EXCLUSIVE;
- }
-
- if( pPager && rc==SQLITE_OK ){
- pPager->pTmpSpace = sqlite3PageMalloc(szPageDflt);
- }
-
- /* If an error occured in either of the blocks above.
- ** Free the Pager structure and close the file.
- ** Since the pager is not allocated there is no need to set
- ** any Pager.errMask variables.
- */
- if( !pPager || !pPager->pTmpSpace ){
- sqlite3OsClose(pPager->fd);
- sqlite3_free(pPager);
- return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc);
- }
- nExtra = FORCE_ALIGNMENT(nExtra);
- sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
- !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
-
- PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename));
- IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
-
- /* Fill in Pager.zDirectory[] */
- memcpy(pPager->zDirectory, pPager->zFilename, nPathname+1);
- for(i=sqlite3Strlen30(pPager->zDirectory);
- i>0 && pPager->zDirectory[i-1]!='/'; i--){}
- if( i>0 ) pPager->zDirectory[i-1] = 0;
-
- /* Fill in Pager.zJournal[] */
- if( zPathname ){
- memcpy(pPager->zJournal, pPager->zFilename, nPathname);
- memcpy(&pPager->zJournal[nPathname], "-journal", 9);
- }else{
- pPager->zJournal = 0;
- }
-
- /* pPager->journalOpen = 0; */
- pPager->useJournal = (u8)useJournal;
- pPager->noReadlock = (noReadlock && readOnly) ?1:0;
- /* pPager->stmtOpen = 0; */
- /* pPager->stmtInUse = 0; */
- /* pPager->nRef = 0; */
- pPager->dbSizeValid = (u8)memDb;
- pPager->pageSize = szPageDflt;
- /* pPager->stmtSize = 0; */
- /* pPager->stmtJSize = 0; */
- /* pPager->nPage = 0; */
- pPager->mxPage = 100;
- pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
- /* pPager->state = PAGER_UNLOCK; */
- assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) );
- /* pPager->errMask = 0; */
- pPager->tempFile = (u8)tempFile;
- assert( tempFile==PAGER_LOCKINGMODE_NORMAL
- || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
- assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
- pPager->exclusiveMode = (u8)tempFile;
- pPager->memDb = (u8)memDb;
- pPager->readOnly = (u8)readOnly;
- /* pPager->needSync = 0; */
- pPager->noSync = (pPager->tempFile || !useJournal) ?1:0;
- pPager->fullSync = pPager->noSync ?0:1;
- pPager->sync_flags = SQLITE_SYNC_NORMAL;
- /* pPager->pFirst = 0; */
- /* pPager->pFirstSynced = 0; */
- /* pPager->pLast = 0; */
- pPager->nExtra = nExtra;
- pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
- assert(pPager->fd->pMethods||tempFile);
- setSectorSize(pPager);
- if( memDb ){
- pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
- }
- /* pPager->xBusyHandler = 0; */
- /* pPager->pBusyHandlerArg = 0; */
- /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
- *ppPager = pPager;
- return SQLITE_OK;
+ assert( rc!=SQLITE_OK || isOpen(pFile) );
+ return rc;
}
/*
** Set the busy handler function.
+**
+** The pager invokes the busy-handler if sqlite3OsLock() returns
+** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock,
+** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE
+** lock. It does *not* invoke the busy handler when upgrading from
+** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE
+** (which occurs during hot-journal rollback). Summary:
+**
+** Transition | Invokes xBusyHandler
+** --------------------------------------------------------
+** NO_LOCK -> SHARED_LOCK | Yes
+** SHARED_LOCK -> RESERVED_LOCK | No
+** SHARED_LOCK -> EXCLUSIVE_LOCK | No
+** RESERVED_LOCK -> EXCLUSIVE_LOCK | Yes
+**
+** If the busy-handler callback returns non-zero, the lock is
+** retried. If it returns zero, then the SQLITE_BUSY error is
+** returned to the caller of the pager API function.
*/
SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(
- Pager *pPager,
- int (*xBusyHandler)(void *),
- void *pBusyHandlerArg
+ Pager *pPager, /* Pager object */
+ int (*xBusyHandler)(void *), /* Pointer to busy-handler function */
+ void *pBusyHandlerArg /* Argument to pass to xBusyHandler */
){
pPager->xBusyHandler = xBusyHandler;
pPager->pBusyHandlerArg = pBusyHandlerArg;
}
/*
-** Set the reinitializer for this pager. If not NULL, the reinitializer
-** is called when the content of a page in cache is restored to its original
-** value as a result of a rollback. The callback gives higher-level code
-** an opportunity to restore the EXTRA section to agree with the restored
-** page data.
+** Set the reinitializer for this pager. If not NULL, the reinitializer
+** is called when the content of a page in cache is modified (restored)
+** as part of a transaction or savepoint rollback. The callback gives
+** higher-level code an opportunity to restore the EXTRA section to
+** agree with the restored page data.
*/
SQLITE_PRIVATE void sqlite3PagerSetReiniter(Pager *pPager, void (*xReinit)(DbPage*)){
pPager->xReiniter = xReinit;
}
/*
-** Set the page size to *pPageSize. If the suggest new page size is
-** inappropriate, then an alternative page size is set to that
-** value before returning.
+** Change the page size used by the Pager object. The new page size
+** is passed in *pPageSize.
+**
+** If the pager is in the error state when this function is called, it
+** is a no-op. The value returned is the error state error code (i.e.
+** one of SQLITE_IOERR, SQLITE_CORRUPT or SQLITE_FULL).
+**
+** Otherwise, if all of the following are true:
+**
+** * the new page size (value of *pPageSize) is valid (a power
+** of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and
+**
+** * there are no outstanding page references, and
+**
+** * the database is either not an in-memory database or it is
+** an in-memory database that currently consists of zero pages.
+**
+** then the pager object page size is set to *pPageSize.
+**
+** If the page size is changed, then this function uses sqlite3PagerMalloc()
+** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt
+** fails, SQLITE_NOMEM is returned and the page size remains unchanged.
+** In all other cases, SQLITE_OK is returned.
+**
+** If the page size is not changed, either because one of the enumerated
+** conditions above is not true, the pager was in error state when this
+** function was called, or because the memory allocation attempt failed,
+** then *pPageSize is set to the old, retained page size before returning.
*/
SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize){
int rc = pPager->errCode;
if( rc==SQLITE_OK ){
@@ -32966,9 +32269,8 @@
rc = SQLITE_NOMEM;
}else{
pager_reset(pPager);
pPager->pageSize = pageSize;
- if( !pPager->memDb ) setSectorSize(pPager);
sqlite3PageFree(pPager->pTmpSpace);
pPager->pTmpSpace = pNew;
sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
}
@@ -33032,19 +32334,23 @@
/*
** Read the first N bytes from the beginning of the file into memory
** that pDest points to.
**
-** No error checking is done. The rational for this is that this function
-** may be called even if the file does not exist or contain a header. In
-** these cases sqlite3OsRead() will return an error, to which the correct
-** response is to zero the memory at pDest and continue. A real IO error
-** will presumably recur and be picked up later (Todo: Think about this).
+** If the pager was opened on a transient file (zFilename==""), or
+** opened on a file less than N bytes in size, the output buffer is
+** zeroed and SQLITE_OK returned. The rationale for this is that this
+** function is used to read database headers, and a new transient or
+** zero sized database has a header than consists entirely of zeroes.
+**
+** If any IO error apart from SQLITE_IOERR_SHORT_READ is encountered,
+** the error code is returned to the caller and the contents of the
+** output buffer undefined.
*/
SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){
int rc = SQLITE_OK;
memset(pDest, 0, N);
- assert(pPager->fd->pMethods||pPager->tempFile);
- if( pPager->fd->pMethods ){
+ assert( isOpen(pPager->fd) || pPager->tempFile );
+ if( isOpen(pPager->fd) ){
IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
rc = sqlite3OsRead(pPager->fd, pDest, N, 0);
if( rc==SQLITE_IOERR_SHORT_READ ){
rc = SQLITE_OK;
@@ -33053,71 +32359,86 @@
return rc;
}
/*
-** Return the total number of pages in the disk file associated with
-** pPager.
-**
-** If the PENDING_BYTE lies on the page directly after the end of the
-** file, then consider this page part of the file too. For example, if
-** PENDING_BYTE is byte 4096 (the first byte of page 5) and the size of the
-** file is 4096 bytes, 5 is returned instead of 4.
+** Return the total number of pages in the database file associated
+** with pPager. Normally, this is calculated as (<db file size>/<page-size>).
+** However, if the file is between 1 and <page-size> bytes in size, then
+** this is considered a 1 page file.
+**
+** If the pager is in error state when this function is called, then the
+** error state error code is returned and *pnPage left unchanged. Or,
+** if the file system has to be queried for the size of the file and
+** the query attempt returns an IO error, the IO error code is returned
+** and *pnPage is left unchanged.
+**
+** Otherwise, if everything is successful, then SQLITE_OK is returned
+** and *pnPage is set to the number of pages in the database.
*/
SQLITE_PRIVATE int sqlite3PagerPagecount(Pager *pPager, int *pnPage){
- i64 n = 0;
- int rc;
- assert( pPager!=0 );
+ Pgno nPage; /* Value to return via *pnPage */
+
+ /* If the pager is already in the error state, return the error code. */
if( pPager->errCode ){
- rc = pPager->errCode;
- return rc;
- }
+ return pPager->errCode;
+ }
+
+ /* Determine the number of pages in the file. Store this in nPage. */
if( pPager->dbSizeValid ){
- n = pPager->dbSize;
- } else {
- assert(pPager->fd->pMethods||pPager->tempFile);
- if( (pPager->fd->pMethods)
- && (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){
+ nPage = pPager->dbSize;
+ }else{
+ int rc; /* Error returned by OsFileSize() */
+ i64 n = 0; /* File size in bytes returned by OsFileSize() */
+
+ assert( isOpen(pPager->fd) || pPager->tempFile );
+ if( isOpen(pPager->fd) && (0 != (rc = sqlite3OsFileSize(pPager->fd, &n))) ){
pager_error(pPager, rc);
return rc;
}
if( n>0 && n<pPager->pageSize ){
- n = 1;
- }else{
- n /= pPager->pageSize;
+ nPage = 1;
+ }else{
+ nPage = (Pgno)(n / pPager->pageSize);
}
if( pPager->state!=PAGER_UNLOCK ){
- pPager->dbSize = (Pgno)n;
- pPager->dbFileSize = (Pgno)n;
+ pPager->dbSize = nPage;
+ pPager->dbFileSize = nPage;
pPager->dbSizeValid = 1;
}
}
- if( n==(PENDING_BYTE/pPager->pageSize) ){
- n++;
- }
- if( n>pPager->mxPgno ){
- pPager->mxPgno = (Pgno)n;
- }
+
+ /* If the current number of pages in the file is greater than the
+ ** configured maximum pager number, increase the allowed limit so
+ ** that the file can be read.
+ */
+ if( nPage>pPager->mxPgno ){
+ pPager->mxPgno = (Pgno)nPage;
+ }
+
+ /* Set the output variable and return SQLITE_OK */
if( pnPage ){
- *pnPage = (int)n;
- }
- return SQLITE_OK;
-}
-
-/*
-** Forward declaration
-*/
-static int syncJournal(Pager*);
-
-/*
-** Try to obtain a lock on a file. Invoke the busy callback if the lock
-** is currently not available. Repeat until the busy callback returns
-** false or until the lock succeeds.
+ *pnPage = nPage;
+ }
+ return SQLITE_OK;
+}
+
+
+/*
+** Try to obtain a lock of type locktype on the database file. If
+** a similar or greater lock is already held, this function is a no-op
+** (returning SQLITE_OK immediately).
+**
+** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke
+** the busy callback if the lock is currently not available. Repeat
+** until the busy callback returns false or until the attempt to
+** obtain the lock succeeds.
**
** Return SQLITE_OK on success and an error code if we cannot obtain
-** the lock.
+** the lock. If the lock is obtained successfully, set the Pager.state
+** variable to locktype before returning.
*/
static int pager_wait_on_lock(Pager *pPager, int locktype){
- int rc;
+ int rc; /* Return code */
/* The OS lock values must be the same as the Pager lock values */
assert( PAGER_SHARED==SHARED_LOCK );
assert( PAGER_RESERVED==RESERVED_LOCK );
@@ -33124,8 +32445,18 @@
assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
/* If the file is currently unlocked then the size must be unknown */
assert( pPager->state>=PAGER_SHARED || pPager->dbSizeValid==0 );
+
+ /* Check that this is either a no-op (because the requested lock is
+ ** already held, or one of the transistions that the busy-handler
+ ** may be invoked during, according to the comment above
+ ** sqlite3PagerSetBusyhandler().
+ */
+ assert( (pPager->state>=locktype)
+ || (pPager->state==PAGER_UNLOCK && locktype==PAGER_SHARED)
+ || (pPager->state==PAGER_RESERVED && locktype==PAGER_EXCLUSIVE)
+ );
if( pPager->state>=locktype ){
rc = SQLITE_OK;
}else{
@@ -33139,9 +32470,8 @@
}
return rc;
}
-#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** Truncate the in-memory database file image to nPage pages. This
** function does not actually modify the database file on disk. It
** just sets the internal state of the pager object so that the
@@ -33149,26 +32479,11 @@
*/
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
assert( pPager->dbSizeValid );
assert( pPager->dbSize>=nPage );
+ assert( pPager->state>=PAGER_RESERVED );
pPager->dbSize = nPage;
}
-
-/*
-** Return the current size of the database file image in pages. This
-** function differs from sqlite3PagerPagecount() in two ways:
-**
-** a) It may only be called when at least one reference to a database
-** page is held. This guarantees that the database size is already
-** known and a call to sqlite3OsFileSize() is not required.
-**
-** b) The return value is not adjusted for the locking page.
-*/
-SQLITE_PRIVATE Pgno sqlite3PagerImageSize(Pager *pPager){
- assert( pPager->dbSizeValid );
- return pPager->dbSize;
-}
-#endif /* ifndef SQLITE_OMIT_AUTOVACUUM */
/*
** Shutdown the page cache. Free all memory and close all files.
**
@@ -33183,15 +32498,16 @@
** a hot journal may be left in the filesystem but no error is returned
** to the caller.
*/
SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
-
disable_simulated_io_errors();
sqlite3BeginBenignMalloc();
pPager->errCode = 0;
pPager->exclusiveMode = 0;
pager_reset(pPager);
- if( !MEMDB ){
+ if( MEMDB ){
+ pager_unlock(pPager);
+ }else{
/* Set Pager.journalHdr to -1 for the benefit of the pager_playback()
** call which may be made from within pagerUnlockAndRollback(). If it
** is not -1, then the unsynced portion of an open journal file may
** be played back into the database. If a power failure occurs while
@@ -33199,89 +32515,91 @@
*/
pPager->journalHdr = -1;
pagerUnlockAndRollback(pPager);
}
- enable_simulated_io_errors();
sqlite3EndBenignMalloc();
+ enable_simulated_io_errors();
PAGERTRACE(("CLOSE %d\n", PAGERID(pPager)));
IOTRACE(("CLOSE %p\n", pPager))
- if( pPager->journalOpen ){
- sqlite3OsClose(pPager->jfd);
- }
- sqlite3BitvecDestroy(pPager->pInJournal);
- sqlite3BitvecDestroy(pPager->pAlwaysRollback);
- releaseAllSavepoint(pPager);
- sqlite3OsClose(pPager->fd);
- /* Temp files are automatically deleted by the OS
- ** if( pPager->tempFile ){
- ** sqlite3OsDelete(pPager->zFilename);
- ** }
- */
-
+ sqlite3OsClose(pPager->fd);
sqlite3PageFree(pPager->pTmpSpace);
sqlite3PcacheClose(pPager->pPCache);
+
+ assert( !pPager->aSavepoint && !pPager->pInJournal );
+ assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );
+
sqlite3_free(pPager);
return SQLITE_OK;
}
#if !defined(NDEBUG) || defined(SQLITE_TEST)
/*
-** Return the page number for the given page data.
-*/
-SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *p){
- return p->pgno;
-}
-#endif
-
-/*
-** Increment the reference count for a page. The input pointer is
-** a reference to the page data.
-*/
-SQLITE_PRIVATE int sqlite3PagerRef(DbPage *pPg){
+** Return the page number for page pPg.
+*/
+SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *pPg){
+ return pPg->pgno;
+}
+#endif
+
+/*
+** Increment the reference count for page pPg.
+*/
+SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){
sqlite3PcacheRef(pPg);
- return SQLITE_OK;
-}
-
-/*
-** Sync the journal. In other words, make sure all the pages that have
+}
+
+/*
+** Sync the journal. In other words, make sure all the pages that have
** been written to the journal have actually reached the surface of the
-** disk. It is not safe to modify the original database file until after
-** the journal has been synced. If the original database is modified before
-** the journal is synced and a power failure occurs, the unsynced journal
-** data would be lost and we would be unable to completely rollback the
-** database changes. Database corruption would occur.
-**
-** This routine also updates the nRec field in the header of the journal.
-** (See comments on the pager_playback() routine for additional information.)
-** If the sync mode is FULL, two syncs will occur. First the whole journal
-** is synced, then the nRec field is updated, then a second sync occurs.
-**
-** For temporary databases, we do not care if we are able to rollback
-** after a power failure, so no sync occurs.
-**
-** If the IOCAP_SEQUENTIAL flag is set for the persistent media on which
-** the database is stored, then OsSync() is never called on the journal
-** file. In this case all that is required is to update the nRec field in
-** the journal header.
-**
-** This routine clears the needSync field of every page current held in
-** memory.
-*/
-static int syncJournal(Pager *pPager){
- int rc = SQLITE_OK;
-
- /* Sync the journal before modifying the main database
- ** (assuming there is a journal and it needs to be synced.)
- */
+** disk and can be restored in the event of a hot-journal rollback.
+**
+** If the Pager.needSync flag is not set, then this function is a
+** no-op. Otherwise, the actions required depend on the journal-mode
+** and the device characteristics of the the file-system, as follows:
+**
+** * If the journal file is an in-memory journal file, no action need
+** be taken.
+**
+** * Otherwise, if the device does not support the SAFE_APPEND property,
+** then the nRec field of the most recently written journal header
+** is updated to contain the number of journal records that have
+** been written following it. If the pager is operating in full-sync
+** mode, then the journal file is synced before this field is updated.
+**
+** * If the device does not support the SEQUENTIAL property, then
+** journal file is synced.
+**
+** Or, in pseudo-code:
+**
+** if( NOT <in-memory journal> ){
+** if( NOT SAFE_APPEND ){
+** if( <full-sync mode> ) xSync(<journal file>);
+** <update nRec field>
+** }
+** if( NOT SEQUENTIAL ) xSync(<journal file>);
+** }
+**
+** The Pager.needSync flag is never be set for temporary files, or any
+** file operating in no-sync mode (Pager.noSync set to non-zero).
+**
+** If successful, this routine clears the PGHDR_NEED_SYNC flag of every
+** page currently held in memory before returning SQLITE_OK. If an IO
+** error is encountered, then the IO error code is returned to the caller.
+*/
+static int syncJournal(Pager *pPager){
if( pPager->needSync ){
assert( !pPager->tempFile );
if( pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){
- int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
- assert( pPager->journalOpen );
+ int rc; /* Return code */
+ const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
+ assert( isOpen(pPager->jfd) );
if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
- i64 jrnlOff = journalHdrOffset(pPager);
- u8 zMagic[8];
+ /* Variable iNRecOffset is set to the offset in the journal file
+ ** of the nRec field of the most recently written journal header.
+ ** This field will be updated following the xSync() operation
+ ** on the journal file. */
+ i64 iNRecOffset = pPager->journalHdr + sizeof(aJournalMagic);
/* This block deals with an obscure problem. If the last connection
** that wrote to this database was operating in persistent-journal
** mode, then the journal file may at this point actually be larger
@@ -33297,13 +32615,20 @@
**
** To work around this, if the journal file does appear to contain
** a valid header following Pager.journalOff, then write a 0x00
** byte to the start of it to prevent it from being recognized.
- */
- rc = sqlite3OsRead(pPager->jfd, zMagic, 8, jrnlOff);
- if( rc==SQLITE_OK && 0==memcmp(zMagic, aJournalMagic, 8) ){
+ **
+ ** Variable iNextHdrOffset is set to the offset at which this
+ ** problematic header will occur, if it exists. aMagic is used
+ ** as a temporary buffer to inspect the first couple of bytes of
+ ** the potential journal header.
+ */
+ i64 iNextHdrOffset = journalHdrOffset(pPager);
+ u8 aMagic[8];
+ rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset);
+ if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){
static const u8 zerobyte = 0;
- rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, jrnlOff);
+ rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset);
}
if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
return rc;
}
@@ -33322,53 +32647,77 @@
if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
IOTRACE(("JSYNC %p\n", pPager))
rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags);
- if( rc!=0 ) return rc;
- }
-
- jrnlOff = pPager->journalHdr + sizeof(aJournalMagic);
- IOTRACE(("JHDR %p %lld %d\n", pPager, jrnlOff, 4));
- rc = write32bits(pPager->jfd, jrnlOff, pPager->nRec);
- if( rc ) return rc;
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ IOTRACE(("JHDR %p %lld %d\n", pPager, iNRecOffset, 4));
+ rc = write32bits(pPager->jfd, iNRecOffset, pPager->nRec);
+ if( rc!=SQLITE_OK ) return rc;
}
if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
IOTRACE(("JSYNC %p\n", pPager))
rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags|
(pPager->sync_flags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0)
);
- if( rc!=0 ) return rc;
- }
- pPager->journalStarted = 1;
- }
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ }
+
+ /* The journal file was just successfully synced. Set Pager.needSync
+ ** to zero and clear the PGHDR_NEED_SYNC flag on all pagess.
+ */
pPager->needSync = 0;
-
- /* Erase the needSync flag from every page.
- */
+ pPager->journalStarted = 1;
sqlite3PcacheClearSyncFlags(pPager->pPCache);
}
- return rc;
-}
-
-/*
-** Given a list of pages (connected by the PgHdr.pDirty pointer) write
-** every one of those pages out to the database file. No calls are made
-** to the page-cache to mark the pages as clean. It is the responsibility
-** of the caller to use PcacheCleanAll() or PcacheMakeClean() to mark
-** the pages as clean.
+ return SQLITE_OK;
+}
+
+/*
+** The argument is the first in a linked list of dirty pages connected
+** by the PgHdr.pDirty pointer. This function writes each one of the
+** in-memory pages in the list to the database file. The argument may
+** be NULL, representing an empty list. In this case this function is
+** a no-op.
+**
+** The pager must hold at least a RESERVED lock when this function
+** is called. Before writing anything to the database file, this lock
+** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained,
+** SQLITE_BUSY is returned and no data is written to the database file.
+**
+** If the pager is a temp-file pager and the actual file-system file
+** is not yet open, it is created and opened before any data is
+** written out.
+**
+** Once the lock has been upgraded and, if necessary, the file opened,
+** the pages are written out to the database file in list order. Writing
+** a page is skipped if it meets either of the following criteria:
+**
+** * The page number is greater than Pager.dbSize, or
+** * The PGHDR_DONT_WRITE flag is set on the page.
+**
+** If writing out a page causes the database file to grow, Pager.dbFileSize
+** is updated accordingly. If page 1 is written out, then the value cached
+** in Pager.dbFileVers[] is updated to match the new value stored in
+** the database file.
+**
+** If everything is successful, SQLITE_OK is returned. If an IO error
+** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot
+** be obtained, SQLITE_BUSY is returned.
*/
static int pager_write_pagelist(PgHdr *pList){
- Pager *pPager;
- int rc;
+ Pager *pPager; /* Pager object */
+ int rc; /* Return code */
if( pList==0 ) return SQLITE_OK;
pPager = pList->pPager;
/* At this point there may be either a RESERVED or EXCLUSIVE lock on the
** database file. If there is already an EXCLUSIVE lock, the following
- ** calls to sqlite3OsLock() are no-ops.
+ ** call is a no-op.
**
** Moving the lock from RESERVED to EXCLUSIVE actually involves going
** through an intermediate state PENDING. A PENDING lock prevents new
** readers from attaching to the database but is unsufficient for us to
@@ -33380,231 +32729,652 @@
** journal into the original database file. Once we transition to
** EXCLUSIVE, it means the database file has been changed and any rollback
** will require a journal playback.
*/
+ assert( pPager->state>=PAGER_RESERVED );
rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- while( pList ){
-
- /* If the file has not yet been opened, open it now. */
- if( !pPager->fd->pMethods ){
- assert(pPager->tempFile);
- rc = sqlite3PagerOpentemp(pPager, pPager->fd, pPager->vfsFlags);
- if( rc ) return rc;
- }
+
+ /* If the file is a temp-file has not yet been opened, open it now. It
+ ** is not possible for rc to be other than SQLITE_OK if this branch
+ ** is taken, as pager_wait_on_lock() is a no-op for temp-files.
+ */
+ if( !isOpen(pPager->fd) ){
+ assert( pPager->tempFile && rc==SQLITE_OK );
+ rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags);
+ }
+
+ while( rc==SQLITE_OK && pList ){
+ Pgno pgno = pList->pgno;
/* If there are dirty pages in the page cache with page numbers greater
** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to
** make the file smaller (presumably by auto-vacuum code). Do not write
** any such pages to the file.
- */
- if( pList->pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
- i64 offset = (pList->pgno-1)*(i64)pPager->pageSize;
- char *pData = CODEC2(pPager, pList->pData, pList->pgno, 6);
-
- PAGERTRACE(("STORE %d page %d hash(%08x)\n",
- PAGERID(pPager), pList->pgno, pager_pagehash(pList)));
- IOTRACE(("PGOUT %p %d\n", pPager, pList->pgno));
+ **
+ ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag
+ ** set (set by sqlite3PagerDontWrite()).
+ */
+ if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
+ i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */
+ char *pData = CODEC2(pPager, pList->pData, pgno, 6); /* Data to write */
+
+ /* Write out the page data. */
rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
- PAGER_INCR(sqlite3_pager_writedb_count);
- PAGER_INCR(pPager->nWrite);
- if( pList->pgno==1 ){
+
+ /* If page 1 was just written, update Pager.dbFileVers to match
+ ** the value now stored in the database file. If writing this
+ ** page caused the database file to grow, update dbFileSize.
+ */
+ if( pgno==1 ){
memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers));
}
- if( pList->pgno>pPager->dbFileSize ){
- pPager->dbFileSize = pList->pgno;
- }
- }
-#ifndef NDEBUG
- else{
- PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno));
- }
-#endif
- if( rc ) return rc;
+ if( pgno>pPager->dbFileSize ){
+ pPager->dbFileSize = pgno;
+ }
+
+ /* Update any backup objects copying the contents of this pager. */
+ sqlite3BackupUpdate(pPager->pBackup, pgno, (u8 *)pData);
+
+ PAGERTRACE(("STORE %d page %d hash(%08x)\n",
+ PAGERID(pPager), pgno, pager_pagehash(pList)));
+ IOTRACE(("PGOUT %p %d\n", pPager, pgno));
+ PAGER_INCR(sqlite3_pager_writedb_count);
+ PAGER_INCR(pPager->nWrite);
+ }else{
+ PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno));
+ }
#ifdef SQLITE_CHECK_PAGES
pList->pageHash = pager_pagehash(pList);
#endif
pList = pList->pDirty;
}
- return SQLITE_OK;
-}
-
-/*
-** Add the page to the sub-journal. It is the callers responsibility to
-** use subjRequiresPage() to check that it is really required before
-** calling this function.
+ return rc;
+}
+
+/*
+** Append a record of the current state of page pPg to the sub-journal.
+** It is the callers responsibility to use subjRequiresPage() to check
+** that it is really required before calling this function.
+**
+** If successful, set the bit corresponding to pPg->pgno in the bitvecs
+** for all open savepoints before returning.
+**
+** This function returns SQLITE_OK if everything is successful, an IO
+** error code if the attempt to write to the sub-journal fails, or
+** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint
+** bitvec.
*/
static int subjournalPage(PgHdr *pPg){
- int rc;
- void *pData = pPg->pData;
+ int rc = SQLITE_OK;
Pager *pPager = pPg->pPager;
- i64 offset = pPager->stmtNRec*(4+pPager->pageSize);
- char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
-
- PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
-
- assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
- rc = write32bits(pPager->sjfd, offset, pPg->pgno);
- if( rc==SQLITE_OK ){
- rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
- }
- if( rc==SQLITE_OK ){
- pPager->stmtNRec++;
+ if( isOpen(pPager->sjfd) ){
+ void *pData = pPg->pData;
+ i64 offset = pPager->nSubRec*(4+pPager->pageSize);
+ char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
+
+ PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
+
+ assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
+ rc = write32bits(pPager->sjfd, offset, pPg->pgno);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
+ }
+ }
+ if( rc==SQLITE_OK ){
+ pPager->nSubRec++;
assert( pPager->nSavepoint>0 );
rc = addToSavepointBitvecs(pPager, pPg->pgno);
+ testcase( rc!=SQLITE_OK );
}
return rc;
}
/*
** This function is called by the pcache layer when it has reached some
-** soft memory limit. The argument is a pointer to a purgeable Pager
-** object. This function attempts to make a single dirty page that has no
-** outstanding references (if one exists) clean so that it can be recycled
-** by the pcache layer.
+** soft memory limit. The first argument is a pointer to a Pager object
+** (cast as a void*). The pager is always 'purgeable' (not an in-memory
+** database). The second argument is a reference to a page that is
+** currently dirty but has no outstanding references. The page
+** is always associated with the Pager object passed as the first
+** argument.
+**
+** The job of this function is to make pPg clean by writing its contents
+** out to the database file, if possible. This may involve syncing the
+** journal file.
+**
+** If successful, sqlite3PcacheMakeClean() is called on the page and
+** SQLITE_OK returned. If an IO error occurs while trying to make the
+** page clean, the IO error code is returned. If the page cannot be
+** made clean for some other reason, but no error occurs, then SQLITE_OK
+** is returned by sqlite3PcacheMakeClean() is not called.
*/
static int pagerStress(void *p, PgHdr *pPg){
Pager *pPager = (Pager *)p;
int rc = SQLITE_OK;
- if( pPager->doNotSync ){
- return SQLITE_OK;
- }
-
+ assert( pPg->pPager==pPager );
assert( pPg->flags&PGHDR_DIRTY );
- if( pPager->errCode==SQLITE_OK ){
- if( pPg->flags&PGHDR_NEED_SYNC ){
- rc = syncJournal(pPager);
- if( rc==SQLITE_OK && pPager->fullSync &&
- !(pPager->journalMode==PAGER_JOURNALMODE_MEMORY) &&
- !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
- ){
- pPager->nRec = 0;
- rc = writeJournalHdr(pPager);
- }
- }
- if( rc==SQLITE_OK ){
- pPg->pDirty = 0;
- if( pPg->pgno>pPager->dbSize && subjRequiresPage(pPg) ){
- rc = subjournalPage(pPg);
- }
- if( rc==SQLITE_OK ){
- rc = pager_write_pagelist(pPg);
- }
- }
- if( rc!=SQLITE_OK ){
- pager_error(pPager, rc);
- }
- }
-
+
+ /* The doNotSync flag is set by the sqlite3PagerWrite() function while it
+ ** is journalling a set of two or more database pages that are stored
+ ** on the same disk sector. Syncing the journal is not allowed while
+ ** this is happening as it is important that all members of such a
+ ** set of pages are synced to disk together. So, if the page this function
+ ** is trying to make clean will require a journal sync and the doNotSync
+ ** flag is set, return without doing anything. The pcache layer will
+ ** just have to go ahead and allocate a new page buffer instead of
+ ** reusing pPg.
+ **
+ ** Similarly, if the pager has already entered the error state, do not
+ ** try to write the contents of pPg to disk.
+ */
+ if( pPager->errCode || (pPager->doNotSync && pPg->flags&PGHDR_NEED_SYNC) ){
+ return SQLITE_OK;
+ }
+
+ /* Sync the journal file if required. */
+ if( pPg->flags&PGHDR_NEED_SYNC ){
+ rc = syncJournal(pPager);
+ if( rc==SQLITE_OK && pPager->fullSync &&
+ !(pPager->journalMode==PAGER_JOURNALMODE_MEMORY) &&
+ !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
+ ){
+ pPager->nRec = 0;
+ rc = writeJournalHdr(pPager);
+ }
+ }
+
+ /* If the page number of this page is larger than the current size of
+ ** the database image, it may need to be written to the sub-journal.
+ ** This is because the call to pager_write_pagelist() below will not
+ ** actually write data to the file in this case.
+ **
+ ** Consider the following sequence of events:
+ **
+ ** BEGIN;
+ ** <journal page X>
+ ** <modify page X>
+ ** SAVEPOINT sp;
+ ** <shrink database file to Y pages>
+ ** pagerStress(page X)
+ ** ROLLBACK TO sp;
+ **
+ ** If (X>Y), then when pagerStress is called page X will not be written
+ ** out to the database file, but will be dropped from the cache. Then,
+ ** following the "ROLLBACK TO sp" statement, reading page X will read
+ ** data from the database file. This will be the copy of page X as it
+ ** was when the transaction started, not as it was when "SAVEPOINT sp"
+ ** was executed.
+ **
+ ** The solution is to write the current data for page X into the
+ ** sub-journal file now (if it is not already there), so that it will
+ ** be restored to its current value when the "ROLLBACK TO sp" is
+ ** executed.
+ */
+ if( rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg) ){
+ rc = subjournalPage(pPg);
+ }
+
+ /* Write the contents of the page out to the database file. */
+ if( rc==SQLITE_OK ){
+ pPg->pDirty = 0;
+ rc = pager_write_pagelist(pPg);
+ }
+
+ /* Mark the page as clean. */
if( rc==SQLITE_OK ){
PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno));
sqlite3PcacheMakeClean(pPg);
}
- return rc;
-}
-
-
-/*
-** Return 1 if there is a hot journal on the given pager.
-** A hot journal is one that needs to be played back.
+
+ return pager_error(pPager, rc);
+}
+
+
+/*
+** Allocate and initialize a new Pager object and put a pointer to it
+** in *ppPager. The pager should eventually be freed by passing it
+** to sqlite3PagerClose().
+**
+** The zFilename argument is the path to the database file to open.
+** If zFilename is NULL then a randomly-named temporary file is created
+** and used as the file to be cached. Temporary files are be deleted
+** automatically when they are closed. If zFilename is ":memory:" then
+** all information is held in cache. It is never written to disk.
+** This can be used to implement an in-memory database.
+**
+** The nExtra parameter specifies the number of bytes of space allocated
+** along with each page reference. This space is available to the user
+** via the sqlite3PagerGetExtra() API.
+**
+** The flags argument is used to specify properties that affect the
+** operation of the pager. It should be passed some bitwise combination
+** of the PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK flags.
+**
+** The vfsFlags parameter is a bitmask to pass to the flags parameter
+** of the xOpen() method of the supplied VFS when opening files.
+**
+** If the pager object is allocated and the specified file opened
+** successfully, SQLITE_OK is returned and *ppPager set to point to
+** the new pager object. If an error occurs, *ppPager is set to NULL
+** and error code returned. This function may return SQLITE_NOMEM
+** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or
+** various SQLITE_IO_XXX errors.
+*/
+SQLITE_PRIVATE int sqlite3PagerOpen(
+ sqlite3_vfs *pVfs, /* The virtual file system to use */
+ Pager **ppPager, /* OUT: Return the Pager structure here */
+ const char *zFilename, /* Name of the database file to open */
+ int nExtra, /* Extra bytes append to each in-memory page */
+ int flags, /* flags controlling this file */
+ int vfsFlags /* flags passed through to sqlite3_vfs.xOpen() */
+){
+ u8 *pPtr;
+ Pager *pPager = 0; /* Pager object to allocate and return */
+ int rc = SQLITE_OK; /* Return code */
+ int tempFile = 0; /* True for temp files (incl. in-memory files) */
+ int memDb = 0; /* True if this is an in-memory file */
+ int readOnly = 0; /* True if this is a read-only file */
+ int journalFileSize; /* Bytes to allocate for each journal fd */
+ char *zPathname = 0; /* Full path to database file */
+ int nPathname = 0; /* Number of bytes in zPathname */
+ int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
+ int noReadlock = (flags & PAGER_NO_READLOCK)!=0; /* True to omit read-lock */
+ int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */
+ u16 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */
+
+ /* Figure out how much space is required for each journal file-handle
+ ** (there are two of them, the main journal and the sub-journal). This
+ ** is the maximum space required for an in-memory journal file handle
+ ** and a regular journal file-handle. Note that a "regular journal-handle"
+ ** may be a wrapper capable of caching the first portion of the journal
+ ** file in memory to implement the atomic-write optimization (see
+ ** source file journal.c).
+ */
+ if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
+ journalFileSize = sqlite3JournalSize(pVfs);
+ }else{
+ journalFileSize = sqlite3MemJournalSize();
+ }
+
+ /* Set the output variable to NULL in case an error occurs. */
+ *ppPager = 0;
+
+ /* Compute and store the full pathname in an allocated buffer pointed
+ ** to by zPathname, length nPathname. Or, if this is a temporary file,
+ ** leave both nPathname and zPathname set to 0.
+ */
+ if( zFilename && zFilename[0] ){
+ nPathname = pVfs->mxPathname+1;
+ zPathname = sqlite3Malloc(nPathname*2);
+ if( zPathname==0 ){
+ return SQLITE_NOMEM;
+ }
+#ifndef SQLITE_OMIT_MEMORYDB
+ if( strcmp(zFilename,":memory:")==0 ){
+ memDb = 1;
+ zPathname[0] = 0;
+ }else
+#endif
+ {
+ zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
+ rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
+ }
+
+ nPathname = sqlite3Strlen30(zPathname);
+ if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){
+ /* This branch is taken when the journal path required by
+ ** the database being opened will be more than pVfs->mxPathname
+ ** bytes in length. This means the database cannot be opened,
+ ** as it will not be possible to open the journal file or even
+ ** check for a hot-journal before reading.
+ */
+ rc = SQLITE_CANTOPEN;
+ }
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(zPathname);
+ return rc;
+ }
+ }
+
+ /* Allocate memory for the Pager structure, PCache object, the
+ ** three file descriptors, the database file name and the journal
+ ** file name. The layout in memory is as follows:
+ **
+ ** Pager object (sizeof(Pager) bytes)
+ ** PCache object (sqlite3PcacheSize() bytes)
+ ** Database file handle (pVfs->szOsFile bytes)
+ ** Sub-journal file handle (journalFileSize bytes)
+ ** Main journal file handle (journalFileSize bytes)
+ ** Database file name (nPathname+1 bytes)
+ ** Journal file name (nPathname+8+1 bytes)
+ */
+ pPtr = (u8 *)sqlite3MallocZero(
+ sizeof(*pPager) + /* Pager structure */
+ pcacheSize + /* PCache object */
+ pVfs->szOsFile + /* The main db file */
+ journalFileSize * 2 + /* The two journal files */
+ nPathname + 1 + /* zFilename */
+ nPathname + 8 + 1 /* zJournal */
+ );
+ if( !pPtr ){
+ sqlite3_free(zPathname);
+ return SQLITE_NOMEM;
+ }
+ pPager = (Pager*)(pPtr);
+ pPager->pPCache = (PCache*)(pPtr += sizeof(*pPager));
+ pPager->fd = (sqlite3_file*)(pPtr += pcacheSize);
+ pPager->sjfd = (sqlite3_file*)(pPtr += pVfs->szOsFile);
+ pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize);
+ pPager->zFilename = (char*)(pPtr += journalFileSize);
+
+ /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
+ if( zPathname ){
+ pPager->zJournal = (char*)(pPtr += nPathname + 1);
+ memcpy(pPager->zFilename, zPathname, nPathname);
+ memcpy(pPager->zJournal, zPathname, nPathname);
+ memcpy(&pPager->zJournal[nPathname], "-journal", 8);
+ sqlite3_free(zPathname);
+ }
+ pPager->pVfs = pVfs;
+ pPager->vfsFlags = vfsFlags;
+
+ /* Open the pager file.
+ */
+ if( zFilename && zFilename[0] && !memDb ){
+ int fout = 0; /* VFS flags returned by xOpen() */
+ rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
+ readOnly = (fout&SQLITE_OPEN_READONLY);
+
+ /* If the file was successfully opened for read/write access,
+ ** choose a default page size in case we have to create the
+ ** database file. The default page size is the maximum of:
+ **
+ ** + SQLITE_DEFAULT_PAGE_SIZE,
+ ** + The value returned by sqlite3OsSectorSize()
+ ** + The largest page size that can be written atomically.
+ */
+ if( rc==SQLITE_OK && !readOnly ){
+ setSectorSize(pPager);
+ assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE);
+ if( szPageDflt<pPager->sectorSize ){
+ if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
+ szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE;
+ }else{
+ szPageDflt = (u16)pPager->sectorSize;
+ }
+ }
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+ {
+ int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
+ int ii;
+ assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
+ assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
+ assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536);
+ for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){
+ if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){
+ szPageDflt = ii;
+ }
+ }
+ }
+#endif
+ }
+ }else{
+ /* If a temporary file is requested, it is not opened immediately.
+ ** In this case we accept the default page size and delay actually
+ ** opening the file until the first call to OsWrite().
+ **
+ ** This branch is also run for an in-memory database. An in-memory
+ ** database is the same as a temp-file that is never written out to
+ ** disk and uses an in-memory rollback journal.
+ */
+ tempFile = 1;
+ pPager->state = PAGER_EXCLUSIVE;
+ }
+
+ /* The following call to PagerSetPagesize() serves to set the value of
+ ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer.
+ */
+ if( rc==SQLITE_OK ){
+ assert( pPager->memDb==0 );
+ rc = sqlite3PagerSetPagesize(pPager, &szPageDflt);
+ testcase( rc!=SQLITE_OK );
+ }
+
+ /* If an error occurred in either of the blocks above, free the
+ ** Pager structure and close the file.
+ */
+ if( rc!=SQLITE_OK ){
+ assert( !pPager->pTmpSpace );
+ sqlite3OsClose(pPager->fd);
+ sqlite3_free(pPager);
+ return rc;
+ }
+
+ /* Initialize the PCache object. */
+ nExtra = ROUND8(nExtra);
+ sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
+ !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
+
+ PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename));
+ IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
+
+ pPager->useJournal = (u8)useJournal;
+ pPager->noReadlock = (noReadlock && readOnly) ?1:0;
+ /* pPager->stmtOpen = 0; */
+ /* pPager->stmtInUse = 0; */
+ /* pPager->nRef = 0; */
+ pPager->dbSizeValid = (u8)memDb;
+ /* pPager->stmtSize = 0; */
+ /* pPager->stmtJSize = 0; */
+ /* pPager->nPage = 0; */
+ pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
+ /* pPager->state = PAGER_UNLOCK; */
+ assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) );
+ /* pPager->errMask = 0; */
+ pPager->tempFile = (u8)tempFile;
+ assert( tempFile==PAGER_LOCKINGMODE_NORMAL
+ || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
+ assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
+ pPager->exclusiveMode = (u8)tempFile;
+ pPager->changeCountDone = pPager->tempFile;
+ pPager->memDb = (u8)memDb;
+ pPager->readOnly = (u8)readOnly;
+ /* pPager->needSync = 0; */
+ pPager->noSync = (pPager->tempFile || !useJournal) ?1:0;
+ pPager->fullSync = pPager->noSync ?0:1;
+ pPager->sync_flags = SQLITE_SYNC_NORMAL;
+ /* pPager->pFirst = 0; */
+ /* pPager->pFirstSynced = 0; */
+ /* pPager->pLast = 0; */
+ pPager->nExtra = nExtra;
+ pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
+ assert( isOpen(pPager->fd) || tempFile );
+ setSectorSize(pPager);
+ if( memDb ){
+ pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
+ }
+ /* pPager->xBusyHandler = 0; */
+ /* pPager->pBusyHandlerArg = 0; */
+ /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
+ *ppPager = pPager;
+ return SQLITE_OK;
+}
+
+
+
+/*
+** This function is called after transitioning from PAGER_UNLOCK to
+** PAGER_SHARED state. It tests if there is a hot journal present in
+** the file-system for the given pager. A hot journal is one that
+** needs to be played back. According to this function, a hot-journal
+** file exists if the following criteria are met:
+**
+** * The journal file exists in the file system, and
+** * No process holds a RESERVED or greater lock on the database file, and
+** * The database file itself is greater than 0 bytes in size, and
+** * The first byte of the journal file exists and is not 0x00.
**
** If the current size of the database file is 0 but a journal file
** exists, that is probably an old journal left over from a prior
-** database with the same name. Just delete the journal.
-**
-** Return negative if unable to determine the status of the journal.
-**
-** This routine does not open the journal file to examine its
-** content. Hence, the journal might contain the name of a master
-** journal file that has been deleted, and hence not be hot. Or
-** the header of the journal might be zeroed out. This routine
-** does not discover these cases of a non-hot journal - if the
-** journal file exists and is not empty this routine assumes it
-** is hot. The pager_playback() routine will discover that the
-** journal file is not really hot and will no-op.
+** database with the same name. In this case the journal file is
+** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK
+** is returned.
+**
+** This routine does not check if there is a master journal filename
+** at the end of the file. If there is, and that master journal file
+** does not exist, then the journal file is not really hot. In this
+** case this routine will return a false-positive. The pager_playback()
+** routine will discover that the journal file is not really hot and
+** will not roll it back.
+**
+** If a hot-journal file is found to exist, *pExists is set to 1 and
+** SQLITE_OK returned. If no hot-journal file is present, *pExists is
+** set to 0 and SQLITE_OK returned. If an IO error occurs while trying
+** to determine whether or not a hot-journal file exists, the IO error
+** code is returned and the value of *pExists is undefined.
*/
static int hasHotJournal(Pager *pPager, int *pExists){
- sqlite3_vfs *pVfs = pPager->pVfs;
- int rc = SQLITE_OK;
- int exists = 0;
- int locked = 0;
+ sqlite3_vfs * const pVfs = pPager->pVfs;
+ int rc; /* Return code */
+ int exists; /* True if a journal file is present */
+
assert( pPager!=0 );
assert( pPager->useJournal );
- assert( pPager->fd->pMethods );
+ assert( isOpen(pPager->fd) );
+ assert( !isOpen(pPager->jfd) );
+
*pExists = 0;
rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
if( rc==SQLITE_OK && exists ){
+ int locked; /* True if some process holds a RESERVED lock */
rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
- }
- if( rc==SQLITE_OK && exists && !locked ){
- int nPage;
- rc = sqlite3PagerPagecount(pPager, &nPage);
- if( rc==SQLITE_OK ){
- if( nPage==0 ){
- sqlite3OsDelete(pVfs, pPager->zJournal, 0);
- }else{
- *pExists = 1;
- }
- }
- }
- return rc;
-}
-
-/*
-** Read the content of page pPg out of the database file.
-*/
-static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){
- int rc;
- i64 offset;
- assert( MEMDB==0 );
- assert(pPager->fd->pMethods||pPager->tempFile);
- if( !pPager->fd->pMethods ){
- return SQLITE_IOERR_SHORT_READ;
- }
- offset = (pgno-1)*(i64)pPager->pageSize;
- rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, offset);
+ if( rc==SQLITE_OK && !locked ){
+ int nPage;
+
+ /* Check the size of the database file. If it consists of 0 pages,
+ ** then delete the journal file. See the header comment above for
+ ** the reasoning here.
+ */
+ rc = sqlite3PagerPagecount(pPager, &nPage);
+ if( rc==SQLITE_OK ){
+ if( nPage==0 ){
+ rc = sqlite3OsDelete(pVfs, pPager->zJournal, 0);
+ }else{
+ /* The journal file exists and no other connection has a reserved
+ ** or greater lock on the database file. Now check that there is
+ ** at least one non-zero bytes at the start of the journal file.
+ ** If there is, then we consider this journal to be hot. If not,
+ ** it can be ignored.
+ */
+ int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL;
+ rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f);
+ if( rc==SQLITE_OK ){
+ u8 first = 0;
+ rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0);
+ if( rc==SQLITE_IOERR_SHORT_READ ){
+ rc = SQLITE_OK;
+ }
+ sqlite3OsClose(pPager->jfd);
+ *pExists = (first!=0);
+ }
+ }
+ }
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Read the content for page pPg out of the database file and into
+** pPg->pData. A shared lock or greater must be held on the database
+** file before this function is called.
+**
+** If page 1 is read, then the value of Pager.dbFileVers[] is set to
+** the value read from the database file.
+**
+** If an IO error occurs, then the IO error is returned to the caller.
+** Otherwise, SQLITE_OK is returned.
+*/
+static int readDbPage(PgHdr *pPg){
+ Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
+ Pgno pgno = pPg->pgno; /* Page number to read */
+ int rc; /* Return code */
+ i64 iOffset; /* Byte offset of file to read from */
+
+ assert( pPager->state>=PAGER_SHARED && !MEMDB );
+
+ if( !isOpen(pPager->fd) ){
+ assert( pPager->tempFile );
+ memset(pPg->pData, 0, pPager->pageSize);
+ return SQLITE_OK;
+ }
+ iOffset = (pgno-1)*(i64)pPager->pageSize;
+ rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset);
+ if( rc==SQLITE_IOERR_SHORT_READ ){
+ rc = SQLITE_OK;
+ }
+ if( pgno==1 ){
+ u8 *dbFileVers = &((u8*)pPg->pData)[24];
+ memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
+ }
+ CODEC1(pPager, pPg->pData, pgno, 3);
+
PAGER_INCR(sqlite3_pager_readdb_count);
PAGER_INCR(pPager->nRead);
IOTRACE(("PGIN %p %d\n", pPager, pgno));
- if( pgno==1 ){
- memcpy(&pPager->dbFileVers, &((u8*)pPg->pData)[24],
- sizeof(pPager->dbFileVers));
- }
- CODEC1(pPager, pPg->pData, pPg->pgno, 3);
PAGERTRACE(("FETCH %d page %d hash(%08x)\n",
- PAGERID(pPager), pPg->pgno, pager_pagehash(pPg)));
- return rc;
-}
-
-
-/*
-** This function is called to obtain the shared lock required before
-** data may be read from the pager cache. If the shared lock has already
-** been obtained, this function is a no-op.
-**
-** Immediately after obtaining the shared lock (if required), this function
-** checks for a hot-journal file. If one is found, an emergency rollback
-** is performed immediately.
+ PAGERID(pPager), pgno, pager_pagehash(pPg)));
+
+ return rc;
+}
+
+/*
+** This function is called whenever the upper layer requests a database
+** page is requested, before the cache is checked for a suitable page
+** or any data is read from the database. It performs the following
+** two functions:
+**
+** 1) If the pager is currently in PAGER_UNLOCK state (no lock held
+** on the database file), then an attempt is made to obtain a
+** SHARED lock on the database file. Immediately after obtaining
+** the SHARED lock, the file-system is checked for a hot-journal,
+** which is played back if present. Following any hot-journal
+** rollback, the contents of the cache are validated by checking
+** the 'change-counter' field of the database file header and
+** discarded if they are found to be invalid.
+**
+** 2) If the pager is running in exclusive-mode, and there are currently
+** no outstanding references to any pages, and is in the error state,
+** then an attempt is made to clear the error state by discarding
+** the contents of the page cache and rolling back any open journal
+** file.
+**
+** If the operation described by (2) above is not attempted, and if the
+** pager is in an error state other than SQLITE_FULL when this is called,
+** the error state error code is returned. It is permitted to read the
+** database when in SQLITE_FULL error state.
+**
+** Otherwise, if everything is successful, SQLITE_OK is returned. If an
+** IO error occurs while locking the database, checking for a hot-journal
+** file or rolling back a journal file, the IO error code is returned.
*/
static int pagerSharedLock(Pager *pPager){
- int rc = SQLITE_OK;
- int isErrorReset = 0;
+ int rc = SQLITE_OK; /* Return code */
+ int isErrorReset = 0; /* True if recovering from error state */
/* If this database is opened for exclusive access, has no outstanding
- ** page references and is in an error-state, now is the chance to clear
+ ** page references and is in an error-state, this is a chance to clear
** the error. Discard the contents of the pager-cache and treat any
** open journal file as a hot-journal.
*/
if( !MEMDB && pPager->exclusiveMode
&& sqlite3PcacheRefCount(pPager->pPCache)==0 && pPager->errCode
){
- if( pPager->journalOpen ){
+ if( isOpen(pPager->jfd) ){
isErrorReset = 1;
}
pPager->errCode = SQLITE_OK;
pager_reset(pPager);
@@ -33618,9 +33388,9 @@
return pPager->errCode;
}
if( pPager->state==PAGER_UNLOCK || isErrorReset ){
- sqlite3_vfs *pVfs = pPager->pVfs;
+ sqlite3_vfs * const pVfs = pPager->pVfs;
int isHotJournal = 0;
assert( !MEMDB );
assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
if( !pPager->noReadlock ){
@@ -33647,14 +33417,15 @@
/* Get an EXCLUSIVE lock on the database file. At this point it is
** important that a RESERVED lock is not obtained on the way to the
** EXCLUSIVE lock. If it were, another process might open the
** database file, detect the RESERVED lock, and conclude that the
- ** database is safe to read while this process is still rolling it
- ** back.
- **
- ** Because the intermediate RESERVED lock is not requested, the
- ** second process will get to this point in the code and fail to
- ** obtain its own EXCLUSIVE lock on the database file.
+ ** database is safe to read while this process is still rolling the
+ ** hot-journal back.
+ **
+ ** Because the intermediate RESERVED lock is not requested, any
+ ** other process attempting to access the database file will get to
+ ** this point in the code and fail to obtain its own EXCLUSIVE lock
+ ** on the database file.
*/
if( pPager->state<EXCLUSIVE_LOCK ){
rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
if( rc!=SQLITE_OK ){
@@ -33669,9 +33440,9 @@
** possibly used for a transaction later on. On some systems, the
** OsTruncate() call used in exclusive-access mode also requires
** a read/write file handle.
*/
- if( !isErrorReset && pPager->journalOpen==0 ){
+ if( !isOpen(pPager->jfd) ){
int res;
rc = sqlite3OsAccess(pVfs,pPager->zJournal,SQLITE_ACCESS_EXISTS,&res);
if( rc==SQLITE_OK ){
if( res ){
@@ -33678,9 +33449,9 @@
int fout = 0;
int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
assert( !pPager->tempFile );
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
- assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
+ assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){
rc = SQLITE_CANTOPEN;
sqlite3OsClose(pPager->jfd);
}
@@ -33693,9 +33464,10 @@
}
if( rc!=SQLITE_OK ){
goto failed;
}
- pPager->journalOpen = 1;
+
+ /* TODO: Why are these cleared here? Is it necessary? */
pPager->journalStarted = 0;
pPager->journalOff = 0;
pPager->setMaster = 0;
pPager->journalHdr = 0;
@@ -33704,16 +33476,15 @@
** lock and reacquire the read lock. Purge the cache before
** playing back the hot-journal so that we don't end up with
** an inconsistent cache.
*/
- sqlite3PcacheClear(pPager->pPCache);
rc = pager_playback(pPager, 1);
if( rc!=SQLITE_OK ){
rc = pager_error(pPager, rc);
goto failed;
}
- assert(pPager->state==PAGER_SHARED ||
- (pPager->exclusiveMode && pPager->state>PAGER_SHARED)
+ assert( (pPager->state==PAGER_SHARED)
+ || (pPager->exclusiveMode && pPager->state>PAGER_SHARED)
);
}
if( sqlite3PcachePagecount(pPager->pPCache)>0 ){
@@ -33767,34 +33538,13 @@
return rc;
}
/*
-** Make sure we have the content for a page. If the page was
-** previously acquired with noContent==1, then the content was
-** just initialized to zeros instead of being read from disk.
-** But now we need the real data off of disk. So make sure we
-** have it. Read it in if we do not have it already.
-*/
-static int pager_get_content(PgHdr *pPg){
- if( pPg->flags&PGHDR_NEED_READ ){
- int rc = readDbPage(pPg->pPager, pPg, pPg->pgno);
- if( rc==SQLITE_OK ){
- pPg->flags &= ~PGHDR_NEED_READ;
- }else{
- return rc;
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** If the reference count has reached zero, and the pager is not in the
-** middle of a write transaction or opened in exclusive mode, unlock it.
+** If the reference count has reached zero, rollback any active
+** transaction and unlock the pager.
*/
static void pagerUnlockIfUnused(Pager *pPager){
- if( (sqlite3PcacheRefCount(pPager->pPCache)==0)
- && (!pPager->exclusiveMode || pPager->journalOff>0)
- ){
+ if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){
pagerUnlockAndRollback(pPager);
}
}
@@ -33810,18 +33560,50 @@
pagerUnlockIfUnused(pPager);
}
/*
-** Acquire a page.
-**
-** A read lock on the disk file is obtained when the first page is acquired.
-** This read lock is dropped when the last page is released.
-**
-** This routine works for any page number greater than 0. If the database
-** file is smaller than the requested page, then no actual disk
-** read occurs and the memory image of the page is initialized to
-** all zeros. The extra data appended to a page is always initialized
-** to zeros the first time a page is loaded into memory.
+** Acquire a reference to page number pgno in pager pPager (a page
+** reference has type DbPage*). If the requested reference is
+** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
+**
+** This function calls pagerSharedLock() to obtain a SHARED lock on
+** the database file if such a lock or greater is not already held.
+** This may cause hot-journal rollback or a cache purge. See comments
+** above function pagerSharedLock() for details.
+**
+** If the requested page is already in the cache, it is returned.
+** Otherwise, a new page object is allocated and populated with data
+** read from the database file. In some cases, the pcache module may
+** choose not to allocate a new page object and may reuse an existing
+** object with no outstanding references.
+**
+** The extra data appended to a page is always initialized to zeros the
+** first time a page is loaded into memory. If the page requested is
+** already in the cache when this function is called, then the extra
+** data is left as it was when the page object was last used.
+**
+** If the database image is smaller than the requested page or if a
+** non-zero value is passed as the noContent parameter and the
+** requested page is not already stored in the cache, then no
+** actual disk read occurs. In this case the memory image of the
+** page is initialized to all zeros.
+**
+** If noContent is true, it means that we do not care about the contents
+** of the page. This occurs in two seperate scenarios:
+**
+** a) When reading a free-list leaf page from the database, and
+**
+** b) When a savepoint is being rolled back and we need to load
+** a new page into the cache to populate with the data read
+** from the savepoint journal.
+**
+** If noContent is true, then the data returned is zeroed instead of
+** being read from the database. Additionally, the bits corresponding
+** to pgno in Pager.pInJournal (bitvec of pages already written to the
+** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open
+** savepoints are set. This means if the page is made writable at any
+** point in the future, using a call to sqlite3PagerWrite(), its contents
+** will not be journaled. This saves IO.
**
** The acquisition might fail for several reasons. In all cases,
** an appropriate error code is returned and *ppPage is set to NULL.
**
@@ -33831,17 +33613,8 @@
** just returns 0. This routine acquires a read-lock the first time it
** has to go to disk, and could also playback an old journal if necessary.
** Since Lookup() never goes to disk, it never has to deal with locks
** or journal files.
-**
-** If noContent is false, the page contents are actually read from disk.
-** If noContent is true, it means that we do not care about the contents
-** of the page at this time, so do not do a disk read. Just fill in the
-** page content with zeros. But mark the fact that we have not read the
-** content by setting the PgHdr.needRead flag. Later on, if
-** sqlite3PagerWrite() is called on this page or if this routine is
-** called again with noContent==0, that means that the content is needed
-** and the disk read should occur at that point.
*/
SQLITE_PRIVATE int sqlite3PagerAcquire(
Pager *pPager, /* The pager open on the database file */
Pgno pgno, /* Page number to fetch */
@@ -33850,8 +33623,9 @@
){
PgHdr *pPg = 0;
int rc;
+ assert( assert_pager_state(pPager) );
assert( pPager->state==PAGER_UNLOCK
|| sqlite3PcacheRefCount(pPager->pPCache)>0
|| pgno==1
);
@@ -33881,16 +33655,17 @@
rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, &pPg);
if( rc!=SQLITE_OK ){
return rc;
}
+ assert( pPg->pgno==pgno );
+ assert( pPg->pPager==pPager || pPg->pPager==0 );
if( pPg->pPager==0 ){
/* The pager cache has created a new page. Its content needs to
** be initialized.
*/
int nMax;
PAGER_INCR(pPager->nMiss);
pPg->pPager = pPager;
- memset(pPg->pExtra, 0, pPager->nExtra);
rc = sqlite3PagerPagecount(pPager, &nMax);
if( rc!=SQLITE_OK ){
sqlite3PagerUnref(pPg);
@@ -33901,17 +33676,31 @@
if( pgno>pPager->mxPgno ){
sqlite3PagerUnref(pPg);
return SQLITE_FULL;
}
- memset(pPg->pData, 0, pPager->pageSize);
if( noContent ){
- pPg->flags |= PGHDR_NEED_READ;
+ /* Failure to set the bits in the InJournal bit-vectors is benign.
+ ** It merely means that we might do some extra work to journal a
+ ** page that does not need to be journaled. Nevertheless, be sure
+ ** to test the case where a malloc error occurs while trying to set
+ ** a bit in a bit vector.
+ */
+ sqlite3BeginBenignMalloc();
+ if( pgno<=pPager->dbOrigSize ){
+ TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pgno);
+ testcase( rc==SQLITE_NOMEM );
+ }
+ TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno);
+ testcase( rc==SQLITE_NOMEM );
+ sqlite3EndBenignMalloc();
+ }else{
+ memset(pPg->pData, 0, pPager->pageSize);
}
IOTRACE(("ZERO %p %d\n", pPager, pgno));
}else{
- rc = readDbPage(pPager, pPg, pgno);
- if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
- /* sqlite3PagerUnref(pPg); */
+ assert( pPg->pPager==pPager );
+ rc = readDbPage(pPg);
+ if( rc!=SQLITE_OK ){
pagerDropPage(pPg);
return rc;
}
}
@@ -33919,17 +33708,9 @@
pPg->pageHash = pager_pagehash(pPg);
#endif
}else{
/* The requested page is in the page cache. */
- assert(sqlite3PcacheRefCount(pPager->pPCache)>0 || pgno==1);
- PAGER_INCR(pPager->nHit);
- if( !noContent ){
- rc = pager_get_content(pPg);
- if( rc ){
- sqlite3PagerUnref(pPg);
- return rc;
- }
- }
+ PAGER_INCR(pPager->nHit);
}
*ppPage = pPg;
return SQLITE_OK;
@@ -33937,9 +33718,11 @@
/*
** Acquire a page if it is already in the in-memory cache. Do
** not read the page from disk. Return a pointer to the page,
-** or 0 if the page is not in cache.
+** or 0 if the page is not in cache. Also, return 0 if the
+** pager is in PAGER_UNLOCK state when this function is called,
+** or if the pager is in an error state other than SQLITE_FULL.
**
** See also sqlite3PagerGet(). The difference between this routine
** and sqlite3PagerGet() is that _get() will go to the disk and read
** in the page if the page is not already in cache. This routine
@@ -33960,77 +33743,101 @@
return pPg;
}
/*
-** Release a page.
+** Release a page reference.
**
** If the number of references to the page drop to zero, then the
** page is added to the LRU list. When all references to all pages
** are released, a rollback occurs and the lock on the database is
** removed.
*/
-SQLITE_PRIVATE int sqlite3PagerUnref(DbPage *pPg){
+SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
if( pPg ){
Pager *pPager = pPg->pPager;
sqlite3PcacheRelease(pPg);
pagerUnlockIfUnused(pPager);
}
- return SQLITE_OK;
}
/*
** If the main journal file has already been opened, ensure that the
** sub-journal file is open too. If the main journal is not open,
** this function is a no-op.
**
-** SQLITE_OK is returned if everything goes according to plan. An
-** SQLITE_IOERR_XXX error code is returned if the call to
+** SQLITE_OK is returned if everything goes according to plan.
+** An SQLITE_IOERR_XXX error code is returned if a call to
** sqlite3OsOpen() fails.
*/
static int openSubJournal(Pager *pPager){
int rc = SQLITE_OK;
- if( pPager->journalOpen && !pPager->sjfd->pMethods ){
+ if( isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ){
if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
sqlite3MemJournalOpen(pPager->sjfd);
}else{
- rc = sqlite3PagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
- }
- }
- return rc;
-}
-
-/*
-** Create a journal file for pPager. There should already be a RESERVED
-** or EXCLUSIVE lock on the database file when this routine is called.
-**
-** Return SQLITE_OK if everything. Return an error code and release the
-** write lock if anything goes wrong.
+ rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
+ }
+ }
+ return rc;
+}
+
+/*
+** This function is called at the start of every write transaction.
+** There must already be a RESERVED or EXCLUSIVE lock on the database
+** file when this routine is called.
+**
+** Open the journal file for pager pPager and write a journal header
+** to the start of it. If there are active savepoints, open the sub-journal
+** as well. This function is only used when the journal file is being
+** opened to write a rollback log for a transaction. It is not used
+** when opening a hot journal file to roll it back.
+**
+** If the journal file is already open (as it may be in exclusive mode),
+** then this function just writes a journal header to the start of the
+** already open file.
+**
+** Whether or not the journal file is opened by this function, the
+** Pager.pInJournal bitvec structure is allocated.
+**
+** Return SQLITE_OK if everything is successful. Otherwise, return
+** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or
+** an IO error code if opening or writing the journal file fails.
*/
static int pager_open_journal(Pager *pPager){
- sqlite3_vfs *pVfs = pPager->pVfs;
- int flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_CREATE);
-
- int rc;
+ int rc = SQLITE_OK; /* Return code */
+ sqlite3_vfs * const pVfs = pPager->pVfs; /* Local cache of vfs pointer */
+
assert( pPager->state>=PAGER_RESERVED );
assert( pPager->useJournal );
assert( pPager->pInJournal==0 );
+
+ /* If already in the error state, this function is a no-op. */
+ if( pPager->errCode ){
+ return pPager->errCode;
+ }
+
+ /* TODO: Is it really possible to get here with dbSizeValid==0? If not,
+ ** the call to PagerPagecount() can be removed.
+ */
+ testcase( pPager->dbSizeValid==0 );
sqlite3PagerPagecount(pPager, 0);
+
pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
if( pPager->pInJournal==0 ){
- rc = SQLITE_NOMEM;
- goto failed_to_open_journal;
- }
-
- if( pPager->journalOpen==0 ){
- if( pPager->tempFile ){
- flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL);
- }else{
- flags |= (SQLITE_OPEN_MAIN_JOURNAL);
- }
+ return SQLITE_NOMEM;
+ }
+
+ /* Open the journal file if it is not already open. */
+ if( !isOpen(pPager->jfd) ){
if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
sqlite3MemJournalOpen(pPager->jfd);
- rc = SQLITE_OK;
- }else{
+ }else{
+ const int flags = /* VFS flags to open journal file */
+ SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
+ (pPager->tempFile ?
+ (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
+ (SQLITE_OPEN_MAIN_JOURNAL)
+ );
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
rc = sqlite3JournalOpen(
pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
);
@@ -34037,100 +33844,83 @@
#else
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
#endif
}
- assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
+ assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
+ }
+
+
+ /* Write the first journal header to the journal file and open
+ ** the sub-journal if necessary.
+ */
+ if( rc==SQLITE_OK ){
+ /* TODO: Check if all of these are really required. */
+ pPager->dbOrigSize = pPager->dbSize;
+ pPager->journalStarted = 0;
+ pPager->needSync = 0;
+ pPager->nRec = 0;
pPager->journalOff = 0;
pPager->setMaster = 0;
pPager->journalHdr = 0;
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_NOMEM ){
- sqlite3OsDelete(pVfs, pPager->zJournal, 0);
- }
- goto failed_to_open_journal;
- }
- }
- pPager->journalOpen = 1;
- pPager->journalStarted = 0;
- pPager->needSync = 0;
- pPager->nRec = 0;
- if( pPager->errCode ){
- rc = pPager->errCode;
- goto failed_to_open_journal;
- }
- pPager->dbOrigSize = pPager->dbSize;
-
- rc = writeJournalHdr(pPager);
-
- if( pPager->nSavepoint && rc==SQLITE_OK ){
+ rc = writeJournalHdr(pPager);
+ }
+ if( rc==SQLITE_OK && pPager->nSavepoint ){
rc = openSubJournal(pPager);
}
- if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && rc!=SQLITE_IOERR_NOMEM ){
- rc = pager_end_transaction(pPager, 0);
- if( rc==SQLITE_OK ){
- rc = SQLITE_FULL;
- }
- }
- return rc;
-
-failed_to_open_journal:
- sqlite3BitvecDestroy(pPager->pInJournal);
- pPager->pInJournal = 0;
- return rc;
-}
-
-/*
-** Acquire a write-lock on the database. The lock is removed when
-** the any of the following happen:
-**
-** * sqlite3PagerCommitPhaseTwo() is called.
-** * sqlite3PagerRollback() is called.
-** * sqlite3PagerClose() is called.
-** * sqlite3PagerUnref() is called to on every outstanding page.
-**
-** The first parameter to this routine is a pointer to any open page of the
-** database file. Nothing changes about the page - it is used merely to
-** acquire a pointer to the Pager structure and as proof that there is
-** already a read-lock on the database.
-**
-** The second parameter indicates how much space in bytes to reserve for a
-** master journal file-name at the start of the journal when it is created.
-**
-** A journal file is opened if this is not a temporary file. For temporary
-** files, the opening of the journal file is deferred until there is an
-** actual need to write to the journal.
-**
-** If the database is already reserved for writing, this routine is a no-op.
-**
-** If exFlag is true, go ahead and get an EXCLUSIVE lock on the file
-** immediately instead of waiting until we try to flush the cache. The
-** exFlag is ignored if a transaction is already active.
-*/
-SQLITE_PRIVATE int sqlite3PagerBegin(DbPage *pPg, int exFlag){
- Pager *pPager = pPg->pPager;
- int rc = SQLITE_OK;
- assert( pPg->nRef>0 );
+
+ if( rc!=SQLITE_OK ){
+ sqlite3BitvecDestroy(pPager->pInJournal);
+ pPager->pInJournal = 0;
+ }
+ return rc;
+}
+
+/*
+** Begin a write-transaction on the specified pager object. If a
+** write-transaction has already been opened, this function is a no-op.
+**
+** If the exFlag argument is false, then acquire at least a RESERVED
+** lock on the database file. If exFlag is true, then acquire at least
+** an EXCLUSIVE lock. If such a lock is already held, no locking
+** functions need be called.
+**
+** If this is not a temporary or in-memory file and, the journal file is
+** opened if it has not been already. For a temporary file, the opening
+** of the journal file is deferred until there is an actual need to
+** write to the journal. TODO: Why handle temporary files differently?
+**
+** If the journal file is opened (or if it is already open), then a
+** journal-header is written to the start of it.
+*/
+SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag){
+ int rc = SQLITE_OK;
assert( pPager->state!=PAGER_UNLOCK );
if( pPager->state==PAGER_SHARED ){
assert( pPager->pInJournal==0 );
- assert( !MEMDB );
+ assert( !MEMDB && !pPager->tempFile );
+
+ /* Obtain a RESERVED lock on the database file. If the exFlag parameter
+ ** is true, then immediately upgrade this to an EXCLUSIVE lock. The
+ ** busy-handler callback can be used when upgrading to the EXCLUSIVE
+ ** lock, but not when obtaining the RESERVED lock.
+ */
rc = sqlite3OsLock(pPager->fd, RESERVED_LOCK);
if( rc==SQLITE_OK ){
pPager->state = PAGER_RESERVED;
if( exFlag ){
rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
}
}
- if( rc!=SQLITE_OK ){
- return rc;
- }
- pPager->dirtyCache = 0;
- PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager)));
- if( pPager->useJournal && !pPager->tempFile
- && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
+
+ /* If the required locks were successfully obtained, open the journal
+ ** file and write the first journal-header to it.
+ */
+ if( rc==SQLITE_OK && pPager->useJournal
+ && pPager->journalMode!=PAGER_JOURNALMODE_OFF
+ ){
rc = pager_open_journal(pPager);
}
- }else if( pPager->journalOpen && pPager->journalOff==0 ){
+ }else if( isOpen(pPager->jfd) && pPager->journalOff==0 ){
/* This happens when the pager was in exclusive-access mode the last
** time a (read or write) transaction was successfully concluded
** by this connection. Instead of deleting the journal file it was
** kept open and either was truncated to 0 bytes or its header was
@@ -34138,37 +33928,22 @@
*/
assert( pPager->nRec==0 );
assert( pPager->dbOrigSize==0 );
assert( pPager->pInJournal==0 );
- sqlite3PagerPagecount(pPager, 0);
- pPager->pInJournal = sqlite3BitvecCreate( pPager->dbSize );
- if( !pPager->pInJournal ){
- rc = SQLITE_NOMEM;
- }else{
- pPager->dbOrigSize = pPager->dbSize;
- rc = writeJournalHdr(pPager);
- }
- }
- assert( !pPager->journalOpen || pPager->journalOff>0 || rc!=SQLITE_OK );
- return rc;
-}
-
-/*
-** Mark a data page as writeable. The page is written into the journal
-** if it is not there already. This routine must be called before making
-** changes to a page.
-**
-** The first time this routine is called, the pager creates a new
-** journal and acquires a RESERVED lock on the database. If the RESERVED
-** lock could not be acquired, this routine returns SQLITE_BUSY. The
-** calling routine must check for that return value and be careful not to
-** change any page data until this routine returns SQLITE_OK.
-**
-** If the journal file could not be written because the disk is full,
-** then this routine returns SQLITE_FULL and does an immediate rollback.
-** All subsequent write attempts also return SQLITE_FULL until there
-** is a call to sqlite3PagerCommit() or sqlite3PagerRollback() to
-** reset.
+ rc = pager_open_journal(pPager);
+ }
+
+ PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager)));
+ assert( !isOpen(pPager->jfd) || pPager->journalOff>0 || rc!=SQLITE_OK );
+ return rc;
+}
+
+/*
+** Mark a single data page as writeable. The page is written into the
+** main journal or sub-journal as required. If the page is written into
+** one of the journals, the corresponding bit is set in the
+** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs
+** of any open savepoints as appropriate.
*/
static int pager_write(PgHdr *pPg){
void *pData = pPg->pData;
Pager *pPager = pPg->pPager;
@@ -34186,27 +33961,13 @@
assert( !pPager->setMaster );
CHECK_PAGE(pPg);
- /* If this page was previously acquired with noContent==1, that means
- ** we didn't really read in the content of the page. This can happen
- ** (for example) when the page is being moved to the freelist. But
- ** now we are (perhaps) moving the page off of the freelist for
- ** reuse and we need to know its original content so that content
- ** can be stored in the rollback journal. So do the read at this
- ** time.
- */
- rc = pager_get_content(pPg);
- if( rc ){
- return rc;
- }
-
/* Mark the page as dirty. If the page has already been written
** to the journal then we can return right away.
*/
sqlite3PcacheMakeDirty(pPg);
if( pageInJournal(pPg) && !subjRequiresPage(pPg) ){
- pPager->dirtyCache = 1;
pPager->dbModified = 1;
}else{
/* If we get this far, it means that the page needs to be
@@ -34216,26 +33977,25 @@
** First check to see that the transaction journal exists and
** create it if it does not.
*/
assert( pPager->state!=PAGER_UNLOCK );
- rc = sqlite3PagerBegin(pPg, 0);
+ rc = sqlite3PagerBegin(pPager, 0);
if( rc!=SQLITE_OK ){
return rc;
}
assert( pPager->state>=PAGER_RESERVED );
- if( !pPager->journalOpen && pPager->useJournal
+ if( !isOpen(pPager->jfd) && pPager->useJournal
&& pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
rc = pager_open_journal(pPager);
if( rc!=SQLITE_OK ) return rc;
}
- pPager->dirtyCache = 1;
pPager->dbModified = 1;
/* The transaction journal now exists and we have a RESERVED or an
** EXCLUSIVE lock on the main database file. Write the current page to
** the transaction journal if it is not there already.
*/
- if( !pageInJournal(pPg) && pPager->journalOpen ){
+ if( !pageInJournal(pPg) && isOpen(pPager->jfd) ){
if( pPg->pgno<=pPager->dbOrigSize ){
u32 cksum;
char *pData2;
@@ -34273,9 +34033,9 @@
pPg->flags |= PGHDR_NEED_SYNC;
pPager->needSync = 1;
}
- /* An error has occured writing to the journal file. The
+ /* An error has occurred writing to the journal file. The
** transaction will be rolled back by the layer above.
*/
if( rc!=SQLITE_OK ){
return rc;
@@ -34316,24 +34076,25 @@
*/
assert( pPager->state>=PAGER_SHARED );
if( pPager->dbSize<pPg->pgno ){
pPager->dbSize = pPg->pgno;
- if( pPager->dbSize==(PAGER_MJ_PGNO(pPager)-1) ){
- pPager->dbSize++;
- }
- }
- return rc;
-}
-
-/*
-** This function is used to mark a data-page as writable. It uses
-** pager_write() to open a journal file (if it is not already open)
-** and write the page *pData to the journal.
+ }
+ return rc;
+}
+
+/*
+** Mark a data page as writeable. This routine must be called before
+** making changes to a page. The caller must check the return value
+** of this function and be careful not to change any page data unless
+** this routine returns SQLITE_OK.
**
** The difference between this function and pager_write() is that this
** function also deals with the special case where 2 or more pages
** fit on a single disk sector. In this case all co-resident pages
** must have been written to the journal file before returning.
+**
+** If an error occurs, SQLITE_NOMEM or an IO error code is returned
+** as appropriate. Otherwise, SQLITE_OK.
*/
SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
int rc = SQLITE_OK;
@@ -34344,10 +34105,10 @@
if( nPagePerSector>1 ){
Pgno nPageCount; /* Total number of pages in database file */
Pgno pg1; /* First page of the sector pPg is located on. */
int nPage; /* Number of pages starting at pg1 to journal */
- int ii;
- int needSync = 0;
+ int ii; /* Loop counter */
+ int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */
/* Set the doNotSync flag to 1. This is because we cannot allow a journal
** header to be written between the pages journaled by this function.
*/
@@ -34440,186 +34201,116 @@
** the page has been added as a leaf of the freelist and so its
** content no longer matters.
**
** The overlying software layer calls this routine when all of the data
-** on the given page is unused. The pager marks the page as clean so
+** on the given page is unused. The pager marks the page as clean so
** that it does not get written to disk.
**
-** Tests show that this optimization, together with the
-** sqlite3PagerDontRollback() below, more than double the speed
-** of large INSERT operations and quadruple the speed of large DELETEs.
-**
-** When this routine is called, set the bit corresponding to pDbPage in
-** the Pager.pAlwaysRollback bitvec. Subsequent calls to
-** sqlite3PagerDontRollback() for the same page will thereafter be ignored.
-** This is necessary to avoid a problem where a page with data is added to
-** the freelist during one part of a transaction then removed from the
-** freelist during a later part of the same transaction and reused for some
-** other purpose. When it is first added to the freelist, this routine is
-** called. When reused, the sqlite3PagerDontRollback() routine is called.
-** But because the page contains critical data, we still need to be sure it
-** gets rolled back in spite of the sqlite3PagerDontRollback() call.
-*/
-SQLITE_PRIVATE int sqlite3PagerDontWrite(DbPage *pDbPage){
- PgHdr *pPg = pDbPage;
+** Tests show that this optimization can quadruple the speed of large
+** DELETE operations.
+*/
+SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){
Pager *pPager = pPg->pPager;
- int rc;
-
- if( pPg->pgno>pPager->dbOrigSize ){
- return SQLITE_OK;
- }
- if( pPager->pAlwaysRollback==0 ){
- assert( pPager->pInJournal );
- pPager->pAlwaysRollback = sqlite3BitvecCreate(pPager->dbOrigSize);
- if( !pPager->pAlwaysRollback ){
- return SQLITE_NOMEM;
- }
- }
- rc = sqlite3BitvecSet(pPager->pAlwaysRollback, pPg->pgno);
-
- if( rc==SQLITE_OK && (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
- assert( pPager->state>=PAGER_SHARED );
- if( pPager->dbSize==pPg->pgno && pPager->dbOrigSize<pPager->dbSize ){
- /* If this pages is the last page in the file and the file has grown
- ** during the current transaction, then do NOT mark the page as clean.
- ** When the database file grows, we must make sure that the last page
- ** gets written at least once so that the disk file will be the correct
- ** size. If you do not write this page and the size of the file
- ** on the disk ends up being too small, that can lead to database
- ** corruption during the next transaction.
- */
- }else{
- PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
- IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
- pPg->flags |= PGHDR_DONT_WRITE;
+ if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
+ PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
+ IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
+ pPg->flags |= PGHDR_DONT_WRITE;
#ifdef SQLITE_CHECK_PAGES
- pPg->pageHash = pager_pagehash(pPg);
-#endif
- }
- }
- return rc;
-}
-
-/*
-** A call to this routine tells the pager that if a rollback occurs,
-** it is not necessary to restore the data on the given page. This
-** means that the pager does not have to record the given page in the
-** rollback journal.
-**
-** If we have not yet actually read the content of this page (if
-** the PgHdr.needRead flag is set) then this routine acts as a promise
-** that we will never need to read the page content in the future.
-** so the needRead flag can be cleared at this point.
-*/
-SQLITE_PRIVATE void sqlite3PagerDontRollback(DbPage *pPg){
- Pager *pPager = pPg->pPager;
- TESTONLY( int rc; ) /* Return value from sqlite3BitvecSet() */
+ pPg->pageHash = pager_pagehash(pPg);
+#endif
+ }
+}
+
+/*
+** This routine is called to increment the value of the database file
+** change-counter, stored as a 4-byte big-endian integer starting at
+** byte offset 24 of the pager file.
+**
+** If the isDirect flag is zero, then this is done by calling
+** sqlite3PagerWrite() on page 1, then modifying the contents of the
+** page data. In this case the file will be updated when the current
+** transaction is committed.
+**
+** The isDirect flag may only be non-zero if the library was compiled
+** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case,
+** if isDirect is non-zero, then the database file is updated directly
+** by writing an updated version of page 1 using a call to the
+** sqlite3OsWrite() function.
+*/
+static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
+ int rc = SQLITE_OK;
+
+ /* Declare and initialize constant integer 'isDirect'. If the
+ ** atomic-write optimization is enabled in this build, then isDirect
+ ** is initialized to the value passed as the isDirectMode parameter
+ ** to this function. Otherwise, it is always set to zero.
+ **
+ ** The idea is that if the atomic-write optimization is not
+ ** enabled at compile time, the compiler can omit the tests of
+ ** 'isDirect' below, as well as the block enclosed in the
+ ** "if( isDirect )" condition.
+ */
+#ifndef SQLITE_ENABLE_ATOMIC_WRITE
+ const int isDirect = 0;
+ assert( isDirectMode==0 );
+ UNUSED_PARAMETER(isDirectMode);
+#else
+ const int isDirect = isDirectMode;
+#endif
assert( pPager->state>=PAGER_RESERVED );
-
- /* If the journal file is not open, or DontWrite() has been called on
- ** this page (DontWrite() sets the Pager.pAlwaysRollback bit), then this
- ** function is a no-op.
- */
- if( pPager->journalOpen==0
- || sqlite3BitvecTest(pPager->pAlwaysRollback, pPg->pgno)
- || pPg->pgno>pPager->dbOrigSize
- ){
- return;
- }
-
-#ifdef SQLITE_SECURE_DELETE
- if( sqlite3BitvecTest(pPager->pInJournal, pPg->pgno)!=0
- || pPg->pgno>pPager->dbOrigSize ){
- return;
- }
-#endif
-
- /* If SECURE_DELETE is disabled, then there is no way that this
- ** routine can be called on a page for which sqlite3PagerDontWrite()
- ** has not been previously called during the same transaction.
- ** And if DontWrite() has previously been called, the following
- ** conditions must be met.
- **
- ** (Later:) Not true. If the database is corrupted by having duplicate
- ** pages on the freelist (ex: corrupt9.test) then the following is not
- ** necessarily true:
- */
- /* assert( !pPg->inJournal && (int)pPg->pgno <= pPager->dbOrigSize ); */
-
- assert( pPager->pInJournal!=0 );
- pPg->flags &= ~PGHDR_NEED_READ;
-
- /* Failure to set the bits in the InJournal bit-vectors is benign.
- ** It merely means that we might do some extra work to journal a page
- ** that does not need to be journaled. Nevertheless, be sure to test the
- ** case where a malloc error occurs while trying to set a bit in a
- ** bit vector.
- */
- sqlite3BeginBenignMalloc();
- TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
- testcase( rc==SQLITE_NOMEM );
- TESTONLY( rc = ) addToSavepointBitvecs(pPager, pPg->pgno);
- testcase( rc==SQLITE_NOMEM );
- sqlite3EndBenignMalloc();
-
-
- PAGERTRACE(("DONT_ROLLBACK page %d of %d\n", pPg->pgno, PAGERID(pPager)));
- IOTRACE(("GARBAGE %p %d\n", pPager, pPg->pgno))
-}
-
-
-/*
-** This routine is called to increment the database file change-counter,
-** stored at byte 24 of the pager file.
-*/
-static int pager_incr_changecounter(Pager *pPager, int isDirect){
- PgHdr *pPgHdr;
- u32 change_counter;
- int rc = SQLITE_OK;
-
-#ifndef SQLITE_ENABLE_ATOMIC_WRITE
- assert( isDirect==0 ); /* isDirect is only true for atomic writes */
-#endif
if( !pPager->changeCountDone && pPager->dbSize>0 ){
+ PgHdr *pPgHdr; /* Reference to page 1 */
+ u32 change_counter; /* Initial value of change-counter field */
+
+ assert( !pPager->tempFile && isOpen(pPager->fd) );
+
/* Open page 1 of the file for writing. */
rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
- if( rc!=SQLITE_OK ) return rc;
-
- if( !isDirect ){
+ assert( pPgHdr==0 || rc==SQLITE_OK );
+
+ /* If page one was fetched successfully, and this function is not
+ ** operating in direct-mode, make page 1 writable.
+ */
+ if( rc==SQLITE_OK && !isDirect ){
rc = sqlite3PagerWrite(pPgHdr);
- if( rc!=SQLITE_OK ){
- sqlite3PagerUnref(pPgHdr);
- return rc;
- }
- }
-
- /* Increment the value just read and write it back to byte 24. */
- change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers);
- change_counter++;
- put32bits(((char*)pPgHdr->pData)+24, change_counter);
-
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
- if( isDirect && pPager->fd->pMethods ){
- const void *zBuf = pPgHdr->pData;
- assert( pPager->dbFileSize>0 );
- rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
- }
-#endif
+ }
+
+ if( rc==SQLITE_OK ){
+ /* Increment the value just read and write it back to byte 24. */
+ change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers);
+ change_counter++;
+ put32bits(((char*)pPgHdr->pData)+24, change_counter);
+
+ /* If running in direct mode, write the contents of page 1 to the file. */
+ if( isDirect ){
+ const void *zBuf = pPgHdr->pData;
+ assert( pPager->dbFileSize>0 );
+ rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
+ }
+
+ /* If everything worked, set the changeCountDone flag. */
+ if( rc==SQLITE_OK ){
+ pPager->changeCountDone = 1;
+ }
+ }
/* Release the page reference. */
sqlite3PagerUnref(pPgHdr);
- pPager->changeCountDone = 1;
- }
- return rc;
-}
-
-/*
-** Sync the pager file to disk.
+ }
+ return rc;
+}
+
+/*
+** Sync the pager file to disk. This is a no-op for in-memory files
+** or pages with the Pager.noSync flag set.
+**
+** If successful, or called on a pager for which it is a no-op, this
+** function returns SQLITE_OK. Otherwise, an IO error code is returned.
*/
SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager){
- int rc;
- if( MEMDB ){
+ int rc; /* Return code */
+ if( MEMDB || pPager->noSync ){
rc = SQLITE_OK;
}else{
rc = sqlite3OsSync(pPager->fd, pPager->sync_flags);
}
@@ -34631,12 +34322,19 @@
** of a master journal file that should be written into the individual
** journal file. zMaster may be NULL, which is interpreted as no master
** journal (a single database transaction).
**
-** This routine ensures that the journal is synced, all dirty pages written
-** to the database file and the database file synced. The only thing that
-** remains to commit the transaction is to delete the journal file (or
-** master journal file if specified).
+** This routine ensures that:
+**
+** * The database file change-counter is updated,
+** * the journal is synced (unless the atomic-write optimization is used),
+** * all dirty pages are written to the database file,
+** * the database file is truncated (if required), and
+** * the database file synced.
+**
+** The only thing that remains to commit the transaction is to finalize
+** (delete, truncate or zero the first part of) the journal file (or
+** delete the master journal file if specified).
**
** Note that if zMaster==NULL, this does not overwrite a previous value
** passed to an sqlite3PagerCommitPhaseOne() call.
**
@@ -34645,25 +34343,16 @@
** sync the database file before calling CommitPhaseTwo() to delete the
** journal file in this case.
*/
SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
- Pager *pPager,
- const char *zMaster,
- int noSync
-){
- int rc = SQLITE_OK;
+ Pager *pPager, /* Pager object */
+ const char *zMaster, /* If not NULL, the master journal name */
+ int noSync /* True to omit the xSync on the db file */
+){
+ int rc = SQLITE_OK; /* Return code */
if( pPager->errCode ){
return pPager->errCode;
- }
-
- /* If no changes have been made, we can leave the transaction early.
- */
- if( pPager->dbModified==0 &&
- (pPager->journalMode!=PAGER_JOURNALMODE_DELETE ||
- pPager->exclusiveMode!=0) ){
- assert( pPager->dirtyCache==0 || pPager->journalOpen==0 );
- return SQLITE_OK;
}
PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n",
pPager->zFilename, zMaster, pPager->dbSize));
@@ -34670,117 +34359,126 @@
/* If this is an in-memory db, or no pages have been written to, or this
** function has already been called, it is a no-op.
*/
- if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){
- PgHdr *pPg;
-
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
- /* The atomic-write optimization can be used if all of the
- ** following are true:
- **
- ** + The file-system supports the atomic-write property for
+ if( MEMDB && pPager->dbModified ){
+ sqlite3BackupRestart(pPager->pBackup);
+ }else if( pPager->state!=PAGER_SYNCED && pPager->dbModified ){
+
+ /* The following block updates the change-counter. Exactly how it
+ ** does this depends on whether or not the atomic-update optimization
+ ** was enabled at compile time, and if this transaction meets the
+ ** runtime criteria to use the operation:
+ **
+ ** * The file-system supports the atomic-write property for
** blocks of size page-size, and
- ** + This commit is not part of a multi-file transaction, and
- ** + Exactly one page has been modified and store in the journal file.
- **
- ** If the optimization can be used, then the journal file will never
- ** be created for this transaction.
- */
- int useAtomicWrite;
- pPg = sqlite3PcacheDirtyList(pPager->pPCache);
- useAtomicWrite = (
- !zMaster &&
- pPager->journalOpen &&
- pPager->journalOff==jrnlBufferSize(pPager) &&
- pPager->dbSize>=pPager->dbFileSize &&
- (pPg==0 || pPg->pDirty==0)
- );
- assert( pPager->journalOpen || pPager->journalMode==PAGER_JOURNALMODE_OFF );
- if( useAtomicWrite ){
- /* Update the nRec field in the journal file. */
- int offset = pPager->journalHdr + sizeof(aJournalMagic);
- assert(pPager->nRec==1);
- rc = write32bits(pPager->jfd, offset, pPager->nRec);
-
- /* Update the db file change counter. The following call will modify
- ** the in-memory representation of page 1 to include the updated
- ** change counter and then write page 1 directly to the database
- ** file. Because of the atomic-write property of the host file-system,
- ** this is safe.
- */
- if( rc==SQLITE_OK ){
- rc = pager_incr_changecounter(pPager, 1);
- }
+ ** * This commit is not part of a multi-file transaction, and
+ ** * Exactly one page has been modified and store in the journal file.
+ **
+ ** If the optimization was not enabled at compile time, then the
+ ** pager_incr_changecounter() function is called to update the change
+ ** counter in 'indirect-mode'. If the optimization is compiled in but
+ ** is not applicable to this transaction, call sqlite3JournalCreate()
+ ** to make sure the journal file has actually been created, then call
+ ** pager_incr_changecounter() to update the change-counter in indirect
+ ** mode.
+ **
+ ** Otherwise, if the optimization is both enabled and applicable,
+ ** then call pager_incr_changecounter() to update the change-counter
+ ** in 'direct' mode. In this case the journal file will never be
+ ** created for this transaction.
+ */
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+ PgHdr *pPg;
+ assert( isOpen(pPager->jfd) || pPager->journalMode==PAGER_JOURNALMODE_OFF );
+ if( !zMaster && isOpen(pPager->jfd)
+ && pPager->journalOff==jrnlBufferSize(pPager)
+ && pPager->dbSize>=pPager->dbFileSize
+ && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
+ ){
+ /* Update the db file change counter via the direct-write method. The
+ ** following call will modify the in-memory representation of page 1
+ ** to include the updated change counter and then write page 1
+ ** directly to the database file. Because of the atomic-write
+ ** property of the host file-system, this is safe.
+ */
+ rc = pager_incr_changecounter(pPager, 1);
}else{
rc = sqlite3JournalCreate(pPager->jfd);
- }
-
- if( !useAtomicWrite && rc==SQLITE_OK )
-#endif
-
- /* If a master journal file name has already been written to the
- ** journal file, then no sync is required. This happens when it is
- ** written, then the process fails to upgrade from a RESERVED to an
- ** EXCLUSIVE lock. The next time the process tries to commit the
- ** transaction the m-j name will have already been written.
- */
- if( !pPager->setMaster ){
- rc = pager_incr_changecounter(pPager, 0);
- if( rc!=SQLITE_OK ) goto sync_exit;
- if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pPager->dbSize<pPager->dbOrigSize ){
- /* If this transaction has made the database smaller, then all pages
- ** being discarded by the truncation must be written to the journal
- ** file.
- */
- Pgno i;
- Pgno iSkip = PAGER_MJ_PGNO(pPager);
- Pgno dbSize = pPager->dbSize;
- pPager->dbSize = pPager->dbOrigSize;
- for( i=dbSize+1; i<=pPager->dbOrigSize; i++ ){
- if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
- rc = sqlite3PagerGet(pPager, i, &pPg);
- if( rc!=SQLITE_OK ) goto sync_exit;
- rc = sqlite3PagerWrite(pPg);
- sqlite3PagerUnref(pPg);
- if( rc!=SQLITE_OK ) goto sync_exit;
- }
- }
- pPager->dbSize = dbSize;
- }
-#endif
- rc = writeMasterJournal(pPager, zMaster);
- if( rc!=SQLITE_OK ) goto sync_exit;
- rc = syncJournal(pPager);
- }
- }
- if( rc!=SQLITE_OK ) goto sync_exit;
-
- /* Write all dirty pages to the database file */
- pPg = sqlite3PcacheDirtyList(pPager->pPCache);
- rc = pager_write_pagelist(pPg);
+ if( rc==SQLITE_OK ){
+ rc = pager_incr_changecounter(pPager, 0);
+ }
+ }
+#else
+ rc = pager_incr_changecounter(pPager, 0);
+#endif
+ if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+
+ /* If this transaction has made the database smaller, then all pages
+ ** being discarded by the truncation must be written to the journal
+ ** file. This can only happen in auto-vacuum mode.
+ **
+ ** Before reading the pages with page numbers larger than the
+ ** current value of Pager.dbSize, set dbSize back to the value
+ ** that it took at the start of the transaction. Otherwise, the
+ ** calls to sqlite3PagerGet() return zeroed pages instead of
+ ** reading data from the database file.
+ */
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pPager->dbSize<pPager->dbOrigSize
+ && pPager->journalMode!=PAGER_JOURNALMODE_OFF
+ ){
+ Pgno i; /* Iterator variable */
+ const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */
+ const Pgno dbSize = pPager->dbSize; /* Database image size */
+ pPager->dbSize = pPager->dbOrigSize;
+ for( i=dbSize+1; i<=pPager->dbOrigSize; i++ ){
+ if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
+ PgHdr *pPage; /* Page to journal */
+ rc = sqlite3PagerGet(pPager, i, &pPage);
+ if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+ rc = sqlite3PagerWrite(pPage);
+ sqlite3PagerUnref(pPage);
+ if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+ }
+ }
+ pPager->dbSize = dbSize;
+ }
+#endif
+
+ /* Write the master journal name into the journal file. If a master
+ ** journal file name has already been written to the journal file,
+ ** or if zMaster is NULL (no master journal), then this call is a no-op.
+ */
+ rc = writeMasterJournal(pPager, zMaster);
+ if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+
+ /* Sync the journal file. If the atomic-update optimization is being
+ ** used, this call will not create the journal file or perform any
+ ** real IO.
+ */
+ rc = syncJournal(pPager);
+ if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+
+ /* Write all dirty pages to the database file. */
+ rc = pager_write_pagelist(sqlite3PcacheDirtyList(pPager->pPCache));
if( rc!=SQLITE_OK ){
assert( rc!=SQLITE_IOERR_BLOCKED );
- /* The error might have left the dirty list all fouled up here,
- ** but that does not matter because if the if the dirty list did
- ** get corrupted, then the transaction will roll back and
- ** discard the dirty list. There is an assert in
- ** pager_get_all_dirty_pages() that verifies that no attempt
- ** is made to use an invalid dirty list.
- */
- goto sync_exit;
+ goto commit_phase_one_exit;
}
sqlite3PcacheCleanAll(pPager->pPCache);
- if( pPager->dbSize<pPager->dbFileSize ){
+ /* If the file on disk is not the same size as the database image,
+ ** then use pager_truncate to grow or shrink the file here.
+ */
+ if( pPager->dbSize!=pPager->dbFileSize ){
+ Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
assert( pPager->state>=PAGER_EXCLUSIVE );
- rc = pager_truncate(pPager, pPager->dbSize);
- if( rc!=SQLITE_OK ) goto sync_exit;
- }
-
- /* Sync the database file. */
+ rc = pager_truncate(pPager, nNew);
+ if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+ }
+
+ /* Finally, sync the database file. */
if( !pPager->noSync && !noSync ){
rc = sqlite3OsSync(pPager->fd, pPager->sync_flags);
}
IOTRACE(("DBSYNC %p\n", pPager))
@@ -34787,66 +34485,123 @@
pPager->state = PAGER_SYNCED;
}
-sync_exit:
+commit_phase_one_exit:
if( rc==SQLITE_IOERR_BLOCKED ){
/* pager_incr_changecounter() may attempt to obtain an exclusive
- * lock to spill the cache and return IOERR_BLOCKED. But since
- * there is no chance the cache is inconsistent, it is
- * better to return SQLITE_BUSY.
- */
+ ** lock to spill the cache and return IOERR_BLOCKED. But since
+ ** there is no chance the cache is inconsistent, it is
+ ** better to return SQLITE_BUSY.
+ **/
rc = SQLITE_BUSY;
}
return rc;
}
/*
-** Commit all changes to the database and release the write lock.
-**
-** If the commit fails for any reason, a rollback attempt is made
-** and an error code is returned. If the commit worked, SQLITE_OK
-** is returned.
+** When this function is called, the database file has been completely
+** updated to reflect the changes made by the current transaction and
+** synced to disk. The journal file still exists in the file-system
+** though, and if a failure occurs at this point it will eventually
+** be used as a hot-journal and the current transaction rolled back.
+**
+** This function finalizes the journal file, either by deleting,
+** truncating or partially zeroing it, so that it cannot be used
+** for hot-journal rollback. Once this is done the transaction is
+** irrevocably committed.
+**
+** If an error occurs, an IO error code is returned and the pager
+** moves into the error state. Otherwise, SQLITE_OK is returned.
*/
SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){
- int rc = SQLITE_OK;
-
+ int rc = SQLITE_OK; /* Return code */
+
+ /* Do not proceed if the pager is already in the error state. */
if( pPager->errCode ){
return pPager->errCode;
}
- if( pPager->state<PAGER_RESERVED ){
- return SQLITE_ERROR;
- }
- if( pPager->dbModified==0 &&
- (pPager->journalMode!=PAGER_JOURNALMODE_DELETE ||
- pPager->exclusiveMode!=0) ){
- assert( pPager->dirtyCache==0 || pPager->journalOpen==0 );
- return SQLITE_OK;
- }
+
+ /* This function should not be called if the pager is not in at least
+ ** PAGER_RESERVED state. And indeed SQLite never does this. But it is
+ ** nice to have this defensive block here anyway.
+ */
+ if( NEVER(pPager->state<PAGER_RESERVED) ){
+ return SQLITE_ERROR;
+ }
+
+ /* An optimization. If the database was not actually modified during
+ ** this transaction, the pager is running in exclusive-mode and is
+ ** using persistent journals, then this function is a no-op.
+ **
+ ** The start of the journal file currently contains a single journal
+ ** header with the nRec field set to 0. If such a journal is used as
+ ** a hot-journal during hot-journal rollback, 0 changes will be made
+ ** to the database file. So there is no need to zero the journal
+ ** header. Since the pager is in exclusive mode, there is no need
+ ** to drop any locks either.
+ */
+ if( pPager->dbModified==0 && pPager->exclusiveMode
+ && pPager->journalMode==PAGER_JOURNALMODE_PERSIST
+ ){
+ assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) );
+ return SQLITE_OK;
+ }
+
PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
- assert( pPager->state==PAGER_SYNCED || MEMDB || !pPager->dirtyCache );
+ assert( pPager->state==PAGER_SYNCED || MEMDB || !pPager->dbModified );
rc = pager_end_transaction(pPager, pPager->setMaster);
- rc = pager_error(pPager, rc);
- return rc;
-}
-
-/*
-** Rollback all changes. The database falls back to PAGER_SHARED mode.
-** All in-memory cache pages revert to their original data contents.
-** The journal is deleted.
-**
-** This routine cannot fail unless some other process is not following
-** the correct locking protocol or unless some other
-** process is writing trash into the journal file (SQLITE_CORRUPT) or
-** unless a prior malloc() failed (SQLITE_NOMEM). Appropriate error
-** codes are returned for all these occasions. Otherwise,
-** SQLITE_OK is returned.
+ return pager_error(pPager, rc);
+}
+
+/*
+** Rollback all changes. The database falls back to PAGER_SHARED mode.
+**
+** This function performs two tasks:
+**
+** 1) It rolls back the journal file, restoring all database file and
+** in-memory cache pages to the state they were in when the transaction
+** was opened, and
+** 2) It finalizes the journal file, so that it is not used for hot
+** rollback at any point in the future.
+**
+** subject to the following qualifications:
+**
+** * If the journal file is not yet open when this function is called,
+** then only (2) is performed. In this case there is no journal file
+** to roll back.
+**
+** * If in an error state other than SQLITE_FULL, then task (1) is
+** performed. If successful, task (2). Regardless of the outcome
+** of either, the error state error code is returned to the caller
+** (i.e. either SQLITE_IOERR or SQLITE_CORRUPT).
+**
+** * If the pager is in PAGER_RESERVED state, then attempt (1). Whether
+** or not (1) is succussful, also attempt (2). If successful, return
+** SQLITE_OK. Otherwise, enter the error state and return the first
+** error code encountered.
+**
+** In this case there is no chance that the database was written to.
+** So is safe to finalize the journal file even if the playback
+** (operation 1) failed. However the pager must enter the error state
+** as the contents of the in-memory cache are now suspect.
+**
+** * Finally, if in PAGER_EXCLUSIVE state, then attempt (1). Only
+** attempt (2) if (1) is successful. Return SQLITE_OK if successful,
+** otherwise enter the error state and return the error code from the
+** failing operation.
+**
+** In this case the database file may have been written to. So if the
+** playback operation did not succeed it would not be safe to finalize
+** the journal file. It needs to be left in the file-system so that
+** some other process can use it to restore the database state (by
+** hot-journal rollback).
*/
SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
- int rc = SQLITE_OK;
+ int rc = SQLITE_OK; /* Return code */
PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager)));
- if( !pPager->dirtyCache || !pPager->journalOpen ){
+ if( !pPager->dbModified || !isOpen(pPager->jfd) ){
rc = pager_end_transaction(pPager, pPager->setMaster);
}else if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
if( pPager->state>=PAGER_EXCLUSIVE ){
pager_playback(pPager, 0);
@@ -34917,26 +34672,38 @@
a[9] = pPager->nRead;
a[10] = pPager->nWrite;
return a;
}
+#endif
+
+/*
+** Return true if this is an in-memory pager.
+*/
SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
return MEMDB;
}
-#endif
-
-/*
-** Ensure that there are at least nSavepoint savepoints open.
+
+/*
+** Check that there are at least nSavepoint savepoints open. If there are
+** currently less than nSavepoints open, then open one or more savepoints
+** to make up the difference. If the number of savepoints is already
+** equal to nSavepoint, then this function is a no-op.
+**
+** If a memory allocation fails, SQLITE_NOMEM is returned. If an error
+** occurs while opening the sub-journal file, then an IO error code is
+** returned. Otherwise, SQLITE_OK.
*/
SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
- int rc = SQLITE_OK;
-
- if( nSavepoint>pPager->nSavepoint && pPager->useJournal ){
- int ii;
- PagerSavepoint *aNew;
+ int rc = SQLITE_OK; /* Return code */
+ int nCurrent = pPager->nSavepoint; /* Current number of savepoints */
+
+ if( nSavepoint>nCurrent && pPager->useJournal ){
+ int ii; /* Iterator variable */
+ PagerSavepoint *aNew; /* New Pager.aSavepoint array */
/* Either there is no active journal or the sub-journal is open or
** the journal is always stored in memory */
- assert( pPager->nSavepoint==0 || pPager->sjfd->pMethods ||
+ assert( pPager->nSavepoint==0 || isOpen(pPager->sjfd) ||
pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
/* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM
** if the allocation fails. Otherwise, zero the new portion in case a
@@ -34947,25 +34714,22 @@
);
if( !aNew ){
return SQLITE_NOMEM;
}
- memset(&aNew[pPager->nSavepoint], 0,
- (nSavepoint - pPager->nSavepoint) * sizeof(PagerSavepoint)
- );
- pPager->aSavepoint = aNew;
- ii = pPager->nSavepoint;
+ memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
+ pPager->aSavepoint = aNew;
pPager->nSavepoint = nSavepoint;
/* Populate the PagerSavepoint structures just allocated. */
- for(/* no-op */; ii<nSavepoint; ii++){
+ for(ii=nCurrent; ii<nSavepoint; ii++){
assert( pPager->dbSizeValid );
aNew[ii].nOrig = pPager->dbSize;
- if( pPager->journalOpen && pPager->journalOff>0 ){
+ if( isOpen(pPager->jfd) && pPager->journalOff>0 ){
aNew[ii].iOffset = pPager->journalOff;
}else{
aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager);
}
- aNew[ii].iSubRec = pPager->stmtNRec;
+ aNew[ii].iSubRec = pPager->nSubRec;
aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
if( !aNew[ii].pInSavepoint ){
return SQLITE_NOMEM;
}
@@ -34978,44 +34742,74 @@
return rc;
}
/*
+** This function is called to rollback or release (commit) a savepoint.
+** The savepoint to release or rollback need not be the most recently
+** created savepoint.
+**
** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE.
** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with
** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes
-** that have occured since savepoint iSavepoint was created.
-**
-** In either case, all savepoints with an index greater than iSavepoint
-** are destroyed.
-**
-** If there are less than (iSavepoint+1) active savepoints when this
-** function is called it is a no-op.
+** that have occurred since the specified savepoint was created.
+**
+** The savepoint to rollback or release is identified by parameter
+** iSavepoint. A value of 0 means to operate on the outermost savepoint
+** (the first created). A value of (Pager.nSavepoint-1) means operate
+** on the most recently created savepoint. If iSavepoint is greater than
+** (Pager.nSavepoint-1), then this function is a no-op.
+**
+** If a negative value is passed to this function, then the current
+** transaction is rolled back. This is different to calling
+** sqlite3PagerRollback() because this function does not terminate
+** the transaction or unlock the database, it just restores the
+** contents of the database to its original state.
+**
+** In any case, all savepoints with an index greater than iSavepoint
+** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE),
+** then savepoint iSavepoint is also destroyed.
+**
+** This function may return SQLITE_NOMEM if a memory allocation fails,
+** or an IO error code if an IO error occurs while rolling back a
+** savepoint. If no errors occur, SQLITE_OK is returned.
*/
SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
int rc = SQLITE_OK;
assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
+ assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
if( iSavepoint<pPager->nSavepoint ){
- int ii;
- int nNew = iSavepoint + (op==SAVEPOINT_ROLLBACK);
+ int ii; /* Iterator variable */
+ int nNew; /* Number of remaining savepoints after this op. */
+
+ /* Figure out how many savepoints will still be active after this
+ ** operation. Store this value in nNew. Then free resources associated
+ ** with any savepoints that are destroyed by this operation.
+ */
+ nNew = iSavepoint + (op==SAVEPOINT_ROLLBACK);
for(ii=nNew; ii<pPager->nSavepoint; ii++){
sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
}
pPager->nSavepoint = nNew;
- if( op==SAVEPOINT_ROLLBACK && pPager->jfd->pMethods ){
+ /* If this is a rollback operation, playback the specified savepoint.
+ ** If this is a temp-file, it is possible that the journal file has
+ ** not yet been opened. In this case there have been no changes to
+ ** the database file, so the playback operation can be skipped.
+ */
+ if( op==SAVEPOINT_ROLLBACK && isOpen(pPager->jfd) ){
PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1];
rc = pagerPlaybackSavepoint(pPager, pSavepoint);
assert(rc!=SQLITE_DONE);
}
/* If this is a release of the outermost savepoint, truncate
- ** the sub-journal. */
- if( nNew==0 && op==SAVEPOINT_RELEASE && pPager->sjfd->pMethods ){
+ ** the sub-journal to zero bytes in size. */
+ if( nNew==0 && op==SAVEPOINT_RELEASE && isOpen(pPager->sjfd) ){
assert( rc==SQLITE_OK );
rc = sqlite3OsTruncate(pPager->sjfd, 0);
- pPager->stmtNRec = 0;
+ pPager->nSubRec = 0;
}
}
return rc;
}
@@ -35040,15 +34834,8 @@
** not yet been opened.
*/
SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
return pPager->fd;
-}
-
-/*
-** Return the directory of the database file.
-*/
-SQLITE_PRIVATE const char *sqlite3PagerDirname(Pager *pPager){
- return pPager->zDirectory;
}
/*
** Return the full pathname of the journal file.
@@ -35100,13 +34887,17 @@
** If the fourth argument, isCommit, is non-zero, then this page is being
** moved as part of a database reorganization just before the transaction
** is being committed. In this case, it is guaranteed that the database page
** pPg refers to will not be written to again within this transaction.
+**
+** This function may return SQLITE_NOMEM or an IO error code if an error
+** occurs. Otherwise, it returns SQLITE_OK.
*/
SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
- PgHdr *pPgOld; /* The page being overwritten. */
- Pgno needSyncPgno = 0;
- int rc;
+ PgHdr *pPgOld; /* The page being overwritten. */
+ Pgno needSyncPgno = 0; /* Old value of pPg->pgno, if sync is required */
+ int rc; /* Return code */
+ Pgno origPgno; /* The original page number */
assert( pPg->nRef>0 );
/* If the page being moved is dirty and has not been saved by the latest
@@ -35120,9 +34911,13 @@
** ROLLBACK TO one;
**
** If page X were not written to the sub-journal here, it would not
** be possible to restore its contents when the "ROLLBACK TO one"
- ** statement were processed.
+ ** statement were is processed.
+ **
+ ** subjournalPage() may need to allocate space to store pPg->pgno into
+ ** one or more savepoint bitvecs. This is the reason this function
+ ** may return SQLITE_NOMEM.
*/
if( pPg->flags&PGHDR_DIRTY
&& subjRequiresPage(pPg)
&& SQLITE_OK!=(rc = subjournalPage(pPg))
@@ -35132,10 +34927,8 @@
PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n",
PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno));
IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno))
-
- pager_get_content(pPg);
/* If the journal needs to be sync()ed before page pPg->pgno can
** be written to, store pPg->pgno in local variable needSyncPgno.
**
@@ -35161,15 +34954,15 @@
if( pPgOld ){
pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
}
+ origPgno = pPg->pgno;
sqlite3PcacheMove(pPg, pgno);
if( pPgOld ){
sqlite3PcacheDrop(pPgOld);
}
sqlite3PcacheMakeDirty(pPg);
- pPager->dirtyCache = 1;
pPager->dbModified = 1;
if( needSyncPgno ){
/* If needSyncPgno is non-zero, then the journal file needs to be
@@ -35202,8 +34995,21 @@
assert( pPager->noSync==0 && !MEMDB );
pPgHdr->flags |= PGHDR_NEED_SYNC;
sqlite3PcacheMakeDirty(pPgHdr);
sqlite3PagerUnref(pPgHdr);
+ }
+
+ /*
+ ** For an in-memory database, make sure the original page continues
+ ** to exist, in case the transaction needs to roll back. We allocate
+ ** the page now, instead of at rollback, because we can better deal
+ ** with an out-of-memory error now. Ticket #3761.
+ */
+ if( MEMDB ){
+ DbPage *pNew;
+ rc = sqlite3PagerAcquire(pPager, origPgno, &pNew, 1);
+ if( rc!=SQLITE_OK ) return rc;
+ sqlite3PagerUnref(pNew);
}
return SQLITE_OK;
}
@@ -35255,14 +35061,14 @@
** PAGER_JOURNALMODE_DELETE
** PAGER_JOURNALMODE_TRUNCATE
** PAGER_JOURNALMODE_PERSIST
** PAGER_JOURNALMODE_OFF
+** PAGER_JOURNALMODE_MEMORY
**
** If the parameter is not _QUERY, then the journal-mode is set to the
** value specified.
**
-** The returned indicate the current (possibly updated)
-** journal-mode.
+** The returned indicate the current (possibly updated) journal-mode.
*/
SQLITE_PRIVATE int sqlite3PagerJournalMode(Pager *pPager, int eMode){
if( !MEMDB ){
assert( eMode==PAGER_JOURNALMODE_QUERY
@@ -35290,8 +35096,18 @@
}
return pPager->journalSizeLimit;
}
+/*
+** Return a pointer to the pPager->pBackup variable. The backup module
+** in backup.c maintains the content of this variable. This module
+** uses it opaquely as an argument to sqlite3BackupRestart() and
+** sqlite3BackupUpdate() only.
+*/
+SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
+ return &pPager->pBackup;
+}
+
#endif /* SQLITE_OMIT_DISKIO */
/************** End of pager.c ***********************************************/
/************** Begin file btmutex.c *****************************************/
@@ -35306,9 +35122,9 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
**
-** $Id: btmutex.c,v 1.12 2008/11/17 19:18:55 danielk1977 Exp $
+** $Id: btmutex.c,v 1.13 2009/03/05 04:20:32 shane Exp $
**
** This file contains code used to implement mutexes on Btree objects.
** This code really belongs in btree.c. But btree.c is getting too
** big and we want to break it down some. This packaged seemed like
@@ -35326,9 +35142,9 @@
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btreeInt.h,v 1.38 2008/12/27 15:23:13 danielk1977 Exp $
+** $Id: btreeInt.h,v 1.46 2009/03/20 14:18:52 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
@@ -35521,13 +35337,8 @@
** 4 Number of leaf pointers on this page
** * zero or more pages numbers of leaves
*/
-/* Round up a number to the next larger multiple of 8. This is used
-** to force 8-byte alignment on 64-bit architectures.
-*/
-#define ROUND8(x) ((x+7)&~7)
-
/* The following value is the maximum cell size assuming a maximum page
** size give above.
*/
@@ -35640,8 +35451,9 @@
u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
u8 sharable; /* True if we can share pBt with another db */
u8 locked; /* True if db currently has pBt locked */
int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
+ int nBackup; /* Number of backup operations reading this btree */
Btree *pNext; /* List of other sharable Btrees from the same db */
Btree *pPrev; /* Back pointer of the same list */
};
@@ -35671,15 +35483,32 @@
** global SQLITE_MUTEX_STATIC_MASTER mutex. The pPager field
** may not be modified once it is initially set as long as nRef>0.
** The pSchema field may be set once under BtShared.mutex and
** thereafter is unchanged as long as nRef>0.
+**
+** isPending:
+**
+** If a BtShared client fails to obtain a write-lock on a database
+** table (because there exists one or more read-locks on the table),
+** the shared-cache enters 'pending-lock' state and isPending is
+** set to true.
+**
+** The shared-cache leaves the 'pending lock' state when either of
+** the following occur:
+**
+** 1) The current writer (BtShared.pWriter) concludes its transaction, OR
+** 2) The number of locks held by other connections drops to zero.
+**
+** while in the 'pending-lock' state, no connection may start a new
+** transaction.
+**
+** This feature is included to help prevent writer-starvation.
*/
struct BtShared {
Pager *pPager; /* The page cache */
sqlite3 *db; /* Database connection currently using this Btree */
BtCursor *pCursor; /* A list of all open cursors */
MemPage *pPage1; /* First page of the database */
- u8 inStmt; /* True if we are in a statement subtransaction */
u8 readOnly; /* True if the underlying file is readonly */
u8 pageSizeFixed; /* True if the page size can no longer be changed */
#ifndef SQLITE_OMIT_AUTOVACUUM
u8 autoVacuum; /* True if auto-vacuum is enabled */
@@ -35695,13 +35524,16 @@
int nTransaction; /* Number of open transactions (read + write) */
void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */
void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */
sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */
+ Bitvec *pHasContent; /* Set of pages moved to free-list this transaction */
#ifndef SQLITE_OMIT_SHARED_CACHE
int nRef; /* Number of references to this structure */
BtShared *pNext; /* Next on a list of sharable BtShared structs */
BtLock *pLock; /* List of locks held on this shared-btree struct */
- Btree *pExclusive; /* Btree with an EXCLUSIVE lock on the whole db */
+ Btree *pWriter; /* Btree with currently open write transaction */
+ u8 isExclusive; /* True if pWriter has an EXCLUSIVE lock on the db */
+ u8 isPending; /* If waiting for read-locks to clear */
#endif
u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */
};
@@ -35752,8 +35584,9 @@
BtShared *pBt; /* The BtShared this cursor points to */
BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */
struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
Pgno pgnoRoot; /* The root page of this tree */
+ sqlite3_int64 cachedRowid; /* Next rowid cache. 0 means not valid */
CellInfo info; /* A parse of the cell we are pointing at */
u8 wrFlag; /* True if writable */
u8 atLast; /* Cursor pointing to the last entry */
u8 validNKey; /* True if info.nKey is valid */
@@ -35802,20 +35635,12 @@
#define CURSOR_VALID 1
#define CURSOR_REQUIRESEEK 2
#define CURSOR_FAULT 3
-/* The database page the PENDING_BYTE occupies. This page is never used.
-** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They
-** should possibly be consolidated (presumably in pager.h).
-**
-** If disk I/O is omitted (meaning that the database is stored purely
-** in memory) then there is no pending byte.
-*/
-#ifdef SQLITE_OMIT_DISKIO
-# define PENDING_BYTE_PAGE(pBt) 0x7fffffff
-#else
-# define PENDING_BYTE_PAGE(pBt) ((Pgno)((PENDING_BYTE/(pBt)->pageSize)+1))
-#endif
+/*
+** The database page the PENDING_BYTE occupies. This page is never used.
+*/
+# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
/*
** A linked list of the following structures is stored at BtShared.pLock.
** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor
@@ -36044,9 +35869,9 @@
#ifndef NDEBUG
/*
** Return true if the BtShared mutex is held on the btree.
**
-** This routine makes no determination one why or another if the
+** This routine makes no determination one way or another if the
** database connection mutex is held.
**
** This routine is used only from within assert() statements.
*/
@@ -36258,9 +36083,9 @@
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.558 2009/01/10 16:15:21 drh Exp $
+** $Id: btree.c,v 1.582 2009/03/30 18:50:05 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
@@ -36290,8 +36115,10 @@
** A list of BtShared objects that are eligible for participation
** in shared cache. This variable has file scope during normal builds,
** but the test harness needs to access it so we make it global for
** test builds.
+**
+** Access to this variable is protected by SQLITE_MUTEX_STATIC_MASTER.
*/
#ifdef SQLITE_TEST
SQLITE_PRIVATE BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
#else
@@ -36316,33 +36143,34 @@
/*
** Forward declaration
*/
-static int checkReadLocks(Btree*, Pgno, BtCursor*, i64);
+static int checkForReadConflicts(Btree*, Pgno, BtCursor*, i64);
#ifdef SQLITE_OMIT_SHARED_CACHE
/*
- ** The functions queryTableLock(), lockTable() and unlockAllTables()
+ ** The functions querySharedCacheTableLock(), setSharedCacheTableLock(),
+ ** and clearAllSharedCacheTableLocks()
** manipulate entries in the BtShared.pLock linked list used to store
** shared-cache table level locks. If the library is compiled with the
** shared-cache feature disabled, then there is only ever one user
** of each BtShared structure and so this locking is not necessary.
** So define the lock related functions as no-ops.
*/
- #define queryTableLock(a,b,c) SQLITE_OK
- #define lockTable(a,b,c) SQLITE_OK
- #define unlockAllTables(a)
+ #define querySharedCacheTableLock(a,b,c) SQLITE_OK
+ #define setSharedCacheTableLock(a,b,c) SQLITE_OK
+ #define clearAllSharedCacheTableLocks(a)
#endif
#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** Query to see if btree handle p may obtain a lock of type eLock
** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
-** SQLITE_OK if the lock may be obtained (by calling lockTable()), or
-** SQLITE_LOCKED if not.
-*/
-static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){
+** SQLITE_OK if the lock may be obtained (by calling
+** setSharedCacheTableLock()), or SQLITE_LOCKED if not.
+*/
+static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){
BtShared *pBt = p->pBt;
BtLock *pIter;
assert( sqlite3BtreeHoldsMutex(p) );
@@ -36356,25 +36184,28 @@
/* If some other connection is holding an exclusive lock, the
** requested lock may not be obtained.
*/
- if( pBt->pExclusive && pBt->pExclusive!=p ){
- return SQLITE_LOCKED;
- }
-
- /* This (along with lockTable()) is where the ReadUncommitted flag is
- ** dealt with. If the caller is querying for a read-lock and the flag is
- ** set, it is unconditionally granted - even if there are write-locks
+ if( pBt->pWriter!=p && pBt->isExclusive ){
+ sqlite3ConnectionBlocked(p->db, pBt->pWriter->db);
+ return SQLITE_LOCKED_SHAREDCACHE;
+ }
+
+ /* This (along with setSharedCacheTableLock()) is where
+ ** the ReadUncommitted flag is dealt with.
+ ** If the caller is querying for a read-lock on any table
+ ** other than the sqlite_master table (table 1) and if the ReadUncommitted
+ ** flag is set, then the lock granted even if there are write-locks
** on the table. If a write-lock is requested, the ReadUncommitted flag
** is not considered.
**
- ** In function lockTable(), if a read-lock is demanded and the
+ ** In function setSharedCacheTableLock(), if a read-lock is demanded and the
** ReadUncommitted flag is set, no entry is added to the locks list
** (BtShared.pLock).
**
- ** To summarize: If the ReadUncommitted flag is set, then read cursors do
- ** not create or respect table locks. The locking procedure for a
- ** write-cursor does not change.
+ ** To summarize: If the ReadUncommitted flag is set, then read cursors
+ ** on non-schema tables do not create or respect table locks. The locking
+ ** procedure for a write-cursor does not change.
*/
if(
0==(p->db->flags&SQLITE_ReadUncommitted) ||
eLock==WRITE_LOCK ||
@@ -36382,9 +36213,14 @@
){
for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
if( pIter->pBtree!=p && pIter->iTable==iTab &&
(pIter->eLock!=eLock || eLock!=READ_LOCK) ){
- return SQLITE_LOCKED;
+ sqlite3ConnectionBlocked(p->db, pIter->pBtree->db);
+ if( eLock==WRITE_LOCK ){
+ assert( p==pBt->pWriter );
+ pBt->isPending = 1;
+ }
+ return SQLITE_LOCKED_SHAREDCACHE;
}
}
}
return SQLITE_OK;
@@ -36399,9 +36235,9 @@
**
** SQLITE_OK is returned if the lock is added successfully. SQLITE_BUSY and
** SQLITE_NOMEM may also be returned.
*/
-static int lockTable(Btree *p, Pgno iTable, u8 eLock){
+static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
BtShared *pBt = p->pBt;
BtLock *pLock = 0;
BtLock *pIter;
@@ -36413,14 +36249,15 @@
if( !p->sharable ){
return SQLITE_OK;
}
- assert( SQLITE_OK==queryTableLock(p, iTable, eLock) );
-
- /* If the read-uncommitted flag is set and a read-lock is requested,
- ** return early without adding an entry to the BtShared.pLock list. See
- ** comment in function queryTableLock() for more info on handling
- ** the ReadUncommitted flag.
+ assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) );
+
+ /* If the read-uncommitted flag is set and a read-lock is requested on
+ ** a non-schema table, then the lock is always granted. Return early
+ ** without adding an entry to the BtShared.pLock list. See
+ ** comment in function querySharedCacheTableLock() for more info
+ ** on handling the ReadUncommitted flag.
*/
if(
(p->db->flags&SQLITE_ReadUncommitted) &&
(eLock==READ_LOCK) &&
@@ -36465,12 +36302,12 @@
#endif /* !SQLITE_OMIT_SHARED_CACHE */
#ifndef SQLITE_OMIT_SHARED_CACHE
/*
-** Release all the table locks (locks obtained via calls to the lockTable()
-** procedure) held by Btree handle p.
-*/
-static void unlockAllTables(Btree *p){
+** Release all the table locks (locks obtained via calls to
+** the setSharedCacheTableLock() procedure) held by Btree handle p.
+*/
+static void clearAllSharedCacheTableLocks(Btree *p){
BtShared *pBt = p->pBt;
BtLock **ppIter = &pBt->pLock;
assert( sqlite3BtreeHoldsMutex(p) );
@@ -36477,9 +36314,9 @@
assert( p->sharable || 0==*ppIter );
while( *ppIter ){
BtLock *pLock = *ppIter;
- assert( pBt->pExclusive==0 || pBt->pExclusive==pLock->pBtree );
+ assert( pBt->isExclusive==0 || pBt->pWriter==pLock->pBtree );
if( pLock->pBtree==p ){
*ppIter = pLock->pNext;
sqlite3_free(pLock);
}else{
@@ -36486,10 +36323,24 @@
ppIter = &pLock->pNext;
}
}
- if( pBt->pExclusive==p ){
- pBt->pExclusive = 0;
+ assert( pBt->isPending==0 || pBt->pWriter );
+ if( pBt->pWriter==p ){
+ pBt->pWriter = 0;
+ pBt->isExclusive = 0;
+ pBt->isPending = 0;
+ }else if( pBt->nTransaction==2 ){
+ /* This function is called when connection p is concluding its
+ ** transaction. If there currently exists a writer, and p is not
+ ** that writer, then the number of locks held by connections other
+ ** than the writer must be about to drop to zero. In this case
+ ** set the isPending flag to 0.
+ **
+ ** If there is not currently a writer, then BtShared.isPending must
+ ** be zero already. So this next line is harmless in that case.
+ */
+ pBt->isPending = 0;
}
}
#endif /* SQLITE_OMIT_SHARED_CACHE */
@@ -36529,8 +36380,82 @@
#else
#define invalidateOverflowCache(x)
#define invalidateAllOverflowCache(x)
#endif
+
+/*
+** Set bit pgno of the BtShared.pHasContent bitvec. This is called
+** when a page that previously contained data becomes a free-list leaf
+** page.
+**
+** The BtShared.pHasContent bitvec exists to work around an obscure
+** bug caused by the interaction of two useful IO optimizations surrounding
+** free-list leaf pages:
+**
+** 1) When all data is deleted from a page and the page becomes
+** a free-list leaf page, the page is not written to the database
+** (as free-list leaf pages contain no meaningful data). Sometimes
+** such a page is not even journalled (as it will not be modified,
+** why bother journalling it?).
+**
+** 2) When a free-list leaf page is reused, its content is not read
+** from the database or written to the journal file (why should it
+** be, if it is not at all meaningful?).
+**
+** By themselves, these optimizations work fine and provide a handy
+** performance boost to bulk delete or insert operations. However, if
+** a page is moved to the free-list and then reused within the same
+** transaction, a problem comes up. If the page is not journalled when
+** it is moved to the free-list and it is also not journalled when it
+** is extracted from the free-list and reused, then the original data
+** may be lost. In the event of a rollback, it may not be possible
+** to restore the database to its original configuration.
+**
+** The solution is the BtShared.pHasContent bitvec. Whenever a page is
+** moved to become a free-list leaf page, the corresponding bit is
+** set in the bitvec. Whenever a leaf page is extracted from the free-list,
+** optimization 2 above is ommitted if the corresponding bit is already
+** set in BtShared.pHasContent. The contents of the bitvec are cleared
+** at the end of every transaction.
+*/
+static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
+ int rc = SQLITE_OK;
+ if( !pBt->pHasContent ){
+ int nPage;
+ rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
+ if( rc==SQLITE_OK ){
+ pBt->pHasContent = sqlite3BitvecCreate((u32)nPage);
+ if( !pBt->pHasContent ){
+ rc = SQLITE_NOMEM;
+ }
+ }
+ }
+ if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){
+ rc = sqlite3BitvecSet(pBt->pHasContent, pgno);
+ }
+ return rc;
+}
+
+/*
+** Query the BtShared.pHasContent vector.
+**
+** This function is called when a free-list leaf page is removed from the
+** free-list for reuse. It returns false if it is safe to retrieve the
+** page from the pager layer with the 'no-content' flag set. True otherwise.
+*/
+static int btreeGetHasContent(BtShared *pBt, Pgno pgno){
+ Bitvec *p = pBt->pHasContent;
+ return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno)));
+}
+
+/*
+** Clear (destroy) the BtShared.pHasContent bitvec. This should be
+** invoked at the conclusion of each write-transaction.
+*/
+static void btreeClearHasContent(BtShared *pBt){
+ sqlite3BitvecDestroy(pBt->pHasContent);
+ pBt->pHasContent = 0;
+}
/*
** Save the current cursor position in the variables BtCursor.nKey
** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
@@ -37004,9 +36929,9 @@
** space. This routine will never fail.
**
** If the page contains nBytes of free space but does not contain
** nBytes of contiguous free space, then this routine automatically
-** calls defragementPage() to consolidate all free space before
+** calls defragmentPage() to consolidate all free space before
** allocating the new chunk.
*/
static int allocateSpace(MemPage *pPage, int nByte){
int addr, pc, hdr;
@@ -37349,8 +37274,23 @@
return SQLITE_OK;
}
/*
+** Retrieve a page from the pager cache. If the requested page is not
+** already in the pager cache return NULL. Initialize the MemPage.pBt and
+** MemPage.aData elements if needed.
+*/
+static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){
+ DbPage *pDbPage;
+ assert( sqlite3_mutex_held(pBt->mutex) );
+ pDbPage = sqlite3PagerLookup(pBt->pPager, pgno);
+ if( pDbPage ){
+ return btreePageFromDbPage(pDbPage, pgno, pBt);
+ }
+ return 0;
+}
+
+/*
** Return the size of the database file in pages. If there is any kind of
** error, return ((unsigned int)-1).
*/
static Pgno pagerPagecount(BtShared *pBt){
@@ -37372,9 +37312,8 @@
Pgno pgno, /* Number of the page to get */
MemPage **ppPage /* Write the page pointer here */
){
int rc;
- DbPage *pDbPage;
MemPage *pPage;
assert( sqlite3_mutex_held(pBt->mutex) );
if( pgno==0 ){
@@ -37385,12 +37324,11 @@
** If so, get it directly. This saves us from having to call
** pagerPagecount() to make sure pgno is within limits, which results
** in a measureable performance improvements.
*/
- pDbPage = sqlite3PagerLookup(pBt->pPager, pgno);
- if( pDbPage ){
- /* Page is already in cache */
- *ppPage = pPage = btreePageFromDbPage(pDbPage, pgno, pBt);
+ *ppPage = pPage = btreePageLookup(pBt, pgno);
+ if( pPage ){
+ /* Page is already in cache */
rc = SQLITE_OK;
}else{
/* Page not in cache. Acquire it. */
if( pgno>pagerPagecount(pBt) ){
@@ -37440,8 +37378,14 @@
if( pPage->isInit ){
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
pPage->isInit = 0;
if( sqlite3PagerPageRefcount(pData)>0 ){
+ /* pPage might not be a btree page; it might be an overflow page
+ ** or ptrmap page or a free page. In those cases, the following
+ ** call to sqlite3BtreeInitPage() will likely return SQLITE_CORRUPT.
+ ** But no harm is done by this. And it is very important that
+ ** sqlite3BtreeInitPage() be called on every btree page so we make
+ ** the call for every page that comes in for re-initing. */
sqlite3BtreeInitPage(pPage);
}
}
}
@@ -37471,14 +37415,15 @@
Btree **ppBtree, /* Pointer to new Btree object written here */
int flags, /* Options */
int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */
){
- sqlite3_vfs *pVfs; /* The VFS to use for this btree */
- BtShared *pBt = 0; /* Shared part of btree structure */
- Btree *p; /* Handle to return */
- int rc = SQLITE_OK;
- u8 nReserve;
- unsigned char zDbHeader[100];
+ sqlite3_vfs *pVfs; /* The VFS to use for this btree */
+ BtShared *pBt = 0; /* Shared part of btree structure */
+ Btree *p; /* Handle to return */
+ sqlite3_mutex *mutexOpen = 0; /* Prevents a race condition. Ticket #3537 */
+ int rc = SQLITE_OK; /* Result code from this function */
+ u8 nReserve; /* Byte of unused space on each page */
+ unsigned char zDbHeader[100]; /* Database header content */
/* Set the variable isMemdb to true for an in-memory database, or
** false for a file-based database. This symbol is only required if
** either of the shared-data or autovacuum features are compiled
@@ -37522,8 +37467,10 @@
sqlite3_free(p);
return SQLITE_NOMEM;
}
sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
+ mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
+ sqlite3_mutex_enter(mutexOpen);
mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
sqlite3_mutex_enter(mutexShared);
for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
assert( pBt->nRef>0 );
@@ -37674,8 +37621,12 @@
}
sqlite3_free(pBt);
sqlite3_free(p);
*ppBtree = 0;
+ }
+ if( mutexOpen ){
+ assert( sqlite3_mutex_held(mutexOpen) );
+ sqlite3_mutex_leave(mutexOpen);
}
return rc;
}
@@ -37901,8 +37852,14 @@
*/
SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){
return p->pBt->pageSize;
}
+
+/*
+** Return the number of bytes of space at the end of every page that
+** are intentually left unused. This is the "reserved" space that is
+** sometimes used by extensions.
+*/
SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree *p){
int n;
sqlite3BtreeEnter(p);
n = p->pBt->pageSize - p->pBt->usableSize;
@@ -37935,15 +37892,16 @@
return SQLITE_READONLY;
#else
BtShared *pBt = p->pBt;
int rc = SQLITE_OK;
- u8 av = autoVacuum ?1:0;
-
- sqlite3BtreeEnter(p);
- if( pBt->pageSizeFixed && av!=pBt->autoVacuum ){
+ u8 av = (u8)autoVacuum;
+
+ sqlite3BtreeEnter(p);
+ if( pBt->pageSizeFixed && (av ?1:0)!=pBt->autoVacuum ){
rc = SQLITE_READONLY;
}else{
- pBt->autoVacuum = av;
+ pBt->autoVacuum = av ?1:0;
+ pBt->incrVacuum = av==2 ?1:0;
}
sqlite3BtreeLeave(p);
return rc;
#endif
@@ -38126,9 +38084,8 @@
#endif
releasePage(pBt->pPage1);
}
pBt->pPage1 = 0;
- pBt->inStmt = 0;
}
}
/*
@@ -38208,8 +38165,9 @@
** when A already has a read lock, we encourage A to give up and let B
** proceed.
*/
SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
+ sqlite3 *pBlock = 0;
BtShared *pBt = p->pBt;
int rc = SQLITE_OK;
sqlite3BtreeEnter(p);
@@ -38229,26 +38187,28 @@
rc = SQLITE_READONLY;
goto trans_begun;
}
+#ifndef SQLITE_OMIT_SHARED_CACHE
/* If another database handle has already opened a write transaction
** on this shared-btree structure and a second write transaction is
- ** requested, return SQLITE_BUSY.
- */
- if( pBt->inTransaction==TRANS_WRITE && wrflag ){
- rc = SQLITE_BUSY;
- goto trans_begun;
- }
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
- if( wrflag>1 ){
+ ** requested, return SQLITE_LOCKED.
+ */
+ if( (wrflag && pBt->inTransaction==TRANS_WRITE) || pBt->isPending ){
+ pBlock = pBt->pWriter->db;
+ }else if( wrflag>1 ){
BtLock *pIter;
for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
if( pIter->pBtree!=p ){
- rc = SQLITE_BUSY;
- goto trans_begun;
- }
- }
+ pBlock = pIter->pBtree->db;
+ break;
+ }
+ }
+ }
+ if( pBlock ){
+ sqlite3ConnectionBlocked(p->db, pBlock);
+ rc = SQLITE_LOCKED_SHAREDCACHE;
+ goto trans_begun;
}
#endif
do {
@@ -38261,18 +38221,16 @@
if( rc==SQLITE_OK && wrflag ){
if( pBt->readOnly ){
rc = SQLITE_READONLY;
}else{
- rc = sqlite3PagerBegin(pBt->pPage1->pDbPage, wrflag>1);
+ rc = sqlite3PagerBegin(pBt->pPager, wrflag>1);
if( rc==SQLITE_OK ){
rc = newDatabase(pBt);
}
}
}
- if( rc==SQLITE_OK ){
- if( wrflag ) pBt->inStmt = 0;
- }else{
+ if( rc!=SQLITE_OK ){
unlockBtreeIfUnused(pBt);
}
}while( rc==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
btreeInvokeBusyHandler(pBt) );
@@ -38285,11 +38243,12 @@
if( p->inTrans>pBt->inTransaction ){
pBt->inTransaction = p->inTrans;
}
#ifndef SQLITE_OMIT_SHARED_CACHE
- if( wrflag>1 ){
- assert( !pBt->pExclusive );
- pBt->pExclusive = p;
+ if( wrflag ){
+ assert( !pBt->pWriter );
+ pBt->pWriter = p;
+ pBt->isExclusive = (u8)(wrflag>1);
}
#endif
}
@@ -38594,8 +38553,20 @@
if( nFin==0 ){
iLastPg--;
while( iLastPg==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, iLastPg) ){
+ if( PTRMAP_ISPAGE(pBt, iLastPg) ){
+ MemPage *pPg;
+ int rc = sqlite3BtreeGetPage(pBt, iLastPg, &pPg, 0);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ rc = sqlite3PagerWrite(pPg->pDbPage);
+ releasePage(pPg);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ }
iLastPg--;
}
sqlite3PagerTruncateImage(pBt->pPager, iLastPg);
}
@@ -38606,9 +38577,9 @@
** A write-transaction must be opened before calling this function.
** It performs a single unit of work towards an incremental vacuum.
**
** If the incremental vacuum is finished after this function has run,
-** SQLITE_DONE is returned. If it is not finished, but no error occured,
+** SQLITE_DONE is returned. If it is not finished, but no error occurred,
** SQLITE_OK is returned. Otherwise an SQLite error code.
*/
SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){
int rc;
@@ -38620,9 +38591,9 @@
if( !pBt->autoVacuum ){
rc = SQLITE_DONE;
}else{
invalidateAllOverflowCache(pBt);
- rc = incrVacuumStep(pBt, 0, sqlite3PagerImageSize(pBt->pPager));
+ rc = incrVacuumStep(pBt, 0, pagerPagecount(pBt));
}
sqlite3BtreeLeave(p);
return rc;
}
@@ -38769,11 +38740,10 @@
sqlite3BtreeLeave(p);
return rc;
}
pBt->inTransaction = TRANS_READ;
- pBt->inStmt = 0;
- }
- unlockAllTables(p);
+ }
+ clearAllSharedCacheTableLocks(p);
/* If the handle has any kind of transaction open, decrement the transaction
** count of the shared btree. If the transaction count reaches 0, set
** the shared state to TRANS_NONE. The unlockBtreeIfUnused() call below
@@ -38788,8 +38758,9 @@
/* Set the handles current transaction state to TRANS_NONE and unlock
** the pager if this call closed the only read or write transaction.
*/
+ btreeClearHasContent(pBt);
p->inTrans = TRANS_NONE;
unlockBtreeIfUnused(pBt);
btreeIntegrity(p);
@@ -38883,9 +38854,9 @@
pBt->db = p->db;
rc = saveAllCursors(pBt, 0, 0);
#ifndef SQLITE_OMIT_SHARED_CACHE
if( rc!=SQLITE_OK ){
- /* This is a horrible situation. An IO or malloc() error occured whilst
+ /* This is a horrible situation. An IO or malloc() error occurred whilst
** trying to save cursor positions. If this is an automatic rollback (as
** the result of a constraint, malloc() failure or IO error) then
** the cache may be internally inconsistent (not contain valid trees) so
** we cannot simply return the error to the caller. Instead, abort
@@ -38894,9 +38865,9 @@
sqlite3BtreeTripAllCursors(p, rc);
}
#endif
btreeIntegrity(p);
- unlockAllTables(p);
+ clearAllSharedCacheTableLocks(p);
if( p->inTrans==TRANS_WRITE ){
int rc2;
@@ -38923,10 +38894,10 @@
pBt->inTransaction = TRANS_NONE;
}
}
- p->inTrans = TRANS_NONE;
- pBt->inStmt = 0;
+ btreeClearHasContent(pBt);
+ p->inTrans = TRANS_NONE;
unlockBtreeIfUnused(pBt);
btreeIntegrity(p);
sqlite3BtreeLeave(p);
@@ -38933,31 +38904,35 @@
return rc;
}
/*
-** Start a statement subtransaction. The subtransaction can
-** can be rolled back independently of the main transaction.
-** You must start a transaction before starting a subtransaction.
-** The subtransaction is ended automatically if the main transaction
-** commits or rolls back.
-**
-** Only one subtransaction may be active at a time. It is an error to try
-** to start a new subtransaction if another subtransaction is already active.
+** Start a statement subtransaction. The subtransaction can can be rolled
+** back independently of the main transaction. You must start a transaction
+** before starting a subtransaction. The subtransaction is ended automatically
+** if the main transaction commits or rolls back.
**
** Statement subtransactions are used around individual SQL statements
** that are contained within a BEGIN...COMMIT block. If a constraint
** error occurs within the statement, the effect of that one statement
** can be rolled back without having to rollback the entire transaction.
-*/
-SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree *p){
+**
+** A statement sub-transaction is implemented as an anonymous savepoint. The
+** value passed as the second parameter is the total number of savepoints,
+** including the new anonymous savepoint, open on the B-Tree. i.e. if there
+** are no active savepoints and no other statement-transactions open,
+** iStatement is 1. This anonymous savepoint can be released or rolled back
+** using the sqlite3BtreeSavepoint() function.
+*/
+SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree *p, int iStatement){
int rc;
BtShared *pBt = p->pBt;
sqlite3BtreeEnter(p);
pBt->db = p->db;
assert( p->inTrans==TRANS_WRITE );
- assert( !pBt->inStmt );
assert( pBt->readOnly==0 );
- if( NEVER(p->inTrans!=TRANS_WRITE || pBt->inStmt || pBt->readOnly) ){
+ assert( iStatement>0 );
+ assert( iStatement>p->db->nSavepoint );
+ if( NEVER(p->inTrans!=TRANS_WRITE || pBt->readOnly) ){
rc = SQLITE_INTERNAL;
}else{
assert( pBt->inTransaction==TRANS_WRITE );
/* At the pager level, a statement transaction is a savepoint with
@@ -38964,57 +38939,9 @@
** an index greater than all savepoints created explicitly using
** SQL statements. It is illegal to open, release or rollback any
** such savepoints while the statement transaction savepoint is active.
*/
- rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint+1);
- pBt->inStmt = 1;
- }
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Commit the statment subtransaction currently in progress. If no
-** subtransaction is active, this is a no-op.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCommitStmt(Btree *p){
- int rc;
- BtShared *pBt = p->pBt;
- sqlite3BtreeEnter(p);
- pBt->db = p->db;
- assert( pBt->readOnly==0 );
- if( pBt->inStmt ){
- int iStmtpoint = p->db->nSavepoint;
- rc = sqlite3PagerSavepoint(pBt->pPager, SAVEPOINT_RELEASE, iStmtpoint);
- }else{
- rc = SQLITE_OK;
- }
- pBt->inStmt = 0;
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Rollback the active statement subtransaction. If no subtransaction
-** is active this routine is a no-op.
-**
-** All cursors will be invalidated by this operation. Any attempt
-** to use a cursor that was open at the beginning of this operation
-** will result in an error.
-*/
-SQLITE_PRIVATE int sqlite3BtreeRollbackStmt(Btree *p){
- int rc = SQLITE_OK;
- BtShared *pBt = p->pBt;
- sqlite3BtreeEnter(p);
- pBt->db = p->db;
- assert( pBt->readOnly==0 );
- if( pBt->inStmt ){
- int iStmtpoint = p->db->nSavepoint;
- rc = sqlite3PagerSavepoint(pBt->pPager, SAVEPOINT_ROLLBACK, iStmtpoint);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerSavepoint(pBt->pPager, SAVEPOINT_RELEASE, iStmtpoint);
- }
- pBt->inStmt = 0;
+ rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement);
}
sqlite3BtreeLeave(p);
return rc;
}
@@ -39034,9 +38961,8 @@
SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
int rc = SQLITE_OK;
if( p && p->inTrans==TRANS_WRITE ){
BtShared *pBt = p->pBt;
- assert( pBt->inStmt==0 );
assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) );
sqlite3BtreeEnter(p);
pBt->db = p->db;
@@ -39096,10 +39022,12 @@
assert( !pBt->readOnly );
if( NEVER(pBt->readOnly) ){
return SQLITE_READONLY;
}
- if( checkReadLocks(p, iTable, 0, 0) ){
- return SQLITE_LOCKED;
+ rc = checkForReadConflicts(p, iTable, 0, 0);
+ if( rc!=SQLITE_OK ){
+ assert( rc==SQLITE_LOCKED_SHAREDCACHE );
+ return rc;
}
}
if( pBt->pPage1==0 ){
@@ -39135,8 +39063,9 @@
pCur->pNext->pPrev = pCur;
}
pBt->pCursor = pCur;
pCur->eState = CURSOR_INVALID;
+ pCur->cachedRowid = 0;
return SQLITE_OK;
create_cursor_exception:
@@ -39157,13 +39086,50 @@
rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
sqlite3BtreeLeave(p);
return rc;
}
-SQLITE_PRIVATE int sqlite3BtreeCursorSize(){
+
+/*
+** Return the size of a BtCursor object in bytes.
+**
+** This interfaces is needed so that users of cursors can preallocate
+** sufficient storage to hold a cursor. The BtCursor object is opaque
+** to users so they cannot do the sizeof() themselves - they must call
+** this routine.
+*/
+SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){
return sizeof(BtCursor);
}
-
+/*
+** Set the cached rowid value of every cursor in the same database file
+** as pCur and having the same root page number as pCur. The value is
+** set to iRowid.
+**
+** Only positive rowid values are considered valid for this cache.
+** The cache is initialized to zero, indicating an invalid cache.
+** A btree will work fine with zero or negative rowids. We just cannot
+** cache zero or negative rowids, which means tables that use zero or
+** negative rowids might run a little slower. But in practice, zero
+** or negative rowids are very uncommon so this should not be a problem.
+*/
+SQLITE_PRIVATE void sqlite3BtreeSetCachedRowid(BtCursor *pCur, sqlite3_int64 iRowid){
+ BtCursor *p;
+ for(p=pCur->pBt->pCursor; p; p=p->pNext){
+ if( p->pgnoRoot==pCur->pgnoRoot ) p->cachedRowid = iRowid;
+ }
+ assert( pCur->cachedRowid==iRowid );
+}
+
+/*
+** Return the cached rowid for the given cursor. A negative or zero
+** return value indicates that the rowid cache is invalid and should be
+** ignored. If the rowid cache has never before been set, then a
+** zero is returned.
+*/
+SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor *pCur){
+ return pCur->cachedRowid;
+}
/*
** Close a cursor. The read lock on the database file is released
** when the last cursor is closed.
@@ -39222,8 +39188,10 @@
sqlite3PagerUnref(pCur->apPage[i]->pDbPage);
}
sqlite3_free(pCur->pKey);
}
+
+
/*
** Make sure the BtCursor* given in the argument has a valid
** BtCursor.info structure. If it is not already valid, call
@@ -39330,36 +39298,31 @@
** pointer-map data instead of reading the content of page ovfl to do so.
**
** If an error occurs an SQLite error code is returned. Otherwise:
**
-** Unless pPgnoNext is NULL, the page number of the next overflow
-** page in the linked list is written to *pPgnoNext. If page ovfl
-** is the last page in its linked list, *pPgnoNext is set to zero.
-**
-** If ppPage is not NULL, *ppPage is set to the MemPage* handle
-** for page ovfl. The underlying pager page may have been requested
-** with the noContent flag set, so the page data accessable via
-** this handle may not be trusted.
+** The page number of the next overflow page in the linked list is
+** written to *pPgnoNext. If page ovfl is the last page in its linked
+** list, *pPgnoNext is set to zero.
+**
+** If ppPage is not NULL, and a reference to the MemPage object corresponding
+** to page number pOvfl was obtained, then *ppPage is set to point to that
+** reference. It is the responsibility of the caller to call releasePage()
+** on *ppPage to free the reference. In no reference was obtained (because
+** the pointer-map was used to obtain the value for *pPgnoNext), then
+** *ppPage is set to zero.
*/
static int getOverflowPage(
BtShared *pBt,
Pgno ovfl, /* Overflow page */
- MemPage **ppPage, /* OUT: MemPage handle */
+ MemPage **ppPage, /* OUT: MemPage handle (may be NULL) */
Pgno *pPgnoNext /* OUT: Next overflow page number */
){
Pgno next = 0;
+ MemPage *pPage = 0;
int rc = SQLITE_OK;
assert( sqlite3_mutex_held(pBt->mutex) );
- /* One of these must not be NULL. Otherwise, why call this function? */
- assert(ppPage || pPgnoNext);
-
- /* If pPgnoNext is NULL, then this function is being called to obtain
- ** a MemPage* reference only. No page-data is required in this case.
- */
- if( !pPgnoNext ){
- return sqlite3BtreeGetPage(pBt, ovfl, ppPage, 1);
- }
+ assert(pPgnoNext);
#ifndef SQLITE_OMIT_AUTOVACUUM
/* Try to find the next page in the overflow list using the
** autovacuum pointer-map pages. Guess that the next page in
@@ -39377,36 +39340,31 @@
}
if( iGuess<=pagerPagecount(pBt) ){
rc = ptrmapGet(pBt, iGuess, &eType, &pgno);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- if( eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){
+ if( rc==SQLITE_OK && eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){
next = iGuess;
- }
- }
- }
-#endif
-
- if( next==0 || ppPage ){
- MemPage *pPage = 0;
-
- rc = sqlite3BtreeGetPage(pBt, ovfl, &pPage, next!=0);
+ rc = SQLITE_DONE;
+ }
+ }
+ }
+#endif
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3BtreeGetPage(pBt, ovfl, &pPage, 0);
assert(rc==SQLITE_OK || pPage==0);
if( next==0 && rc==SQLITE_OK ){
next = get4byte(pPage->aData);
}
-
- if( ppPage ){
- *ppPage = pPage;
- }else{
- releasePage(pPage);
- }
- }
+ }
+
*pPgnoNext = next;
-
- return rc;
+ if( ppPage ){
+ *ppPage = pPage;
+ }else{
+ releasePage(pPage);
+ }
+ return (rc==SQLITE_DONE ? SQLITE_OK : rc);
}
/*
** Copy data from a buffer to a page, or from a page to a buffer.
@@ -39670,9 +39628,9 @@
** This routine is an optimization. It is common for the entire key
** and data to fit on the local page and for there to be no overflow
** pages. When that is so, this routine can be used to access the
** key and data without making a copy. If the key and/or data spills
-** onto overflow pages, then accessPayload() must be used to reassembly
+** onto overflow pages, then accessPayload() must be used to reassemble
** the key/data and copy it into a preallocated buffer.
**
** The pointer returned by this routine looks directly into the cached
** page of the database. The data might change or move the next time
@@ -40513,8 +40471,9 @@
}
iPage = get4byte(&aData[8+closest*4]);
if( !searchList || iPage==nearby ){
+ int noContent;
Pgno nPage;
*pPgno = iPage;
nPage = pagerPagecount(pBt);
if( *pPgno>nPage ){
@@ -40529,11 +40488,11 @@
memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
}
put4byte(&aData[4], k-1);
assert( sqlite3PagerIswriteable(pTrunk->pDbPage) );
- rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, 1);
- if( rc==SQLITE_OK ){
- sqlite3PagerDontRollback((*ppPage)->pDbPage);
+ noContent = !btreeGetHasContent(pBt, *pPgno);
+ rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, noContent);
+ if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
if( rc!=SQLITE_OK ){
releasePage(*ppPage);
}
@@ -40549,16 +40508,27 @@
** end of the file */
int nPage = pagerPagecount(pBt);
*pPgno = nPage + 1;
+ if( *pPgno==PENDING_BYTE_PAGE(pBt) ){
+ (*pPgno)++;
+ }
+
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, *pPgno) ){
/* If *pPgno refers to a pointer-map page, allocate two new pages
** at the end of the file instead of one. The first allocated page
** becomes a new pointer-map page, the second is used by the caller.
*/
+ MemPage *pPg = 0;
TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno));
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
+ rc = sqlite3BtreeGetPage(pBt, *pPgno, &pPg, 0);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerWrite(pPg->pDbPage);
+ releasePage(pPg);
+ }
+ if( rc ) return rc;
(*pPgno)++;
if( *pPgno==PENDING_BYTE_PAGE(pBt) ){ (*pPgno)++; }
}
#endif
@@ -40588,62 +40558,88 @@
return rc;
}
/*
-** Add a page of the database file to the freelist.
-**
-** sqlite3PagerUnref() is NOT called for pPage.
-*/
-static int freePage(MemPage *pPage){
- BtShared *pBt = pPage->pBt;
- MemPage *pPage1 = pBt->pPage1;
- int rc, n, k;
-
- /* Prepare the page for freeing */
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( pPage->pgno>1 );
- pPage->isInit = 0;
+** This function is used to add page iPage to the database file free-list.
+** It is assumed that the page is not already a part of the free-list.
+**
+** The value passed as the second argument to this function is optional.
+** If the caller happens to have a pointer to the MemPage object
+** corresponding to page iPage handy, it may pass it as the second value.
+** Otherwise, it may pass NULL.
+**
+** If a pointer to a MemPage object is passed as the second argument,
+** its reference count is not altered by this function.
+*/
+static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
+ MemPage *pTrunk = 0; /* Free-list trunk page */
+ Pgno iTrunk = 0; /* Page number of free-list trunk page */
+ MemPage *pPage1 = pBt->pPage1; /* Local reference to page 1 */
+ MemPage *pPage; /* Page being freed. May be NULL. */
+ int rc; /* Return Code */
+ int nFree; /* Initial number of pages on free-list */
+
+ assert( sqlite3_mutex_held(pBt->mutex) );
+ assert( iPage>1 );
+ assert( !pMemPage || pMemPage->pgno==iPage );
+
+ if( pMemPage ){
+ pPage = pMemPage;
+ sqlite3PagerRef(pPage->pDbPage);
+ }else{
+ pPage = btreePageLookup(pBt, iPage);
+ }
/* Increment the free page count on pPage1 */
rc = sqlite3PagerWrite(pPage1->pDbPage);
- if( rc ) return rc;
- n = get4byte(&pPage1->aData[36]);
- put4byte(&pPage1->aData[36], n+1);
+ if( rc ) goto freepage_out;
+ nFree = get4byte(&pPage1->aData[36]);
+ put4byte(&pPage1->aData[36], nFree+1);
#ifdef SQLITE_SECURE_DELETE
/* If the SQLITE_SECURE_DELETE compile-time option is enabled, then
** always fully overwrite deleted information with zeros.
*/
- rc = sqlite3PagerWrite(pPage->pDbPage);
- if( rc ) return rc;
+ if( (!pPage && (rc = sqlite3BtreeGetPage(pBt, iPage, &pPage, 0)))
+ || (rc = sqlite3PagerWrite(pPage->pDbPage))
+ ){
+ goto freepage_out;
+ }
memset(pPage->aData, 0, pPage->pBt->pageSize);
#endif
/* If the database supports auto-vacuum, write an entry in the pointer-map
** to indicate that the page is free.
*/
if( ISAUTOVACUUM ){
- rc = ptrmapPut(pBt, pPage->pgno, PTRMAP_FREEPAGE, 0);
- if( rc ) return rc;
- }
-
- if( n==0 ){
- /* This is the first free page */
- rc = sqlite3PagerWrite(pPage->pDbPage);
- if( rc ) return rc;
- memset(pPage->aData, 0, 8);
- put4byte(&pPage1->aData[32], pPage->pgno);
- TRACE(("FREE-PAGE: %d first\n", pPage->pgno));
- }else{
- /* Other free pages already exist. Retrive the first trunk page
- ** of the freelist and find out how many leaves it has. */
- MemPage *pTrunk;
- rc = sqlite3BtreeGetPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk, 0);
- if( rc ) return rc;
- k = get4byte(&pTrunk->aData[4]);
- if( k>=pBt->usableSize/4 - 8 ){
- /* The trunk is full. Turn the page being freed into a new
- ** trunk page with no leaves.
+ rc = ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0);
+ if( rc ) goto freepage_out;
+ }
+
+ /* Now manipulate the actual database free-list structure. There are two
+ ** possibilities. If the free-list is currently empty, or if the first
+ ** trunk page in the free-list is full, then this page will become a
+ ** new free-list trunk page. Otherwise, it will become a leaf of the
+ ** first trunk page in the current free-list. This block tests if it
+ ** is possible to add the page as a new free-list leaf.
+ */
+ if( nFree!=0 ){
+ int nLeaf; /* Initial number of leaf cells on trunk page */
+
+ iTrunk = get4byte(&pPage1->aData[32]);
+ rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0);
+ if( rc!=SQLITE_OK ){
+ goto freepage_out;
+ }
+
+ nLeaf = get4byte(&pTrunk->aData[4]);
+ if( nLeaf<0 ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto freepage_out;
+ }
+ if( nLeaf<pBt->usableSize/4 - 8 ){
+ /* In this case there is room on the trunk page to insert the page
+ ** being freed as a new leaf.
**
** Note that the trunk page is not really full until it contains
** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have
** coded. But due to a coding error in versions of SQLite prior to
@@ -40654,33 +40650,50 @@
** for now. At some point in the future (once everyone has upgraded
** to 3.6.0 or later) we should consider fixing the conditional above
** to read "usableSize/4-2" instead of "usableSize/4-8".
*/
- rc = sqlite3PagerWrite(pPage->pDbPage);
- if( rc==SQLITE_OK ){
- put4byte(pPage->aData, pTrunk->pgno);
- put4byte(&pPage->aData[4], 0);
- put4byte(&pPage1->aData[32], pPage->pgno);
- TRACE(("FREE-PAGE: %d new trunk page replacing %d\n",
- pPage->pgno, pTrunk->pgno));
- }
- }else if( k<0 ){
- rc = SQLITE_CORRUPT;
- }else{
- /* Add the newly freed page as a leaf on the current trunk */
rc = sqlite3PagerWrite(pTrunk->pDbPage);
if( rc==SQLITE_OK ){
- put4byte(&pTrunk->aData[4], k+1);
- put4byte(&pTrunk->aData[8+k*4], pPage->pgno);
+ put4byte(&pTrunk->aData[4], nLeaf+1);
+ put4byte(&pTrunk->aData[8+nLeaf*4], iPage);
#ifndef SQLITE_SECURE_DELETE
- rc = sqlite3PagerDontWrite(pPage->pDbPage);
-#endif
+ if( pPage ){
+ sqlite3PagerDontWrite(pPage->pDbPage);
+ }
+#endif
+ rc = btreeSetHasContent(pBt, iPage);
}
TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno));
- }
- releasePage(pTrunk);
- }
- return rc;
+ goto freepage_out;
+ }
+ }
+
+ /* If control flows to this point, then it was not possible to add the
+ ** the page being freed as a leaf page of the first trunk in the free-list.
+ ** Possibly because the free-list is empty, or possibly because the
+ ** first trunk in the free-list is full. Either way, the page being freed
+ ** will become the new first trunk page in the free-list.
+ */
+ if( ((!pPage) && (0 != (rc = sqlite3BtreeGetPage(pBt, iPage, &pPage, 0))))
+ || (0 != (rc = sqlite3PagerWrite(pPage->pDbPage)))
+ ){
+ goto freepage_out;
+ }
+ put4byte(pPage->aData, iTrunk);
+ put4byte(&pPage->aData[4], 0);
+ put4byte(&pPage1->aData[32], iPage);
+ TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", pPage->pgno, iTrunk));
+
+freepage_out:
+ if( pPage ){
+ pPage->isInit = 0;
+ }
+ releasePage(pPage);
+ releasePage(pTrunk);
+ return rc;
+}
+static int freePage(MemPage *pPage){
+ return freePage2(pPage->pBt, pPage, pPage->pgno);
}
/*
** Free any overflow pages associated with the given Cell.
@@ -40690,30 +40703,36 @@
CellInfo info;
Pgno ovflPgno;
int rc;
int nOvfl;
- int ovflPageSize;
+ u16 ovflPageSize;
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
sqlite3BtreeParseCellPtr(pPage, pCell, &info);
if( info.iOverflow==0 ){
return SQLITE_OK; /* No overflow pages. Return without doing anything */
}
ovflPgno = get4byte(&pCell[info.iOverflow]);
+ assert( pBt->usableSize > 4 );
ovflPageSize = pBt->usableSize - 4;
nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
assert( ovflPgno==0 || nOvfl>0 );
while( nOvfl-- ){
- MemPage *pOvfl;
+ Pgno iNext = 0;
+ MemPage *pOvfl = 0;
if( ovflPgno==0 || ovflPgno>pagerPagecount(pBt) ){
return SQLITE_CORRUPT_BKPT;
}
-
- rc = getOverflowPage(pBt, ovflPgno, &pOvfl, (nOvfl==0)?0:&ovflPgno);
- if( rc ) return rc;
- rc = freePage(pOvfl);
- sqlite3PagerUnref(pOvfl->pDbPage);
+ if( nOvfl ){
+ rc = getOverflowPage(pBt, ovflPgno, &pOvfl, &iNext);
+ if( rc ) return rc;
+ }
+ rc = freePage2(pBt, pOvfl, ovflPgno);
+ if( pOvfl ){
+ sqlite3PagerUnref(pOvfl->pDbPage);
+ }
if( rc ) return rc;
+ ovflPgno = iNext;
}
return SQLITE_OK;
}
@@ -40779,9 +40798,11 @@
pSrc = pData;
nSrc = nData;
nData = 0;
}else{
- /* TBD: Perhaps raise SQLITE_CORRUPT if nKey is larger than 31 bits? */
+ if( nKey>0x7fffffff || pKey==0 ){
+ return SQLITE_CORRUPT;
+ }
nPayload += (int)nKey;
pSrc = pKey;
nSrc = (int)nKey;
}
@@ -41701,9 +41722,12 @@
CellInfo info;
j--;
sqlite3BtreeParseCellPtr(pNew, apCell[j], &info);
pCell = pTemp;
- fillInCell(pParent, pCell, 0, info.nKey, 0, 0, 0, &sz);
+ rc = fillInCell(pParent, pCell, 0, info.nKey, 0, 0, 0, &sz);
+ if( rc!=SQLITE_OK ){
+ goto balance_cleanup;
+ }
pTemp = 0;
}else{
pCell -= 4;
/* Obscure case for non-leaf-data trees: If the cell at pCell was
@@ -42023,11 +42047,11 @@
** cache with the current connection) and that other connection
** is not in the ReadUncommmitted state, then this routine returns
** SQLITE_LOCKED.
**
-** As well as cursors with wrFlag==0, cursors with wrFlag==1 and
-** isIncrblobHandle==1 are also considered 'read' cursors. Incremental
-** blob cursors are used for both reading and writing.
+** As well as cursors with wrFlag==0, cursors with
+** isIncrblobHandle==1 are also considered 'read' cursors because
+** incremental blob cursors are used for both reading and writing.
**
** When pgnoRoot is the root page of an intkey table, this function is also
** responsible for invalidating incremental blob cursors when the table row
** on which they are opened is deleted or modified. Cursors are invalidated
@@ -42047,13 +42071,13 @@
**
** 3) If both pExclude and iRow are set to zero, no incremental blob
** cursors are invalidated.
*/
-static int checkReadLocks(
- Btree *pBtree,
- Pgno pgnoRoot,
- BtCursor *pExclude,
- i64 iRow
+static int checkForReadConflicts(
+ Btree *pBtree, /* The database file to check */
+ Pgno pgnoRoot, /* Look for read cursors on this btree */
+ BtCursor *pExclude, /* Ignore this cursor */
+ i64 iRow /* The rowid that might be changing */
){
BtCursor *p;
BtShared *pBt = pBtree->pBt;
sqlite3 *db = pBtree->db;
@@ -42075,11 +42099,12 @@
|| p->isIncrblobHandle
#endif
){
sqlite3 *dbOther = p->pBtree->db;
- if( dbOther==0 ||
- (dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0) ){
- return SQLITE_LOCKED;
+ assert(dbOther);
+ if( dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0 ){
+ sqlite3ConnectionBlocked(db, dbOther);
+ return SQLITE_LOCKED_SHAREDCACHE;
}
}
}
return SQLITE_OK;
@@ -42114,10 +42139,13 @@
assert( cursorHoldsMutex(pCur) );
assert( pBt->inTransaction==TRANS_WRITE );
assert( !pBt->readOnly );
assert( pCur->wrFlag );
- if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur, nKey) ){
- return SQLITE_LOCKED; /* The table pCur points to has a read lock */
+ rc = checkForReadConflicts(pCur->pBtree, pCur->pgnoRoot, pCur, nKey);
+ if( rc ){
+ /* The table pCur points to has a read lock */
+ assert( rc==SQLITE_LOCKED_SHAREDCACHE );
+ return rc;
}
if( pCur->eState==CURSOR_FAULT ){
return pCur->skip;
}
@@ -42211,10 +42239,13 @@
if( NEVER(pCur->aiIdx[pCur->iPage]>=pPage->nCell) ){
return SQLITE_ERROR; /* The cursor is not pointing to anything */
}
assert( pCur->wrFlag );
- if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur, pCur->info.nKey) ){
- return SQLITE_LOCKED; /* The table pCur points to has a read lock */
+ rc = checkForReadConflicts(p, pCur->pgnoRoot, pCur, pCur->info.nKey);
+ if( rc!=SQLITE_OK ){
+ /* The table pCur points to has a read lock */
+ assert( rc==SQLITE_LOCKED_SHAREDCACHE );
+ return rc;
}
/* Restore the current cursor position (a no-op if the cursor is not in
** CURSOR_REQUIRESEEK state) and save the positions of any other cursors
@@ -42477,13 +42508,8 @@
return rc;
}
assert( eType!=PTRMAP_ROOTPAGE );
assert( eType!=PTRMAP_FREEPAGE );
- rc = sqlite3PagerWrite(pRoot->pDbPage);
- if( rc!=SQLITE_OK ){
- releasePage(pRoot);
- return rc;
- }
rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0);
releasePage(pRoot);
/* Obtain the page at pgnoRoot */
@@ -42602,9 +42628,9 @@
BtShared *pBt = p->pBt;
sqlite3BtreeEnter(p);
pBt->db = p->db;
assert( p->inTrans==TRANS_WRITE );
- if( (rc = checkReadLocks(p, iTable, 0, 1))!=SQLITE_OK ){
+ if( (rc = checkForReadConflicts(p, iTable, 0, 1))!=SQLITE_OK ){
/* nothing to do */
}else if( SQLITE_OK!=(rc = saveAllCursors(pBt, iTable, 0)) ){
/* nothing to do */
}else{
@@ -42648,9 +42674,10 @@
** root page. If an open cursor was using this page a problem would
** occur.
*/
if( pBt->pCursor ){
- return SQLITE_LOCKED;
+ sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db);
+ return SQLITE_LOCKED_SHAREDCACHE;
}
rc = sqlite3BtreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
if( rc ) return rc;
@@ -42770,11 +42797,12 @@
/* Reading a meta-data value requires a read-lock on page 1 (and hence
** the sqlite_master table. We grab this lock regardless of whether or
** not the SQLITE_ReadUncommitted flag is set (the table rooted at page
- ** 1 is treated as a special case by queryTableLock() and lockTable()).
- */
- rc = queryTableLock(p, 1, READ_LOCK);
+ ** 1 is treated as a special case by querySharedCacheTableLock()
+ ** and setSharedCacheTableLock()).
+ */
+ rc = querySharedCacheTableLock(p, 1, READ_LOCK);
if( rc!=SQLITE_OK ){
sqlite3BtreeLeave(p);
return rc;
}
@@ -42814,9 +42842,9 @@
if( idx==4 && *pMeta>0 ) pBt->readOnly = 1;
#endif
/* Grab the read-lock on page 1. */
- rc = lockTable(p, 1, READ_LOCK);
+ rc = setSharedCacheTableLock(p, 1, READ_LOCK);
sqlite3BtreeLeave(p);
return rc;
}
@@ -42865,8 +42893,77 @@
assert( pPage->pBt==pCur->pBt );
return pPage->aData[pPage->hdrOffset];
}
+#ifndef SQLITE_OMIT_BTREECOUNT
+/*
+** The first argument, pCur, is a cursor opened on some b-tree. Count the
+** number of entries in the b-tree and write the result to *pnEntry.
+**
+** SQLITE_OK is returned if the operation is successfully executed.
+** Otherwise, if an error is encountered (i.e. an IO error or database
+** corruption) an SQLite error code is returned.
+*/
+SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
+ i64 nEntry = 0; /* Value to return in *pnEntry */
+ int rc; /* Return code */
+ rc = moveToRoot(pCur);
+
+ /* Unless an error occurs, the following loop runs one iteration for each
+ ** page in the B-Tree structure (not including overflow pages).
+ */
+ while( rc==SQLITE_OK ){
+ int iIdx; /* Index of child node in parent */
+ MemPage *pPage; /* Current page of the b-tree */
+
+ /* If this is a leaf page or the tree is not an int-key tree, then
+ ** this page contains countable entries. Increment the entry counter
+ ** accordingly.
+ */
+ pPage = pCur->apPage[pCur->iPage];
+ if( pPage->leaf || !pPage->intKey ){
+ nEntry += pPage->nCell;
+ }
+
+ /* pPage is a leaf node. This loop navigates the cursor so that it
+ ** points to the first interior cell that it points to the parent of
+ ** the next page in the tree that has not yet been visited. The
+ ** pCur->aiIdx[pCur->iPage] value is set to the index of the parent cell
+ ** of the page, or to the number of cells in the page if the next page
+ ** to visit is the right-child of its parent.
+ **
+ ** If all pages in the tree have been visited, return SQLITE_OK to the
+ ** caller.
+ */
+ if( pPage->leaf ){
+ do {
+ if( pCur->iPage==0 ){
+ /* All pages of the b-tree have been visited. Return successfully. */
+ *pnEntry = nEntry;
+ return SQLITE_OK;
+ }
+ sqlite3BtreeMoveToParent(pCur);
+ }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
+
+ pCur->aiIdx[pCur->iPage]++;
+ pPage = pCur->apPage[pCur->iPage];
+ }
+
+ /* Descend to the child node of the cell that the cursor currently
+ ** points at. This is the right-child if (iIdx==pPage->nCell).
+ */
+ iIdx = pCur->aiIdx[pCur->iPage];
+ if( iIdx==pPage->nCell ){
+ rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
+ }else{
+ rc = moveToChild(pCur, get4byte(findCell(pPage, iIdx)));
+ }
+ }
+
+ /* An error has occurred. Return an error code. */
+ return rc;
+}
+#endif
/*
** Return the pager associated with a BTree. This routine is used for
** testing and debugging only.
@@ -43101,9 +43198,11 @@
sqlite3BtreeParseCellPtr(pPage, pCell, &info);
sz = info.nData;
if( !pPage->intKey ) sz += (int)info.nKey;
assert( sz==info.nPayload );
- if( sz>info.nLocal ){
+ if( (sz>info.nLocal)
+ && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize])
+ ){
int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->autoVacuum ){
@@ -43343,19 +43442,8 @@
return sqlite3PagerFilename(p->pBt->pPager);
}
/*
-** Return the pathname of the directory that contains the database file.
-**
-** The pager directory name is invariant as long as the pager is
-** open so it is safe to access without the BtShared mutex.
-*/
-SQLITE_PRIVATE const char *sqlite3BtreeGetDirname(Btree *p){
- assert( p->pBt->pPager!=0 );
- return sqlite3PagerDirname(p->pBt->pPager);
-}
-
-/*
** Return the pathname of the journal file for this database. The return
** value of this routine is the same regardless of whether the journal file
** has been created or not.
**
@@ -43366,223 +43454,8 @@
assert( p->pBt->pPager!=0 );
return sqlite3PagerJournalname(p->pBt->pPager);
}
-#ifndef SQLITE_OMIT_VACUUM
-/*
-** Copy the complete content of pBtFrom into pBtTo. A transaction
-** must be active for both files.
-**
-** The size of file pTo may be reduced by this operation.
-** If anything goes wrong, the transaction on pTo is rolled back.
-**
-** If successful, CommitPhaseOne() may be called on pTo before returning.
-** The caller should finish committing the transaction on pTo by calling
-** sqlite3BtreeCommit().
-*/
-static int btreeCopyFile(Btree *pTo, Btree *pFrom){
- int rc = SQLITE_OK;
- Pgno i;
-
- Pgno nFromPage; /* Number of pages in pFrom */
- Pgno nToPage; /* Number of pages in pTo */
- Pgno nNewPage; /* Number of pages in pTo after the copy */
-
- Pgno iSkip; /* Pending byte page in pTo */
- int nToPageSize; /* Page size of pTo in bytes */
- int nFromPageSize; /* Page size of pFrom in bytes */
-
- BtShared *pBtTo = pTo->pBt;
- BtShared *pBtFrom = pFrom->pBt;
- pBtTo->db = pTo->db;
- pBtFrom->db = pFrom->db;
-
- nToPageSize = pBtTo->pageSize;
- nFromPageSize = pBtFrom->pageSize;
-
- assert( pTo->inTrans==TRANS_WRITE );
- assert( pFrom->inTrans==TRANS_WRITE );
- if( NEVER(pBtTo->pCursor) ){
- return SQLITE_BUSY;
- }
-
- nToPage = pagerPagecount(pBtTo);
- nFromPage = pagerPagecount(pBtFrom);
- iSkip = PENDING_BYTE_PAGE(pBtTo);
-
- /* Variable nNewPage is the number of pages required to store the
- ** contents of pFrom using the current page-size of pTo.
- */
- nNewPage = (Pgno)
- (((i64)nFromPage*(i64)nFromPageSize+(i64)nToPageSize-1)/(i64)nToPageSize);
-
- for(i=1; rc==SQLITE_OK && (i<=nToPage || i<=nNewPage); i++){
-
- /* Journal the original page.
- **
- ** iSkip is the page number of the locking page (PENDING_BYTE_PAGE)
- ** in database *pTo (before the copy). This page is never written
- ** into the journal file. Unless i==iSkip or the page was not
- ** present in pTo before the copy operation, journal page i from pTo.
- */
- if( i!=iSkip && i<=nToPage ){
- DbPage *pDbPage = 0;
- rc = sqlite3PagerGet(pBtTo->pPager, i, &pDbPage);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerWrite(pDbPage);
- if( rc==SQLITE_OK && i>nFromPage ){
- /* Yeah. It seems wierd to call DontWrite() right after Write(). But
- ** that is because the names of those procedures do not exactly
- ** represent what they do. Write() really means "put this page in the
- ** rollback journal and mark it as dirty so that it will be written
- ** to the database file later." DontWrite() undoes the second part of
- ** that and prevents the page from being written to the database. The
- ** page is still on the rollback journal, though. And that is the
- ** whole point of this block: to put pages on the rollback journal.
- */
- rc = sqlite3PagerDontWrite(pDbPage);
- }
- sqlite3PagerUnref(pDbPage);
- }
- }
-
- /* Overwrite the data in page i of the target database */
- if( rc==SQLITE_OK && i!=iSkip && i<=nNewPage ){
-
- DbPage *pToPage = 0;
- sqlite3_int64 iOff;
-
- rc = sqlite3PagerGet(pBtTo->pPager, i, &pToPage);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerWrite(pToPage);
- }
-
- for(
- iOff=(i-1)*nToPageSize;
- rc==SQLITE_OK && iOff<i*nToPageSize;
- iOff += nFromPageSize
- ){
- DbPage *pFromPage = 0;
- Pgno iFrom = (Pgno)(iOff/nFromPageSize)+1;
-
- if( iFrom==PENDING_BYTE_PAGE(pBtFrom) ){
- continue;
- }
-
- rc = sqlite3PagerGet(pBtFrom->pPager, iFrom, &pFromPage);
- if( rc==SQLITE_OK ){
- char *zTo = sqlite3PagerGetData(pToPage);
- char *zFrom = sqlite3PagerGetData(pFromPage);
- int nCopy;
-
- if( nFromPageSize>=nToPageSize ){
- zFrom += ((i-1)*nToPageSize - ((iFrom-1)*nFromPageSize));
- nCopy = nToPageSize;
- }else{
- zTo += (((iFrom-1)*nFromPageSize) - (i-1)*nToPageSize);
- nCopy = nFromPageSize;
- }
-
- memcpy(zTo, zFrom, nCopy);
- sqlite3PagerUnref(pFromPage);
- }
- }
-
- if( pToPage ){
- MemPage *p = (MemPage *)sqlite3PagerGetExtra(pToPage);
- p->isInit = 0;
- sqlite3PagerUnref(pToPage);
- }
- }
- }
-
- /* If things have worked so far, the database file may need to be
- ** truncated. The complex part is that it may need to be truncated to
- ** a size that is not an integer multiple of nToPageSize - the current
- ** page size used by the pager associated with B-Tree pTo.
- **
- ** For example, say the page-size of pTo is 2048 bytes and the original
- ** number of pages is 5 (10 KB file). If pFrom has a page size of 1024
- ** bytes and 9 pages, then the file needs to be truncated to 9KB.
- */
- if( rc==SQLITE_OK ){
- sqlite3_file *pFile = sqlite3PagerFile(pBtTo->pPager);
- i64 iSize = (i64)nFromPageSize * (i64)nFromPage;
- i64 iNow = (i64)((nToPage>nNewPage)?nToPage:nNewPage) * (i64)nToPageSize;
- i64 iPending = ((i64)PENDING_BYTE_PAGE(pBtTo)-1) *(i64)nToPageSize;
-
- assert( iSize<=iNow );
-
- /* Commit phase one syncs the journal file associated with pTo
- ** containing the original data. It does not sync the database file
- ** itself. After doing this it is safe to use OsTruncate() and other
- ** file APIs on the database file directly.
- */
- pBtTo->db = pTo->db;
- rc = sqlite3PagerCommitPhaseOne(pBtTo->pPager, 0, 1);
- if( iSize<iNow && rc==SQLITE_OK ){
- rc = sqlite3OsTruncate(pFile, iSize);
- }
-
- /* The loop that copied data from database pFrom to pTo did not
- ** populate the locking page of database pTo. If the page-size of
- ** pFrom is smaller than that of pTo, this means some data will
- ** not have been copied.
- **
- ** This block copies the missing data from database pFrom to pTo
- ** using file APIs. This is safe because at this point we know that
- ** all of the original data from pTo has been synced into the
- ** journal file. At this point it would be safe to do anything at
- ** all to the database file except truncate it to zero bytes.
- */
- if( rc==SQLITE_OK && nFromPageSize<nToPageSize && iSize>iPending){
- i64 iOff;
- for(
- iOff=iPending;
- rc==SQLITE_OK && iOff<(iPending+nToPageSize);
- iOff += nFromPageSize
- ){
- DbPage *pFromPage = 0;
- Pgno iFrom = (Pgno)(iOff/nFromPageSize)+1;
-
- if( iFrom==PENDING_BYTE_PAGE(pBtFrom) || iFrom>nFromPage ){
- continue;
- }
-
- rc = sqlite3PagerGet(pBtFrom->pPager, iFrom, &pFromPage);
- if( rc==SQLITE_OK ){
- char *zFrom = sqlite3PagerGetData(pFromPage);
- rc = sqlite3OsWrite(pFile, zFrom, nFromPageSize, iOff);
- sqlite3PagerUnref(pFromPage);
- }
- }
- }
- }
-
- /* Sync the database file */
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerSync(pBtTo->pPager);
- }
- if( rc==SQLITE_OK ){
- pBtTo->pageSizeFixed = 0;
- }else{
- sqlite3BtreeRollback(pTo);
- }
-
- return rc;
-}
-SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
- int rc;
- sqlite3BtreeEnter(pTo);
- sqlite3BtreeEnter(pFrom);
- rc = btreeCopyFile(pTo, pFrom);
- sqlite3BtreeLeave(pFrom);
- sqlite3BtreeLeave(pTo);
- return rc;
-}
-
-#endif /* SQLITE_OMIT_VACUUM */
-
/*
** Return non-zero if a transaction is active.
*/
SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree *p){
@@ -43590,22 +43463,20 @@
return (p && (p->inTrans==TRANS_WRITE));
}
/*
-** Return non-zero if a statement transaction is active.
-*/
-SQLITE_PRIVATE int sqlite3BtreeIsInStmt(Btree *p){
- assert( sqlite3BtreeHoldsMutex(p) );
- return ALWAYS(p->pBt) && p->pBt->inStmt;
-}
-
-/*
** Return non-zero if a read (or write) transaction is active.
*/
SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree *p){
assert( p );
assert( sqlite3_mutex_held(p->db->mutex) );
return p->inTrans!=TRANS_NONE;
+}
+
+SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){
+ assert( p );
+ assert( sqlite3_mutex_held(p->db->mutex) );
+ return p->nBackup!=0;
}
/*
** This function returns a pointer to a blob of memory associated with
@@ -43638,16 +43509,18 @@
return pBt->pSchema;
}
/*
-** Return true if another user of the same shared btree as the argument
-** handle holds an exclusive lock on the sqlite_master table.
+** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared
+** btree as the argument handle holds an exclusive lock on the
+** sqlite_master table. Otherwise SQLITE_OK.
*/
SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){
int rc;
assert( sqlite3_mutex_held(p->db->mutex) );
sqlite3BtreeEnter(p);
- rc = (queryTableLock(p, MASTER_ROOT, READ_LOCK)!=SQLITE_OK);
+ rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK);
+ assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE );
sqlite3BtreeLeave(p);
return rc;
}
@@ -43664,11 +43537,11 @@
u8 lockType = READ_LOCK + isWriteLock;
assert( READ_LOCK+1==WRITE_LOCK );
assert( isWriteLock==0 || isWriteLock==1 );
sqlite3BtreeEnter(p);
- rc = queryTableLock(p, iTab, lockType);
- if( rc==SQLITE_OK ){
- rc = lockTable(p, iTab, lockType);
+ rc = querySharedCacheTableLock(p, iTab, lockType);
+ if( rc==SQLITE_OK ){
+ rc = setSharedCacheTableLock(p, iTab, lockType);
}
sqlite3BtreeLeave(p);
}
return rc;
@@ -43683,8 +43556,10 @@
** Only the data content may only be modified, it is not possible
** to change the length of the data stored.
*/
SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
+ int rc;
+
assert( cursorHoldsMutex(pCsr) );
assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
assert(pCsr->isIncrblobHandle);
@@ -43703,10 +43578,13 @@
return SQLITE_READONLY;
}
assert( !pCsr->pBt->readOnly
&& pCsr->pBt->inTransaction==TRANS_WRITE );
- if( checkReadLocks(pCsr->pBtree, pCsr->pgnoRoot, pCsr, 0) ){
- return SQLITE_LOCKED; /* The table pCur points to has a read lock */
+ rc = checkForReadConflicts(pCsr->pBtree, pCsr->pgnoRoot, pCsr, 0);
+ if( rc!=SQLITE_OK ){
+ /* The table pCur points to has a read lock */
+ assert( rc==SQLITE_LOCKED_SHAREDCACHE );
+ return rc;
}
if( pCsr->eState==CURSOR_INVALID || !pCsr->apPage[pCsr->iPage]->intKey ){
return SQLITE_ERROR;
}
@@ -43733,8 +43611,620 @@
}
#endif
/************** End of btree.c ***********************************************/
+/************** Begin file backup.c ******************************************/
+/*
+** 2009 January 28
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains the implementation of the sqlite3_backup_XXX()
+** API functions and the related features.
+**
+** $Id: backup.c,v 1.13 2009/03/16 13:19:36 danielk1977 Exp $
+*/
+
+/* Macro to find the minimum of two numeric values.
+*/
+#ifndef MIN
+# define MIN(x,y) ((x)<(y)?(x):(y))
+#endif
+
+/*
+** Structure allocated for each backup operation.
+*/
+struct sqlite3_backup {
+ sqlite3* pDestDb; /* Destination database handle */
+ Btree *pDest; /* Destination b-tree file */
+ u32 iDestSchema; /* Original schema cookie in destination */
+ int bDestLocked; /* True once a write-transaction is open on pDest */
+
+ Pgno iNext; /* Page number of the next source page to copy */
+ sqlite3* pSrcDb; /* Source database handle */
+ Btree *pSrc; /* Source b-tree file */
+
+ int rc; /* Backup process error code */
+
+ /* These two variables are set by every call to backup_step(). They are
+ ** read by calls to backup_remaining() and backup_pagecount().
+ */
+ Pgno nRemaining; /* Number of pages left to copy */
+ Pgno nPagecount; /* Total number of pages to copy */
+
+ sqlite3_backup *pNext; /* Next backup associated with source pager */
+};
+
+/*
+** THREAD SAFETY NOTES:
+**
+** Once it has been created using backup_init(), a single sqlite3_backup
+** structure may be accessed via two groups of thread-safe entry points:
+**
+** * Via the sqlite3_backup_XXX() API function backup_step() and
+** backup_finish(). Both these functions obtain the source database
+** handle mutex and the mutex associated with the source BtShared
+** structure, in that order.
+**
+** * Via the BackupUpdate() and BackupRestart() functions, which are
+** invoked by the pager layer to report various state changes in
+** the page cache associated with the source database. The mutex
+** associated with the source database BtShared structure will always
+** be held when either of these functions are invoked.
+**
+** The other sqlite3_backup_XXX() API functions, backup_remaining() and
+** backup_pagecount() are not thread-safe functions. If they are called
+** while some other thread is calling backup_step() or backup_finish(),
+** the values returned may be invalid. There is no way for a call to
+** BackupUpdate() or BackupRestart() to interfere with backup_remaining()
+** or backup_pagecount().
+**
+** Depending on the SQLite configuration, the database handles and/or
+** the Btree objects may have their own mutexes that require locking.
+** Non-sharable Btrees (in-memory databases for example), do not have
+** associated mutexes.
+*/
+
+/*
+** Return a pointer corresponding to database zDb (i.e. "main", "temp")
+** in connection handle pDb. If such a database cannot be found, return
+** a NULL pointer and write an error message to pErrorDb.
+**
+** If the "temp" database is requested, it may need to be opened by this
+** function. If an error occurs while doing so, return 0 and write an
+** error message to pErrorDb.
+*/
+static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
+ int i = sqlite3FindDbName(pDb, zDb);
+
+ if( i==1 ){
+ Parse sParse;
+ memset(&sParse, 0, sizeof(sParse));
+ sParse.db = pDb;
+ if( sqlite3OpenTempDatabase(&sParse) ){
+ sqlite3ErrorClear(&sParse);
+ sqlite3Error(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
+ return 0;
+ }
+ assert( sParse.zErrMsg==0 );
+ }
+
+ if( i<0 ){
+ sqlite3Error(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb);
+ return 0;
+ }
+
+ return pDb->aDb[i].pBt;
+}
+
+/*
+** Create an sqlite3_backup process to copy the contents of zSrcDb from
+** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
+** a pointer to the new sqlite3_backup object.
+**
+** If an error occurs, NULL is returned and an error code and error message
+** stored in database handle pDestDb.
+*/
+SQLITE_API sqlite3_backup *sqlite3_backup_init(
+ sqlite3* pDestDb, /* Database to write to */
+ const char *zDestDb, /* Name of database within pDestDb */
+ sqlite3* pSrcDb, /* Database connection to read from */
+ const char *zSrcDb /* Name of database within pSrcDb */
+){
+ sqlite3_backup *p; /* Value to return */
+
+ /* Lock the source database handle. The destination database
+ ** handle is not locked in this routine, but it is locked in
+ ** sqlite3_backup_step(). The user is required to ensure that no
+ ** other thread accesses the destination handle for the duration
+ ** of the backup operation. Any attempt to use the destination
+ ** database connection while a backup is in progress may cause
+ ** a malfunction or a deadlock.
+ */
+ sqlite3_mutex_enter(pSrcDb->mutex);
+ sqlite3_mutex_enter(pDestDb->mutex);
+
+ if( pSrcDb==pDestDb ){
+ sqlite3Error(
+ pDestDb, SQLITE_ERROR, "source and destination must be distinct"
+ );
+ p = 0;
+ }else {
+ /* Allocate space for a new sqlite3_backup object */
+ p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup));
+ if( !p ){
+ sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
+ }
+ }
+
+ /* If the allocation succeeded, populate the new object. */
+ if( p ){
+ memset(p, 0, sizeof(sqlite3_backup));
+ p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
+ p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
+ p->pDestDb = pDestDb;
+ p->pSrcDb = pSrcDb;
+ p->iNext = 1;
+
+ if( 0==p->pSrc || 0==p->pDest ){
+ /* One (or both) of the named databases did not exist. An error has
+ ** already been written into the pDestDb handle. All that is left
+ ** to do here is free the sqlite3_backup structure.
+ */
+ sqlite3_free(p);
+ p = 0;
+ }
+ }
+
+ /* If everything has gone as planned, attach the backup object to the
+ ** source pager. The source pager calls BackupUpdate() and BackupRestart()
+ ** to notify this module if the source file is modified mid-backup.
+ */
+ if( p ){
+ sqlite3_backup **pp; /* Pointer to head of pagers backup list */
+ sqlite3BtreeEnter(p->pSrc);
+ pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
+ p->pNext = *pp;
+ *pp = p;
+ sqlite3BtreeLeave(p->pSrc);
+ p->pSrc->nBackup++;
+ }
+
+ sqlite3_mutex_leave(pDestDb->mutex);
+ sqlite3_mutex_leave(pSrcDb->mutex);
+ return p;
+}
+
+/*
+** Argument rc is an SQLite error code. Return true if this error is
+** considered fatal if encountered during a backup operation. All errors
+** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED.
+*/
+static int isFatalError(int rc){
+ return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED);
+}
+
+/*
+** Parameter zSrcData points to a buffer containing the data for
+** page iSrcPg from the source database. Copy this data into the
+** destination database.
+*/
+static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
+ Pager * const pDestPager = sqlite3BtreePager(p->pDest);
+ const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
+ int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
+ const int nCopy = MIN(nSrcPgsz, nDestPgsz);
+ const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
+
+ int rc = SQLITE_OK;
+ i64 iOff;
+
+ assert( p->bDestLocked );
+ assert( !isFatalError(p->rc) );
+ assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
+ assert( zSrcData );
+
+ /* Catch the case where the destination is an in-memory database and the
+ ** page sizes of the source and destination differ.
+ */
+ if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(sqlite3BtreePager(p->pDest)) ){
+ rc = SQLITE_READONLY;
+ }
+
+ /* This loop runs once for each destination page spanned by the source
+ ** page. For each iteration, variable iOff is set to the byte offset
+ ** of the destination page.
+ */
+ for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){
+ DbPage *pDestPg = 0;
+ Pgno iDest = (Pgno)(iOff/nDestPgsz)+1;
+ if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt) ) continue;
+ if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg))
+ && SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg))
+ ){
+ const u8 *zIn = &zSrcData[iOff%nSrcPgsz];
+ u8 *zDestData = sqlite3PagerGetData(pDestPg);
+ u8 *zOut = &zDestData[iOff%nDestPgsz];
+
+ /* Copy the data from the source page into the destination page.
+ ** Then clear the Btree layer MemPage.isInit flag. Both this module
+ ** and the pager code use this trick (clearing the first byte
+ ** of the page 'extra' space to invalidate the Btree layers
+ ** cached parse of the page). MemPage.isInit is marked
+ ** "MUST BE FIRST" for this purpose.
+ */
+ memcpy(zOut, zIn, nCopy);
+ ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0;
+ }
+ sqlite3PagerUnref(pDestPg);
+ }
+
+ return rc;
+}
+
+/*
+** If pFile is currently larger than iSize bytes, then truncate it to
+** exactly iSize bytes. If pFile is not larger than iSize bytes, then
+** this function is a no-op.
+**
+** Return SQLITE_OK if everything is successful, or an SQLite error
+** code if an error occurs.
+*/
+static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){
+ i64 iCurrent;
+ int rc = sqlite3OsFileSize(pFile, &iCurrent);
+ if( rc==SQLITE_OK && iCurrent>iSize ){
+ rc = sqlite3OsTruncate(pFile, iSize);
+ }
+ return rc;
+}
+
+/*
+** Copy nPage pages from the source b-tree to the destination.
+*/
+SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
+ int rc;
+
+ sqlite3_mutex_enter(p->pSrcDb->mutex);
+ sqlite3BtreeEnter(p->pSrc);
+ if( p->pDestDb ){
+ sqlite3_mutex_enter(p->pDestDb->mutex);
+ }
+
+ rc = p->rc;
+ if( !isFatalError(rc) ){
+ Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */
+ Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest pager */
+ int ii; /* Iterator variable */
+ int nSrcPage = -1; /* Size of source db in pages */
+ int bCloseTrans = 0; /* True if src db requires unlocking */
+
+ /* If the source pager is currently in a write-transaction, return
+ ** SQLITE_BUSY immediately.
+ */
+ if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){
+ rc = SQLITE_BUSY;
+ }else{
+ rc = SQLITE_OK;
+ }
+
+ /* Lock the destination database, if it is not locked already. */
+ if( SQLITE_OK==rc && p->bDestLocked==0
+ && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2))
+ ){
+ p->bDestLocked = 1;
+ rc = sqlite3BtreeGetMeta(p->pDest, 1, &p->iDestSchema);
+ }
+
+ /* If there is no open read-transaction on the source database, open
+ ** one now. If a transaction is opened here, then it will be closed
+ ** before this function exits.
+ */
+ if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){
+ rc = sqlite3BtreeBeginTrans(p->pSrc, 0);
+ bCloseTrans = 1;
+ }
+
+ /* Now that there is a read-lock on the source database, query the
+ ** source pager for the number of pages in the database.
+ */
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerPagecount(pSrcPager, &nSrcPage);
+ }
+ for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){
+ const Pgno iSrcPg = p->iNext; /* Source page number */
+ if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
+ DbPage *pSrcPg; /* Source page object */
+ rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
+ if( rc==SQLITE_OK ){
+ rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg));
+ sqlite3PagerUnref(pSrcPg);
+ }
+ }
+ p->iNext++;
+ }
+ if( rc==SQLITE_OK ){
+ p->nPagecount = nSrcPage;
+ p->nRemaining = nSrcPage+1-p->iNext;
+ if( p->iNext>(Pgno)nSrcPage ){
+ rc = SQLITE_DONE;
+ }
+ }
+
+ if( rc==SQLITE_DONE ){
+ const int nSrcPagesize = sqlite3BtreeGetPageSize(p->pSrc);
+ const int nDestPagesize = sqlite3BtreeGetPageSize(p->pDest);
+ int nDestTruncate;
+
+ /* Update the schema version field in the destination database. This
+ ** is to make sure that the schema-version really does change in
+ ** the case where the source and destination databases have the
+ ** same schema version.
+ */
+ sqlite3BtreeUpdateMeta(p->pDest, 1, p->iDestSchema+1);
+ if( p->pDestDb ){
+ sqlite3ResetInternalSchema(p->pDestDb, 0);
+ }
+
+ /* Set nDestTruncate to the final number of pages in the destination
+ ** database. The complication here is that the destination page
+ ** size may be different to the source page size.
+ **
+ ** If the source page size is smaller than the destination page size,
+ ** round up. In this case the call to sqlite3OsTruncate() below will
+ ** fix the size of the file. However it is important to call
+ ** sqlite3PagerTruncateImage() here so that any pages in the
+ ** destination file that lie beyond the nDestTruncate page mark are
+ ** journalled by PagerCommitPhaseOne() before they are destroyed
+ ** by the file truncation.
+ */
+ if( nSrcPagesize<nDestPagesize ){
+ int ratio = nDestPagesize/nSrcPagesize;
+ nDestTruncate = (nSrcPage+ratio-1)/ratio;
+ if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){
+ nDestTruncate--;
+ }
+ }else{
+ nDestTruncate = nSrcPage * (nSrcPagesize/nDestPagesize);
+ }
+ sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
+
+ if( nSrcPagesize<nDestPagesize ){
+ /* If the source page-size is smaller than the destination page-size,
+ ** two extra things may need to happen:
+ **
+ ** * The destination may need to be truncated, and
+ **
+ ** * Data stored on the pages immediately following the
+ ** pending-byte page in the source database may need to be
+ ** copied into the destination database.
+ */
+ const i64 iSize = (i64)nSrcPagesize * (i64)nSrcPage;
+ sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
+
+ assert( pFile );
+ assert( (i64)nDestTruncate*(i64)nDestPagesize >= iSize || (
+ nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
+ && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+nDestPagesize
+ ));
+ if( SQLITE_OK==(rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1))
+ && SQLITE_OK==(rc = backupTruncateFile(pFile, iSize))
+ && SQLITE_OK==(rc = sqlite3PagerSync(pDestPager))
+ ){
+ i64 iOff;
+ i64 iEnd = MIN(PENDING_BYTE + nDestPagesize, iSize);
+ for(
+ iOff=PENDING_BYTE+nSrcPagesize;
+ rc==SQLITE_OK && iOff<iEnd;
+ iOff+=nSrcPagesize
+ ){
+ PgHdr *pSrcPg = 0;
+ const Pgno iSrcPg = (Pgno)((iOff/nSrcPagesize)+1);
+ rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
+ if( rc==SQLITE_OK ){
+ u8 *zData = sqlite3PagerGetData(pSrcPg);
+ rc = sqlite3OsWrite(pFile, zData, nSrcPagesize, iOff);
+ }
+ sqlite3PagerUnref(pSrcPg);
+ }
+ }
+ }else{
+ rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
+ }
+
+ /* Finish committing the transaction to the destination database. */
+ if( SQLITE_OK==rc
+ && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest))
+ ){
+ rc = SQLITE_DONE;
+ }
+ }
+
+ /* If bCloseTrans is true, then this function opened a read transaction
+ ** on the source database. Close the read transaction here. There is
+ ** no need to check the return values of the btree methods here, as
+ ** "committing" a read-only transaction cannot fail.
+ */
+ if( bCloseTrans ){
+ TESTONLY( int rc2 );
+ TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0);
+ TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc);
+ assert( rc2==SQLITE_OK );
+ }
+
+ p->rc = rc;
+ }
+ if( p->pDestDb ){
+ sqlite3_mutex_leave(p->pDestDb->mutex);
+ }
+ sqlite3BtreeLeave(p->pSrc);
+ sqlite3_mutex_leave(p->pSrcDb->mutex);
+ return rc;
+}
+
+/*
+** Release all resources associated with an sqlite3_backup* handle.
+*/
+SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
+ sqlite3_backup **pp; /* Ptr to head of pagers backup list */
+ sqlite3_mutex *mutex; /* Mutex to protect source database */
+ int rc; /* Value to return */
+
+ /* Enter the mutexes */
+ sqlite3_mutex_enter(p->pSrcDb->mutex);
+ sqlite3BtreeEnter(p->pSrc);
+ mutex = p->pSrcDb->mutex;
+ if( p->pDestDb ){
+ sqlite3_mutex_enter(p->pDestDb->mutex);
+ }
+
+ /* Detach this backup from the source pager. */
+ if( p->pDestDb ){
+ pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
+ while( *pp!=p ){
+ pp = &(*pp)->pNext;
+ }
+ *pp = p->pNext;
+ p->pSrc->nBackup--;
+ }
+
+ /* If a transaction is still open on the Btree, roll it back. */
+ sqlite3BtreeRollback(p->pDest);
+
+ /* Set the error code of the destination database handle. */
+ rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
+ sqlite3Error(p->pDestDb, rc, 0);
+
+ /* Exit the mutexes and free the backup context structure. */
+ if( p->pDestDb ){
+ sqlite3_mutex_leave(p->pDestDb->mutex);
+ }
+ sqlite3BtreeLeave(p->pSrc);
+ if( p->pDestDb ){
+ sqlite3_free(p);
+ }
+ sqlite3_mutex_leave(mutex);
+ return rc;
+}
+
+/*
+** Return the number of pages still to be backed up as of the most recent
+** call to sqlite3_backup_step().
+*/
+SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
+ return p->nRemaining;
+}
+
+/*
+** Return the total number of pages in the source database as of the most
+** recent call to sqlite3_backup_step().
+*/
+SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){
+ return p->nPagecount;
+}
+
+/*
+** This function is called after the contents of page iPage of the
+** source database have been modified. If page iPage has already been
+** copied into the destination database, then the data written to the
+** destination is now invalidated. The destination copy of iPage needs
+** to be updated with the new data before the backup operation is
+** complete.
+**
+** It is assumed that the mutex associated with the BtShared object
+** corresponding to the source database is held when this function is
+** called.
+*/
+SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){
+ sqlite3_backup *p; /* Iterator variable */
+ for(p=pBackup; p; p=p->pNext){
+ assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
+ if( !isFatalError(p->rc) && iPage<p->iNext ){
+ /* The backup process p has already copied page iPage. But now it
+ ** has been modified by a transaction on the source pager. Copy
+ ** the new data into the backup.
+ */
+ int rc = backupOnePage(p, iPage, aData);
+ assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
+ if( rc!=SQLITE_OK ){
+ p->rc = rc;
+ }
+ }
+ }
+}
+
+/*
+** Restart the backup process. This is called when the pager layer
+** detects that the database has been modified by an external database
+** connection. In this case there is no way of knowing which of the
+** pages that have been copied into the destination database are still
+** valid and which are not, so the entire process needs to be restarted.
+**
+** It is assumed that the mutex associated with the BtShared object
+** corresponding to the source database is held when this function is
+** called.
+*/
+SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *pBackup){
+ sqlite3_backup *p; /* Iterator variable */
+ for(p=pBackup; p; p=p->pNext){
+ assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
+ p->iNext = 1;
+ }
+}
+
+#ifndef SQLITE_OMIT_VACUUM
+/*
+** Copy the complete content of pBtFrom into pBtTo. A transaction
+** must be active for both files.
+**
+** The size of file pTo may be reduced by this operation. If anything
+** goes wrong, the transaction on pTo is rolled back. If successful, the
+** transaction is committed before returning.
+*/
+SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
+ int rc;
+ sqlite3_backup b;
+ sqlite3BtreeEnter(pTo);
+ sqlite3BtreeEnter(pFrom);
+
+ /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set
+ ** to 0. This is used by the implementations of sqlite3_backup_step()
+ ** and sqlite3_backup_finish() to detect that they are being called
+ ** from this function, not directly by the user.
+ */
+ memset(&b, 0, sizeof(b));
+ b.pSrcDb = pFrom->db;
+ b.pSrc = pFrom;
+ b.pDest = pTo;
+ b.iNext = 1;
+
+ /* 0x7FFFFFFF is the hard limit for the number of pages in a database
+ ** file. By passing this as the number of pages to copy to
+ ** sqlite3_backup_step(), we can guarantee that the copy finishes
+ ** within a single call (unless an error occurs). The assert() statement
+ ** checks this assumption - (p->rc) should be set to either SQLITE_DONE
+ ** or an error code.
+ */
+ sqlite3_backup_step(&b, 0x7FFFFFFF);
+ assert( b.rc!=SQLITE_OK );
+ rc = sqlite3_backup_finish(&b);
+ if( rc==SQLITE_OK ){
+ pTo->pBt->pageSizeFixed = 0;
+ }
+
+ sqlite3BtreeLeave(pFrom);
+ sqlite3BtreeLeave(pTo);
+ return rc;
+}
+#endif /* SQLITE_OMIT_VACUUM */
+
+/************** End of backup.c **********************************************/
/************** Begin file vdbemem.c *****************************************/
/*
** 2004 May 26
**
@@ -43751,9 +44241,9 @@
** stores a single value in the VDBE. Mem is an opaque structure visible
** only within the VDBE. Interface routines refer to a Mem using the
** name sqlite_value
**
-** $Id: vdbemem.c,v 1.134 2009/01/05 22:30:39 drh Exp $
+** $Id: vdbemem.c,v 1.139 2009/03/29 15:12:10 drh Exp $
*/
/*
** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*)
@@ -44055,8 +44545,12 @@
if( r<(double)minInt ){
return minInt;
}else if( r>(double)maxInt ){
+ /* minInt is correct here - not maxInt. It turns out that assigning
+ ** a very large positive number to an integer results in a very large
+ ** negative integer. This makes no sense, but it is what x86 hardware
+ ** does so for compatibility we will do the same in software. */
return minInt;
}else{
return (i64)r;
}
@@ -44067,11 +44561,12 @@
** at representing the value that *pMem describes as an integer.
** If pMem is an integer, then the value is exact. If pMem is
** a floating-point then the value returned is the integer part.
** If pMem is a string or blob, then we make an attempt to convert
-** it into a integer and return that. If pMem is NULL, return 0.
-**
-** If pMem is a string, its encoding might be changed.
+** it into a integer and return that. If pMem represents an
+** an SQL-NULL value, return 0.
+**
+** If pMem represents a string value, its encoding might be changed.
*/
SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
int flags;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
@@ -44107,19 +44602,22 @@
return pMem->r;
}else if( pMem->flags & MEM_Int ){
return (double)pMem->u.i;
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
- double val = 0.0;
+ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
+ double val = (double)0;
pMem->flags |= MEM_Str;
if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
|| sqlite3VdbeMemNulTerminate(pMem) ){
- return 0.0;
+ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
+ return (double)0;
}
assert( pMem->z );
sqlite3AtoF(pMem->z, &val);
return val;
}else{
- return 0.0;
+ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
+ return (double)0;
}
}
/*
@@ -44603,57 +45101,8 @@
return rc;
}
-#if 0
-/*
-** Perform various checks on the memory cell pMem. An assert() will
-** fail if pMem is internally inconsistent.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemSanity(Mem *pMem){
- int flags = pMem->flags;
- assert( flags!=0 ); /* Must define some type */
- if( flags & (MEM_Str|MEM_Blob) ){
- int x = flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
- assert( x!=0 ); /* Strings must define a string subtype */
- assert( (x & (x-1))==0 ); /* Only one string subtype can be defined */
- assert( pMem->z!=0 ); /* Strings must have a value */
- /* Mem.z points to Mem.zShort iff the subtype is MEM_Short */
- assert( (x & MEM_Short)==0 || pMem->z==pMem->zShort );
- assert( (x & MEM_Short)!=0 || pMem->z!=pMem->zShort );
- /* No destructor unless there is MEM_Dyn */
- assert( pMem->xDel==0 || (pMem->flags & MEM_Dyn)!=0 );
-
- if( (flags & MEM_Str) ){
- assert( pMem->enc==SQLITE_UTF8 ||
- pMem->enc==SQLITE_UTF16BE ||
- pMem->enc==SQLITE_UTF16LE
- );
- /* If the string is UTF-8 encoded and nul terminated, then pMem->n
- ** must be the length of the string. (Later:) If the database file
- ** has been corrupted, '\000' characters might have been inserted
- ** into the middle of the string. In that case, the sqlite3Strlen30()
- ** might be less.
- */
- if( pMem->enc==SQLITE_UTF8 && (flags & MEM_Term) ){
- assert( sqlite3Strlen30(pMem->z)<=pMem->n );
- assert( pMem->z[pMem->n]==0 );
- }
- }
- }else{
- /* Cannot define a string subtype for non-string objects */
- assert( (pMem->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );
- assert( pMem->xDel==0 );
- }
- /* MEM_Null excludes all other types */
- assert( (pMem->flags&(MEM_Str|MEM_Int|MEM_Real|MEM_Blob))==0
- || (pMem->flags&MEM_Null)==0 );
- /* If the MEM is both real and integer, the values are equal */
- assert( (pMem->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real)
- || pMem->r==pMem->u.i );
-}
-#endif
-
/* This function is only available internally, it is not part of the
** external API. It works in a similar way to sqlite3_value_text(),
** except the data returned is in the encoding specified by the second
** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
@@ -44752,9 +45201,10 @@
}
}else if( op==TK_UMINUS ) {
if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){
pVal->u.i = -1 * pVal->u.i;
- pVal->r = -1.0 * pVal->r;
+ /* (double)-1 In case of SQLITE_OMIT_FLOATING_POINT... */
+ pVal->r = (double)-1 * pVal->r;
}
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
else if( op==TK_BLOB ){
@@ -44838,9 +45288,9 @@
** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior
** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out.
**
-** $Id: vdbeaux.c,v 1.430 2009/01/07 08:12:16 danielk1977 Exp $
+** $Id: vdbeaux.c,v 1.446 2009/03/25 15:43:09 danielk1977 Exp $
*/
@@ -44874,19 +45324,24 @@
/*
** Remember the SQL string for a prepared statement.
*/
-SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n){
+SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
if( p==0 ) return;
+#ifdef SQLITE_OMIT_TRACE
+ if( !isPrepareV2 ) return;
+#endif
assert( p->zSql==0 );
p->zSql = sqlite3DbStrNDup(p->db, z, n);
+ p->isPrepareV2 = isPrepareV2 ? 1 : 0;
}
/*
** Return the SQL associated with a prepared statement
*/
SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){
- return ((Vdbe *)pStmt)->zSql;
+ Vdbe *p = (Vdbe *)pStmt;
+ return (p->isPrepareV2 ? p->zSql : 0);
}
/*
** Swap all content between two VDBE structures.
@@ -44893,9 +45348,8 @@
*/
SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
Vdbe tmp, *pTmp;
char *zTmp;
- int nTmp;
tmp = *pA;
*pA = *pB;
*pB = tmp;
pTmp = pA->pNext;
@@ -44906,11 +45360,9 @@
pB->pPrev = pTmp;
zTmp = pA->zSql;
pA->zSql = pB->zSql;
pB->zSql = zTmp;
- nTmp = pA->nSql;
- pA->nSql = pB->nSql;
- pB->nSql = nTmp;
+ pB->isPrepareV2 = pA->isPrepareV2;
}
#ifdef SQLITE_DEBUG
/*
@@ -44934,9 +45386,9 @@
VdbeOp *pNew;
int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
pNew = sqlite3DbRealloc(p->db, p->aOp, nNew*sizeof(Op));
if( pNew ){
- p->nOpAlloc = nNew;
+ p->nOpAlloc = sqlite3DbMallocSize(p->db, pNew)/sizeof(Op);
p->aOp = pNew;
}
return (pNew ? SQLITE_OK : SQLITE_NOMEM);
}
@@ -45723,10 +46175,10 @@
pMem++;
}
if( sqlite3VdbeMemGrow(pMem, 32, 0) ){ /* P4 */
- p->db->mallocFailed = 1;
- return SQLITE_NOMEM;
+ assert( p->db->mallocFailed );
+ return SQLITE_ERROR;
}
pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
z = displayP4(pOp, pMem->z, 32);
if( z!=pMem->z ){
@@ -45740,10 +46192,10 @@
pMem++;
if( p->explain==1 ){
if( sqlite3VdbeMemGrow(pMem, 4, 0) ){
- p->db->mallocFailed = 1;
- return SQLITE_NOMEM;
+ assert( p->db->mallocFailed );
+ return SQLITE_ERROR;
}
pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
pMem->n = 2;
sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
@@ -45784,9 +46236,9 @@
if( nOp<1 ) return;
pOp = &p->aOp[0];
if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
const char *z = pOp->p4.z;
- while( isspace(*(u8*)z) ) z++;
+ while( sqlite3Isspace(*z) ) z++;
printf("SQL: [%s]\n", z);
}
}
#endif
@@ -45804,11 +46256,11 @@
if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
int i, j;
char z[1000];
sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z);
- for(i=0; isspace((unsigned char)z[i]); i++){}
+ for(i=0; sqlite3Isspace(z[i]); i++){}
for(j=0; z[i]; i++){
- if( isspace((unsigned char)z[i]) ){
+ if( sqlite3Isspace(z[i]) ){
if( z[i-1]!=' ' ){
z[j++] = ' ';
}
}else{
@@ -45820,8 +46272,41 @@
}
}
#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
+/*
+** Allocate space from a fixed size buffer. Make *pp point to the
+** allocated space. (Note: pp is a char* rather than a void** to
+** work around the pointer aliasing rules of C.) *pp should initially
+** be zero. If *pp is not zero, that means that the space has already
+** been allocated and this routine is a noop.
+**
+** nByte is the number of bytes of space needed.
+**
+** *ppFrom point to available space and pEnd points to the end of the
+** available space.
+**
+** *pnByte is a counter of the number of bytes of space that have failed
+** to allocate. If there is insufficient space in *ppFrom to satisfy the
+** request, then increment *pnByte by the amount of the request.
+*/
+static void allocSpace(
+ char *pp, /* IN/OUT: Set *pp to point to allocated buffer */
+ int nByte, /* Number of bytes to allocate */
+ u8 **ppFrom, /* IN/OUT: Allocate from *ppFrom */
+ u8 *pEnd, /* Pointer to 1 byte past the end of *ppFrom buffer */
+ int *pnByte /* If allocation cannot be made, increment *pnByte */
+){
+ if( (*(void**)pp)==0 ){
+ nByte = ROUND8(nByte);
+ if( (pEnd - *ppFrom)>=nByte ){
+ *(void**)pp = (void *)*ppFrom;
+ *ppFrom += nByte;
+ }else{
+ *pnByte += nByte;
+ }
+ }
+}
/*
** Prepare a virtual machine for execution. This involves things such
** as allocating stack space and initializing the program counter.
@@ -45829,8 +46314,16 @@
** calls to sqlite3VdbeExec().
**
** This is the only way to move a VDBE from VDBE_MAGIC_INIT to
** VDBE_MAGIC_RUN.
+**
+** This function may be called more than once on a single virtual machine.
+** The first call is made while compiling the SQL statement. Subsequent
+** calls are made as part of the process of resetting a statement to be
+** re-executed (from a call to sqlite3_reset()). The nVar, nMem, nCursor
+** and isExplain parameters are only passed correct values the first time
+** the function is called. On subsequent calls, from sqlite3_reset(), nVar
+** is passed -1 and nMem, nCursor and isExplain are all passed zero.
*/
SQLITE_PRIVATE void sqlite3VdbeMakeReady(
Vdbe *p, /* The VDBE */
int nVar, /* Number of '?' see in the SQL statement */
@@ -45861,39 +46354,51 @@
** See also: allocateCursor().
*/
nMem += nCursor;
- /*
- ** Allocation space for registers.
- */
- if( p->aMem==0 ){
+ /* Allocate space for memory registers, SQL variables, VDBE cursors and
+ ** an array to marshal SQL function arguments in. This is only done the
+ ** first time this function is called for a given VDBE, not when it is
+ ** being called from sqlite3_reset() to reset the virtual machine.
+ */
+ if( nVar>=0 && !db->mallocFailed ){
+ u8 *zCsr = (u8 *)&p->aOp[p->nOp];
+ u8 *zEnd = (u8 *)&p->aOp[p->nOpAlloc];
+ int nByte;
int nArg; /* Maximum number of args passed to a user function. */
resolveP2Values(p, &nArg);
- assert( nVar>=0 );
if( isExplain && nMem<10 ){
nMem = 10;
}
- p->aMem = sqlite3DbMallocZero(db,
- nMem*sizeof(Mem) /* aMem */
- + nVar*sizeof(Mem) /* aVar */
- + nArg*sizeof(Mem*) /* apArg */
- + nVar*sizeof(char*) /* azVar */
- + nCursor*sizeof(VdbeCursor*)+1 /* apCsr */
- );
- if( !db->mallocFailed ){
- p->aMem--; /* aMem[] goes from 1..nMem */
- p->nMem = nMem; /* not from 0..nMem-1 */
- p->aVar = &p->aMem[nMem+1];
- p->nVar = nVar;
- p->okVar = 0;
- p->apArg = (Mem**)&p->aVar[nVar];
- p->azVar = (char**)&p->apArg[nArg];
- p->apCsr = (VdbeCursor**)&p->azVar[nVar];
- p->nCursor = nCursor;
+
+ do {
+ memset(zCsr, 0, zEnd-zCsr);
+ nByte = 0;
+ allocSpace((char*)&p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
+ allocSpace((char*)&p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
+ allocSpace((char*)&p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
+ allocSpace((char*)&p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
+ allocSpace((char*)&p->apCsr,
+ nCursor*sizeof(VdbeCursor*), &zCsr, zEnd, &nByte
+ );
+ if( nByte ){
+ p->pFree = sqlite3DbMallocRaw(db, nByte);
+ }
+ zCsr = p->pFree;
+ zEnd = &zCsr[nByte];
+ }while( nByte && !db->mallocFailed );
+
+ p->nCursor = nCursor;
+ if( p->aVar ){
+ p->nVar = nVar;
for(n=0; n<nVar; n++){
p->aVar[n].flags = MEM_Null;
p->aVar[n].db = db;
}
+ }
+ if( p->aMem ){
+ p->aMem--; /* aMem[] goes from 1..nMem */
+ p->nMem = nMem; /* not from 0..nMem-1 */
for(n=1; n<=nMem; n++){
p->aMem[n].flags = MEM_Null;
p->aMem[n].db = db;
}
@@ -45906,16 +46411,15 @@
#endif
p->pc = -1;
p->rc = SQLITE_OK;
- p->uniqueCnt = 0;
p->errorAction = OE_Abort;
p->explain |= isExplain;
p->magic = VDBE_MAGIC_RUN;
p->nChange = 0;
p->cacheCtr = 1;
p->minWriteFileFormat = 255;
- p->openedStatement = 0;
+ p->iStatement = 0;
#ifdef VDBE_PROFILE
{
int i;
for(i=0; i<p->nOp; i++){
@@ -46209,12 +46713,12 @@
/* Sync the master journal file. If the IOCAP_SEQUENTIAL device
** flag is set this is not required.
*/
- zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt);
- if( (needSync
- && (0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL))
- && (rc=sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))!=SQLITE_OK) ){
+ if( needSync
+ && 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
+ && SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
+ ){
sqlite3OsCloseFree(pMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
sqlite3DbFree(db, zMaster);
return rc;
@@ -46227,9 +46731,9 @@
** If the error occurs during the first call to
** sqlite3BtreeCommitPhaseOne(), then there is a chance that the
** master journal file will be orphaned. But we cannot delete it,
** in case the master journal file name was written into the journal
- ** file before the failure occured.
+ ** file before the failure occurred.
*/
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
@@ -46333,8 +46837,50 @@
}
}
/*
+** If the Vdbe passed as the first argument opened a statement-transaction,
+** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or
+** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement
+** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the
+** statement transaction is commtted.
+**
+** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned.
+** Otherwise SQLITE_OK.
+*/
+SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
+ sqlite3 *const db = p->db;
+ int rc = SQLITE_OK;
+ if( p->iStatement && db->nStatement ){
+ int i;
+ const int iSavepoint = p->iStatement-1;
+
+ assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
+ assert( db->nStatement>0 );
+ assert( p->iStatement==(db->nStatement+db->nSavepoint) );
+
+ for(i=0; i<db->nDb; i++){
+ int rc2 = SQLITE_OK;
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt ){
+ if( eOp==SAVEPOINT_ROLLBACK ){
+ rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint);
+ }
+ if( rc2==SQLITE_OK ){
+ rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint);
+ }
+ if( rc==SQLITE_OK ){
+ rc = rc2;
+ }
+ }
+ }
+ db->nStatement--;
+ p->iStatement = 0;
+ }
+ return rc;
+}
+
+/*
** This routine is called the when a VDBE tries to halt. If the VDBE
** has made changes and is in autocommit mode, then commit those
** changes. If a rollback is needed, then do the rollback.
**
@@ -46346,12 +46892,10 @@
** lock contention, return SQLITE_BUSY. If SQLITE_BUSY is returned, it
** means the close did not happen and needs to be repeated.
*/
SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
- sqlite3 *db = p->db;
- int i;
- int (*xFunc)(Btree *pBt) = 0; /* Function to call on each btree backend */
- int isSpecialError; /* Set to true if SQLITE_NOMEM or IOERR */
+ int rc; /* Used to store transient return codes */
+ sqlite3 *db = p->db;
/* This function contains the logic that determines if a statement or
** transaction will be committed or rolled back as a result of the
** execution of this virtual machine.
@@ -46379,8 +46923,10 @@
/* No commit or rollback needed if the program never started */
if( p->pc>=0 ){
int mrc; /* Primary error code from p->rc */
+ int eStatementOp = 0;
+ int isSpecialError; /* Set to true if a 'special' error */
/* Lock all btrees used by the statement */
sqlite3BtreeMutexArrayEnter(&p->aMutex);
@@ -46393,13 +46939,13 @@
** proceed with the special handling.
*/
if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){
if( p->rc==SQLITE_IOERR_BLOCKED && p->usesStmtJournal ){
- xFunc = sqlite3BtreeRollbackStmt;
+ eStatementOp = SAVEPOINT_ROLLBACK;
p->rc = SQLITE_BUSY;
}else if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL)
&& p->usesStmtJournal ){
- xFunc = sqlite3BtreeRollbackStmt;
+ eStatementOp = SAVEPOINT_ROLLBACK;
}else{
/* We are forced to roll back the active transaction. Before doing
** so, abort any other statements this handle currently has active.
*/
@@ -46410,10 +46956,10 @@
}
}
}
- /* If the auto-commit flag is set and this is the only active vdbe, then
- ** we do either a commit or rollback of the current transaction.
+ /* If the auto-commit flag is set and this is the only active writer
+ ** VM, then we do either a commit or rollback of the current transaction.
**
** Note: This block also runs if one of the special errors handled
** above has occurred.
*/
@@ -46426,9 +46972,9 @@
/* The auto-commit flag is true, and the vdbe program was
** successful or hit an 'OR FAIL' constraint. This means a commit
** is required.
*/
- int rc = vdbeCommit(db, p);
+ rc = vdbeCommit(db, p);
if( rc==SQLITE_BUSY ){
sqlite3BtreeMutexArrayLeave(&p->aMutex);
return SQLITE_BUSY;
}else if( rc!=SQLITE_OK ){
@@ -46439,15 +46985,14 @@
}
}else{
sqlite3RollbackAll(db);
}
- }else if( !xFunc ){
+ db->nStatement = 0;
+ }else if( eStatementOp==0 ){
if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
- if( p->openedStatement ){
- xFunc = sqlite3BtreeCommitStmt;
- }
+ eStatementOp = SAVEPOINT_RELEASE;
}else if( p->errorAction==OE_Abort ){
- xFunc = sqlite3BtreeRollbackStmt;
+ eStatementOp = SAVEPOINT_ROLLBACK;
}else{
invalidateCursorsOnModifiedBtrees(db);
sqlite3RollbackAll(db);
sqlite3CloseSavepoints(db);
@@ -46454,35 +46999,28 @@
db->autoCommit = 1;
}
}
- /* If xFunc is not NULL, then it is one of sqlite3BtreeRollbackStmt or
- ** sqlite3BtreeCommitStmt. Call it once on each backend. If an error occurs
- ** and the return code is still SQLITE_OK, set the return code to the new
- ** error value.
- */
- assert(!xFunc ||
- xFunc==sqlite3BtreeCommitStmt ||
- xFunc==sqlite3BtreeRollbackStmt
- );
- for(i=0; xFunc && i<db->nDb; i++){
- int rc;
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- rc = xFunc(pBt);
- if( rc && (p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT) ){
- p->rc = rc;
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
- }
- }
- }
-
- /* If this was an INSERT, UPDATE or DELETE and the statement was committed,
- ** set the change counter.
+ /* If eStatementOp is non-zero, then a statement transaction needs to
+ ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to
+ ** do so. If this operation returns an error, and the current statement
+ ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then set the error
+ ** code to the new value.
+ */
+ if( eStatementOp ){
+ rc = sqlite3VdbeCloseStatement(p, eStatementOp);
+ if( rc && (p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT) ){
+ p->rc = rc;
+ sqlite3DbFree(db, p->zErrMsg);
+ p->zErrMsg = 0;
+ }
+ }
+
+ /* If this was an INSERT, UPDATE or DELETE and no statement transaction
+ ** has been rolled back, update the database connection change-counter.
*/
if( p->changeCntOn && p->pc>=0 ){
- if( !xFunc || xFunc==sqlite3BtreeCommitStmt ){
+ if( eStatementOp!=SAVEPOINT_ROLLBACK ){
sqlite3VdbeSetChanges(db, p->nChange);
}else{
sqlite3VdbeSetChanges(db, 0);
}
@@ -46512,8 +47050,17 @@
if( p->db->mallocFailed ){
p->rc = SQLITE_NOMEM;
}
+ /* If the auto-commit flag is set to true, then any locks that were held
+ ** by connection db have now been released. Call sqlite3ConnectionUnlocked()
+ ** to invoke any required unlock-notify callbacks.
+ */
+ if( db->autoCommit ){
+ sqlite3ConnectionUnlocked(db);
+ }
+
+ assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 );
return SQLITE_OK;
}
@@ -46669,19 +47216,17 @@
#ifdef SQLITE_DEBUG
sqlite3DbFree(db, pOp->zComment);
#endif
}
- sqlite3DbFree(db, p->aOp);
}
releaseMemArray(p->aVar, p->nVar);
sqlite3DbFree(db, p->aLabel);
- if( p->aMem ){
- sqlite3DbFree(db, &p->aMem[1]);
- }
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
sqlite3DbFree(db, p->aColName);
sqlite3DbFree(db, p->zSql);
p->magic = VDBE_MAGIC_DEAD;
+ sqlite3DbFree(db, p->aOp);
+ sqlite3DbFree(db, p->pFree);
sqlite3DbFree(db, p);
}
/*
@@ -47382,9 +47927,9 @@
**
** This file contains code use to implement APIs that are part of the
** VDBE.
**
-** $Id: vdbeapi.c,v 1.150 2008/12/10 18:03:47 drh Exp $
+** $Id: vdbeapi.c,v 1.156 2009/03/25 15:43:09 danielk1977 Exp $
*/
#if 0 && defined(SQLITE_ENABLE_MEMORY_MANAGEMENT)
/*
@@ -47571,14 +48116,16 @@
if( pStmt==0 ){
rc = SQLITE_OK;
}else{
Vdbe *v = (Vdbe*)pStmt;
+ sqlite3 *db = v->db;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = v->db->mutex;
#endif
sqlite3_mutex_enter(mutex);
stmtLruRemove(v);
rc = sqlite3VdbeFinalize(v);
+ rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(mutex);
}
return rc;
}
@@ -47601,8 +48148,9 @@
rc = sqlite3VdbeReset(v);
stmtLruAdd(v);
sqlite3VdbeMakeReady(v, -1, 0, 0, 0);
assert( (rc & (v->db->errMask))==rc );
+ rc = sqlite3ApiExit(v->db, rc);
sqlite3_mutex_leave(v->db->mutex);
}
return rc;
}
@@ -47855,36 +48403,43 @@
#ifndef SQLITE_OMIT_TRACE
/* Invoke the profile callback if there is one
*/
- if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy && p->nOp>0
- && p->aOp[0].opcode==OP_Trace && p->aOp[0].p4.z!=0 ){
+ if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy && p->zSql ){
double rNow;
u64 elapseTime;
sqlite3OsCurrentTime(db->pVfs, &rNow);
elapseTime = (u64)((rNow - (int)rNow)*3600.0*24.0*1000000000.0);
elapseTime -= p->startTime;
- db->xProfile(db->pProfileArg, p->aOp[0].p4.z, elapseTime);
+ db->xProfile(db->pProfileArg, p->zSql, elapseTime);
}
#endif
db->errCode = rc;
- /*sqlite3Error(p->db, rc, 0);*/
- p->rc = sqlite3ApiExit(p->db, p->rc);
+ if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){
+ p->rc = SQLITE_NOMEM;
+ }
end_of_step:
- assert( (rc&0xff)==rc );
- if( p->zSql && (rc&0xff)<SQLITE_ROW ){
- /* This behavior occurs if sqlite3_prepare_v2() was used to build
- ** the prepared statement. Return error codes directly */
- p->db->errCode = p->rc;
- /* sqlite3Error(p->db, p->rc, 0); */
- return p->rc;
- }else{
- /* This is for legacy sqlite3_prepare() builds and when the code
- ** is SQLITE_ROW or SQLITE_DONE */
- return rc;
- }
+ /* At this point local variable rc holds the value that should be
+ ** returned if this statement was compiled using the legacy
+ ** sqlite3_prepare() interface. According to the docs, this can only
+ ** be one of the values in the first assert() below. Variable p->rc
+ ** contains the value that would be returned if sqlite3_finalize()
+ ** were called on statement p.
+ */
+ assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR
+ || rc==SQLITE_BUSY || rc==SQLITE_MISUSE
+ );
+ assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE );
+ if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
+ /* If this statement was prepared using sqlite3_prepare_v2(), and an
+ ** error has occured, then return the error code in p->rc to the
+ ** caller. Set the error code in the database handle to the same value.
+ */
+ rc = db->errCode = p->rc;
+ }
+ return (rc&db->errMask);
}
/*
** This is the top-level implementation of sqlite3_step(). Call
@@ -47912,13 +48467,13 @@
sqlite3 *db = v->db;
sqlite3_mutex_enter(db->mutex);
while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
&& cnt++ < 5
- && vdbeReprepare(v) ){
+ && (rc = vdbeReprepare(v))==SQLITE_OK ){
sqlite3_reset(pStmt);
v->expired = 0;
}
- if( rc==SQLITE_SCHEMA && v->zSql && db->pErr ){
+ if( rc==SQLITE_SCHEMA && v->isPrepareV2 && db->pErr ){
/* This case occurs after failing to recompile an sql statement.
** The error message from the SQL compiler has already been loaded
** into the database handle. This block copies the error message
** from the database handle into the statement and sets the statement
@@ -48078,9 +48633,9 @@
** implementations should keep their own counts within their aggregate
** context.
*/
SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){
- assert( p && p->pFunc && p->pFunc->xStep );
+ assert( p && p->pMem && p->pFunc && p->pFunc->xStep );
return p->pMem->n;
}
#endif
@@ -48119,10 +48674,11 @@
sqlite3_mutex_enter(pVm->db->mutex);
vals = sqlite3_data_count(pStmt);
pOut = &pVm->pResultSet[i];
}else{
- static const Mem nullMem = {{0}, 0.0, 0, "", 0, MEM_Null, SQLITE_NULL, 0, 0, 0 };
- if( pVm->db ){
+ /* ((double)0) In case of SQLITE_OMIT_FLOATING_POINT... */
+ static const Mem nullMem = {{0}, (double)0, 0, "", 0, MEM_Null, SQLITE_NULL, 0, 0, 0 };
+ if( pVm && pVm->db ){
sqlite3_mutex_enter(pVm->db->mutex);
sqlite3Error(pVm->db, SQLITE_RANGE, 0);
}
pOut = (Mem*)&nullMem;
@@ -48723,9 +49279,9 @@
** of the code in this file is, therefore, important. See other comments
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.811 2009/01/14 00:55:10 drh Exp $
+** $Id: vdbe.c,v 1.828 2009/03/23 17:11:27 danielk1977 Exp $
*/
/*
** The following global variable is incremented every time a cursor
@@ -48865,9 +49421,9 @@
*/
static VdbeCursor *allocateCursor(
Vdbe *p, /* The virtual machine */
int iCur, /* Index of the new VdbeCursor */
- Op *pOp, /* */
+ int nField, /* Number of fields in the table or index */
int iDb, /* When database the cursor belongs to, or -1 */
int isBtreeCursor /* */
){
/* Find the memory cell that will be used to store the blob of memory
@@ -48891,17 +49447,8 @@
Mem *pMem = &p->aMem[p->nMem-iCur];
int nByte;
VdbeCursor *pCx = 0;
- /* If the opcode of pOp is OP_SetNumColumns, then pOp->p2 contains
- ** the number of fields in the records contained in the table or
- ** index being opened. Use this to reserve space for the
- ** VdbeCursor.aType[] array.
- */
- int nField = 0;
- if( pOp->opcode==OP_SetNumColumns || pOp->opcode==OP_OpenEphemeral ){
- nField = pOp->p2;
- }
nByte =
sizeof(VdbeCursor) +
(isBtreeCursor?sqlite3BtreeCursorSize():0) +
2*nField*sizeof(u32);
@@ -49332,9 +49879,9 @@
Mem *pIn3 = 0; /* 3rd input operand */
Mem *pOut = 0; /* Output operand */
u8 opProperty;
int iCompare = 0; /* Result of last OP_Compare operation */
- int *aPermute = 0; /* Permuation of columns for OP_Compare */
+ int *aPermute = 0; /* Permutation of columns for OP_Compare */
#ifdef VDBE_PROFILE
u64 start; /* CPU clock count at start of opcode */
int origPc; /* Program counter at start of opcode */
#endif
@@ -49588,8 +50135,18 @@
pc = pcDest;
break;
}
+/* Opcode: HaltIfNull P1 P2 P3 P4 *
+**
+** Check the value in register P3. If is is NULL then Halt using
+** parameter P1, P2, and P4 as if this were a Halt instruction. If the
+** value in register P3 is not NULL, then this routine is a no-op.
+*/
+case OP_HaltIfNull: { /* in3 */
+ if( (pIn3->flags & MEM_Null)==0 ) break;
+ /* Fall through into OP_Halt */
+}
/* Opcode: Halt P1 P2 * P4 *
**
** Exit immediately. All open cursors, etc are closed
@@ -49736,28 +50293,36 @@
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
-/* Opcode: Variable P1 P2 * * *
-**
-** The value of variable P1 is written into register P2. A variable is
-** an unknown in the original SQL string as handed to sqlite3_compile().
-** Any occurrence of the '?' character in the original SQL is considered
-** a variable. Variables in the SQL string are number from left to
-** right beginning with 1. The values of variables are set using the
-** sqlite3_bind() API.
-*/
-case OP_Variable: { /* out2-prerelease */
+/* Opcode: Variable P1 P2 P3 P4 *
+**
+** Transfer the values of bound parameters P1..P1+P3-1 into registers
+** P2..P2+P3-1.
+**
+** If the parameter is named, then its name appears in P4 and P3==1.
+** The P4 value is used by sqlite3_bind_parameter_name().
+*/
+case OP_Variable: {
int j = pOp->p1 - 1;
+ int k = pOp->p2;
Mem *pVar;
- assert( j>=0 && j<p->nVar );
-
- pVar = &p->aVar[j];
- if( sqlite3VdbeMemTooBig(pVar) ){
- goto too_big;
- }
- sqlite3VdbeMemShallowCopy(pOut, &p->aVar[j], MEM_Static);
- UPDATE_MAX_BLOBSIZE(pOut);
+ int n = pOp->p3;
+ assert( j>=0 && j+n<=p->nVar );
+ assert( k>=1 && k+n-1<=p->nMem );
+ assert( pOp->p4.z==0 || pOp->p3==1 );
+
+ while( n-- > 0 ){
+ pVar = &p->aVar[j++];
+ if( sqlite3VdbeMemTooBig(pVar) ){
+ goto too_big;
+ }
+ pOut = &p->aMem[k++];
+ sqlite3VdbeMemReleaseExternal(pOut);
+ pOut->flags = MEM_Null;
+ sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
+ UPDATE_MAX_BLOBSIZE(pOut);
+ }
break;
}
/* Opcode: Move P1 P2 P3 * *
@@ -49771,17 +50336,16 @@
char *zMalloc;
int n = pOp->p3;
int p1 = pOp->p1;
int p2 = pOp->p2;
- assert( n>0 );
- assert( p1>0 );
- assert( p1+n<p->nMem );
+ assert( n>0 && p1>0 && p2>0 );
+ assert( p1+n<=p2 || p2+n<=p1 );
+
pIn1 = &p->aMem[p1];
- assert( p2>0 );
- assert( p2+n<p->nMem );
pOut = &p->aMem[p2];
- assert( p1+n<=p2 || p2+n<=p1 );
while( n-- ){
+ assert( pOut<=&p->aMem[p->nMem] );
+ assert( pIn1<=&p->aMem[p->nMem] );
zMalloc = pOut->zMalloc;
pOut->zMalloc = 0;
sqlite3VdbeMemMove(pOut, pIn1);
pIn1->zMalloc = zMalloc;
@@ -49845,9 +50409,26 @@
Mem *pMem;
int i;
assert( p->nResColumn==pOp->p2 );
assert( pOp->p1>0 );
- assert( pOp->p1+pOp->p2<=p->nMem );
+ assert( pOp->p1+pOp->p2<=p->nMem+1 );
+
+ /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then
+ ** DML statements invoke this opcode to return the number of rows
+ ** modified to the user. This is the only way that a VM that
+ ** opens a statement transaction may invoke this opcode.
+ **
+ ** In case this is such a statement, close any statement transaction
+ ** opened by this VM before returning control to the user. This is to
+ ** ensure that statement-transactions are always nested, not overlapping.
+ ** If the open statement-transaction is not closed here, then the user
+ ** may step another VM that opens its own statement transaction. This
+ ** may lead to overlapping statement transactions.
+ */
+ assert( p->iStatement==0 || db->flags&SQLITE_CountRows );
+ if( SQLITE_OK!=(rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE)) ){
+ break;
+ }
/* Invalidate all ephemeral cursor row caches */
p->cacheCtr = (p->cacheCtr + 2)|1;
@@ -49864,9 +50445,8 @@
if( db->mallocFailed ) goto no_mem;
/* Return SQLITE_ROW
*/
- p->nCallback++;
p->pc = pc + 1;
rc = SQLITE_ROW;
goto vdbe_return;
}
@@ -49997,9 +50577,10 @@
case OP_Add: b += a; break;
case OP_Subtract: b -= a; break;
case OP_Multiply: b *= a; break;
case OP_Divide: {
- if( a==0.0 ) goto arithmetic_result_is_null;
+ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
+ if( a==(double)0 ) goto arithmetic_result_is_null;
b /= a;
break;
}
default: {
@@ -50068,9 +50649,9 @@
apVal = p->apArg;
assert( apVal || n==0 );
- assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem) );
+ assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem+1) );
assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
pArg = &p->aMem[pOp->p2];
for(i=0; i<n; i++, pArg++){
apVal[i] = pArg;
@@ -50469,9 +51050,9 @@
}
/* Opcode: Permutation * * * P4 *
**
-** Set the permuation used by the OP_Compare operator to be the array
+** Set the permutation used by the OP_Compare operator to be the array
** of integers in P4.
**
** The permutation is only valid until the next OP_Permutation, OP_Compare,
** OP_Halt, or OP_ResultRow. Typically the OP_Permutation should occur
@@ -50504,11 +51085,11 @@
const KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
assert( n>0 );
assert( pKeyInfo!=0 );
p1 = pOp->p1;
- assert( p1>0 && p1+n-1<p->nMem );
+ assert( p1>0 && p1+n<=p->nMem+1 );
p2 = pOp->p2;
- assert( p2>0 && p2+n-1<p->nMem );
+ assert( p2>0 && p2+n<=p->nMem+1 );
for(i=0; i<n; i++){
int idx = aPermute ? aPermute[i] : i;
CollSeq *pColl; /* Collating sequence to use on this term */
int bRev; /* True for DESCENDING sort order */
@@ -50642,9 +51223,9 @@
if( pIn1->flags & MEM_Null ){
c = pOp->p3;
}else{
#ifdef SQLITE_OMIT_FLOATING_POINT
- c = sqlite3VdbeIntValue(pIn1);
+ c = sqlite3VdbeIntValue(pIn1)!=0;
#else
c = sqlite3VdbeRealValue(pIn1)!=0.0;
#endif
if( pOp->opcode==OP_IfNot ) c = !c;
@@ -50700,11 +51281,13 @@
** If the OP_Column opcode is to be executed on a cursor, then
** this opcode must be present immediately before the opcode that
** opens the cursor.
*/
+#if 0
case OP_SetNumColumns: {
break;
}
+#endif
/* Opcode: Column P1 P2 P3 P4 *
**
** Interpret the data that cursor P1 points to as a structure built using
@@ -51021,9 +51604,9 @@
int i; /* Space used in zNewRecord[] */
nField = pOp->p1;
zAffinity = pOp->p4.z;
- assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem );
+ assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem+1 );
pData0 = &p->aMem[nField];
nField = pOp->p2;
pLast = &pData0[nField-1];
file_format = p->minWriteFileFormat;
@@ -51098,8 +51681,24 @@
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
+/* Opcode: Count P1 P2 * * *
+**
+** 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 */
+ i64 nEntry;
+ BtCursor *pCrsr = p->apCsr[pOp->p1]->pCursor;
+ rc = sqlite3BtreeCount(pCrsr, &nEntry);
+ pOut->flags = MEM_Int;
+ pOut->u.i = nEntry;
+ break;
+}
+#endif
+
/* Opcode: Statement P1 * * * *
**
** Begin an individual statement transaction which is part of a larger
** transaction. This is needed so that the statement
@@ -51129,12 +51728,14 @@
assert( db->aDb[i].pBt!=0 );
pBt = db->aDb[i].pBt;
assert( sqlite3BtreeIsInTrans(pBt) );
assert( (p->btreeMask & (1<<i))!=0 );
- if( !sqlite3BtreeIsInStmt(pBt) ){
- rc = sqlite3BtreeBeginStmt(pBt);
- p->openedStatement = 1;
- }
+ if( p->iStatement==0 ){
+ assert( db->nStatement>=0 && db->nSavepoint>=0 );
+ db->nStatement++;
+ p->iStatement = db->nSavepoint + db->nStatement;
+ }
+ rc = sqlite3BtreeBeginStmt(pBt, p->iStatement);
}
break;
}
@@ -51239,9 +51840,9 @@
for(ii=0; ii<db->nDb; ii++){
rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
- }
+ }
}
if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetInternalSchema(db, 0);
@@ -51275,9 +51876,10 @@
/* Opcode: AutoCommit P1 P2 * * *
**
** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll
** back any currently active btree transactions. If there are any active
-** VMs (apart from this one), then the COMMIT or ROLLBACK statement fails.
+** VMs (apart from this one), then a ROLLBACK fails. A COMMIT fails if
+** there are active writing VMs or active VMs that use shared cache.
**
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {
@@ -51318,8 +51920,9 @@
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
}
+ assert( db->nStatement==0 );
sqlite3CloseSavepoints(db);
if( p->rc==SQLITE_OK ){
rc = SQLITE_DONE;
}else{
@@ -51535,11 +52138,13 @@
** released when all cursors are closed. If this instruction attempts
** to get a read lock but fails, the script terminates with an
** SQLITE_BUSY error code.
**
-** The P4 value is a pointer to a KeyInfo structure that defines the
-** content and collating sequence of indices. P4 is NULL for cursors
-** that are not pointing to indices.
+** The P4 value may be either an integer (P4_INT32) or a pointer to
+** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
+** structure, then said structure defines the content and collating
+** sequence of the index being opened. Otherwise, if P4 is an integer
+** value, it is set to the number of columns in the table.
**
** See also OpenWrite.
*/
/* Opcode: OpenWrite P1 P2 P3 P4 P5
@@ -51547,11 +52152,13 @@
** Open a read/write cursor named P1 on the table or index whose root
** page is P2. Or if P5!=0 use the content of register P2 to find the
** root page.
**
-** The P4 value is a pointer to a KeyInfo structure that defines the
-** content and collating sequence of indices. P4 is NULL for cursors
-** that are not pointing to indices.
+** The P4 value may be either an integer (P4_INT32) or a pointer to
+** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
+** structure, then said structure defines the content and collating
+** sequence of the index being opened. Otherwise, if P4 is an integer
+** value, it is set to the number of columns in the table.
**
** This instruction works just like OpenRead except that it opens the cursor
** in read/write mode. For a given table, there can be one or more read-only
** cursors or a single read/write cursor but not both.
@@ -51559,8 +52166,10 @@
** See also OpenRead.
*/
case OP_OpenRead:
case OP_OpenWrite: {
+ int nField = 0;
+ KeyInfo *pKeyInfo = 0;
int i = pOp->p1;
int p2 = pOp->p2;
int iDb = pOp->p3;
int wrFlag;
@@ -51592,18 +52201,21 @@
goto abort_due_to_error;
}
}
assert( i>=0 );
- pCur = allocateCursor(p, i, &pOp[-1], iDb, 1);
+ if( pOp->p4type==P4_KEYINFO ){
+ pKeyInfo = pOp->p4.pKeyInfo;
+ pKeyInfo->enc = ENC(p->db);
+ nField = pKeyInfo->nField+1;
+ }else if( pOp->p4type==P4_INT32 ){
+ nField = pOp->p4.i;
+ }
+ pCur = allocateCursor(p, i, nField, iDb, 1);
if( pCur==0 ) goto no_mem;
pCur->nullRow = 1;
- rc = sqlite3BtreeCursor(pX, p2, wrFlag, pOp->p4.p, pCur->pCursor);
- if( pOp->p4type==P4_KEYINFO ){
- pCur->pKeyInfo = pOp->p4.pKeyInfo;
- pCur->pKeyInfo->enc = ENC(p->db);
- }else{
- pCur->pKeyInfo = 0;
- }
+ rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
+ pCur->pKeyInfo = pKeyInfo;
+
switch( rc ){
case SQLITE_BUSY: {
p->pc = pc;
p->rc = rc = SQLITE_BUSY;
@@ -51676,9 +52288,9 @@
SQLITE_OPEN_DELETEONCLOSE |
SQLITE_OPEN_TRANSIENT_DB;
assert( i>=0 );
- pCx = allocateCursor(p, i, pOp, -1, 1);
+ pCx = allocateCursor(p, i, pOp->p2, -1, 1);
if( pCx==0 ) goto no_mem;
pCx->nullRow = 1;
rc = sqlite3BtreeFactory(db, 0, 1, SQLITE_DEFAULT_TEMP_CACHE_SIZE, openFlags,
&pCx->pBt);
@@ -51711,9 +52323,9 @@
pCx->isIndex = !pCx->isTable;
break;
}
-/* Opcode: OpenPseudo P1 P2 * * *
+/* Opcode: OpenPseudo P1 P2 P3 * *
**
** Open a new cursor that points to a fake table that contains a single
** row of data. Any attempt to write a second row of data causes the
** first row to be deleted. All data is deleted when the cursor is
@@ -51730,14 +52342,17 @@
** original row data. Otherwise, a pointer to the original memory cell
** is stored. In this case, the vdbe program must ensure that the
** memory cell containing the row data is not overwritten until the
** pseudo table is closed (or a new row is inserted into it).
+**
+** P3 is the number of fields in the records that will be stored by
+** the pseudo-table.
*/
case OP_OpenPseudo: {
int i = pOp->p1;
VdbeCursor *pCx;
assert( i>=0 );
- pCx = allocateCursor(p, i, &pOp[-1], -1, 0);
+ pCx = allocateCursor(p, i, pOp->p3, -1, 0);
if( pCx==0 ) goto no_mem;
pCx->nullRow = 1;
pCx->pseudoTable = 1;
pCx->ephemPseudoTable = (u8)pOp->p2;
@@ -52258,9 +52873,9 @@
** first few attempts at choosing a random rowid pick values just a little
** larger than the previous rowid. This has been shown experimentally
** to double the speed of the COPY operation.
*/
- int res, rx=SQLITE_OK, cnt;
+ int res=0, rx=SQLITE_OK, cnt;
i64 x;
cnt = 0;
if( (sqlite3BtreeFlags(pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) !=
BTREE_INTKEY ){
@@ -52280,11 +52895,10 @@
# define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
#endif
if( !pC->useRandomRowid ){
- if( pC->nextRowidValid ){
- v = pC->nextRowid;
- }else{
+ v = sqlite3BtreeGetCachedRowid(pC->pCursor);
+ if( v==0 ){
rc = sqlite3BtreeLast(pC->pCursor, &res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
@@ -52319,14 +52933,9 @@
pMem->u.i = v;
}
#endif
- if( v<MAX_ROWID ){
- pC->nextRowidValid = 1;
- pC->nextRowid = v+1;
- }else{
- pC->nextRowidValid = 0;
- }
+ sqlite3BtreeSetCachedRowid(pC->pCursor, v<MAX_ROWID ? v+1 : 0);
}
if( pC->useRandomRowid ){
assert( pOp->p3==0 ); /* SQLITE_FULL must have occurred prior to this */
v = db->priorNewRowid;
@@ -52402,11 +53011,8 @@
iKey = intToKey(pKey->u.i);
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = pKey->u.i;
- if( pC->nextRowidValid && pKey->u.i>=pC->nextRowid ){
- pC->nextRowidValid = 0;
- }
if( pData->flags & MEM_Null ){
pData->z = 0;
pData->n = 0;
}else{
@@ -52439,8 +53045,9 @@
nZero = pData->u.nZero;
}else{
nZero = 0;
}
+ sqlite3BtreeSetCachedRowid(pC->pCursor, 0);
rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
pData->z, pData->n, nZero,
pOp->p5 & OPFLAG_APPEND);
}
@@ -52482,9 +53089,9 @@
** using OP_NotFound prior to invoking this opcode.
*/
case OP_Delete: {
int i = pOp->p1;
- i64 iKey;
+ i64 iKey = 0;
VdbeCursor *pC;
assert( i>=0 && i<p->nCursor );
pC = p->apCsr[i];
@@ -52501,10 +53108,10 @@
}
rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error;
- rc = sqlite3BtreeDelete(pC->pCursor);
- pC->nextRowidValid = 0;
+ sqlite3BtreeSetCachedRowid(pC->pCursor, 0);
+ rc = sqlite3BtreeDelete(pC->pCursor);
pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
@@ -52793,9 +53400,9 @@
/* Opcode: IdxInsert P1 P2 P3 * *
**
** Register P2 holds a SQL index key made using the
-** MakeIdxRec instructions. This opcode writes that key
+** MakeRecord instructions. This opcode writes that key
** into the index P1. Data for the entry is nil.
**
** P3 is a flag that provides a hint to the b-tree layer that this
** insert is likely to be an append.
@@ -52834,9 +53441,9 @@
int i = pOp->p1;
VdbeCursor *pC;
BtCursor *pCrsr;
assert( pOp->p3>0 );
- assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem );
+ assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 );
assert( i>=0 && i<p->nCursor );
assert( p->apCsr[i]!=0 );
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
int res;
@@ -52860,9 +53467,9 @@
** Write into register P2 an integer which is the last entry in the record at
** 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, MakeIdxRec.
+** See also: Rowid, MakeRecord.
*/
case OP_IdxRowid: { /* out2-prerelease */
int i = pOp->p1;
BtCursor *pCrsr;
@@ -53010,9 +53617,9 @@
** The table being clear is in the main database file if P2==0. If
** P2==1 then the table to be clear is in the auxiliary database file
** that is used to store tables create using CREATE TEMPORARY TABLE.
**
-** If the P3 value is non-zero, then the table refered to must be an
+** If the P3 value is non-zero, then the table referred to must be an
** intkey table (an SQL table, not an index). In this case the row change
** count is incremented by the number of rows in the table being cleared.
** If P3 is greater than zero, then the value stored in register P3 is
** also incremented by the number of rows in the table being cleared.
@@ -53089,35 +53696,60 @@
** This opcode invokes the parser to create a new virtual machine,
** then runs the new virtual machine. It is thus a re-entrant opcode.
*/
case OP_ParseSchema: {
- char *zSql;
- int iDb = pOp->p1;
- const char *zMaster;
- InitData initData;
-
+ int iDb = pOp->p1;
assert( iDb>=0 && iDb<db->nDb );
- if( !pOp->p2 && !DbHasProperty(db, iDb, DB_SchemaLoaded) ){
- break;
- }
- zMaster = SCHEMA_TABLE(iDb);
- initData.db = db;
- initData.iDb = pOp->p1;
- initData.pzErrMsg = &p->zErrMsg;
- zSql = sqlite3MPrintf(db,
- "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
- db->aDb[iDb].zName, zMaster, pOp->p4.z);
- if( zSql==0 ) goto no_mem;
- (void)sqlite3SafetyOff(db);
- assert( db->init.busy==0 );
- db->init.busy = 1;
- initData.rc = SQLITE_OK;
- assert( !db->mallocFailed );
- rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
- if( rc==SQLITE_OK ) rc = initData.rc;
- sqlite3DbFree(db, zSql);
- db->init.busy = 0;
- (void)sqlite3SafetyOn(db);
+
+ /* If pOp->p2 is 0, then this opcode is being executed to read a
+ ** single row, for example the row corresponding to a new index
+ ** created by this VDBE, from the sqlite_master table. It only
+ ** does this if the corresponding in-memory schema is currently
+ ** loaded. Otherwise, the new index definition can be loaded along
+ ** with the rest of the schema when it is required.
+ **
+ ** Although the mutex on the BtShared object that corresponds to
+ ** database iDb (the database containing the sqlite_master table
+ ** read by this instruction) is currently held, it is necessary to
+ ** obtain the mutexes on all attached databases before checking if
+ ** the schema of iDb is loaded. This is because, at the start of
+ ** the sqlite3_exec() call below, SQLite will invoke
+ ** sqlite3BtreeEnterAll(). If all mutexes are not already held, the
+ ** iDb mutex may be temporarily released to avoid deadlock. If
+ ** this happens, then some other thread may delete the in-memory
+ ** schema of database iDb before the SQL statement runs. The schema
+ ** will not be reloaded becuase the db->init.busy flag is set. This
+ ** can result in a "no such table: sqlite_master" or "malformed
+ ** database schema" error being returned to the user.
+ */
+ assert( sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
+ sqlite3BtreeEnterAll(db);
+ if( pOp->p2 || DbHasProperty(db, iDb, DB_SchemaLoaded) ){
+ const char *zMaster = SCHEMA_TABLE(iDb);
+ char *zSql;
+ InitData initData;
+ initData.db = db;
+ initData.iDb = pOp->p1;
+ initData.pzErrMsg = &p->zErrMsg;
+ zSql = sqlite3MPrintf(db,
+ "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
+ db->aDb[iDb].zName, zMaster, pOp->p4.z);
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ (void)sqlite3SafetyOff(db);
+ assert( db->init.busy==0 );
+ db->init.busy = 1;
+ initData.rc = SQLITE_OK;
+ assert( !db->mallocFailed );
+ rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
+ if( rc==SQLITE_OK ) rc = initData.rc;
+ sqlite3DbFree(db, zSql);
+ db->init.busy = 0;
+ (void)sqlite3SafetyOn(db);
+ }
+ }
+ sqlite3BtreeLeaveAll(db);
if( rc==SQLITE_NOMEM ){
goto no_mem;
}
break;
@@ -53549,9 +54181,9 @@
assert( p1>=0 && p1<db->nDb );
assert( (p->btreeMask & (1<<p1))!=0 );
assert( isWriteLock==0 || isWriteLock==1 );
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
- if( rc==SQLITE_LOCKED ){
+ if( (rc&0xFF)==SQLITE_LOCKED ){
const char *z = pOp->p4.z;
sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
}
break;
@@ -53564,10 +54196,10 @@
** P4 may be a pointer to an sqlite3_vtab structure. If so, call the
** xBegin method for that table.
**
** Also, whether or not P4 is set, check that this is not being called from
-** within a callback to a virtual table xSync() method. If it is, set the
-** error code to SQLITE_LOCKED.
+** within a callback to a virtual table xSync() method. If it is, the error
+** code will be set to SQLITE_LOCKED.
*/
case OP_VBegin: {
sqlite3_vtab *pVtab = pOp->p4.pVtab;
rc = sqlite3VtabBegin(db, pVtab);
@@ -53631,9 +54263,9 @@
/* Initialize sqlite3_vtab_cursor base class */
pVtabCursor->pVtab = pVtab;
/* Initialise vdbe cursor object */
- pCur = allocateCursor(p, pOp->p1, &pOp[-1], -1, 0);
+ pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
if( pCur ){
pCur->pVtabCursor = pVtabCursor;
pCur->pModule = pVtabCursor->pVtab->pModule;
}else{
@@ -53791,9 +54423,9 @@
p->zErrMsg = pVtab->zErrMsg;
pVtab->zErrMsg = 0;
/* Copy the result of the function to the P3 register. We
- ** do this regardless of whether or not an error occured to ensure any
+ ** do this regardless of whether or not an error occurred to ensure any
** dynamic allocation in sContext.s (a Mem struct) is released.
*/
sqlite3VdbeChangeEncoding(&sContext.s, encoding);
REGISTER_TRACE(pOp->p3, pDest);
@@ -53972,15 +54604,16 @@
** If tracing is enabled (by the sqlite3_trace()) interface, then
** the UTF-8 string contained in P4 is emitted on the trace callback.
*/
case OP_Trace: {
- if( pOp->p4.z ){
+ char *zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
+ if( zTrace ){
if( db->xTrace ){
- db->xTrace(db->pTraceArg, pOp->p4.z);
+ db->xTrace(db->pTraceArg, zTrace);
}
#ifdef SQLITE_DEBUG
if( (db->flags & SQLITE_SqlTrace)!=0 ){
- sqlite3DebugPrintf("SQL-trace: %s\n", pOp->p4.z);
+ sqlite3DebugPrintf("SQL-trace: %s\n", zTrace);
}
#endif /* SQLITE_DEBUG */
}
break;
@@ -54121,9 +54754,9 @@
*************************************************************************
**
** This file contains code used to implement incremental BLOB I/O.
**
-** $Id: vdbeblob.c,v 1.26 2008/10/02 14:49:02 danielk1977 Exp $
+** $Id: vdbeblob.c,v 1.31 2009/03/24 15:08:10 drh Exp $
*/
#ifndef SQLITE_OMIT_INCRBLOB
@@ -54177,19 +54810,17 @@
/* One of the following two instructions is replaced by an
** OP_Noop before exection.
*/
- {OP_SetNumColumns, 0, 0, 0}, /* 2: Num cols for cursor */
- {OP_OpenRead, 0, 0, 0}, /* 3: Open cursor 0 for reading */
- {OP_SetNumColumns, 0, 0, 0}, /* 4: Num cols for cursor */
- {OP_OpenWrite, 0, 0, 0}, /* 5: Open cursor 0 for read/write */
-
- {OP_Variable, 1, 1, 0}, /* 6: Push the rowid to the stack */
- {OP_NotExists, 0, 10, 1}, /* 7: Seek the cursor */
- {OP_Column, 0, 0, 1}, /* 8 */
- {OP_ResultRow, 1, 0, 0}, /* 9 */
- {OP_Close, 0, 0, 0}, /* 10 */
- {OP_Halt, 0, 0, 0}, /* 11 */
+ {OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */
+ {OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */
+
+ {OP_Variable, 1, 1, 1}, /* 4: Push the rowid to the stack */
+ {OP_NotExists, 0, 8, 1}, /* 5: Seek the cursor */
+ {OP_Column, 0, 0, 1}, /* 6 */
+ {OP_ResultRow, 1, 0, 0}, /* 7 */
+ {OP_Close, 0, 0, 0}, /* 8 */
+ {OP_Halt, 0, 0, 0}, /* 9 */
};
Vdbe *v = 0;
int rc = SQLITE_OK;
@@ -54285,21 +54916,21 @@
/* Remove either the OP_OpenWrite or OpenRead. Set the P2
** parameter of the other to pTab->tnum.
*/
- sqlite3VdbeChangeToNoop(v, (flags ? 3 : 5), 1);
- sqlite3VdbeChangeP2(v, (flags ? 5 : 3), pTab->tnum);
- sqlite3VdbeChangeP3(v, (flags ? 5 : 3), iDb);
-
- /* Configure the OP_SetNumColumns. Configure the cursor to
+ sqlite3VdbeChangeToNoop(v, (flags ? 2 : 3), 1);
+ sqlite3VdbeChangeP2(v, (flags ? 3 : 2), pTab->tnum);
+ sqlite3VdbeChangeP3(v, (flags ? 3 : 2), iDb);
+
+ /* Configure the number of columns. Configure the cursor to
** think that the table has one more column than it really
** does. An OP_Column to retrieve this imaginary column will
** always return an SQL NULL. This is useful because it means
** we can invoke OP_Column to fill in the vdbe cursors type
** and offset cache without causing any IO.
*/
- sqlite3VdbeChangeP2(v, flags ? 4 : 2, pTab->nCol+1);
- sqlite3VdbeChangeP2(v, 8, pTab->nCol);
+ sqlite3VdbeChangeP4(v, flags ? 3 : 2, SQLITE_INT_TO_PTR(pTab->nCol+1), P4_INT32);
+ sqlite3VdbeChangeP2(v, 6, pTab->nCol);
if( !db->mallocFailed ){
sqlite3VdbeMakeReady(v, 1, 1, 1, 0);
}
}
@@ -54357,10 +54988,10 @@
}
blob_open_out:
zErr[sizeof(zErr)-1] = '\0';
- if( rc!=SQLITE_OK || db->mallocFailed ){
- sqlite3_finalize((sqlite3_stmt *)v);
+ if( v && (rc!=SQLITE_OK || db->mallocFailed) ){
+ sqlite3VdbeFinalize(v);
}
sqlite3Error(db, rc, (rc==SQLITE_OK?0:zErr));
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
@@ -54373,11 +55004,15 @@
*/
SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
int rc;
-
+ sqlite3 *db;
+
+ db = p->db;
+ sqlite3_mutex_enter(db->mutex);
rc = sqlite3_finalize(p->pStmt);
- sqlite3DbFree(p->db, p);
+ sqlite3DbFree(db, p);
+ sqlite3_mutex_leave(db->mutex);
return rc;
}
/*
@@ -54468,9 +55103,9 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
**
-** @(#) $Id: journal.c,v 1.8 2008/05/01 18:01:47 drh Exp $
+** @(#) $Id: journal.c,v 1.9 2009/01/20 17:06:27 danielk1977 Exp $
*/
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
@@ -54486,9 +55121,9 @@
** on disk is not created or populated until either:
**
** 1) The in-memory representation grows too large for the allocated
** buffer, or
-** 2) The xSync() method is called.
+** 2) The sqlite3JournalCreate() function is called.
*/
@@ -54552,10 +55187,11 @@
int rc = SQLITE_OK;
JournalFile *p = (JournalFile *)pJfd;
if( p->pReal ){
rc = sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
- }else{
- assert( iAmt+iOfst<=p->iSize );
+ }else if( (iAmt+iOfst)>p->iSize ){
+ rc = SQLITE_IOERR_SHORT_READ;
+ }else{
memcpy(zBuf, &p->zBuf[iOfst], iAmt);
}
return rc;
}
@@ -54958,9 +55594,9 @@
*************************************************************************
** This file contains routines used for walking the parser tree for
** an SQL statement.
**
-** $Id: walker.c,v 1.1 2008/08/20 16:35:10 drh Exp $
+** $Id: walker.c,v 1.2 2009/02/19 14:39:25 danielk1977 Exp $
*/
/*
@@ -54988,11 +55624,12 @@
rc = pWalker->xExprCallback(pWalker, pExpr);
if( rc==WRC_Continue ){
if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
- if( sqlite3WalkExprList(pWalker, pExpr->pList) ) return WRC_Abort;
- if( sqlite3WalkSelect(pWalker, pExpr->pSelect) ){
- return WRC_Abort;
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
+ }else{
+ if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
}
}
return rc & WRC_Abort;
}
@@ -55094,9 +55731,9 @@
** This file contains routines used for walking the parser tree and
** resolve all identifiers by associating them with a particular
** table and column.
**
-** $Id: resolve.c,v 1.15 2008/12/10 19:26:24 drh Exp $
+** $Id: resolve.c,v 1.20 2009/03/05 04:23:47 shane Exp $
*/
/*
** Turn the pExpr expression into an alias for the iCol-th column of the
@@ -55140,10 +55777,11 @@
pOrig = pEList->a[iCol].pExpr;
assert( pOrig!=0 );
assert( pOrig->flags & EP_Resolved );
db = pParse->db;
- pDup = sqlite3ExprDup(db, pOrig);
+ pDup = sqlite3ExprDup(db, pOrig, 0);
if( pDup==0 ) return;
+ sqlite3TokenCopy(db, &pDup->token, &pOrig->token);
if( pDup->op!=TK_COLUMN && zType[0]!='G' ){
pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
if( pDup==0 ) return;
if( pEList->a[iCol].iAlias==0 ){
@@ -55206,8 +55844,9 @@
struct SrcList_item *pMatch = 0; /* The matching pSrcList item */
NameContext *pTopNC = pNC; /* First namecontext in the list */
Schema *pSchema = 0; /* Schema of the expression */
+ assert( pNC ); /* the name context cannot be NULL. */
assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */
/* Dequote and zero-terminate the names */
zDb = sqlite3NameFromToken(db, pDbToken);
@@ -55359,10 +55998,10 @@
char *zAs = pEList->a[j].zName;
if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
Expr *pOrig;
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
- assert( pExpr->pList==0 );
- assert( pExpr->pSelect==0 );
+ assert( pExpr->x.pList==0 );
+ assert( pExpr->x.pSelect==0 );
pOrig = pEList->a[j].pExpr;
if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
sqlite3DbFree(db, zCol);
@@ -55551,10 +56190,10 @@
/* Resolve function names
*/
case TK_CONST_FUNC:
case TK_FUNCTION: {
- ExprList *pList = pExpr->pList; /* The argument list */
- int n = pList ? pList->nExpr : 0; /* Number of arguments */
+ ExprList *pList = pExpr->x.pList; /* The argument list */
+ int n = pList ? pList->nExpr : 0; /* Number of arguments */
int no_such_func = 0; /* True if no such function exists */
int wrong_num_args = 0; /* True if wrong number of arguments */
int is_agg = 0; /* True if is an aggregate function */
int auth; /* Authorization to use the function */
@@ -55562,8 +56201,9 @@
const char *zId; /* The function name. */
FuncDef *pDef; /* Information about the function */
u8 enc = ENC(pParse->db); /* The database encoding */
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
zId = (char*)pExpr->token.z;
nId = pExpr->token.n;
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
if( pDef==0 ){
@@ -55618,16 +56258,16 @@
case TK_SELECT:
case TK_EXISTS:
#endif
case TK_IN: {
- if( pExpr->pSelect ){
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
int nRef = pNC->nRef;
#ifndef SQLITE_OMIT_CHECK
if( pNC->isCheck ){
sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
}
#endif
- sqlite3WalkSelect(pWalker, pExpr->pSelect);
+ sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
ExprSetProperty(pExpr, EP_VarSelect);
}
@@ -55813,9 +56453,9 @@
}
}else{
iCol = resolveAsName(pParse, pEList, pE);
if( iCol==0 ){
- pDup = sqlite3ExprDup(db, pE);
+ pDup = sqlite3ExprDup(db, pE, 0);
if( !db->mallocFailed ){
assert(pDup);
iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup);
}
@@ -56261,9 +56901,9 @@
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.409 2009/01/10 13:24:51 drh Exp $
+** $Id: expr.c,v 1.424 2009/03/25 16:51:43 drh Exp $
*/
/*
** Return the 'affinity' of the expression pExpr if any.
@@ -56283,9 +56923,10 @@
*/
SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
int op = pExpr->op;
if( op==TK_SELECT ){
- return sqlite3ExprAffinity(pExpr->pSelect->pEList->a[0].pExpr);
+ assert( pExpr->flags&EP_xIsSelect );
+ return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
}
#ifndef SQLITE_OMIT_CAST
if( op==TK_CAST ){
return sqlite3AffinityType(&pExpr->token);
@@ -56403,13 +57044,11 @@
assert( pExpr->pLeft );
aff = sqlite3ExprAffinity(pExpr->pLeft);
if( pExpr->pRight ){
aff = sqlite3CompareAffinity(pExpr->pRight, aff);
- }
- else if( pExpr->pSelect ){
- aff = sqlite3CompareAffinity(pExpr->pSelect->pEList->a[0].pExpr, aff);
- }
- else if( !aff ){
+ }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
+ }else if( !aff ){
aff = SQLITE_AFF_NONE;
}
return aff;
}
@@ -56593,10 +57232,13 @@
static void exprSetHeight(Expr *p){
int nHeight = 0;
heightOfExpr(p->pLeft, &nHeight);
heightOfExpr(p->pRight, &nHeight);
- heightOfExprList(p->pList, &nHeight);
- heightOfSelect(p->pSelect, &nHeight);
+ if( ExprHasProperty(p, EP_xIsSelect) ){
+ heightOfSelect(p->x.pSelect, &nHeight);
+ }else{
+ heightOfExprList(p->x.pList, &nHeight);
+ }
p->nHeight = nHeight + 1;
}
/*
@@ -56650,10 +57292,26 @@
pNew->pRight = pRight;
pNew->iAgg = -1;
pNew->span.z = (u8*)"";
if( pToken ){
+ int c;
assert( pToken->dyn==0 );
- pNew->span = pNew->token = *pToken;
+ pNew->span = *pToken;
+
+ /* The pToken->z value is read-only. But the new expression
+ ** node created here might be passed to sqlite3DequoteExpr() which
+ ** will attempt to modify pNew->token.z. Hence, if the token
+ ** is quoted, make a copy now so that DequoteExpr() will change
+ ** the copy rather than the original text.
+ */
+ if( pToken->n>=2
+ && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
+ sqlite3TokenCopy(db, &pNew->token, pToken);
+ }else{
+ pNew->token = *pToken;
+ pNew->flags |= EP_Dequoted;
+ VVA_ONLY( pNew->vvaFlags |= EVVA_ReadOnlyToken; )
+ }
}else if( pLeft ){
if( pRight ){
if( pRight->span.dyn==0 && pLeft->span.dyn==0 ){
sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);
@@ -56740,9 +57398,12 @@
assert( pRight!=0 );
assert( pLeft!=0 );
if( pExpr ){
pExpr->span.z = pLeft->z;
- pExpr->span.n = pRight->n + (pRight->z - pLeft->z);
+ /* The following assert() may fail when this is called
+ ** via sqlite3PExpr()/sqlite3Expr() from addWhereTerm(). */
+ /* assert(pRight->z >= pLeft->z); */
+ pExpr->span.n = pRight->n + (unsigned)(pRight->z - pLeft->z);
}
}
/*
@@ -56754,17 +57415,17 @@
sqlite3 *db = pParse->db;
assert( pToken );
pNew = sqlite3DbMallocZero(db, sizeof(Expr) );
if( pNew==0 ){
- sqlite3ExprListDelete(db, pList); /* Avoid leaking memory when malloc fails */
+ sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
return 0;
}
pNew->op = TK_FUNCTION;
- pNew->pList = pList;
+ pNew->x.pList = pList;
+ assert( !ExprHasProperty(pNew, EP_xIsSelect) );
assert( pToken->dyn==0 );
- pNew->token = *pToken;
- pNew->span = pNew->token;
-
+ pNew->span = *pToken;
+ sqlite3TokenCopy(db, &pNew->token, pToken);
sqlite3ExprSetHeight(pParse, pNew);
return pNew;
}
@@ -56855,14 +57516,24 @@
** Clear an expression structure without deleting the structure itself.
** Substructure is deleted.
*/
SQLITE_PRIVATE void sqlite3ExprClear(sqlite3 *db, Expr *p){
- if( p->span.dyn ) sqlite3DbFree(db, (char*)p->span.z);
if( p->token.dyn ) sqlite3DbFree(db, (char*)p->token.z);
- sqlite3ExprDelete(db, p->pLeft);
- sqlite3ExprDelete(db, p->pRight);
- sqlite3ExprListDelete(db, p->pList);
- sqlite3SelectDelete(db, p->pSelect);
+ if( !ExprHasAnyProperty(p, EP_TokenOnly|EP_SpanOnly) ){
+ if( p->span.dyn ) sqlite3DbFree(db, (char*)p->span.z);
+ if( ExprHasProperty(p, EP_Reduced) ){
+ if( p->pLeft ) sqlite3ExprClear(db, p->pLeft);
+ if( p->pRight ) sqlite3ExprClear(db, p->pRight);
+ }else{
+ sqlite3ExprDelete(db, p->pLeft);
+ sqlite3ExprDelete(db, p->pRight);
+ }
+ if( ExprHasProperty(p, EP_xIsSelect) ){
+ sqlite3SelectDelete(db, p->x.pSelect);
+ }else{
+ sqlite3ExprListDelete(db, p->x.pList);
+ }
+ }
}
/*
** Recursively delete an expression tree.
@@ -56876,17 +57547,197 @@
/*
** The Expr.token field might be a string literal that is quoted.
** If so, remove the quotation marks.
*/
-SQLITE_PRIVATE void sqlite3DequoteExpr(sqlite3 *db, Expr *p){
- if( ExprHasAnyProperty(p, EP_Dequoted) ){
- return;
- }
- ExprSetProperty(p, EP_Dequoted);
- if( p->token.dyn==0 ){
- sqlite3TokenCopy(db, &p->token, &p->token);
- }
- sqlite3Dequote((char*)p->token.z);
+SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){
+ if( !ExprHasAnyProperty(p, EP_Dequoted) ){
+ ExprSetProperty(p, EP_Dequoted);
+ assert( (p->vvaFlags & EVVA_ReadOnlyToken)==0 );
+ sqlite3Dequote((char*)p->token.z);
+ }
+}
+
+/*
+** Return the number of bytes allocated for the expression structure
+** passed as the first argument. This is always one of EXPR_FULLSIZE,
+** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
+*/
+static int exprStructSize(Expr *p){
+ if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE;
+ if( ExprHasProperty(p, EP_SpanOnly) ) return EXPR_SPANONLYSIZE;
+ if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE;
+ return EXPR_FULLSIZE;
+}
+
+/*
+** sqlite3ExprDup() has been called to create a copy of expression p with
+** the EXPRDUP_XXX flags passed as the second argument. This function
+** returns the space required for the copy of the Expr structure only.
+** This is always one of EXPR_FULLSIZE, EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
+*/
+static int dupedExprStructSize(Expr *p, int flags){
+ int nSize;
+ if( 0==(flags&EXPRDUP_REDUCE) ){
+ nSize = EXPR_FULLSIZE;
+ }else if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
+ nSize = EXPR_REDUCEDSIZE;
+ }else if( flags&(EXPRDUP_SPAN|EXPRDUP_DISTINCTSPAN) ){
+ nSize = EXPR_SPANONLYSIZE;
+ }else{
+ nSize = EXPR_TOKENONLYSIZE;
+ }
+ return nSize;
+}
+
+/*
+** sqlite3ExprDup() has been called to create a copy of expression p with
+** the EXPRDUP_XXX passed as the second argument. This function returns
+** the space in bytes required to store the copy of the Expr structure
+** and the copies of the Expr.token.z and Expr.span.z (if applicable)
+** string buffers.
+*/
+static int dupedExprNodeSize(Expr *p, int flags){
+ int nByte = dupedExprStructSize(p, flags) + (p->token.z ? p->token.n + 1 : 0);
+ if( (flags&EXPRDUP_DISTINCTSPAN)
+ || (flags&EXPRDUP_SPAN && (p->token.z!=p->span.z || p->token.n!=p->span.n))
+ ){
+ nByte += p->span.n;
+ }
+ return ROUND8(nByte);
+}
+
+/*
+** Return the number of bytes required to create a duplicate of the
+** expression passed as the first argument. The second argument is a
+** mask containing EXPRDUP_XXX flags.
+**
+** The value returned includes space to create a copy of the Expr struct
+** itself and the buffer referred to by Expr.token, if any. If the
+** EXPRDUP_SPAN flag is set, then space to create a copy of the buffer
+** refered to by Expr.span is also included.
+**
+** If the EXPRDUP_REDUCE flag is set, then the return value includes
+** space to duplicate all Expr nodes in the tree formed by Expr.pLeft
+** and Expr.pRight variables (but not for any structures pointed to or
+** descended from the Expr.x.pList or Expr.x.pSelect variables).
+*/
+static int dupedExprSize(Expr *p, int flags){
+ int nByte = 0;
+ if( p ){
+ nByte = dupedExprNodeSize(p, flags);
+ if( flags&EXPRDUP_REDUCE ){
+ int f = flags&(~(EXPRDUP_SPAN|EXPRDUP_DISTINCTSPAN));
+ nByte += dupedExprSize(p->pLeft, f) + dupedExprSize(p->pRight, f);
+ }
+ }
+ return nByte;
+}
+
+/*
+** This function is similar to sqlite3ExprDup(), except that if pzBuffer
+** is not NULL then *pzBuffer is assumed to point to a buffer large enough
+** to store the copy of expression p, the copies of p->token and p->span
+** (if applicable), and the copies of the p->pLeft and p->pRight expressions,
+** if any. Before returning, *pzBuffer is set to the first byte passed the
+** portion of the buffer copied into by this function.
+*/
+static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
+ Expr *pNew = 0; /* Value to return */
+ if( p ){
+ const int isRequireDistinctSpan = (flags&EXPRDUP_DISTINCTSPAN);
+ const int isRequireSpan = (flags&(EXPRDUP_SPAN|EXPRDUP_DISTINCTSPAN));
+ const int isReduced = (flags&EXPRDUP_REDUCE);
+ u8 *zAlloc;
+
+ assert( pzBuffer==0 || isReduced );
+
+ /* Figure out where to write the new Expr structure. */
+ if( pzBuffer ){
+ zAlloc = *pzBuffer;
+ }else{
+ zAlloc = sqlite3DbMallocRaw(db, dupedExprSize(p, flags));
+ }
+ pNew = (Expr *)zAlloc;
+
+ if( pNew ){
+ /* Set nNewSize to the size allocated for the structure pointed to
+ ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
+ ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
+ ** by the copy of the p->token.z string (if any).
+ */
+ const int nNewSize = dupedExprStructSize(p, flags);
+ const int nToken = (p->token.z ? p->token.n + 1 : 0);
+ if( isReduced ){
+ assert( ExprHasProperty(p, EP_Reduced)==0 );
+ memcpy(zAlloc, p, nNewSize);
+ }else{
+ int nSize = exprStructSize(p);
+ memcpy(zAlloc, p, nSize);
+ memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
+ }
+
+ /* Set the EP_Reduced and EP_TokenOnly flags appropriately. */
+ pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_SpanOnly);
+ switch( nNewSize ){
+ case EXPR_REDUCEDSIZE: pNew->flags |= EP_Reduced; break;
+ case EXPR_TOKENONLYSIZE: pNew->flags |= EP_TokenOnly; break;
+ case EXPR_SPANONLYSIZE: pNew->flags |= EP_SpanOnly; break;
+ }
+
+ /* Copy the p->token string, if any. */
+ if( nToken ){
+ unsigned char *zToken = &zAlloc[nNewSize];
+ memcpy(zToken, p->token.z, nToken-1);
+ zToken[nToken-1] = '\0';
+ pNew->token.dyn = 0;
+ pNew->token.z = zToken;
+ }
+
+ if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
+ /* Fill in the pNew->span token, if required. */
+ if( isRequireSpan ){
+ if( isRequireDistinctSpan
+ || p->token.z!=p->span.z || p->token.n!=p->span.n
+ ){
+ pNew->span.z = &zAlloc[nNewSize+nToken];
+ memcpy((char *)pNew->span.z, p->span.z, p->span.n);
+ pNew->span.dyn = 0;
+ }else{
+ pNew->span.z = pNew->token.z;
+ pNew->span.n = pNew->token.n;
+ }
+ }else{
+ pNew->span.z = 0;
+ pNew->span.n = 0;
+ }
+ }
+
+ if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_SpanOnly)) ){
+ /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
+ if( ExprHasProperty(p, EP_xIsSelect) ){
+ pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced);
+ }else{
+ pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced);
+ }
+ }
+
+ /* Fill in pNew->pLeft and pNew->pRight. */
+ if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly|EP_SpanOnly) ){
+ zAlloc += dupedExprNodeSize(p, flags);
+ if( ExprHasProperty(pNew, EP_Reduced) ){
+ pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
+ pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc);
+ }
+ if( pzBuffer ){
+ *pzBuffer = zAlloc;
+ }
+ }else if( !ExprHasAnyProperty(p, EP_TokenOnly|EP_SpanOnly) ){
+ pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
+ pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
+ }
+ }
+ }
+ return pNew;
}
/*
** The following group of routines make deep copies of expressions,
@@ -56898,29 +57749,23 @@
** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded
** by subsequent calls to sqlite*ListAppend() routines.
**
** Any tables that the SrcList might point to are not duplicated.
-*/
-SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, Expr *p){
- Expr *pNew;
- if( p==0 ) return 0;
- pNew = sqlite3DbMallocRaw(db, sizeof(*p) );
- if( pNew==0 ) return 0;
- memcpy(pNew, p, sizeof(*pNew));
- if( p->token.z!=0 ){
- pNew->token.z = (u8*)sqlite3DbStrNDup(db, (char*)p->token.z, p->token.n);
- pNew->token.dyn = 1;
- }else{
- assert( pNew->token.z==0 );
- }
- pNew->span.z = 0;
- pNew->pLeft = sqlite3ExprDup(db, p->pLeft);
- pNew->pRight = sqlite3ExprDup(db, p->pRight);
- pNew->pList = sqlite3ExprListDup(db, p->pList);
- pNew->pSelect = sqlite3SelectDup(db, p->pSelect);
- return pNew;
-}
-SQLITE_PRIVATE void sqlite3TokenCopy(sqlite3 *db, Token *pTo, Token *pFrom){
+**
+** The flags parameter contains a combination of the EXPRDUP_XXX flags. If
+** the EXPRDUP_SPAN flag is set in the argument parameter, then the
+** Expr.span field of the input expression is copied. If EXPRDUP_SPAN is
+** clear, then the Expr.span field of the returned expression structure
+** is zeroed.
+**
+** If the EXPRDUP_REDUCE flag is set, then the structure returned is a
+** truncated version of the usual Expr structure that will be stored as
+** part of the in-memory representation of the database schema.
+*/
+SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){
+ return exprDup(db, p, flags, 0);
+}
+SQLITE_PRIVATE void sqlite3TokenCopy(sqlite3 *db, Token *pTo, const Token *pFrom){
if( pTo->dyn ) sqlite3DbFree(db, (char*)pTo->z);
if( pFrom->z ){
pTo->n = pFrom->n;
pTo->z = (u8*)sqlite3DbStrNDup(db, (char*)pFrom->z, pFrom->n);
@@ -56928,9 +57773,9 @@
}else{
pTo->z = 0;
}
}
-SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p){
+SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
ExprList *pNew;
struct ExprList_item *pItem, *pOldItem;
int i;
if( p==0 ) return 0;
@@ -56944,19 +57789,11 @@
return 0;
}
pOldItem = p->a;
for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
- Expr *pNewExpr, *pOldExpr;
- pItem->pExpr = pNewExpr = sqlite3ExprDup(db, pOldExpr = pOldItem->pExpr);
- if( pOldExpr->span.z!=0 && pNewExpr ){
- /* Always make a copy of the span for top-level expressions in the
- ** expression list. The logic in SELECT processing that determines
- ** the names of columns in the result set needs this information */
- sqlite3TokenCopy(db, &pNewExpr->span, &pOldExpr->span);
- }
- assert( pNewExpr==0 || pNewExpr->span.z!=0
- || pOldExpr->span.z==0
- || db->mallocFailed );
+ Expr *pNewExpr;
+ Expr *pOldExpr = pOldItem->pExpr;
+ pItem->pExpr = pNewExpr = sqlite3ExprDup(db, pOldExpr, flags);
pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
pItem->sortOrder = pOldItem->sortOrder;
pItem->done = 0;
pItem->iCol = pOldItem->iCol;
@@ -56972,9 +57809,9 @@
** called with a NULL argument.
*/
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \
|| !defined(SQLITE_OMIT_SUBQUERY)
-SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p){
+SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
SrcList *pNew;
int i;
int nByte;
if( p==0 ) return 0;
@@ -56998,10 +57835,10 @@
pTab = pNewItem->pTab = pOldItem->pTab;
if( pTab ){
pTab->nRef++;
}
- pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect);
- pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn);
+ pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
+ pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags);
pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing);
pNewItem->colUsed = pOldItem->colUsed;
}
return pNew;
@@ -57025,23 +57862,26 @@
pNewItem->idx = pOldItem->idx;
}
return pNew;
}
-SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p){
+SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
Select *pNew;
if( p==0 ) return 0;
pNew = sqlite3DbMallocRaw(db, sizeof(*p) );
if( pNew==0 ) return 0;
- pNew->pEList = sqlite3ExprListDup(db, p->pEList);
- pNew->pSrc = sqlite3SrcListDup(db, p->pSrc);
- pNew->pWhere = sqlite3ExprDup(db, p->pWhere);
- pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy);
- pNew->pHaving = sqlite3ExprDup(db, p->pHaving);
- pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy);
+ /* Always make a copy of the span for top-level expressions in the
+ ** expression list. The logic in SELECT processing that determines
+ ** the names of columns in the result set needs this information */
+ pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags|EXPRDUP_SPAN);
+ pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
+ pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
+ pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
+ pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags);
+ pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags);
pNew->op = p->op;
- pNew->pPrior = sqlite3SelectDup(db, p->pPrior);
- pNew->pLimit = sqlite3ExprDup(db, p->pLimit);
- pNew->pOffset = sqlite3ExprDup(db, p->pOffset);
+ pNew->pPrior = sqlite3SelectDup(db, p->pPrior, flags);
+ pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
+ pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags);
pNew->iLimit = 0;
pNew->iOffset = 0;
pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
pNew->pRightmost = 0;
@@ -57050,9 +57890,9 @@
pNew->addrOpenEphm[2] = -1;
return pNew;
}
#else
-SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p){
+SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
assert( p==0 );
return 0;
}
#endif
@@ -57391,9 +58231,9 @@
**
** If this is the case, it may be possible to use an existing table
** or index instead of generating an epheremal table.
*/
- p = pX->pSelect;
+ p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
if( isCandidateForInOpt(p) ){
sqlite3 *db = pParse->db;
Index *pIdx;
Expr *pExpr = p->pEList->a[0].pExpr;
@@ -57450,9 +58290,8 @@
iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem);
sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
- sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pIdx->nColumn);
sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
pKey,P4_KEYINFO_HANDOFF);
VdbeComment((v, "%s", pIdx->zName));
eType = IN_INDEX_INDEX;
@@ -57470,9 +58309,9 @@
int rMayHaveNull = 0;
eType = IN_INDEX_EPH;
if( prNotFound ){
*prNotFound = rMayHaveNull = ++pParse->nMem;
- }else if( pX->pLeft->iColumn<0 && pX->pSelect==0 ){
+ }else if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
eType = IN_INDEX_ROWID;
}
sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
}else{
@@ -57559,9 +58398,9 @@
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
memset(&keyInfo, 0, sizeof(keyInfo));
keyInfo.nField = 1;
- if( pExpr->pSelect ){
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
/* Case 1: expr IN (SELECT ...)
**
** Generate code to write the results of the select into the temporary
** table allocated and opened above.
@@ -57572,17 +58411,17 @@
assert( !isRowid );
sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
dest.affinity = (u8)affinity;
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
- if( sqlite3Select(pParse, pExpr->pSelect, &dest) ){
+ if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
return;
}
- pEList = pExpr->pSelect->pEList;
+ pEList = pExpr->x.pSelect->pEList;
if( pEList && pEList->nExpr>0 ){
keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
pEList->a[0].pExpr);
}
- }else if( pExpr->pList ){
+ }else if( pExpr->x.pList ){
/* Case 2: expr IN (exprlist)
**
** For each expression, build an index key from the evaluation and
** store it in the temporary table. If <expr> is a column, then use
@@ -57589,9 +58428,9 @@
** that columns affinity when building index keys. If <expr> is not
** a column, use numeric affinity.
*/
int i;
- ExprList *pList = pExpr->pList;
+ ExprList *pList = pExpr->x.pList;
struct ExprList_item *pItem;
int r1, r2, r3;
if( !affinity ){
@@ -57649,9 +58488,10 @@
static const Token one = { (u8*)"1", 0, 1 };
Select *pSel;
SelectDest dest;
- pSel = pExpr->pSelect;
+ assert( ExprHasProperty(pExpr, EP_xIsSelect) );
+ pSel = pExpr->x.pSelect;
sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
if( pExpr->op==TK_SELECT ){
dest.eDest = SRT_Mem;
sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm);
@@ -57699,9 +58539,9 @@
** like the continuation of the number.
*/
static void codeReal(Vdbe *v, const char *z, int n, int negateFlag, int iMem){
assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
- assert( !z || !isdigit(z[n]) );
+ assert( !z || !sqlite3Isdigit(z[n]) );
UNUSED_PARAMETER(n);
if( z ){
double value;
char *zV;
@@ -57733,9 +58573,9 @@
sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
}else if( (z = (char*)pExpr->token.z)!=0 ){
int i;
int n = pExpr->token.n;
- assert( !isdigit(z[n]) );
+ assert( !sqlite3Isdigit(z[n]) );
if( sqlite3GetInt32(z, &i) ){
if( negFlag ) i = -i;
sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
}else if( sqlite3FitsIn64Bits(z, negFlag) ){
@@ -58043,9 +58883,9 @@
codeReal(v, (char*)pExpr->token.z, pExpr->token.n, 0, target);
break;
}
case TK_STRING: {
- sqlite3DequoteExpr(db, pExpr);
+ sqlite3DequoteExpr(pExpr);
sqlite3VdbeAddOp4(v,OP_String8, 0, target, 0,
(char*)pExpr->token.z, pExpr->token.n);
break;
}
@@ -58069,11 +58909,28 @@
break;
}
#endif
case TK_VARIABLE: {
- sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iTable, target);
- if( pExpr->token.n>1 ){
- sqlite3VdbeChangeP4(v, -1, (char*)pExpr->token.z, pExpr->token.n);
+ int iPrior;
+ VdbeOp *pOp;
+ if( pExpr->token.n<=1
+ && (iPrior = sqlite3VdbeCurrentAddr(v)-1)>=0
+ && (pOp = sqlite3VdbeGetOp(v, iPrior))->opcode==OP_Variable
+ && pOp->p1+pOp->p3==pExpr->iTable
+ && pOp->p2+pOp->p3==target
+ && pOp->p4.z==0
+ ){
+ /* If the previous instruction was a copy of the previous unnamed
+ ** parameter into the previous register, then simply increment the
+ ** repeat count on the prior instruction rather than making a new
+ ** instruction.
+ */
+ pOp->p3++;
+ }else{
+ sqlite3VdbeAddOp3(v, OP_Variable, pExpr->iTable, target, 1);
+ if( pExpr->token.n>1 ){
+ sqlite3VdbeChangeP4(v, -1, (char*)pExpr->token.z, pExpr->token.n);
+ }
}
break;
}
case TK_REGISTER: {
@@ -58180,14 +59037,12 @@
}
case TK_UMINUS: {
Expr *pLeft = pExpr->pLeft;
assert( pLeft );
- if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
- if( pLeft->op==TK_FLOAT ){
- codeReal(v, (char*)pLeft->token.z, pLeft->token.n, 1, target);
- }else{
- codeInteger(v, pLeft, 1, target);
- }
+ if( pLeft->op==TK_FLOAT ){
+ codeReal(v, (char*)pLeft->token.z, pLeft->token.n, 1, target);
+ }else if( pLeft->op==TK_INTEGER ){
+ codeInteger(v, pLeft, 1, target);
}else{
regFree1 = r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_Integer, 0, r1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2);
@@ -58235,9 +59090,11 @@
break;
}
case TK_CONST_FUNC:
case TK_FUNCTION: {
- ExprList *pList = pExpr->pList;
+ ExprList *pList = (
+ ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanOnly) ? 0 : pExpr->x.pList
+ );
int nExpr = pList ? pList->nExpr : 0;
FuncDef *pDef;
int nId;
const char *zId;
@@ -58245,8 +59102,9 @@
int i;
u8 enc = ENC(db);
CollSeq *pColl = 0;
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
testcase( op==TK_CONST_FUNC );
testcase( op==TK_FUNCTION );
zId = (char*)pExpr->token.z;
nId = pExpr->token.n;
@@ -58412,9 +59270,9 @@
** Z is stored in pExpr->pList->a[1].pExpr.
*/
case TK_BETWEEN: {
Expr *pLeft = pExpr->pLeft;
- struct ExprList_item *pLItem = pExpr->pList->a;
+ struct ExprList_item *pLItem = pExpr->x.pList->a;
Expr *pRight = pLItem->pExpr;
codeCompareOperands(pParse, pLeft, &r1, ®Free1,
pRight, &r2, ®Free2);
@@ -58472,12 +59330,12 @@
Expr cacheX; /* Cached expression X */
Expr *pX; /* The X expression */
Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
- assert(pExpr->pList);
- assert((pExpr->pList->nExpr % 2) == 0);
- assert(pExpr->pList->nExpr > 0);
- pEList = pExpr->pList;
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
+ assert((pExpr->x.pList->nExpr % 2) == 0);
+ assert(pExpr->x.pList->nExpr > 0);
+ pEList = pExpr->x.pList;
aListelem = pEList->a;
nExpr = pEList->nExpr;
endLabel = sqlite3VdbeMakeLabel(v);
if( (pX = pExpr->pLeft)!=0 ){
@@ -58523,17 +59381,17 @@
sqlite3ErrorMsg(pParse,
"RAISE() may only be used within a trigger-program");
return 0;
}
- if( pExpr->iColumn!=OE_Ignore ){
- assert( pExpr->iColumn==OE_Rollback ||
- pExpr->iColumn == OE_Abort ||
- pExpr->iColumn == OE_Fail );
- sqlite3DequoteExpr(db, pExpr);
- sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn, 0,
+ if( pExpr->affinity!=OE_Ignore ){
+ assert( pExpr->affinity==OE_Rollback ||
+ pExpr->affinity == OE_Abort ||
+ pExpr->affinity == OE_Fail );
+ sqlite3DequoteExpr(pExpr);
+ sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->affinity, 0,
(char*)pExpr->token.z, pExpr->token.n);
} else {
- assert( pExpr->iColumn == OE_Ignore );
+ assert( pExpr->affinity == OE_Ignore );
sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0);
sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->trigStack->ignoreJump);
VdbeComment((v, "raise(IGNORE)"));
}
@@ -58688,9 +59546,10 @@
/* The arguments to a function have a fixed destination.
** Mark them this way to avoid generated unneeded OP_SCopy
** instructions.
*/
- ExprList *pList = pExpr->pList;
+ ExprList *pList = pExpr->x.pList;
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
if( pList ){
int i = pList->nExpr;
struct ExprList_item *pItem = pList->a;
for(; i>0; i--, pItem++){
@@ -58864,18 +59723,19 @@
Expr compLeft;
Expr compRight;
Expr exprX;
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
exprX = *pExpr->pLeft;
exprAnd.op = TK_AND;
exprAnd.pLeft = &compLeft;
exprAnd.pRight = &compRight;
compLeft.op = TK_GE;
compLeft.pLeft = &exprX;
- compLeft.pRight = pExpr->pList->a[0].pExpr;
+ compLeft.pRight = pExpr->x.pList->a[0].pExpr;
compRight.op = TK_LE;
compRight.pLeft = &exprX;
- compRight.pRight = pExpr->pList->a[1].pExpr;
+ compRight.pRight = pExpr->x.pList->a[1].pExpr;
exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, ®Free1);
testcase( regFree1==0 );
exprX.op = TK_REGISTER;
testcase( jumpIfNull==0 );
@@ -59015,18 +59875,19 @@
Expr compLeft;
Expr compRight;
Expr exprX;
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
exprX = *pExpr->pLeft;
exprAnd.op = TK_AND;
exprAnd.pLeft = &compLeft;
exprAnd.pRight = &compRight;
compLeft.op = TK_GE;
compLeft.pLeft = &exprX;
- compLeft.pRight = pExpr->pList->a[0].pExpr;
+ compLeft.pRight = pExpr->x.pList->a[0].pExpr;
compRight.op = TK_LE;
compRight.pLeft = &exprX;
- compRight.pRight = pExpr->pList->a[1].pExpr;
+ compRight.pRight = pExpr->x.pList->a[1].pExpr;
exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, ®Free1);
testcase( regFree1==0 );
exprX.op = TK_REGISTER;
testcase( jumpIfNull==0 );
@@ -59063,24 +59924,27 @@
int i;
if( pA==0||pB==0 ){
return pB==pA;
}
- if( pA->op!=pB->op ) return 0;
+ if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
+ return 0;
+ }
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 0;
+ if( pA->op!=pB->op ) return 0;
if( !sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 0;
if( !sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 0;
- if( pA->pList ){
- if( pB->pList==0 ) return 0;
- if( pA->pList->nExpr!=pB->pList->nExpr ) return 0;
- for(i=0; i<pA->pList->nExpr; i++){
- if( !sqlite3ExprCompare(pA->pList->a[i].pExpr, pB->pList->a[i].pExpr) ){
- return 0;
- }
- }
- }else if( pB->pList ){
- return 0;
- }
- if( pA->pSelect || pB->pSelect ) return 0;
+
+ if( pA->x.pList && pB->x.pList ){
+ if( pA->x.pList->nExpr!=pB->x.pList->nExpr ) return 0;
+ for(i=0; i<pA->x.pList->nExpr; i++){
+ Expr *pExprA = pA->x.pList->a[i].pExpr;
+ Expr *pExprB = pB->x.pList->a[i].pExpr;
+ if( !sqlite3ExprCompare(pExprA, pExprB) ) return 0;
+ }
+ }else if( pA->x.pList || pB->x.pList ){
+ return 0;
+ }
+
if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
if( pA->op!=TK_COLUMN && pA->token.z ){
if( pB->token.z==0 ) return 0;
if( pB->token.n!=pA->token.n ) return 0;
@@ -59226,14 +60090,15 @@
*/
u8 enc = ENC(pParse->db);
i = addAggInfoFunc(pParse->db, pAggInfo);
if( i>=0 ){
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
pItem = &pAggInfo->aFunc[i];
pItem->pExpr = pExpr;
pItem->iMem = ++pParse->nMem;
pItem->pFunc = sqlite3FindFunction(pParse->db,
(char*)pExpr->token.z, pExpr->token.n,
- pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0);
+ pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
if( pExpr->flags & EP_Distinct ){
pItem->iDistinct = pParse->nTab++;
}else{
pItem->iDistinct = -1;
@@ -59348,9 +60213,9 @@
*************************************************************************
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
-** $Id: alter.c,v 1.51 2008/12/10 19:26:22 drh Exp $
+** $Id: alter.c,v 1.55 2009/03/24 15:08:10 drh Exp $
*/
/*
** The code in this file only exists if we are not omitting the
@@ -59528,9 +60393,9 @@
** expression being built up in zWhere.
*/
if( pTab->pSchema!=pTempSchema ){
sqlite3 *db = pParse->db;
- for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){
+ for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
if( pTrig->pSchema==pTempSchema ){
if( !zWhere ){
zWhere = sqlite3MPrintf(db, "name=%Q", pTrig->name);
}else{
@@ -59567,9 +60432,9 @@
assert( iDb>=0 );
#ifndef SQLITE_OMIT_TRIGGER
/* Drop any table triggers from the internal schema. */
- for(pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext){
+ for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
assert( iTrigDb==iDb || iTrigDb==1 );
sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->name, 0);
}
@@ -59788,9 +60653,9 @@
assert( sqlite3BtreeHoldsAllMutexes(db) );
iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
zDb = db->aDb[iDb].zName;
- zTab = pNew->zName;
+ zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */
pCol = &pNew->aCol[pNew->nCol-1];
pDflt = pCol->pDflt;
pTab = sqlite3FindTable(db, zTab, zDb);
assert( pTab );
@@ -59847,9 +60712,9 @@
/* Modify the CREATE TABLE statement. */
zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
if( zCol ){
char *zEnd = &zCol[pColDef->n-1];
- while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){
+ while( (zEnd>zCol && *zEnd==';') || sqlite3Isspace(*zEnd) ){
*zEnd-- = '\0';
}
sqlite3NestedParse(pParse,
"UPDATE \"%w\".%s SET "
@@ -59918,21 +60783,25 @@
assert( pTab->addColOffset>0 );
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
/* Put a copy of the Table struct in Parse.pNewTable for the
- ** sqlite3AddColumn() function and friends to modify.
+ ** sqlite3AddColumn() function and friends to modify. But modify
+ ** the name by adding an "sqlite_altertab_" prefix. By adding this
+ ** prefix, we insure that the name will not collide with an existing
+ ** table because user table are not allowed to have the "sqlite_"
+ ** prefix on their name.
*/
pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table));
if( !pNew ) goto exit_begin_add_column;
pParse->pNewTable = pNew;
pNew->nRef = 1;
- pNew->db = db;
+ pNew->dbMem = pTab->dbMem;
pNew->nCol = pTab->nCol;
assert( pNew->nCol>0 );
nAlloc = (((pNew->nCol-1)/8)*8)+8;
assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );
pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc);
- pNew->zName = sqlite3DbStrDup(db, pTab->zName);
+ pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName);
if( !pNew->aCol || !pNew->zName ){
db->mallocFailed = 1;
goto exit_begin_add_column;
}
@@ -59974,9 +60843,9 @@
**
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
-** @(#) $Id: analyze.c,v 1.47 2008/12/10 16:45:51 drh Exp $
+** @(#) $Id: analyze.c,v 1.51 2009/02/28 10:47:42 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
/*
@@ -60036,10 +60905,10 @@
*/
if( !createStat1 ){
sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1");
}
- sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, 3);
sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur, iRootPage, iDb);
+ sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
sqlite3VdbeChangeP5(v, createStat1);
}
/*
@@ -60079,9 +60948,9 @@
/* Establish a read-lock on the table at the shared-cache level. */
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
- iIdxCur = pParse->nTab;
+ iIdxCur = pParse->nTab++;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
int regFields; /* Register block for building records */
int regRec; /* Register holding completed record */
@@ -60093,9 +60962,8 @@
/* Open a cursor to the index to be analyzed
*/
assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) );
nCol = pIdx->nColumn;
- sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, nCol+1);
sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb,
(char *)pKey, P4_KEYINFO_HANDOFF);
VdbeComment((v, "%s", pIdx->zName));
regFields = iMem+nCol*2;
@@ -60151,9 +61019,9 @@
**
** The result is a single row of the sqlite_stat1 table. The first
** two columns are the names of the table and index. The third column
** is a string composed of a list of integer statistics about the
- ** index. The first integer in the list is the total number of entires
+ ** index. The first integer in the list is the total number of entries
** in the index. There is one additional integer in the list for each
** column of the table. This additional integer is a guess of how many
** rows of the table the index will select. If D is the count of distinct
** values and K is the total number of rows, then the integer is computed
@@ -60378,12 +61246,17 @@
/* Load new statistics out of the sqlite_stat1 table */
zSql = sqlite3MPrintf(db, "SELECT idx, stat FROM %Q.sqlite_stat1",
sInfo.zDatabase);
- (void)sqlite3SafetyOff(db);
- rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
- (void)sqlite3SafetyOn(db);
- sqlite3DbFree(db, zSql);
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ (void)sqlite3SafetyOff(db);
+ rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
+ (void)sqlite3SafetyOn(db);
+ sqlite3DbFree(db, zSql);
+ if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
+ }
return rc;
}
@@ -60403,9 +61276,9 @@
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
-** $Id: attach.c,v 1.81 2008/12/10 16:45:51 drh Exp $
+** $Id: attach.c,v 1.83 2009/02/19 14:39:25 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_ATTACH
/*
@@ -60656,9 +61529,9 @@
sqlite3_snprintf(sizeof(zErr), zErr,
"cannot DETACH database within transaction");
goto detach_error;
}
- if( sqlite3BtreeIsInReadTrans(pDb->pBt) ){
+ if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
goto detach_error;
}
@@ -60879,13 +61752,13 @@
DbFixer *pFix, /* Context of the fixation */
Expr *pExpr /* The expression to be fixed to one database */
){
while( pExpr ){
- if( sqlite3FixSelect(pFix, pExpr->pSelect) ){
- return 1;
- }
- if( sqlite3FixExprList(pFix, pExpr->pList) ){
- return 1;
+ if( ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanOnly) ) break;
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
+ }else{
+ if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1;
}
if( sqlite3FixExpr(pFix, pExpr->pRight) ){
return 1;
}
@@ -61191,9 +62064,9 @@
** BEGIN TRANSACTION
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.511 2008/12/30 06:24:58 danielk1977 Exp $
+** $Id: build.c,v 1.527 2009/03/31 03:41:57 shane Exp $
*/
/*
** This routine is called when a new SQL statement is beginning to
@@ -61346,21 +62219,8 @@
*/
codeTableLocks(pParse);
sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto);
}
-
-#ifndef SQLITE_OMIT_TRACE
- if( !db->init.busy ){
- /* Change the P4 argument of the first opcode (which will always be
- ** an OP_Trace) to be the complete text of the current SQL statement.
- */
- VdbeOp *pOp = sqlite3VdbeGetOp(v, 0);
- if( pOp && pOp->opcode==OP_Trace ){
- sqlite3VdbeChangeP4(v, 0, pParse->zSql,
- (int)(pParse->zTail - pParse->zSql));
- }
- }
-#endif /* SQLITE_OMIT_TRACE */
}
/* Get the VDBE program ready for execution
@@ -61370,10 +62230,10 @@
FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
sqlite3VdbeTrace(v, trace);
#endif
assert( pParse->disableColCache==0 ); /* Disables and re-enables match */
- sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3,
- pParse->nTab+3, pParse->explain);
+ sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem,
+ pParse->nTab, pParse->explain);
pParse->rc = SQLITE_DONE;
pParse->colNamesSet = 0;
}else if( pParse->rc==SQLITE_OK ){
pParse->rc = SQLITE_ERROR;
@@ -61520,9 +62380,9 @@
/*
** Reclaim the memory used by an index
*/
static void freeIndex(Index *p){
- sqlite3 *db = p->pTable->db;
+ sqlite3 *db = p->pTable->dbMem;
sqlite3DbFree(db, p->zColAff);
sqlite3DbFree(db, p);
}
@@ -61533,9 +62393,9 @@
** The index is removed from the database hash tables but
** it is not unlinked from the Table that it indexes.
** Unlinking from the Table must be done by the calling function.
*/
-static void sqliteDeleteIndex(Index *p){
+static void sqlite3DeleteIndex(Index *p){
Index *pOld;
const char *zName = p->zName;
pOld = sqlite3HashInsert(&p->pSchema->idxHash, zName,
@@ -61578,10 +62438,10 @@
** before the database closes. It is also called during a rollback
** if there were schema changes during the transaction or if a
** schema-cookie mismatch occurs.
**
-** If iDb<=0 then reset the internal schema tables for all database
-** files. If iDb>=2 then reset the internal schema for only the
+** If iDb==0 then reset the internal schema tables for all database
+** files. If iDb>=1 then reset the internal schema for only the
** single file indicated.
*/
SQLITE_PRIVATE void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
int i, j;
@@ -61648,9 +62508,9 @@
*/
static void sqliteResetColumnNames(Table *pTable){
int i;
Column *pCol;
- sqlite3 *db = pTable->db;
+ sqlite3 *db = pTable->dbMem;
assert( pTable!=0 );
if( (pCol = pTable->aCol)!=0 ){
for(i=0; i<pTable->nCol; i++, pCol++){
sqlite3DbFree(db, pCol->zName);
@@ -61679,9 +62539,9 @@
FKey *pFKey, *pNextFKey;
sqlite3 *db;
if( pTable==0 ) return;
- db = pTable->db;
+ db = pTable->dbMem;
/* Do not delete the table until the reference count reaches zero. */
pTable->nRef--;
if( pTable->nRef>0 ){
@@ -61693,9 +62553,9 @@
*/
for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
pNext = pIndex->pNext;
assert( pIndex->pSchema==pTable->pSchema );
- sqliteDeleteIndex(pIndex);
+ sqlite3DeleteIndex(pIndex);
}
#ifndef SQLITE_OMIT_FOREIGN_KEY
/* Delete all foreign keys associated with this table. The keys
@@ -61784,10 +62644,34 @@
*/
SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *p, int iDb){
Vdbe *v = sqlite3GetVdbe(p);
sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
- sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, 5);/* sqlite_master has 5 columns */
sqlite3VdbeAddOp3(v, OP_OpenWrite, 0, MASTER_ROOT, iDb);
+ sqlite3VdbeChangeP4(v, -1, (char *)5, P4_INT32); /* 5 column table */
+ if( p->nTab==0 ){
+ p->nTab = 1;
+ }
+}
+
+/*
+** Parameter zName points to a nul-terminated buffer containing the name
+** of a database ("main", "temp" or the name of an attached db). This
+** function returns the index of the named database in db->aDb[], or
+** -1 if the named db cannot be found.
+*/
+SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){
+ int i = -1; /* Database number */
+ if( zName ){
+ Db *pDb;
+ int n = sqlite3Strlen30(zName);
+ for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
+ if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) &&
+ 0==sqlite3StrICmp(pDb->zName, zName) ){
+ break;
+ }
+ }
+ }
+ return i;
}
/*
** The token *pName contains the name of a database (either "main" or
@@ -61795,24 +62679,13 @@
** index of the named database in db->aDb[], or -1 if the named db
** does not exist.
*/
SQLITE_PRIVATE int sqlite3FindDb(sqlite3 *db, Token *pName){
- int i = -1; /* Database number */
- int n; /* Number of characters in the name */
- Db *pDb; /* A database whose name space is being searched */
- char *zName; /* Name we are searching for */
-
+ int i; /* Database number */
+ char *zName; /* Name we are searching for */
zName = sqlite3NameFromToken(db, pName);
- if( zName ){
- n = sqlite3Strlen30(zName);
- for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
- if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) &&
- 0==sqlite3StrICmp(pDb->zName, zName) ){
- break;
- }
- }
- sqlite3DbFree(db, zName);
- }
+ i = sqlite3FindDbName(db, zName);
+ sqlite3DbFree(db, zName);
return i;
}
/* The table or view or trigger name is passed to this routine via tokens
@@ -62004,9 +62877,9 @@
pTable->zName = zName;
pTable->iPKey = -1;
pTable->pSchema = db->aDb[iDb].pSchema;
pTable->nRef = 1;
- pTable->db = db;
+ pTable->dbMem = db->lookaside.bEnabled ? db : 0;
if( pParse->pNewTable ) sqlite3DeleteTable(pParse->pNewTable);
pParse->pNewTable = pTable;
/* If this is the magic sqlite_sequence table used by autoincrement,
@@ -62059,11 +62932,12 @@
/* This just creates a place-holder record in the sqlite_master table.
** The record created does not contain anything yet. It will be replaced
** by the real entry in code generated at sqlite3EndTable().
**
- ** The rowid for the new entry is left on the top of the stack.
- ** The rowid value is needed by the code that sqlite3EndTable will
- ** generate.
+ ** The rowid for the new entry is left in register pParse->regRowid.
+ ** The root page number of the new table is left in reg pParse->regRoot.
+ ** The rowid and root page number values are needed by the code that
+ ** sqlite3EndTable will generate.
*/
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
if( isView || isVirtual ){
sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2);
@@ -62274,14 +63148,16 @@
if( !sqlite3ExprIsConstantOrFunction(pExpr) ){
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
pCol->zName);
}else{
- Expr *pCopy;
+ /* A copy of pExpr is used instead of the original, as pExpr contains
+ ** tokens that point to volatile memory. The 'span' of the expression
+ ** is required by pragma table_info.
+ */
sqlite3ExprDelete(db, pCol->pDflt);
- pCol->pDflt = pCopy = sqlite3ExprDup(db, pExpr);
- if( pCopy ){
- sqlite3TokenCopy(db, &pCopy->span, &pExpr->span);
- }
+ pCol->pDflt = sqlite3ExprDup(
+ db, pExpr, EXPRDUP_REDUCE|EXPRDUP_DISTINCTSPAN
+ );
}
}
sqlite3ExprDelete(db, pExpr);
}
@@ -62375,9 +63251,9 @@
/* The CHECK expression must be duplicated so that tokens refer
** to malloced space and not the (ephemeral) text of the CREATE TABLE
** statement */
pTab->pCheck = sqlite3ExprAnd(db, pTab->pCheck,
- sqlite3ExprDup(db, pCheckExpr));
+ sqlite3ExprDup(db, pCheckExpr, 0));
}
#endif
sqlite3ExprDelete(db, pCheckExpr);
}
@@ -62498,20 +63374,102 @@
return n + 2;
}
/*
-** Write an identifier onto the end of the given string. Add
-** quote characters as needed.
-*/
-static void identPut(char *z, int *pIdx, char *zSignedIdent){
+** This function is a wrapper around sqlite3GetToken() used by
+** isValidDimension(). This function differs from sqlite3GetToken() in
+** that:
+**
+** * Whitespace is ignored, and
+** * The output variable *peToken is set to 0 if the end of the
+** nul-terminated input string is reached.
+*/
+static int getTokenNoSpace(unsigned char *z, int *peToken){
+ int n = 0;
+ while( sqlite3Isspace(z[n]) ) n++;
+ if( !z[n] ){
+ *peToken = 0;
+ return 0;
+ }
+ return n + sqlite3GetToken(&z[n], peToken);
+}
+
+/*
+** Parameter z points to a nul-terminated string. Return true if, when
+** whitespace is ignored, the contents of this string matches one of
+** the following patterns:
+**
+** ""
+** "(number)"
+** "(number,number)"
+*/
+static int isValidDimension(unsigned char *z){
+ int eToken;
+ int n = 0;
+ n += getTokenNoSpace(&z[n], &eToken);
+ if( eToken ){
+ if( eToken!=TK_LP ) return 0;
+ n += getTokenNoSpace(&z[n], &eToken);
+ if( eToken==TK_PLUS || eToken==TK_MINUS ){
+ n += getTokenNoSpace(&z[n], &eToken);
+ }
+ if( eToken!=TK_INTEGER && eToken!=TK_FLOAT ) return 0;
+ n += getTokenNoSpace(&z[n], &eToken);
+ if( eToken==TK_COMMA ){
+ n += getTokenNoSpace(&z[n], &eToken);
+ if( eToken==TK_PLUS || eToken==TK_MINUS ){
+ n += getTokenNoSpace(&z[n], &eToken);
+ }
+ if( eToken!=TK_INTEGER && eToken!=TK_FLOAT ) return 0;
+ n += getTokenNoSpace(&z[n], &eToken);
+ }
+ if( eToken!=TK_RP ) return 0;
+ getTokenNoSpace(&z[n], &eToken);
+ }
+ if( eToken ) return 0;
+ return 1;
+}
+
+/*
+** The first parameter is a pointer to an output buffer. The second
+** parameter is a pointer to an integer that contains the offset at
+** which to write into the output buffer. This function copies the
+** nul-terminated string pointed to by the third parameter, zSignedIdent,
+** to the specified offset in the buffer and updates *pIdx to refer
+** to the first byte after the last byte written before returning.
+**
+** If the string zSignedIdent consists entirely of alpha-numeric
+** characters, does not begin with a digit and is not an SQL keyword,
+** then it is copied to the output buffer exactly as it is. Otherwise,
+** it is quoted using double-quotes.
+*/
+static void identPut(char *z, int *pIdx, char *zSignedIdent, int isTypename){
unsigned char *zIdent = (unsigned char*)zSignedIdent;
int i, j, needQuote;
i = *pIdx;
+
for(j=0; zIdent[j]; j++){
- if( !isalnum(zIdent[j]) && zIdent[j]!='_' ) break;
- }
- needQuote = zIdent[j]!=0 || isdigit(zIdent[0])
- || sqlite3KeywordCode(zIdent, j)!=TK_ID;
+ if( !sqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break;
+ }
+ needQuote = sqlite3Isdigit(zIdent[0]) || sqlite3KeywordCode(zIdent, j)!=TK_ID;
+ if( !needQuote ){
+ if( isTypename ){
+ /* If this is a type-name, allow a little more flexibility. In SQLite,
+ ** a type-name is specified as:
+ **
+ ** ids [ids] [(number [, number])]
+ **
+ ** where "ids" is either a quoted string or a simple identifier (in the
+ ** above notation, [] means optional). It is a bit tricky to check
+ ** for all cases, but it is good to avoid unnecessarily quoting common
+ ** typenames like VARCHAR(10).
+ */
+ needQuote = !isValidDimension(&zIdent[j]);
+ }else{
+ needQuote = zIdent[j];
+ }
+ }
+
if( needQuote ) z[i++] = '"';
for(j=0; zIdent[j]; j++){
z[i++] = zIdent[j];
if( zIdent[j]=='"' ) z[i++] = '"';
@@ -62525,9 +63483,9 @@
** Generate a CREATE TABLE statement appropriate for the given
** table. Memory to hold the text of the statement is obtained
** from sqliteMalloc() and must be freed by the calling function.
*/
-static char *createTableStmt(sqlite3 *db, Table *p, int isTemp){
+static char *createTableStmt(sqlite3 *db, Table *p){
int i, k, n;
char *zStmt;
char *zSep, *zSep2, *zEnd, *z;
Column *pCol;
@@ -62535,9 +63493,9 @@
for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
n += identLength(pCol->zName);
z = pCol->zType;
if( z ){
- n += (sqlite3Strlen30(z) + 1);
+ n += identLength(z);
}
}
n += identLength(p->zName);
if( n<50 ){
@@ -62554,23 +63512,21 @@
if( zStmt==0 ){
db->mallocFailed = 1;
return 0;
}
- sqlite3_snprintf(n, zStmt,
- !OMIT_TEMPDB&&isTemp ? "CREATE TEMP TABLE ":"CREATE TABLE ");
+ sqlite3_snprintf(n, zStmt, "CREATE TABLE ");
k = sqlite3Strlen30(zStmt);
- identPut(zStmt, &k, p->zName);
+ identPut(zStmt, &k, p->zName, 0);
zStmt[k++] = '(';
for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
sqlite3_snprintf(n-k, &zStmt[k], zSep);
k += sqlite3Strlen30(&zStmt[k]);
zSep = zSep2;
- identPut(zStmt, &k, pCol->zName);
+ identPut(zStmt, &k, pCol->zName, 0);
if( (z = pCol->zType)!=0 ){
zStmt[k++] = ' ';
assert( (int)(sqlite3Strlen30(z)+k+1)<=n );
- sqlite3_snprintf(n-k, &zStmt[k], "%s", z);
- k += sqlite3Strlen30(z);
+ identPut(zStmt, &k, z, 1);
}
}
sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd);
return zStmt;
@@ -62648,10 +63604,9 @@
p->tnum = db->init.newTnum;
}
/* If not initializing, then create a record for the new table
- ** in the SQLITE_MASTER table of the database. The record number
- ** for the new table entry should already be on the stack.
+ ** in the SQLITE_MASTER table of the database.
**
** If this is a TEMPORARY table, write the entry into the auxiliary
** file instead of into the main database file.
*/
@@ -62666,11 +63621,10 @@
if( v==0 ) return;
sqlite3VdbeAddOp1(v, OP_Close, 0);
- /* Create the rootpage for the new table and push it onto the stack.
- ** A view has no rootpage, so just push a zero onto the stack for
- ** views. Initialize zType at the same time.
+ /*
+ ** Initialize zType for the new view or table.
*/
if( p->pSelect==0 ){
/* A regular table */
zType = "table";
@@ -62684,9 +63638,9 @@
}
/* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
** statement to populate the new table. The root-page number for the
- ** new table is on the top of the vdbe stack.
+ ** new table is in register pParse->regRoot.
**
** Once the SELECT has been coded by sqlite3Select(), it is in a
** suitable state to query for the column names and types to be used
** by the new table.
@@ -62699,9 +63653,9 @@
if( pSelect ){
SelectDest dest;
Table *pSelTab;
- assert(pParse->nTab==0);
+ assert(pParse->nTab==1);
sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
sqlite3VdbeChangeP5(v, 1);
pParse->nTab = 2;
sqlite3SelectDestInit(&dest, SRT_Table, 1);
@@ -62720,9 +63674,9 @@
}
/* Compute the complete text of the CREATE statement */
if( pSelect ){
- zStmt = createTableStmt(db, p, p->pSchema==db->aDb[1].pSchema);
+ zStmt = createTableStmt(db, p);
}else{
n = (int)(pEnd->z - pParse->sNameToken.z) + 1;
zStmt = sqlite3MPrintf(db,
"CREATE %s %.*s", zType2, n, pParse->sNameToken.z
@@ -62730,11 +63684,9 @@
}
/* A slot for the record has already been allocated in the
** SQLITE_MASTER table. We just need to update that slot with all
- ** the information we've collected. The rowid for the preallocated
- ** slot is the 2nd item on the stack. The top of the stack is the
- ** root page for the new table (or a 0 if this is a view).
+ ** the information we've collected.
*/
sqlite3NestedParse(pParse,
"UPDATE %Q.%s "
"SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q "
@@ -62860,9 +63812,9 @@
** This will force all the Expr.token.z values to be dynamically
** allocated rather than point to the input string - which means that
** they will persist after the current sqlite3_exec() call returns.
*/
- p->pSelect = sqlite3SelectDup(db, pSelect);
+ p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
sqlite3SelectDelete(db, pSelect);
if( db->mallocFailed ){
return;
}
@@ -62879,9 +63831,9 @@
}
sEnd.n = 0;
n = (int)(sEnd.z - pBegin->z);
z = (const unsigned char*)pBegin->z;
- while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; }
+ while( n>0 && (z[n-1]==';' || sqlite3Isspace(z[n-1])) ){ n--; }
sEnd.z = &z[n-1];
sEnd.n = 1;
/* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
@@ -62942,13 +63894,15 @@
** to be permanent. So the computation is done on a copy of the SELECT
** statement that defines the view.
*/
assert( pTable->pSelect );
- pSel = sqlite3SelectDup(db, pTable->pSelect);
+ pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
if( pSel ){
+ u8 enableLookaside = db->lookaside.bEnabled;
n = pParse->nTab;
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
pTable->nCol = -1;
+ db->lookaside.bEnabled = 0;
#ifndef SQLITE_OMIT_AUTHORIZATION
xAuth = db->xAuth;
db->xAuth = 0;
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
@@ -62955,8 +63909,9 @@
db->xAuth = xAuth;
#else
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
#endif
+ db->lookaside.bEnabled = enableLookaside;
pParse->nTab = n;
if( pSelTab ){
assert( pTable->aCol==0 );
pTable->nCol = pSelTab->nCol;
@@ -63051,10 +64006,10 @@
** is non-zero, then it is the root page number of a table moved to
** location iTable. The following code modifies the sqlite_master table to
** reflect this.
**
- ** The "#%d" in the SQL is a special constant that means whatever value
- ** is on the top of the stack. See sqlite3RegisterExpr().
+ ** The "#NNN" in the SQL is a special constant that means whatever value
+ ** is in register NNN. See sqlite3RegisterExpr().
*/
sqlite3NestedParse(pParse,
"UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1);
@@ -63227,9 +64182,9 @@
/* Drop all triggers associated with the table being dropped. Code
** is generated to remove entries from sqlite_master and/or
** sqlite_temp_master if required.
*/
- pTrigger = pTab->pTrigger;
+ pTrigger = sqlite3TriggerList(pParse, pTab);
while( pTrigger ){
assert( pTrigger->pSchema==pTab->pSchema ||
pTrigger->pSchema==db->aDb[1].pSchema );
sqlite3DropTriggerPtr(pParse, pTrigger);
@@ -63436,10 +64391,10 @@
** the root page number of the index is taken from pIndex->tnum.
*/
static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
Table *pTab = pIndex->pTable; /* The table that is indexed */
- int iTab = pParse->nTab; /* Btree cursor used for pTab */
- int iIdx = pParse->nTab+1; /* Btree cursor used for pIndex */
+ int iTab = pParse->nTab++; /* Btree cursor used for pTab */
+ int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */
int addr1; /* Address of top of loop */
int tnum; /* Root page of index */
Vdbe *v; /* Generate code into this virtual machine */
KeyInfo *pKey; /* KeyInfo for index */
@@ -63587,9 +64542,10 @@
}
pDb = &db->aDb[iDb];
if( pTab==0 || pParse->nErr ) goto exit_create_index;
- if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
+ if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
+ && memcmp(&pTab->zName[7],"altertab_",9)!=0 ){
sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
goto exit_create_index;
}
#ifndef SQLITE_OMIT_VIEW
@@ -63931,9 +64887,10 @@
/* Clean up before exiting */
exit_create_index:
if( pIndex ){
- freeIndex(pIndex);
+ sqlite3_free(pIndex->zColAff);
+ sqlite3DbFree(db, pIndex);
}
sqlite3ExprListDelete(db, pList);
sqlite3SrcListDelete(db, pTblName);
sqlite3DbFree(db, zName);
@@ -64589,13 +65546,8 @@
** the way through and which will need to undo some writes without having to
** rollback the whole transaction. For operations where all constraints
** can be checked before any changes are made to the database, it is never
** necessary to undo a write and the checkpoint should not be set.
-**
-** Only database iDb and the temp database are made writable by this call.
-** If iDb==0, then the main and temp databases are made writable. If
-** iDb==1 then only the temp database is made writable. If iDb>1 then the
-** specified auxiliary database and the temp database are made writable.
*/
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
Vdbe *v = sqlite3GetVdbe(pParse);
if( v==0 ) return;
@@ -64602,11 +65554,8 @@
sqlite3CodeVerifySchema(pParse, iDb);
pParse->writeMask |= 1<<iDb;
if( setStatement && pParse->nested==0 ){
sqlite3VdbeAddOp1(v, OP_Statement, iDb);
- }
- if( (OMIT_TEMPDB || iDb!=1) && pParse->db->aDb[1].pBt!=0 ){
- sqlite3BeginWriteOperation(pParse, setStatement, 1);
}
}
/*
@@ -64790,9 +65739,9 @@
**
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
-** $Id: callback.c,v 1.34 2008/12/10 21:19:57 drh Exp $
+** $Id: callback.c,v 1.37 2009/03/24 15:08:10 drh Exp $
*/
/*
@@ -64951,9 +65900,9 @@
memcpy(pColl[0].zName, zName, nName);
pColl[0].zName[nName] = 0;
pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
- /* If a malloc() failure occured in sqlite3HashInsert(), it will
+ /* If a malloc() failure occurred in sqlite3HashInsert(), it will
** return the pColl pointer to be deleted (because it wasn't added
** to the hash table).
*/
assert( pDel==0 || pDel==pColl );
@@ -65004,10 +65953,11 @@
** matches the request for a function with nArg arguments in a system
** that uses encoding enc. The value returned indicates how well the
** request is matched. A higher value indicates a better match.
**
-** The returned value is always between 1 and 6, as follows:
-**
+** The returned value is always between 0 and 6, as follows:
+**
+** 0: Not a match, or if nArg<0 and the function is has no implementation.
** 1: A variable arguments function that prefers UTF-8 when a UTF-16
** encoding is requested, or vice versa.
** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
** requested, or vice versa.
@@ -65020,9 +65970,11 @@
**
*/
static int matchQuality(FuncDef *p, int nArg, u8 enc){
int match = 0;
- if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){
+ if( p->nArg==-1 || p->nArg==nArg
+ || (nArg==-1 && (p->xFunc!=0 || p->xStep!=0))
+ ){
match = 1;
if( p->nArg==nArg || nArg==-1 ){
match = 4;
}
@@ -65196,8 +66148,9 @@
sqlite3HashClear(&temp2);
sqlite3HashInit(&pSchema->tblHash, 0);
for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
Table *pTab = sqliteHashData(pElem);
+ assert( pTab->dbMem==0 );
sqlite3DeleteTable(pTab);
}
sqlite3HashClear(&temp1);
pSchema->pSeqTab = 0;
@@ -65242,9 +66195,9 @@
*************************************************************************
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
**
-** $Id: delete.c,v 1.191 2008/12/23 23:56:22 drh Exp $
+** $Id: delete.c,v 1.198 2009/03/05 03:48:07 shane Exp $
*/
/*
** Look up every table that is named in pSrc. If any table is not found,
@@ -65306,10 +66259,10 @@
if( IsVirtual(pTab) ) return;
v = sqlite3GetVdbe(p);
assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
- sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pTab->nCol);
sqlite3VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb);
+ sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(pTab->nCol), P4_INT32);
VdbeComment((v, "%s", pTab->zName));
}
@@ -65328,14 +66281,14 @@
SelectDest dest;
Select *pDup;
sqlite3 *db = pParse->db;
- pDup = sqlite3SelectDup(db, pView->pSelect);
+ pDup = sqlite3SelectDup(db, pView->pSelect, 0);
if( pWhere ){
SrcList *pFrom;
Token viewName;
- pWhere = sqlite3ExprDup(db, pWhere);
+ pWhere = sqlite3ExprDup(db, pWhere, 0);
viewName.z = (u8*)pView->zName;
viewName.n = (unsigned int)sqlite3Strlen30((const char*)viewName.z);
pFrom = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, &viewName, pDup, 0,0);
pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
@@ -65403,16 +66356,17 @@
if( pEList == 0 ) goto limit_where_cleanup_2;
/* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
** and the SELECT subtree. */
- pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc);
+ pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
if( pSelectSrc == 0 ) {
sqlite3ExprListDelete(pParse->db, pEList);
goto limit_where_cleanup_2;
}
/* generate the SELECT expression tree. */
- pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,pOrderBy,0,pLimit,pOffset);
+ pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,
+ pOrderBy,0,pLimit,pOffset);
if( pSelect == 0 ) return 0;
/* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
pWhereRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0);
@@ -65419,9 +66373,10 @@
if( pWhereRowid == 0 ) goto limit_where_cleanup_1;
pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
if( pInClause == 0 ) goto limit_where_cleanup_1;
- pInClause->pSelect = pSelect;
+ pInClause->x.pSelect = pSelect;
+ pInClause->flags |= EP_xIsSelect;
sqlite3ExprSetHeight(pParse, pInClause);
return pInClause;
/* something went wrong. clean up anything allocated. */
@@ -65467,9 +66422,9 @@
int rcauth; /* Value returned by authorization callback */
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True if attempting to delete from a view */
- int triggers_exist = 0; /* True if any triggers exist */
+ Trigger *pTrigger; /* List of table triggers, if required */
#endif
int iBeginAfterTrigger = 0; /* Address of after trigger program */
int iEndAfterTrigger = 0; /* Exit of after trigger program */
int iBeginBeforeTrigger = 0; /* Address of before trigger program */
@@ -65494,20 +66449,20 @@
/* Figure out if we have any triggers and if the table being
** deleted from is a view
*/
#ifndef SQLITE_OMIT_TRIGGER
- triggers_exist = sqlite3TriggersExist(pTab, TK_DELETE, 0);
+ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
isView = pTab->pSelect!=0;
#else
-# define triggers_exist 0
+# define pTrigger 0
# define isView 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif
- if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
+ if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
goto delete_from_cleanup;
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb<db->nDb );
@@ -65516,9 +66471,9 @@
assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
if( rcauth==SQLITE_DENY ){
goto delete_from_cleanup;
}
- assert(!isView || triggers_exist);
+ assert(!isView || pTrigger);
/* If pTab is really a view, make sure it has been initialized.
*/
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
@@ -65526,9 +66481,9 @@
}
/* Allocate a cursor used to store the old.* data for a trigger.
*/
- if( triggers_exist ){
+ if( pTrigger ){
oldIdx = pParse->nTab++;
}
/* Assign cursor number to the table and all its indices.
@@ -65551,23 +66506,23 @@
if( v==0 ){
goto delete_from_cleanup;
}
if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
- sqlite3BeginWriteOperation(pParse, triggers_exist, iDb);
-
- if( triggers_exist ){
+ sqlite3BeginWriteOperation(pParse, (pTrigger?1:0), iDb);
+
+ if( pTrigger ){
int orconf = ((pParse->trigStack)?pParse->trigStack->orconf:OE_Default);
int iGoto = sqlite3VdbeAddOp0(v, OP_Goto);
addr = sqlite3VdbeMakeLabel(v);
iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v);
- (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab,
- -1, oldIdx, orconf, addr, &old_col_mask, 0);
+ (void)sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0,
+ TRIGGER_BEFORE, pTab, -1, oldIdx, orconf, addr, &old_col_mask, 0);
iEndBeforeTrigger = sqlite3VdbeAddOp0(v, OP_Goto);
iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v);
- (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1,
- oldIdx, orconf, addr, &old_col_mask, 0);
+ (void)sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0,
+ TRIGGER_AFTER, pTab, -1, oldIdx, orconf, addr, &old_col_mask, 0);
iEndAfterTrigger = sqlite3VdbeAddOp0(v, OP_Goto);
sqlite3VdbeJumpHere(v, iGoto);
}
@@ -65602,9 +66557,9 @@
/* Special case: A DELETE without a WHERE clause deletes everything.
** It is easier just to erase the whole table. Note, however, that
** this means that the row change count will be incorrect.
*/
- if( rcauth==SQLITE_OK && pWhere==0 && !triggers_exist && !IsVirtual(pTab) ){
+ if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) ){
assert( !isView );
sqlite3VdbeAddOp3(v, OP_Clear, pTab->tnum, iDb, memCnt);
if( !pParse->nested ){
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
@@ -65634,11 +66589,10 @@
sqlite3WhereEnd(pWInfo);
/* Open the pseudo-table used to store OLD if there are triggers.
*/
- if( triggers_exist ){
- sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pTab->nCol);
- sqlite3VdbeAddOp1(v, OP_OpenPseudo, oldIdx);
+ if( pTrigger ){
+ sqlite3VdbeAddOp3(v, OP_OpenPseudo, oldIdx, 0, pTab->nCol);
}
/* Delete every item whose key was written to the list during the
** database scan. We have to delete items after the scan is complete
@@ -65655,14 +66609,14 @@
/* This is the beginning of the delete loop. If a trigger encounters
** an IGNORE constraint, it jumps back to here.
*/
- if( triggers_exist ){
+ if( pTrigger ){
sqlite3VdbeResolveLabel(v, addr);
}
addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid);
- if( triggers_exist ){
+ if( pTrigger ){
int iData = ++pParse->nMem; /* For storing row data of OLD table */
/* If the record is no longer present in the table, jump to the
** next iteration of the loop through the contents of the fifo.
@@ -65698,9 +66652,9 @@
/* If there are row triggers, close all cursors then invoke
** the AFTER triggers
*/
- if( triggers_exist ){
+ if( pTrigger ){
/* Jump back and run the AFTER triggers */
sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginAfterTrigger);
sqlite3VdbeJumpHere(v, iEndAfterTrigger);
}
@@ -65878,9 +66832,9 @@
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: func.c,v 1.209 2008/12/10 23:04:13 drh Exp $
+** $Id: func.c,v 1.225 2009/03/27 15:26:03 danielk1977 Exp $
*/
/*
** Return the collating function associated with a function.
@@ -65901,9 +66855,9 @@
int mask; /* 0 for min() or 0xffffffff for max() */
int iBest;
CollSeq *pColl;
- if( argc==0 ) return;
+ assert( argc>1 );
mask = sqlite3_user_data(context)==0 ? 0 : -1;
pColl = sqlite3GetFuncCollSeq(context);
assert( pColl );
assert( mask==-1 || mask==0 );
@@ -65911,8 +66865,9 @@
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
for(i=1; i<argc; i++){
if( sqlite3_value_type(argv[i])==SQLITE_NULL ) return;
if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){
+ testcase( mask==0 );
iBest = i;
}
}
sqlite3_result_value(context, argv[iBest]);
@@ -65928,13 +66883,13 @@
){
const char *z = 0;
UNUSED_PARAMETER(NotUsed);
switch( sqlite3_value_type(argv[0]) ){
- case SQLITE_NULL: z = "null"; break;
case SQLITE_INTEGER: z = "integer"; break;
case SQLITE_TEXT: z = "text"; break;
case SQLITE_FLOAT: z = "real"; break;
case SQLITE_BLOB: z = "blob"; break;
+ default: z = "null"; break;
}
sqlite3_result_text(context, z, -1, SQLITE_STATIC);
}
@@ -66027,10 +66982,16 @@
const unsigned char *z2;
int len;
int p0type;
i64 p1, p2;
+ int negP2 = 0;
assert( argc==3 || argc==2 );
+ if( sqlite3_value_type(argv[1])==SQLITE_NULL
+ || (argc==3 && sqlite3_value_type(argv[2])==SQLITE_NULL)
+ ){
+ return;
+ }
p0type = sqlite3_value_type(argv[0]);
if( p0type==SQLITE_BLOB ){
len = sqlite3_value_bytes(argv[0]);
z = sqlite3_value_blob(argv[0]);
@@ -66046,22 +67007,38 @@
}
p1 = sqlite3_value_int(argv[1]);
if( argc==3 ){
p2 = sqlite3_value_int(argv[2]);
+ if( p2<0 ){
+ p2 = -p2;
+ negP2 = 1;
+ }
}else{
p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH];
}
if( p1<0 ){
p1 += len;
if( p1<0 ){
p2 += p1;
+ if( p2<0 ) p2 = 0;
p1 = 0;
}
}else if( p1>0 ){
p1--;
- }
+ }else if( p2>0 ){
+ p2--;
+ }
+ if( negP2 ){
+ p1 -= p2;
+ if( p1<0 ){
+ p2 += p1;
+ p1 = 0;
+ }
+ }
+ assert( p1>=0 && p2>=0 );
if( p1+p2>len ){
p2 = len-p1;
+ if( p2<0 ) p2 = 0;
}
if( p0type!=SQLITE_BLOB ){
while( *z && p1 ){
SQLITE_SKIP_UTF8(z);
@@ -66071,16 +67048,16 @@
SQLITE_SKIP_UTF8(z2);
}
sqlite3_result_text(context, (char*)z, (int)(z2-z), SQLITE_TRANSIENT);
}else{
- if( p2<0 ) p2 = 0;
sqlite3_result_blob(context, (char*)&z[p1], (int)p2, SQLITE_TRANSIENT);
}
}
/*
** Implementation of the round() function
*/
+#ifndef SQLITE_OMIT_FLOATING_POINT
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
int n = 0;
double r;
char zBuf[500]; /* larger than the %f representation of the largest double */
@@ -66096,8 +67073,9 @@
sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r);
sqlite3AtoF(zBuf, &r);
sqlite3_result_double(context, r);
}
+#endif
/*
** Allocate nByte bytes of space using sqlite3_malloc(). If the
** allocation fails, call sqlite3_result_error_nomem() to notify
@@ -66123,9 +67101,9 @@
static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
char *z1;
const char *z2;
int i, n;
- if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
+ UNUSED_PARAMETER(argc);
z2 = (char*)sqlite3_value_text(argv[0]);
n = sqlite3_value_bytes(argv[0]);
/* Verify that the call to _bytes() does not invalidate the _text() pointer */
assert( z2==(char*)sqlite3_value_text(argv[0]) );
@@ -66133,19 +67111,19 @@
z1 = contextMalloc(context, ((i64)n)+1);
if( z1 ){
memcpy(z1, z2, n+1);
for(i=0; z1[i]; i++){
- z1[i] = (char)toupper(z1[i]);
+ z1[i] = (char)sqlite3Toupper(z1[i]);
}
sqlite3_result_text(context, z1, -1, sqlite3_free);
}
}
}
static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- char *z1;
+ u8 *z1;
const char *z2;
int i, n;
- if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
+ UNUSED_PARAMETER(argc);
z2 = (char*)sqlite3_value_text(argv[0]);
n = sqlite3_value_bytes(argv[0]);
/* Verify that the call to _bytes() does not invalidate the _text() pointer */
assert( z2==(char*)sqlite3_value_text(argv[0]) );
@@ -66153,11 +67131,11 @@
z1 = contextMalloc(context, ((i64)n)+1);
if( z1 ){
memcpy(z1, z2, n+1);
for(i=0; z1[i]; i++){
- z1[i] = (char)tolower(z1[i]);
- }
- sqlite3_result_text(context, z1, -1, sqlite3_free);
+ z1[i] = sqlite3Tolower(z1[i]);
+ }
+ sqlite3_result_text(context, (char *)z1, -1, sqlite3_free);
}
}
}
@@ -66544,14 +67522,11 @@
** "NULL". Otherwise, the argument is enclosed in single quotes with
** single-quote escapes.
*/
static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- if( argc<1 ) return;
- switch( sqlite3_value_type(argv[0]) ){
- case SQLITE_NULL: {
- sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
- break;
- }
+ assert( argc==1 );
+ UNUSED_PARAMETER(argc);
+ switch( sqlite3_value_type(argv[0]) ){
case SQLITE_INTEGER:
case SQLITE_FLOAT: {
sqlite3_result_value(context, argv[0]);
break;
@@ -66597,8 +67572,14 @@
z[j++] = '\'';
z[j] = 0;
sqlite3_result_text(context, z, j, sqlite3_free);
}
+ break;
+ }
+ default: {
+ assert( sqlite3_value_type(argv[0])==SQLITE_NULL );
+ sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
+ break;
}
}
}
@@ -66678,9 +67659,18 @@
if( zStr==0 ) return;
nStr = sqlite3_value_bytes(argv[0]);
assert( zStr==sqlite3_value_text(argv[0]) ); /* No encoding change */
zPattern = sqlite3_value_text(argv[1]);
- if( zPattern==0 || zPattern[0]==0 ) return;
+ if( zPattern==0 ){
+ assert( sqlite3_value_type(argv[1])==SQLITE_NULL
+ || sqlite3_context_db_handle(context)->mallocFailed );
+ return;
+ }
+ if( zPattern[0]==0 ){
+ assert( sqlite3_value_type(argv[1])!=SQLITE_NULL );
+ sqlite3_result_value(context, argv[0]);
+ return;
+ }
nPattern = sqlite3_value_bytes(argv[1]);
assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */
zRep = sqlite3_value_text(argv[2]);
if( zRep==0 ) return;
@@ -66834,12 +67824,12 @@
};
assert( argc==1 );
zIn = (u8*)sqlite3_value_text(argv[0]);
if( zIn==0 ) zIn = (u8*)"";
- for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}
+ for(i=0; zIn[i] && !sqlite3Isalpha(zIn[i]); i++){}
if( zIn[i] ){
u8 prevcode = iCode[zIn[i]&0x7f];
- zResult[0] = toupper(zIn[i]);
+ zResult[0] = sqlite3Toupper(zIn[i]);
for(j=1; j<4 && zIn[i]; i++){
int code = iCode[zIn[i]&0x7f];
if( code>0 ){
if( code!=prevcode ){
@@ -66955,9 +67945,10 @@
}
static void totalFinalize(sqlite3_context *context){
SumCtx *p;
p = sqlite3_aggregate_context(context, 0);
- sqlite3_result_double(context, p ? p->rSum : 0.0);
+ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
+ sqlite3_result_double(context, p ? p->rSum : (double)0);
}
/*
** The following structure keeps track of state information for the
@@ -67042,33 +68033,30 @@
){
const char *zVal;
StrAccum *pAccum;
const char *zSep;
- int nVal, nSep, i;
- if( argc==0 || sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
+ int nVal, nSep;
+ assert( argc==1 || argc==2 );
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
if( pAccum ){
sqlite3 *db = sqlite3_context_db_handle(context);
pAccum->useMalloc = 1;
pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
if( pAccum->nChar ){
- if( argc>1 ){
- zSep = (char*)sqlite3_value_text(argv[argc-1]);
- nSep = sqlite3_value_bytes(argv[argc-1]);
+ if( argc==2 ){
+ zSep = (char*)sqlite3_value_text(argv[1]);
+ nSep = sqlite3_value_bytes(argv[1]);
}else{
zSep = ",";
nSep = 1;
}
sqlite3StrAccumAppend(pAccum, zSep, nSep);
}
- i = 0;
- do{
- zVal = (char*)sqlite3_value_text(argv[i]);
- nVal = sqlite3_value_bytes(argv[i]);
- sqlite3StrAccumAppend(pAccum, zVal, nVal);
- i++;
- }while( i<argc-1 );
+ zVal = (char*)sqlite3_value_text(argv[0]);
+ nVal = sqlite3_value_bytes(argv[0]);
+ sqlite3StrAccumAppend(pAccum, zVal, nVal);
}
}
static void groupConcatFinalize(sqlite3_context *context){
StrAccum *pAccum;
@@ -67129,11 +68117,11 @@
pInfo = (struct compareInfo*)&likeInfoAlt;
}else{
pInfo = (struct compareInfo*)&likeInfoNorm;
}
- sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
- sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
- sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
+ sqlite3CreateFunc(db, "like", 2, SQLITE_ANY, pInfo, likeFunc, 0, 0);
+ sqlite3CreateFunc(db, "like", 3, SQLITE_ANY, pInfo, likeFunc, 0, 0);
+ sqlite3CreateFunc(db, "glob", 2, SQLITE_ANY,
(struct compareInfo*)&globInfo, likeFunc, 0,0);
setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
setLikeOptFlag(db, "like",
caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
@@ -67147,14 +68135,15 @@
** return FALSE.
*/
SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
FuncDef *pDef;
- if( pExpr->op!=TK_FUNCTION || !pExpr->pList ){
- return 0;
- }
- if( pExpr->pList->nExpr!=2 ){
- return 0;
- }
+ if( pExpr->op!=TK_FUNCTION
+ || !pExpr->x.pList
+ || pExpr->x.pList->nExpr!=2
+ ){
+ return 0;
+ }
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
pDef = sqlite3FindFunction(db, (char*)pExpr->token.z, pExpr->token.n, 2,
SQLITE_UTF8, 0);
if( pDef==0 || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
return 0;
@@ -67205,18 +68194,20 @@
FUNCTION(length, 1, 0, 0, lengthFunc ),
FUNCTION(substr, 2, 0, 0, substrFunc ),
FUNCTION(substr, 3, 0, 0, substrFunc ),
FUNCTION(abs, 1, 0, 0, absFunc ),
+#ifndef SQLITE_OMIT_FLOATING_POINT
FUNCTION(round, 1, 0, 0, roundFunc ),
FUNCTION(round, 2, 0, 0, roundFunc ),
+#endif
FUNCTION(upper, 1, 0, 0, upperFunc ),
FUNCTION(lower, 1, 0, 0, lowerFunc ),
FUNCTION(coalesce, 1, 0, 0, 0 ),
FUNCTION(coalesce, -1, 0, 0, ifnullFunc ),
FUNCTION(coalesce, 0, 0, 0, 0 ),
FUNCTION(hex, 1, 0, 0, hexFunc ),
FUNCTION(ifnull, 2, 0, 1, ifnullFunc ),
- FUNCTION(random, -1, 0, 0, randomFunc ),
+ FUNCTION(random, 0, 0, 0, randomFunc ),
FUNCTION(randomblob, 1, 0, 0, randomBlob ),
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
FUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
FUNCTION(quote, 1, 0, 0, quoteFunc ),
@@ -67234,11 +68225,13 @@
#endif
AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ),
AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
- AGGREGATE(count, 0, 0, 0, countStep, countFinalize ),
+ /* AGGREGATE(count, 0, 0, 0, countStep, countFinalize ), */
+ {0,SQLITE_UTF8,SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0},
AGGREGATE(count, 1, 0, 0, countStep, countFinalize ),
- AGGREGATE(group_concat, -1, 0, 0, groupConcatStep, groupConcatFinalize),
+ AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize),
+ AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize),
LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
#ifdef SQLITE_CASE_SENSITIVE_LIKE
LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
@@ -67274,9 +68267,9 @@
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
-** $Id: insert.c,v 1.256 2008/12/10 21:19:57 drh Exp $
+** $Id: insert.c,v 1.260 2009/02/28 10:47:42 danielk1977 Exp $
*/
/*
** Set P4 of the most recently inserted opcode to a column affinity
@@ -67429,9 +68422,9 @@
int memId = 0; /* Register holding maximum rowid */
if( pTab->tabFlags & TF_Autoincrement ){
Vdbe *v = pParse->pVdbe;
Db *pDb = &pParse->db->aDb[iDb];
- int iCur = pParse->nTab;
+ int iCur = pParse->nTab++;
int addr; /* Address of the top of the loop */
assert( v );
pParse->nMem++; /* Holds name of table */
memId = ++pParse->nMem;
@@ -67478,9 +68471,9 @@
Table *pTab, /* Table we are inserting into */
int memId /* Memory cell holding the maximum rowid */
){
if( pTab->tabFlags & TF_Autoincrement ){
- int iCur = pParse->nTab;
+ int iCur = pParse->nTab++;
Vdbe *v = pParse->pVdbe;
Db *pDb = &pParse->db->aDb[iDb];
int j1;
int iRec = ++pParse->nMem; /* Memory cell used for record */
@@ -67662,9 +68655,10 @@
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True if attempting to insert into a view */
- int triggers_exist = 0; /* True if there are FOR EACH ROW triggers */
+ Trigger *pTrigger; /* List of triggers on pTab, if required */
+ int tmask; /* Mask of trigger times */
#endif
db = pParse->db;
memset(&dest, 0, sizeof(dest));
@@ -67692,24 +68686,26 @@
/* Figure out if we have any triggers and if the table being
** inserted into is a view
*/
#ifndef SQLITE_OMIT_TRIGGER
- triggers_exist = sqlite3TriggersExist(pTab, TK_INSERT, 0);
+ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask);
isView = pTab->pSelect!=0;
#else
-# define triggers_exist 0
+# define pTrigger 0
+# define tmask 0
# define isView 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif
+ assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );
/* Ensure that:
* (a) the table is not read-only,
* (b) that if it is a view then ON INSERT triggers exist
*/
- if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
+ if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
goto insert_cleanup;
}
assert( pTab!=0 );
@@ -67725,12 +68721,12 @@
*/
v = sqlite3GetVdbe(pParse);
if( v==0 ) goto insert_cleanup;
if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
- sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, iDb);
+ sqlite3BeginWriteOperation(pParse, pSelect || pTrigger, iDb);
/* if there are row triggers, allocate a temp table for new.* references. */
- if( triggers_exist ){
+ if( pTrigger ){
newIdx = pParse->nTab++;
}
#ifndef SQLITE_OMIT_XFER_OPT
@@ -67743,9 +68739,9 @@
**
** This is the 2nd template.
*/
if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
- assert( !triggers_exist );
+ assert( !pTrigger );
assert( pList==0 );
goto insert_cleanup;
}
#endif /* SQLITE_OMIT_XFER_OPT */
@@ -67818,9 +68814,9 @@
** A temp table must be used if the table being updated is also one
** of the tables being read by the SELECT statement. Also use a
** temp table in the case of row triggers.
*/
- if( triggers_exist || readsTable(v, addrSelect, iDb, pTab) ){
+ if( pTrigger || readsTable(v, addrSelect, iDb, pTab) ){
useTempTable = 1;
}
if( useTempTable ){
@@ -67937,11 +68933,10 @@
}
/* Open the temp table for FOR EACH ROW triggers
*/
- if( triggers_exist ){
- sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pTab->nCol);
- sqlite3VdbeAddOp2(v, OP_OpenPseudo, newIdx, 0);
+ if( pTrigger ){
+ sqlite3VdbeAddOp3(v, OP_OpenPseudo, newIdx, 0, pTab->nCol);
}
/* Initialize the count of rows to be inserted
*/
@@ -68006,9 +69001,9 @@
/* Run the BEFORE and INSTEAD OF triggers, if there are any
*/
endOfLoop = sqlite3VdbeMakeLabel(v);
- if( triggers_exist & TRIGGER_BEFORE ){
+ if( tmask & TRIGGER_BEFORE ){
int regTrigRowid;
int regCols;
int regRec;
@@ -68074,10 +69069,10 @@
sqlite3ReleaseTempReg(pParse, regTrigRowid);
sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol);
/* Fire BEFORE or INSTEAD OF triggers */
- if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab,
- newIdx, -1, onError, endOfLoop, 0, 0) ){
+ if( sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE,
+ pTab, newIdx, -1, onError, endOfLoop, 0, 0) ){
goto insert_cleanup;
}
}
@@ -68197,9 +69192,9 @@
baseCur,
regIns,
aRegIdx,
0,
- (triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1,
+ (tmask&TRIGGER_AFTER) ? newIdx : -1,
appendFlag
);
}
}
@@ -68209,12 +69204,12 @@
if( (db->flags & SQLITE_CountRows)!=0 ){
sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
}
- if( triggers_exist ){
+ if( pTrigger ){
/* Code AFTER triggers */
- if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_AFTER, pTab,
- newIdx, -1, onError, endOfLoop, 0, 0) ){
+ if( sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER,
+ pTab, newIdx, -1, onError, endOfLoop, 0, 0) ){
goto insert_cleanup;
}
}
@@ -68386,32 +69381,33 @@
}
if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
onError = OE_Abort;
}
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regData+i);
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|| onError==OE_Ignore || onError==OE_Replace );
switch( onError ){
case OE_Rollback:
case OE_Abort:
case OE_Fail: {
char *zMsg;
- sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_CONSTRAINT, onError);
+ j1 = sqlite3VdbeAddOp3(v, OP_HaltIfNull,
+ SQLITE_CONSTRAINT, onError, regData+i);
zMsg = sqlite3MPrintf(pParse->db, "%s.%s may not be NULL",
pTab->zName, pTab->aCol[i].zName);
sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
break;
}
case OE_Ignore: {
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regData+i, ignoreDest);
break;
}
case OE_Replace: {
+ j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regData+i);
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regData+i);
- break;
- }
- }
- sqlite3VdbeJumpHere(v, j1);
+ sqlite3VdbeJumpHere(v, j1);
+ break;
+ }
+ }
}
/* Test all CHECK constraints
*/
@@ -68791,9 +69787,9 @@
if( pSelect==0 ){
return 0; /* Must be of the form INSERT INTO ... SELECT ... */
}
- if( pDest->pTrigger ){
+ if( sqlite3TriggerList(pParse, pDest) ){
return 0; /* tab1 must not have triggers */
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( pDest->tabFlags & TF_Virtual ){
@@ -69015,9 +70011,9 @@
** implement the programmer interface to the library. Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: legacy.c,v 1.30 2008/12/10 19:26:24 drh Exp $
+** $Id: legacy.c,v 1.32 2009/03/19 18:51:07 danielk1977 Exp $
*/
/*
@@ -69101,22 +70097,22 @@
}
}
if( xCallback(pArg, nCol, azVals, azCols) ){
rc = SQLITE_ABORT;
- sqlite3_finalize(pStmt);
+ sqlite3VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
sqlite3Error(db, SQLITE_ABORT, 0);
goto exec_out;
}
}
if( rc!=SQLITE_ROW ){
- rc = sqlite3_finalize(pStmt);
+ rc = sqlite3VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
if( rc!=SQLITE_SCHEMA ){
nRetry = 0;
zSql = zLeftover;
- while( isspace((unsigned char)zSql[0]) ) zSql++;
+ while( sqlite3Isspace(zSql[0]) ) zSql++;
}
break;
}
}
@@ -69125,9 +70121,9 @@
azCols = 0;
}
exec_out:
- if( pStmt ) sqlite3_finalize(pStmt);
+ if( pStmt ) sqlite3VdbeFinalize((Vdbe *)pStmt);
sqlite3DbFree(db, azCols);
rc = sqlite3ApiExit(db, rc);
if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
@@ -69160,9 +70156,9 @@
*************************************************************************
** This file contains code used to dynamically load extensions into
** the SQLite library.
**
-** $Id: loadext.c,v 1.57 2008/12/08 18:19:18 drh Exp $
+** $Id: loadext.c,v 1.58 2009/01/20 16:53:40 danielk1977 Exp $
*/
#ifndef SQLITE_CORE
#define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
@@ -70146,9 +71142,9 @@
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
-** $Id: pragma.c,v 1.201 2009/01/13 20:14:16 drh Exp $
+** $Id: pragma.c,v 1.204 2009/02/23 16:52:08 drh Exp $
*/
/* Ignore this whole file if pragmas are disabled
*/
@@ -70170,9 +71166,9 @@
static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2};
int i, n;
- if( isdigit(*z) ){
+ if( sqlite3Isdigit(*z) ){
return (u8)atoi(z);
}
n = sqlite3Strlen30(z);
for(i=0; i<ArraySize(iLength); i++){
@@ -70306,8 +71302,9 @@
{ "count_changes", SQLITE_CountRows },
{ "empty_result_callbacks", SQLITE_NullCallback },
{ "legacy_file_format", SQLITE_LegacyFileFmt },
{ "fullfsync", SQLITE_FullFSync },
+ { "reverse_unordered_selects", SQLITE_ReverseOrder },
#ifdef SQLITE_DEBUG
{ "sql_trace", SQLITE_SqlTrace },
{ "vdbe_listing", SQLITE_VdbeListing },
{ "vdbe_trace", SQLITE_VdbeTrace },
@@ -70965,9 +71962,8 @@
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", SQLITE_STATIC);
sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", SQLITE_STATIC);
sqlite3ViewGetColumnNames(pParse, pTab);
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
- const Token *pDflt;
if( IsHiddenColumn(pCol) ){
nHidden++;
continue;
}
@@ -70976,11 +71972,11 @@
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
pCol->zType ? pCol->zType : "", 0);
sqlite3VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4);
if( pCol->pDflt ){
- pDflt = &pCol->pDflt->span;
- assert( pDflt->z );
- sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pDflt->z, pDflt->n);
+ const Token *p = &pCol->pDflt->span;
+ assert( p->z );
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)p->z, p->n);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
}
sqlite3VdbeAddOp2(v, OP_Integer, pCol->isPrimKey, 6);
@@ -71583,9 +72579,9 @@
** This file contains the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
**
-** $Id: prepare.c,v 1.104 2009/01/09 02:49:32 drh Exp $
+** $Id: prepare.c,v 1.114 2009/03/24 15:08:10 drh Exp $
*/
/*
** Fill the InitData structure with an error message that indicates
@@ -71646,23 +72642,19 @@
** structures that describe the table, index, or view.
*/
char *zErr;
int rc;
- u8 lookasideEnabled;
assert( db->init.busy );
db->init.iDb = iDb;
db->init.newTnum = atoi(argv[1]);
- lookasideEnabled = db->lookaside.bEnabled;
- db->lookaside.bEnabled = 0;
rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
db->init.iDb = 0;
- db->lookaside.bEnabled = lookasideEnabled;
assert( rc!=SQLITE_OK || zErr==0 );
if( SQLITE_OK!=rc ){
pData->rc = rc;
if( rc==SQLITE_NOMEM ){
db->mallocFailed = 1;
- }else if( rc!=SQLITE_INTERRUPT ){
+ }else if( rc!=SQLITE_INTERRUPT && (rc&0xff)!=SQLITE_LOCKED ){
corruptSchema(pData, argv[0], zErr);
}
sqlite3DbFree(db, zErr);
}
@@ -71920,12 +72912,12 @@
sqlite3ResetInternalSchema(db, 0);
}
if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
/* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
- ** the schema loaded, even if errors occured. In this situation the
+ ** the schema loaded, even if errors occurred. In this situation the
** current sqlite3_prepare() operation will fail, but the following one
** will attempt to compile the supplied statement against whatever subset
- ** of the schema was loaded before the error occured. The primary
+ ** of the schema was loaded before the error occurred. The primary
** purpose of this is to allow access to the sqlite_master table
** even when its contents have been corrupted.
*/
DbSetProperty(db, iDb, DB_SchemaLoaded);
@@ -72109,20 +73101,42 @@
}
assert( !db->mallocFailed );
assert( sqlite3_mutex_held(db->mutex) );
- /* If any attached database schemas are locked, do not proceed with
- ** compilation. Instead return SQLITE_LOCKED immediately.
+ /* Check to verify that it is possible to get a read lock on all
+ ** database schemas. The inability to get a read lock indicates that
+ ** some other database connection is holding a write-lock, which in
+ ** turn means that the other connection has made uncommitted changes
+ ** to the schema.
+ **
+ ** Were we to proceed and prepare the statement against the uncommitted
+ ** schema changes and if those schema changes are subsequently rolled
+ ** back and different changes are made in their place, then when this
+ ** prepared statement goes to run the schema cookie would fail to detect
+ ** the schema change. Disaster would follow.
+ **
+ ** This thread is currently holding mutexes on all Btrees (because
+ ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it
+ ** is not possible for another thread to start a new schema change
+ ** while this routine is running. Hence, we do not need to hold
+ ** locks on the schema, we just need to make sure nobody else is
+ ** holding them.
+ **
+ ** Note that setting READ_UNCOMMITTED overrides most lock detection,
+ ** but it does *not* override schema lock detection, so this all still
+ ** works even if READ_UNCOMMITTED is set.
*/
for(i=0; i<db->nDb; i++) {
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
+ assert( sqlite3BtreeHoldsMutex(pBt) );
rc = sqlite3BtreeSchemaLocked(pBt);
if( rc ){
const char *zDb = db->aDb[i].zName;
- sqlite3Error(db, SQLITE_LOCKED, "database schema is locked: %s", zDb);
+ sqlite3Error(db, rc, "database schema is locked: %s", zDb);
(void)sqlite3SafetyOff(db);
- return sqlite3ApiExit(db, SQLITE_LOCKED);
+ testcase( db->flags & SQLITE_ReadUncommitted );
+ return sqlite3ApiExit(db, rc);
}
}
}
@@ -72190,13 +73204,15 @@
if( sqlite3SafetyOff(db) ){
rc = SQLITE_MISUSE;
}
- if( saveSqlFlag ){
- sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail - zSql));
- }
- if( rc!=SQLITE_OK || db->mallocFailed ){
- sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);
+ assert( db->init.busy==0 || saveSqlFlag==0 );
+ if( db->init.busy==0 ){
+ Vdbe *pVdbe = sParse.pVdbe;
+ sqlite3VdbeSetSql(pVdbe, zSql, (int)(sParse.zTail-zSql), saveSqlFlag);
+ }
+ if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
+ sqlite3VdbeFinalize(sParse.pVdbe);
assert(!(*ppStmt));
}else{
*ppStmt = (sqlite3_stmt*)sParse.pVdbe;
}
@@ -72233,10 +73249,13 @@
}
/*
** Rerun the compilation of a statement after a schema change.
-** Return true if the statement was recompiled successfully.
-** Return false if there is an error of some kind.
+**
+** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
+** if the statement cannot be recompiled because another connection has
+** locked the sqlite3_master table, return SQLITE_LOCKED. If any other error
+** occurs, return SQLITE_SCHEMA.
*/
SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){
int rc;
sqlite3_stmt *pNew;
@@ -72253,17 +73272,17 @@
if( rc==SQLITE_NOMEM ){
db->mallocFailed = 1;
}
assert( pNew==0 );
- return 0;
+ return (rc==SQLITE_LOCKED) ? SQLITE_LOCKED : SQLITE_SCHEMA;
}else{
assert( pNew!=0 );
}
sqlite3VdbeSwap((Vdbe*)pNew, p);
sqlite3TransferBindings(pNew, (sqlite3_stmt*)p);
sqlite3VdbeResetStepResult((Vdbe*)pNew);
sqlite3VdbeFinalize((Vdbe*)pNew);
- return 1;
+ return SQLITE_OK;
}
/*
@@ -72394,9 +73413,9 @@
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.498 2009/01/09 02:49:32 drh Exp $
+** $Id: select.c,v 1.506 2009/03/31 03:41:57 shane Exp $
*/
/*
@@ -73181,10 +74200,9 @@
iTab = pOrderBy->iECursor;
if( eDest==SRT_Output || eDest==SRT_Coroutine ){
pseudoTab = pParse->nTab++;
- sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, nColumn);
- sqlite3VdbeAddOp2(v, OP_OpenPseudo, pseudoTab, eDest==SRT_Output);
+ sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, eDest==SRT_Output, nColumn);
}
addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
codeOffset(v, p, addrContinue);
regRow = sqlite3GetTempReg(pParse);
@@ -73368,10 +74386,11 @@
** origin info for the single column in the result set of the SELECT
** statement.
*/
NameContext sNC;
- Select *pS = pExpr->pSelect;
+ Select *pS = pExpr->x.pSelect;
Expr *p = pS->pEList->a[0].pExpr;
+ assert( ExprHasProperty(pExpr, EP_xIsSelect) );
sNC.pSrcList = pS->pSrc;
sNC.pNext = pNC;
sNC.pParse = pNC->pParse;
zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
@@ -73610,9 +74629,9 @@
** The column list presumably came from selectColumnNamesFromExprList().
** The column list has only names, not types or collations. This
** routine goes through and adds the types and collations.
**
-** This routine requires that all indentifiers in the SELECT
+** This routine requires that all identifiers in the SELECT
** statement be resolved.
*/
static void selectAddColumnTypeAndCollation(
Parse *pParse, /* Parsing contexts */
@@ -73665,9 +74684,9 @@
pTab = sqlite3DbMallocZero(db, sizeof(Table) );
if( pTab==0 ){
return 0;
}
- pTab->db = db;
+ pTab->dbMem = db->lookaside.bEnabled ? db : 0;
pTab->nRef = 1;
pTab->zName = 0;
selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect);
@@ -74522,9 +75541,9 @@
/* Reattach the ORDER BY clause to the query.
*/
p->pOrderBy = pOrderBy;
- pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy);
+ pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0);
/* Allocate a range of temporary registers and the KeyInfo needed
** for the logic that removes duplicate result rows when the
** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL).
@@ -74773,34 +75792,40 @@
pExpr->op = TK_NULL;
}else{
Expr *pNew;
assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
- assert( pExpr->pLeft==0 && pExpr->pRight==0 && pExpr->pList==0 );
+ assert( pExpr->pLeft==0 && pExpr->pRight==0 );
pNew = pEList->a[pExpr->iColumn].pExpr;
assert( pNew!=0 );
pExpr->op = pNew->op;
assert( pExpr->pLeft==0 );
- pExpr->pLeft = sqlite3ExprDup(db, pNew->pLeft);
+ pExpr->pLeft = sqlite3ExprDup(db, pNew->pLeft, 0);
assert( pExpr->pRight==0 );
- pExpr->pRight = sqlite3ExprDup(db, pNew->pRight);
- assert( pExpr->pList==0 );
- pExpr->pList = sqlite3ExprListDup(db, pNew->pList);
+ pExpr->pRight = sqlite3ExprDup(db, pNew->pRight, 0);
pExpr->iTable = pNew->iTable;
pExpr->pTab = pNew->pTab;
pExpr->iColumn = pNew->iColumn;
pExpr->iAgg = pNew->iAgg;
sqlite3TokenCopy(db, &pExpr->token, &pNew->token);
sqlite3TokenCopy(db, &pExpr->span, &pNew->span);
- pExpr->pSelect = sqlite3SelectDup(db, pNew->pSelect);
+ assert( pExpr->x.pList==0 && pExpr->x.pSelect==0 );
+ if( ExprHasProperty(pNew, EP_xIsSelect) ){
+ pExpr->x.pSelect = sqlite3SelectDup(db, pNew->x.pSelect, 0);
+ }else{
+ pExpr->x.pList = sqlite3ExprListDup(db, pNew->x.pList, 0);
+ }
pExpr->flags = pNew->flags;
pExpr->pAggInfo = pNew->pAggInfo;
pNew->pAggInfo = 0;
}
}else{
substExpr(db, pExpr->pLeft, iTable, pEList);
substExpr(db, pExpr->pRight, iTable, pEList);
- substSelect(db, pExpr->pSelect, iTable, pEList);
- substExprList(db, pExpr->pList, iTable, pEList);
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ substSelect(db, pExpr->x.pSelect, iTable, pEList);
+ }else{
+ substExprList(db, pExpr->x.pList, iTable, pEList);
+ }
}
}
static void substExprList(
sqlite3 *db, /* Report malloc errors here */
@@ -75110,9 +76135,9 @@
p->pOrderBy = 0;
p->pSrc = 0;
p->pPrior = 0;
p->pLimit = 0;
- pNew = sqlite3SelectDup(db, p);
+ pNew = sqlite3SelectDup(db, p, 0);
p->pLimit = pLimit;
p->pOrderBy = pOrderBy;
p->pSrc = pSrc;
p->op = TK_ALL;
@@ -75254,9 +76279,9 @@
}else if( pParent->pOrderBy ){
substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
}
if( pSub->pWhere ){
- pWhere = sqlite3ExprDup(db, pSub->pWhere);
+ pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
}else{
pWhere = 0;
}
if( subqueryIsAgg ){
@@ -75264,11 +76289,11 @@
pParent->pHaving = pParent->pWhere;
pParent->pWhere = pWhere;
substExpr(db, pParent->pHaving, iParent, pSub->pEList);
pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving,
- sqlite3ExprDup(db, pSub->pHaving));
+ sqlite3ExprDup(db, pSub->pHaving, 0));
assert( pParent->pGroupBy==0 );
- pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy);
+ pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
}else{
substExpr(db, pParent->pWhere, iParent, pSub->pEList);
pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
}
@@ -75315,9 +76340,10 @@
ExprList *pEList = p->pEList;
if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL;
pExpr = pEList->a[0].pExpr;
- pEList = pExpr->pList;
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ) return 0;
+ pEList = pExpr->x.pList;
if( pExpr->op!=TK_AGG_FUNCTION || pEList==0 || pEList->nExpr!=1 ) return 0;
if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL;
if( pExpr->token.n!=3 ) return WHERE_ORDERBY_NORMAL;
if( sqlite3StrNICmp((char*)pExpr->token.z,"min",3)==0 ){
@@ -75325,8 +76351,42 @@
}else if( sqlite3StrNICmp((char*)pExpr->token.z,"max",3)==0 ){
return WHERE_ORDERBY_MAX;
}
return WHERE_ORDERBY_NORMAL;
+}
+
+/*
+** The select statement passed as the first argument is an aggregate query.
+** The second argment is the associated aggregate-info object. This
+** function tests if the SELECT is of the form:
+**
+** SELECT count(*) FROM <tbl>
+**
+** where table is a database table, not a sub-select or view. If the query
+** does match this pattern, then a pointer to the Table object representing
+** <tbl> is returned. Otherwise, 0 is returned.
+*/
+static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
+ Table *pTab;
+ Expr *pExpr;
+
+ assert( !p->pGroupBy );
+
+ if( p->pWhere || p->pEList->nExpr!=1
+ || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect
+ ){
+ return 0;
+ }
+ pTab = p->pSrc->a[0].pTab;
+ pExpr = p->pEList->a[0].pExpr;
+ assert( pTab && !pTab->pSelect && pExpr );
+
+ if( IsVirtual(pTab) ) return 0;
+ if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
+ if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0;
+ if( pExpr->flags&EP_Distinct ) return 0;
+
+ return pTab;
}
/*
** If the source-list item passed as an argument was augmented with an
@@ -75420,9 +76480,9 @@
assert( pFrom->pTab==0 );
sqlite3WalkSelect(pWalker, pSel);
pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
if( pTab==0 ) return WRC_Abort;
- pTab->db = db;
+ pTab->dbMem = db->lookaside.bEnabled ? db : 0;
pTab->nRef = 1;
pTab->zName = sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pTab);
while( pSel->pPrior ){ pSel = pSel->pPrior; }
selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
@@ -75446,9 +76506,9 @@
** copied by the outer view so we can skip the copy step here
** in the inner view.
*/
if( pFrom->pSelect==0 ){
- pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect);
+ pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
sqlite3WalkSelect(pWalker, pFrom->pSelect);
}
}
#endif
@@ -75745,14 +76805,15 @@
for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
sqlite3VdbeAddOp2(v, OP_Null, 0, pFunc->iMem);
if( pFunc->iDistinct>=0 ){
Expr *pE = pFunc->pExpr;
- if( pE->pList==0 || pE->pList->nExpr!=1 ){
- sqlite3ErrorMsg(pParse, "DISTINCT in aggregate must be followed "
- "by an expression");
+ assert( !ExprHasProperty(pE, EP_xIsSelect) );
+ if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
+ sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
+ "argument");
pFunc->iDistinct = -1;
}else{
- KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->pList);
+ KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList);
sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
(char*)pKeyInfo, P4_KEYINFO_HANDOFF);
}
}
@@ -75767,9 +76828,10 @@
Vdbe *v = pParse->pVdbe;
int i;
struct AggInfo_func *pF;
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
- ExprList *pList = pF->pExpr->pList;
+ ExprList *pList = pF->pExpr->x.pList;
+ assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0,
(void*)pF->pFunc, P4_FUNCDEF);
}
}
@@ -75788,9 +76850,10 @@
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
int nArg;
int addrNext = 0;
int regAgg;
- ExprList *pList = pF->pExpr->pList;
+ ExprList *pList = pF->pExpr->x.pList;
+ assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
if( pList ){
nArg = pList->nExpr;
regAgg = sqlite3GetTempRange(pParse, nArg);
sqlite3ExprCodeExprList(pParse, pList, regAgg, 0);
@@ -76038,9 +77101,9 @@
/* If possible, rewrite the query to use GROUP BY instead of DISTINCT.
** GROUP BY might use an index, DISTINCT never does.
*/
if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && !p->pGroupBy ){
- p->pGroupBy = sqlite3ExprListDup(db, p->pEList);
+ p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
pGroupBy = p->pGroupBy;
p->selFlags &= ~SF_Distinct;
isDistinct = 0;
}
@@ -76161,9 +77224,10 @@
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
}
sAggInfo.nAccumulator = sAggInfo.nColumn;
for(i=0; i<sAggInfo.nFunc; i++){
- sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList);
+ assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
+ sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
}
if( db->mallocFailed ) goto select_end;
/* Processing for aggregates with GROUP BY is very different and
@@ -76368,70 +77432,129 @@
sqlite3VdbeAddOp1(v, OP_Return, regReset);
} /* endif pGroupBy */
else {
- ExprList *pMinMax = 0;
ExprList *pDel = 0;
- u8 flag;
-
- /* Check if the query is of one of the following forms:
- **
- ** SELECT min(x) FROM ...
- ** SELECT max(x) FROM ...
- **
- ** If it is, then ask the code in where.c to attempt to sort results
- ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause.
- ** If where.c is able to produce results sorted in this order, then
- ** add vdbe code to break out of the processing loop after the
- ** first iteration (since the first iteration of the loop is
- ** guaranteed to operate on the row with the minimum or maximum
- ** value of x, the only row required).
- **
- ** A special flag must be passed to sqlite3WhereBegin() to slightly
- ** modify behaviour as follows:
- **
- ** + If the query is a "SELECT min(x)", then the loop coded by
- ** where.c should not iterate over any values with a NULL value
- ** for x.
- **
- ** + The optimizer code in where.c (the thing that decides which
- ** index or indices to use) should place a different priority on
- ** satisfying the 'ORDER BY' clause than it does in other cases.
- ** Refer to code and comments in where.c for details.
- */
- flag = minMaxQuery(p);
- if( flag ){
- pDel = pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->pList);
- if( pMinMax && !db->mallocFailed ){
- pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
- pMinMax->a[0].pExpr->op = TK_COLUMN;
- }
- }
-
- /* This case runs if the aggregate has no GROUP BY clause. The
- ** processing is much simpler since there is only a single row
- ** of output.
- */
- resetAccumulator(pParse, &sAggInfo);
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, flag, 0);
- if( pWInfo==0 ){
- sqlite3ExprListDelete(db, pDel);
- goto select_end;
- }
- updateAccumulator(pParse, &sAggInfo);
- if( !pMinMax && flag ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
- VdbeComment((v, "%s() by index",(flag==WHERE_ORDERBY_MIN?"min":"max")));
- }
- sqlite3WhereEnd(pWInfo);
- finalizeAggFunctions(pParse, &sAggInfo);
+#ifndef SQLITE_OMIT_BTREECOUNT
+ Table *pTab;
+ if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
+ /* If isSimpleCount() returns a pointer to a Table structure, then
+ ** the SQL statement is of the form:
+ **
+ ** SELECT count(*) FROM <tbl>
+ **
+ ** where the Table structure returned represents table <tbl>.
+ **
+ ** This statement is so common that it is optimized specially. The
+ ** OP_Count instruction is executed either on the intkey table that
+ ** contains the data for table <tbl> or on one of its indexes. It
+ ** is better to execute the op on an index, as indexes are almost
+ ** always spread across less pages than their corresponding tables.
+ */
+ const int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+ const int iCsr = pParse->nTab++; /* Cursor to scan b-tree */
+ Index *pIdx; /* Iterator variable */
+ KeyInfo *pKeyInfo = 0; /* Keyinfo for scanned index */
+ Index *pBest = 0; /* Best index found so far */
+ int iRoot = pTab->tnum; /* Root page of scanned b-tree */
+
+ sqlite3CodeVerifySchema(pParse, iDb);
+ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
+
+ /* Search for the index that has the least amount of columns. If
+ ** there is such an index, and it has less columns than the table
+ ** does, then we can assume that it consumes less space on disk and
+ ** will therefore be cheaper to scan to determine the query result.
+ ** In this case set iRoot to the root page number of the index b-tree
+ ** and pKeyInfo to the KeyInfo structure required to navigate the
+ ** index.
+ **
+ ** In practice the KeyInfo structure will not be used. It is only
+ ** passed to keep OP_OpenRead happy.
+ */
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( !pBest || pIdx->nColumn<pBest->nColumn ){
+ pBest = pIdx;
+ }
+ }
+ if( pBest && pBest->nColumn<pTab->nCol ){
+ iRoot = pBest->tnum;
+ pKeyInfo = sqlite3IndexKeyinfo(pParse, pBest);
+ }
+
+ /* Open a read-only cursor, execute the OP_Count, close the cursor. */
+ sqlite3VdbeAddOp3(v, OP_OpenRead, iCsr, iRoot, iDb);
+ if( pKeyInfo ){
+ sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO_HANDOFF);
+ }
+ sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
+ sqlite3VdbeAddOp1(v, OP_Close, iCsr);
+ }else
+#endif /* SQLITE_OMIT_BTREECOUNT */
+ {
+ /* Check if the query is of one of the following forms:
+ **
+ ** SELECT min(x) FROM ...
+ ** SELECT max(x) FROM ...
+ **
+ ** If it is, then ask the code in where.c to attempt to sort results
+ ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause.
+ ** If where.c is able to produce results sorted in this order, then
+ ** add vdbe code to break out of the processing loop after the
+ ** first iteration (since the first iteration of the loop is
+ ** guaranteed to operate on the row with the minimum or maximum
+ ** value of x, the only row required).
+ **
+ ** A special flag must be passed to sqlite3WhereBegin() to slightly
+ ** modify behaviour as follows:
+ **
+ ** + If the query is a "SELECT min(x)", then the loop coded by
+ ** where.c should not iterate over any values with a NULL value
+ ** for x.
+ **
+ ** + The optimizer code in where.c (the thing that decides which
+ ** index or indices to use) should place a different priority on
+ ** satisfying the 'ORDER BY' clause than it does in other cases.
+ ** Refer to code and comments in where.c for details.
+ */
+ ExprList *pMinMax = 0;
+ u8 flag = minMaxQuery(p);
+ if( flag ){
+ assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
+ pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
+ pDel = pMinMax;
+ if( pMinMax && !db->mallocFailed ){
+ pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
+ pMinMax->a[0].pExpr->op = TK_COLUMN;
+ }
+ }
+
+ /* This case runs if the aggregate has no GROUP BY clause. The
+ ** processing is much simpler since there is only a single row
+ ** of output.
+ */
+ resetAccumulator(pParse, &sAggInfo);
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, flag, 0);
+ if( pWInfo==0 ){
+ sqlite3ExprListDelete(db, pDel);
+ goto select_end;
+ }
+ updateAccumulator(pParse, &sAggInfo);
+ if( !pMinMax && flag ){
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
+ VdbeComment((v, "%s() by index",
+ (flag==WHERE_ORDERBY_MIN?"min":"max")));
+ }
+ sqlite3WhereEnd(pWInfo);
+ finalizeAggFunctions(pParse, &sAggInfo);
+ }
+
pOrderBy = 0;
if( pHaving ){
sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
}
selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1,
pDest, addrEnd, addrEnd);
-
sqlite3ExprListDelete(db, pDel);
}
sqlite3VdbeResolveLabel(v, addrEnd);
@@ -76584,9 +77707,9 @@
**
** These routines are in a separate files so that they will not be linked
** if they are not used.
**
-** $Id: table.c,v 1.38 2008/12/10 19:26:24 drh Exp $
+** $Id: table.c,v 1.39 2009/01/19 20:49:10 drh Exp $
*/
#ifndef SQLITE_OMIT_GET_TABLE
@@ -76697,8 +77820,9 @@
*pazResult = 0;
if( pnColumn ) *pnColumn = 0;
if( pnRow ) *pnRow = 0;
+ if( pzErrMsg ) *pzErrMsg = 0;
res.zErrMsg = 0;
res.nResult = 0;
res.nRow = 0;
res.nColumn = 0;
@@ -76779,9 +77903,9 @@
**
*************************************************************************
**
**
-** $Id: trigger.c,v 1.133 2008/12/26 07:56:39 danielk1977 Exp $
+** $Id: trigger.c,v 1.135 2009/02/28 10:47:42 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_TRIGGER
/*
@@ -76799,8 +77923,32 @@
sqlite3IdListDelete(db, pTmp->pIdList);
sqlite3DbFree(db, pTmp);
}
+}
+
+/*
+** Given table pTab, return a list of all the triggers attached to
+** the table. The list is connected by Trigger.pNext pointers.
+*/
+SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
+ Schema * const pTmpSchema = pParse->db->aDb[1].pSchema;
+ Trigger *pList = 0; /* List of triggers to return */
+
+ if( pTmpSchema!=pTab->pSchema ){
+ HashElem *p;
+ for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){
+ Trigger *pTrig = (Trigger *)sqliteHashData(p);
+ if( pTrig->pTabSchema==pTab->pSchema
+ && 0==sqlite3StrICmp(pTrig->table, pTab->zName)
+ ){
+ pTrig->pNext = (pList ? pList : pTab->pTrigger);
+ pList = pTrig;
+ }
+ }
+ }
+
+ return (pList ? pList : pTab->pTrigger);
}
/*
** This is called by the parser when it sees a CREATE TRIGGER statement
@@ -76950,9 +78098,9 @@
pTrigger->pSchema = db->aDb[iDb].pSchema;
pTrigger->pTabSchema = pTab->pSchema;
pTrigger->op = (u8)op;
pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
- pTrigger->pWhen = sqlite3ExprDup(db, pWhen);
+ pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
pTrigger->pColumns = sqlite3IdListDup(db, pColumns);
sqlite3TokenCopy(db, &pTrigger->nameToken,pName);
assert( pParse->pNewTrigger==0 );
pParse->pNewTrigger = pTrigger;
@@ -76977,16 +78125,18 @@
Parse *pParse, /* Parser context */
TriggerStep *pStepList, /* The triggered program */
Token *pAll /* Token that describes the complete CREATE TRIGGER */
){
- Trigger *pTrig = 0; /* The trigger whose construction is finishing up */
- sqlite3 *db = pParse->db; /* The database */
+ Trigger *pTrig = pParse->pNewTrigger; /* Trigger being finished */
+ char *zName; /* Name of trigger */
+ sqlite3 *db = pParse->db; /* The database */
DbFixer sFix;
- int iDb; /* Database containing the trigger */
+ int iDb; /* Database containing the trigger */
pTrig = pParse->pNewTrigger;
pParse->pNewTrigger = 0;
if( pParse->nErr || !pTrig ) goto triggerfinish_cleanup;
+ zName = pTrig->name;
iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
pTrig->step_list = pStepList;
while( pStepList ){
pStepList->pTrig = pTrig;
@@ -77010,34 +78160,31 @@
sqlite3BeginWriteOperation(pParse, 0, iDb);
z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
sqlite3NestedParse(pParse,
"INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pTrig->name,
+ db->aDb[iDb].zName, SCHEMA_TABLE(iDb), zName,
pTrig->table, z);
sqlite3DbFree(db, z);
sqlite3ChangeCookie(pParse, iDb);
sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, sqlite3MPrintf(
- db, "type='trigger' AND name='%q'", pTrig->name), P4_DYNAMIC
+ db, "type='trigger' AND name='%q'", zName), P4_DYNAMIC
);
}
if( db->init.busy ){
- int n;
- Table *pTab;
- Trigger *pDel;
- pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash,
- pTrig->name, sqlite3Strlen30(pTrig->name), pTrig);
- if( pDel ){
- assert( pDel==pTrig );
+ Trigger *pLink = pTrig;
+ Hash *pHash = &db->aDb[iDb].pSchema->trigHash;
+ pTrig = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), pTrig);
+ if( pTrig ){
db->mallocFailed = 1;
- goto triggerfinish_cleanup;
- }
- n = sqlite3Strlen30(pTrig->table) + 1;
- pTab = sqlite3HashFind(&pTrig->pTabSchema->tblHash, pTrig->table, n);
- assert( pTab!=0 );
- pTrig->pNext = pTab->pTrigger;
- pTab->pTrigger = pTrig;
- pTrig = 0;
+ }else if( pLink->pSchema==pLink->pTabSchema ){
+ Table *pTab;
+ int n = sqlite3Strlen30(pLink->table) + 1;
+ pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table, n);
+ assert( pTab!=0 );
+ pLink->pNext = pTab->pTrigger;
+ pTab->pTrigger = pLink;
+ }
}
triggerfinish_cleanup:
sqlite3DeleteTrigger(db, pTrig);
@@ -77060,19 +78207,19 @@
p->target.z = (u8*)sqlite3DbStrNDup(db, (char*)p->target.z, p->target.n);
p->target.dyn = 1;
}
if( p->pSelect ){
- Select *pNew = sqlite3SelectDup(db, p->pSelect);
+ Select *pNew = sqlite3SelectDup(db, p->pSelect, 1);
sqlite3SelectDelete(db, p->pSelect);
p->pSelect = pNew;
}
if( p->pWhere ){
- Expr *pNew = sqlite3ExprDup(db, p->pWhere);
+ Expr *pNew = sqlite3ExprDup(db, p->pWhere, EXPRDUP_REDUCE);
sqlite3ExprDelete(db, p->pWhere);
p->pWhere = pNew;
}
if( p->pExprList ){
- ExprList *pNew = sqlite3ExprListDup(db, p->pExprList);
+ ExprList *pNew = sqlite3ExprListDup(db, p->pExprList, 1);
sqlite3ExprListDelete(db, p->pExprList);
p->pExprList = pNew;
}
if( p->pIdList ){
@@ -77314,34 +78461,27 @@
sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC);
sqlite3ChangeCookie(pParse, iDb);
sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->name, 0);
+ if( pParse->nMem<3 ){
+ pParse->nMem = 3;
+ }
}
}
/*
** Remove a trigger from the hash tables of the sqlite* pointer.
*/
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
+ Hash *pHash = &(db->aDb[iDb].pSchema->trigHash);
Trigger *pTrigger;
- int nName = sqlite3Strlen30(zName);
- pTrigger = sqlite3HashInsert(&(db->aDb[iDb].pSchema->trigHash),
- zName, nName, 0);
+ pTrigger = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), 0);
if( pTrigger ){
- Table *pTable = tableOfTrigger(pTrigger);
- assert( pTable!=0 );
- if( pTable->pTrigger == pTrigger ){
- pTable->pTrigger = pTrigger->pNext;
- }else{
- Trigger *cc = pTable->pTrigger;
- while( cc ){
- if( cc->pNext == pTrigger ){
- cc->pNext = cc->pNext->pNext;
- break;
- }
- cc = cc->pNext;
- }
- assert(cc);
+ if( pTrigger->pSchema==pTrigger->pTabSchema ){
+ Table *pTab = tableOfTrigger(pTrigger);
+ Trigger **pp;
+ for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext));
+ *pp = (*pp)->pNext;
}
sqlite3DeleteTrigger(db, pTrigger);
db->flags |= SQLITE_InternChanges;
}
@@ -77365,32 +78505,33 @@
return 0;
}
/*
-** Return a bit vector to indicate what kind of triggers exist for operation
-** "op" on table pTab. If pChanges is not NULL then it is a list of columns
-** that are being updated. Triggers only match if the ON clause of the
-** trigger definition overlaps the set of columns being updated.
-**
-** The returned bit vector is some combination of TRIGGER_BEFORE and
-** TRIGGER_AFTER.
-*/
-SQLITE_PRIVATE int sqlite3TriggersExist(
+** Return a list of all triggers on table pTab if there exists at least
+** one trigger that must be fired when an operation of type 'op' is
+** performed on the table, and, if that operation is an UPDATE, if at
+** least one of the columns in pChanges is being modified.
+*/
+SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
+ Parse *pParse, /* Parse context */
Table *pTab, /* The table the contains the triggers */
int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
- ExprList *pChanges /* Columns that change in an UPDATE statement */
-){
- Trigger *pTrigger;
+ ExprList *pChanges, /* Columns that change in an UPDATE statement */
+ int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
+){
int mask = 0;
-
- pTrigger = IsVirtual(pTab) ? 0 : pTab->pTrigger;
- while( pTrigger ){
- if( pTrigger->op==op && checkColumnOverLap(pTrigger->pColumns, pChanges) ){
- mask |= pTrigger->tr_tm;
- }
- pTrigger = pTrigger->pNext;
- }
- return mask;
+ Trigger *pList = sqlite3TriggerList(pParse, pTab);
+ Trigger *p;
+ assert( pList==0 || IsVirtual(pTab)==0 );
+ for(p=pList; p; p=p->pNext){
+ if( p->op==op && checkColumnOverLap(p->pColumns, pChanges) ){
+ mask |= p->tr_tm;
+ }
+ }
+ if( pMask ){
+ *pMask = mask;
+ }
+ return (mask ? pList : 0);
}
/*
** Convert the pStep->target token into a SrcList and return a pointer
@@ -77445,9 +78586,9 @@
orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
pParse->trigStack->orconf = orconf;
switch( pTriggerStep->op ){
case TK_SELECT: {
- Select *ss = sqlite3SelectDup(db, pTriggerStep->pSelect);
+ Select *ss = sqlite3SelectDup(db, pTriggerStep->pSelect, 0);
if( ss ){
SelectDest dest;
sqlite3SelectDestInit(&dest, SRT_Discard, 0);
@@ -77460,10 +78601,10 @@
SrcList *pSrc;
pSrc = targetSrcList(pParse, pTriggerStep);
sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0);
sqlite3Update(pParse, pSrc,
- sqlite3ExprListDup(db, pTriggerStep->pExprList),
- sqlite3ExprDup(db, pTriggerStep->pWhere), orconf);
+ sqlite3ExprListDup(db, pTriggerStep->pExprList, 0),
+ sqlite3ExprDup(db, pTriggerStep->pWhere, 0), orconf);
sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
break;
}
case TK_INSERT: {
@@ -77470,10 +78611,10 @@
SrcList *pSrc;
pSrc = targetSrcList(pParse, pTriggerStep);
sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0);
sqlite3Insert(pParse, pSrc,
- sqlite3ExprListDup(db, pTriggerStep->pExprList),
- sqlite3SelectDup(db, pTriggerStep->pSelect),
+ sqlite3ExprListDup(db, pTriggerStep->pExprList, 0),
+ sqlite3SelectDup(db, pTriggerStep->pSelect, 0),
sqlite3IdListDup(db, pTriggerStep->pIdList), orconf);
sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
break;
}
@@ -77481,9 +78622,9 @@
SrcList *pSrc;
sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0);
pSrc = targetSrcList(pParse, pTriggerStep);
sqlite3DeleteFrom(pParse, pSrc,
- sqlite3ExprDup(db, pTriggerStep->pWhere));
+ sqlite3ExprDup(db, pTriggerStep->pWhere, 0));
sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
break;
}
default:
@@ -77525,8 +78666,9 @@
**
*/
SQLITE_PRIVATE int sqlite3CodeRowTrigger(
Parse *pParse, /* Parse context */
+ Trigger *pTrigger, /* List of triggers on table pTab */
int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
Table *pTab, /* The table to code triggers from */
@@ -77548,9 +78690,9 @@
assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER );
assert(newIdx != -1 || oldIdx != -1);
- for(p=pTab->pTrigger; p; p=p->pNext){
+ for(p=pTrigger; p; p=p->pNext){
int fire_this = 0;
/* Determine whether we should code this trigger */
if(
@@ -77598,9 +78740,9 @@
sqlite3AuthContextPush(pParse, &sContext, p->name);
/* code the WHEN clause */
endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe);
- whenExpr = sqlite3ExprDup(db, p->pWhen);
+ whenExpr = sqlite3ExprDup(db, p->pWhen, 0);
if( db->mallocFailed || sqlite3ResolveExprNames(&sNC, whenExpr) ){
pParse->trigStack = trigStackEntry.pNext;
sqlite3ExprDelete(db, whenExpr);
return 1;
@@ -77638,9 +78780,9 @@
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
-** $Id: update.c,v 1.191 2008/12/23 23:56:22 drh Exp $
+** $Id: update.c,v 1.196 2009/02/28 10:47:42 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
@@ -77732,9 +78874,9 @@
int okOnePass; /* True for one-pass algorithm without the FIFO */
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* Trying to update a view */
- int triggers_exist = 0; /* True if any row triggers exist */
+ Trigger *pTrigger; /* List of triggers on pTab, if required */
#endif
int iBeginAfterTrigger = 0; /* Address of after trigger program */
int iEndAfterTrigger = 0; /* Exit of after trigger program */
int iBeginBeforeTrigger = 0; /* Address of before trigger program */
@@ -77768,20 +78910,20 @@
/* Figure out if we have any triggers and if the table being
** updated is a view
*/
#ifndef SQLITE_OMIT_TRIGGER
- triggers_exist = sqlite3TriggersExist(pTab, TK_UPDATE, pChanges);
+ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, 0);
isView = pTab->pSelect!=0;
#else
-# define triggers_exist 0
+# define pTrigger 0
# define isView 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif
- if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
+ if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
goto update_cleanup;
}
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
goto update_cleanup;
@@ -77792,9 +78934,9 @@
/* If there are FOR EACH ROW triggers, allocate cursors for the
** special OLD and NEW tables
*/
- if( triggers_exist ){
+ if( pTrigger ){
newIdx = pParse->nTab++;
oldIdx = pParse->nTab++;
}
@@ -77924,29 +79066,29 @@
}
/* Generate the code for triggers.
*/
- if( triggers_exist ){
+ if( pTrigger ){
int iGoto;
/* Create pseudo-tables for NEW and OLD
*/
- sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pTab->nCol);
- sqlite3VdbeAddOp2(v, OP_OpenPseudo, oldIdx, 0);
- sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pTab->nCol);
- sqlite3VdbeAddOp2(v, OP_OpenPseudo, newIdx, 0);
+ sqlite3VdbeAddOp3(v, OP_OpenPseudo, oldIdx, 0, pTab->nCol);
+ sqlite3VdbeAddOp3(v, OP_OpenPseudo, newIdx, 0, pTab->nCol);
iGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
addr = sqlite3VdbeMakeLabel(v);
iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v);
- if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab,
- newIdx, oldIdx, onError, addr, &old_col_mask, &new_col_mask) ){
+ if( sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
+ TRIGGER_BEFORE, pTab, newIdx, oldIdx, onError, addr,
+ &old_col_mask, &new_col_mask) ){
goto update_cleanup;
}
iEndBeforeTrigger = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v);
- if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_AFTER, pTab,
- newIdx, oldIdx, onError, addr, &old_col_mask, &new_col_mask) ){
+ if( sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
+ TRIGGER_AFTER, pTab, newIdx, oldIdx, onError, addr,
+ &old_col_mask, &new_col_mask) ){
goto update_cleanup;
}
iEndAfterTrigger = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
sqlite3VdbeJumpHere(v, iGoto);
@@ -78024,9 +79166,9 @@
}
}
/* Jump back to this point if a trigger encounters an IGNORE constraint. */
- if( triggers_exist ){
+ if( pTrigger ){
sqlite3VdbeResolveLabel(v, addr);
}
/* Top of the update loop */
@@ -78037,9 +79179,9 @@
}else{
addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, 0, regOldRowid);
}
- if( triggers_exist ){
+ if( pTrigger ){
int regRowid;
int regRow;
int regCols;
@@ -78166,9 +79308,9 @@
/* If there are triggers, close all the cursors after each iteration
** through the loop. The fire the after triggers.
*/
- if( triggers_exist ){
+ if( pTrigger ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginAfterTrigger);
sqlite3VdbeJumpHere(v, iEndAfterTrigger);
}
@@ -78184,9 +79326,9 @@
sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
}
}
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
- if( triggers_exist ){
+ if( pTrigger ){
sqlite3VdbeAddOp2(v, OP_Close, newIdx, 0);
sqlite3VdbeAddOp2(v, OP_Close, oldIdx, 0);
}
@@ -78258,14 +79400,14 @@
pEList = sqlite3ExprListAppend(pParse, 0,
sqlite3CreateIdExpr(pParse, "_rowid_"), 0);
if( pRowid ){
pEList = sqlite3ExprListAppend(pParse, pEList,
- sqlite3ExprDup(db, pRowid), 0);
+ sqlite3ExprDup(db, pRowid, 0), 0);
}
assert( pTab->iPKey<0 );
for(i=0; i<pTab->nCol; i++){
if( aXRef[i]>=0 ){
- pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr);
+ pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0);
}else{
pExpr = sqlite3CreateIdExpr(pParse, pTab->aCol[i].zName);
}
pEList = sqlite3ExprListAppend(pParse, pEList, pExpr, 0);
@@ -78327,9 +79469,9 @@
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
-** $Id: vacuum.c,v 1.84 2008/11/17 19:18:55 danielk1977 Exp $
+** $Id: vacuum.c,v 1.86 2009/02/03 16:51:25 danielk1977 Exp $
*/
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
/*
@@ -78402,19 +79544,19 @@
Db *pDb = 0; /* Database to detach at end of vacuum */
int isMemDb; /* True is vacuuming a :memory: database */
int nRes;
+ if( !db->autoCommit ){
+ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
+ return SQLITE_ERROR;
+ }
+
/* Save the current value of the write-schema flag before setting it. */
saved_flags = db->flags;
saved_nChange = db->nChange;
saved_nTotalChange = db->nTotalChange;
db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
- if( !db->autoCommit ){
- sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
- rc = SQLITE_ERROR;
- goto end_of_vacuum;
- }
pMain = db->aDb[0].pBt;
pMainPager = sqlite3BtreePager(pMain);
isMemDb = sqlite3PagerFile(pMainPager)->pMethods==0;
@@ -78576,9 +79718,8 @@
if( rc!=SQLITE_OK ) goto end_of_vacuum;
#ifndef SQLITE_OMIT_AUTOVACUUM
sqlite3BtreeSetAutoVacuum(pMain, sqlite3BtreeGetAutoVacuum(pTemp));
#endif
- rc = sqlite3BtreeCommit(pMain);
}
if( rc==SQLITE_OK ){
rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes);
@@ -78625,9 +79766,9 @@
**
*************************************************************************
** This file contains code used to help implement virtual tables.
**
-** $Id: vtab.c,v 1.81 2008/12/10 19:26:24 drh Exp $
+** $Id: vtab.c,v 1.84 2009/03/24 15:08:10 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
static int createModule(
@@ -78731,9 +79872,10 @@
** record.
*/
SQLITE_PRIVATE void sqlite3VtabClear(Table *p){
sqlite3_vtab *pVtab = p->pVtab;
- sqlite3 *db = p->db;
+ Schema *pSchema = p->pSchema;
+ sqlite3 *db = pSchema ? pSchema->db : 0;
if( pVtab ){
assert( p->pMod && p->pMod->pModule );
sqlite3VtabUnlock(db, pVtab);
p->pVtab = 0;
@@ -79184,9 +80326,11 @@
rc = SQLITE_ERROR;
}
sParse.declareVtab = 0;
- sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);
+ if( sParse.pVdbe ){
+ sqlite3VdbeFinalize(sParse.pVdbe);
+ }
sqlite3DeleteTable(sParse.pNewTable);
sParse.pNewTable = 0;
assert( (rc&0xff)==rc );
@@ -79324,9 +80468,9 @@
/* Special case: If db->aVTrans is NULL and db->nVTrans is greater
** than zero, then this function is being called from within a
** virtual module xSync() callback. It is illegal to write to
- ** virtual module tables in this case, so return SQLITE_LOCKED.
+ ** virtual module tables in this case, so return SQLITE_MISUSE.
*/
if( sqlite3VtabInSync(db) ){
return SQLITE_LOCKED;
}
@@ -79475,9 +80619,9 @@
** rows. Indices are selected and used to speed the search when doing
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
-** $Id: where.c,v 1.364 2009/01/14 00:55:10 drh Exp $
+** $Id: where.c,v 1.379 2009/03/29 00:15:54 drh Exp $
*/
/*
** Trace output macros
@@ -79889,10 +81033,13 @@
return mask;
}
mask = exprTableUsage(pMaskSet, p->pRight);
mask |= exprTableUsage(pMaskSet, p->pLeft);
- mask |= exprListTableUsage(pMaskSet, p->pList);
- mask |= exprSelectTableUsage(pMaskSet, p->pSelect);
+ if( ExprHasProperty(p, EP_xIsSelect) ){
+ mask |= exprSelectTableUsage(pMaskSet, p->x.pSelect);
+ }else{
+ mask |= exprListTableUsage(pMaskSet, p->x.pList);
+ }
return mask;
}
static Bitmask exprListTableUsage(WhereMaskSet *pMaskSet, ExprList *pList){
int i;
@@ -80092,9 +81239,9 @@
}
#ifdef SQLITE_EBCDIC
if( *pnoCase ) return 0;
#endif
- pList = pExpr->pList;
+ pList = pExpr->x.pList;
pRight = pList->a[0].pExpr;
if( pRight->op!=TK_STRING ){
return 0;
}
@@ -80111,9 +81258,9 @@
if( (pColl->type!=SQLITE_COLL_BINARY || *pnoCase) &&
(pColl->type!=SQLITE_COLL_NOCASE || !*pnoCase) ){
return 0;
}
- sqlite3DequoteExpr(db, pRight);
+ sqlite3DequoteExpr(pRight);
z = (char *)pRight->token.z;
cnt = 0;
if( z ){
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ cnt++; }
@@ -80147,9 +81294,9 @@
if( pExpr->token.n!=5 ||
sqlite3StrNICmp((const char*)pExpr->token.z,"match",5)!=0 ){
return 0;
}
- pList = pExpr->pList;
+ pList = pExpr->x.pList;
if( pList->nExpr!=2 ){
return 0;
}
if( pList->a[1].pExpr->op != TK_COLUMN ){
@@ -80346,9 +81493,9 @@
*/
if( chngToIN ){
int okToChngToIN = 0; /* True if the conversion to IN is valid */
int iColumn = -1; /* Column index on lhs of IN operator */
- int iCursor; /* Table cursor common to all terms */
+ int iCursor = -1; /* Table cursor common to all terms */
int j = 0; /* Loop counter */
/* Search for a table and column that appears on one side or the
** other of the == operator in every subterm. That table and column
@@ -80411,19 +81558,20 @@
if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
assert( pOrTerm->eOperator==WO_EQ );
assert( pOrTerm->leftCursor==iCursor );
assert( pOrTerm->u.leftColumn==iColumn );
- pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight);
+ pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup, 0);
pLeft = pOrTerm->pExpr->pLeft;
}
assert( pLeft!=0 );
- pDup = sqlite3ExprDup(db, pLeft);
+ pDup = sqlite3ExprDup(db, pLeft, 0);
pNew = sqlite3Expr(db, TK_IN, pDup, 0, 0);
if( pNew ){
int idxNew;
transferJoinMarkings(pNew, pExpr);
- pNew->pList = pList;
+ assert( !ExprHasProperty(pNew, EP_xIsSelect) );
+ pNew->x.pList = pList;
idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
pTerm = &pWC->a[idxTerm];
@@ -80484,10 +81632,13 @@
prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
op = pExpr->op;
if( op==TK_IN ){
assert( pExpr->pRight==0 );
- pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->pList)
- | exprSelectTableUsage(pMaskSet, pExpr->pSelect);
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ pTerm->prereqRight = exprSelectTableUsage(pMaskSet, pExpr->x.pSelect);
+ }else{
+ pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->x.pList);
+ }
}else if( op==TK_ISNULL ){
pTerm->prereqRight = 0;
}else{
pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
@@ -80515,9 +81666,9 @@
WhereTerm *pNew;
Expr *pDup;
if( pTerm->leftCursor>=0 ){
int idxNew;
- pDup = sqlite3ExprDup(db, pExpr);
+ pDup = sqlite3ExprDup(db, pExpr, 0);
if( db->mallocFailed ){
sqlite3ExprDelete(db, pDup);
return;
}
@@ -80558,18 +81709,18 @@
** skipped. Or, if the children are satisfied by an index, the original
** BETWEEN term is skipped.
*/
else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){
- ExprList *pList = pExpr->pList;
+ ExprList *pList = pExpr->x.pList;
int i;
static const u8 ops[] = {TK_GE, TK_LE};
assert( pList!=0 );
assert( pList->nExpr==2 );
for(i=0; i<2; i++){
Expr *pNewExpr;
int idxNew;
- pNewExpr = sqlite3Expr(db, ops[i], sqlite3ExprDup(db, pExpr->pLeft),
- sqlite3ExprDup(db, pList->a[i].pExpr), 0);
+ pNewExpr = sqlite3Expr(db, ops[i], sqlite3ExprDup(db, pExpr->pLeft, 0),
+ sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
pTerm = &pWC->a[idxTerm];
@@ -80606,20 +81757,20 @@
Expr *pStr1, *pStr2;
Expr *pNewExpr1, *pNewExpr2;
int idxNew1, idxNew2;
- pLeft = pExpr->pList->a[1].pExpr;
- pRight = pExpr->pList->a[0].pExpr;
+ pLeft = pExpr->x.pList->a[1].pExpr;
+ pRight = pExpr->x.pList->a[0].pExpr;
pStr1 = sqlite3PExpr(pParse, TK_STRING, 0, 0, 0);
if( pStr1 ){
sqlite3TokenCopy(db, &pStr1->token, &pRight->token);
pStr1->token.n = nPattern;
pStr1->flags = EP_Dequoted;
}
- pStr2 = sqlite3ExprDup(db, pStr1);
+ pStr2 = sqlite3ExprDup(db, pStr1, 0);
if( !db->mallocFailed ){
u8 c, *pC;
- assert( pStr2->token.dyn );
+ /* assert( pStr2->token.dyn ); */
pC = (u8*)&pStr2->token.z[nPattern-1];
c = *pC;
if( noCase ){
if( c=='@' ) isComplete = 0;
@@ -80626,13 +81777,13 @@
c = sqlite3UpperToLower[c];
}
*pC = c + 1;
}
- pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprDup(db,pLeft), pStr1, 0);
+ pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprDup(db,pLeft,0),pStr1,0);
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew1==0 );
exprAnalyze(pSrc, pWC, idxNew1);
- pNewExpr2 = sqlite3PExpr(pParse, TK_LT, sqlite3ExprDup(db,pLeft), pStr2, 0);
+ pNewExpr2 = sqlite3PExpr(pParse, TK_LT, sqlite3ExprDup(db,pLeft,0),pStr2,0);
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew2==0 );
exprAnalyze(pSrc, pWC, idxNew2);
pTerm = &pWC->a[idxTerm];
@@ -80656,15 +81807,15 @@
Expr *pRight, *pLeft;
WhereTerm *pNewTerm;
Bitmask prereqColumn, prereqExpr;
- pRight = pExpr->pList->a[0].pExpr;
- pLeft = pExpr->pList->a[1].pExpr;
+ pRight = pExpr->x.pList->a[0].pExpr;
+ pLeft = pExpr->x.pList->a[1].pExpr;
prereqExpr = exprTableUsage(pMaskSet, pRight);
prereqColumn = exprTableUsage(pMaskSet, pLeft);
if( (prereqExpr & prereqColumn)==0 ){
Expr *pNewExpr;
- pNewExpr = sqlite3Expr(db, TK_MATCH, 0, sqlite3ExprDup(db, pRight), 0);
+ pNewExpr = sqlite3Expr(db, TK_MATCH, 0, sqlite3ExprDup(db, pRight, 0), 0);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
pNewTerm = &pWC->a[idxNew];
pNewTerm->prereqRight = prereqExpr;
@@ -81005,9 +82156,10 @@
+ (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
+ sizeof(*pIdxOrderBy)*nOrderBy );
if( pIdxInfo==0 ){
sqlite3ErrorMsg(pParse, "out of memory");
- return 0.0;
+ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
+ return (double)0;
}
*ppIdxInfo = pIdxInfo;
/* Initialize the structure. The sqlite3_index_info structure contains
@@ -81108,9 +82260,10 @@
pIdxInfo->idxStr = 0;
pIdxInfo->idxNum = 0;
pIdxInfo->needToFreeIdxStr = 0;
pIdxInfo->orderByConsumed = 0;
- pIdxInfo->estimatedCost = SQLITE_BIG_DBL / 2.0;
+ /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
+ pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
nOrderBy = pIdxInfo->nOrderBy;
if( pIdxInfo->nOrderBy && !orderByUsable ){
*(int*)&pIdxInfo->nOrderBy = 0;
}
@@ -81137,9 +82290,10 @@
for(i=0; i<pIdxInfo->nConstraint; i++){
if( !pIdxInfo->aConstraint[i].usable && pUsage[i].argvIndex>0 ){
sqlite3ErrorMsg(pParse,
"table %s: xBestIndex returned an invalid plan", pTab->zName);
- return 0.0;
+ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
+ return (double)0;
}
}
*(int*)&pIdxInfo->nOrderBy = nOrderBy;
@@ -81163,17 +82317,17 @@
**
** * Whether or not there must be separate lookups in the
** index and in the main table.
**
-** If there was an INDEXED BY clause attached to the table in the SELECT
-** statement, then this function only considers plans using the
-** named index. If one cannot be found, then the returned cost is
-** SQLITE_BIG_DBL. If a plan can be found that uses the named index,
+** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in
+** the SQL statement, then this function only considers plans using the
+** named index. If no such plan is found, then the returned cost is
+** SQLITE_BIG_DBL. If a plan is found that uses the named index,
** then the cost is calculated in the usual way.
**
-** If a NOT INDEXED clause was attached to the table in the SELECT
-** statement, then no indexes are considered. However, the selected
-** plan may still take advantage of the tables built-in rowid
+** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table
+** in the SELECT statement, then no indexes are considered. However, the
+** selected plan may still take advantage of the tables built-in rowid
** index.
*/
static void bestIndex(
Parse *pParse, /* The parsing context */
@@ -81231,12 +82385,14 @@
WHERETRACE(("... best is rowid\n"));
pCost->rCost = 0;
pCost->nRow = 1;
return;
- }else if( (pExpr = pTerm->pExpr)->pList!=0 ){
+ }else if( !ExprHasProperty((pExpr = pTerm->pExpr), EP_xIsSelect)
+ && pExpr->x.pList
+ ){
/* Rowid IN (LIST): cost is NlogN where N is the number of list
** elements. */
- pCost->rCost = pCost->nRow = pExpr->pList->nExpr;
+ pCost->rCost = pCost->nRow = pExpr->x.pList->nExpr;
pCost->rCost *= estLog(pCost->rCost);
}else{
/* Rowid IN (SELECT): cost is NlogN where N is the number of rows
** in the result of the inner select. We have no way to estimate
@@ -81283,9 +82439,17 @@
}else{
cost += cost*estLog(cost);
WHERETRACE(("... sorting increases cost to %.9g\n", cost));
}
- }
+ }else if( pParse->db->flags & SQLITE_ReverseOrder ){
+ /* For application testing, randomly reverse the output order for
+ ** SELECT statements that omit the ORDER BY clause. This will help
+ ** to find cases where
+ */
+ wsFlags |= WHERE_REVERSE;
+ }
+
+ /* Remember this case if it is the best so far */
if( cost<pCost->rCost ){
pCost->rCost = cost;
pCost->nRow = nRow;
pCost->plan.wsFlags = wsFlags;
@@ -81364,14 +82528,20 @@
if( pSrc->pIndex ){
pProbe = pSrc->pIndex;
}
for(; pProbe; pProbe=(pSrc->pIndex ? 0 : pProbe->pNext)){
- double inMultiplier = 1;
+ double inMultiplier = 1; /* Number of equality look-ups needed */
+ int inMultIsEst = 0; /* True if inMultiplier is an estimate */
WHERETRACE(("... index %s:\n", pProbe->zName));
/* Count the number of columns in the index that are satisfied
- ** by x=EXPR constraints or x IN (...) constraints.
+ ** by x=EXPR constraints or x IN (...) constraints. For a term
+ ** of the form x=EXPR we only have to do a single binary search.
+ ** But for x IN (...) we have to do a number of binary searched
+ ** equal to the number of entries on the RHS of the IN operator.
+ ** The inMultipler variable with try to estimate the number of
+ ** binary searches needed.
*/
wsFlags = 0;
for(i=0; i<pProbe->nColumn; i++){
int j = pProbe->aiColumn[i];
@@ -81380,25 +82550,35 @@
wsFlags |= WHERE_COLUMN_EQ;
if( pTerm->eOperator & WO_IN ){
Expr *pExpr = pTerm->pExpr;
wsFlags |= WHERE_COLUMN_IN;
- if( pExpr->pSelect!=0 ){
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
inMultiplier *= 25;
- }else if( ALWAYS(pExpr->pList) ){
- inMultiplier *= pExpr->pList->nExpr + 1;
+ inMultIsEst = 1;
+ }else if( pExpr->x.pList ){
+ inMultiplier *= pExpr->x.pList->nExpr + 1;
}
}
}
nRow = pProbe->aiRowEst[i] * inMultiplier;
- cost = nRow * estLog(inMultiplier);
+ /* If inMultiplier is an estimate and that estimate results in an
+ ** nRow it that is more than half number of rows in the table,
+ ** then reduce inMultipler */
+ if( inMultIsEst && nRow*2 > pProbe->aiRowEst[0] ){
+ nRow = pProbe->aiRowEst[0]/2;
+ inMultiplier = nRow/pProbe->aiRowEst[i];
+ }
+ cost = nRow + inMultiplier*estLog(pProbe->aiRowEst[0]);
nEq = i;
if( pProbe->onError!=OE_None && (wsFlags & WHERE_COLUMN_IN)==0
&& nEq==pProbe->nColumn ){
wsFlags |= WHERE_UNIQUE;
}
- WHERETRACE(("...... nEq=%d inMult=%.9g cost=%.9g\n",nEq,inMultiplier,cost));
-
- /* Look for range constraints
+ WHERETRACE(("...... nEq=%d inMult=%.9g nRow=%.9g cost=%.9g\n",
+ nEq, inMultiplier, nRow, cost));
+
+ /* Look for range constraints. Assume that each range constraint
+ ** makes the search space 1/3rd smaller.
*/
if( nEq<pProbe->nColumn ){
int j = pProbe->aiColumn[nEq];
pTerm = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pProbe);
@@ -81413,9 +82593,10 @@
wsFlags |= WHERE_BTM_LIMIT;
cost /= 3;
nRow /= 3;
}
- WHERETRACE(("...... range reduces cost to %.9g\n", cost));
+ WHERETRACE(("...... range reduces nRow to %.9g and cost to %.9g\n",
+ nRow, cost));
}
}
/* Add the additional cost of sorting if that is a factor.
@@ -81433,8 +82614,14 @@
}else{
cost += cost*estLog(cost);
WHERETRACE(("...... orderby increases cost to %.9g\n", cost));
}
+ }else if( pParse->db->flags & SQLITE_ReverseOrder ){
+ /* For application testing, randomly reverse the output order for
+ ** SELECT statements that omit the ORDER BY clause. This will help
+ ** to find cases where
+ */
+ wsFlags |= WHERE_REVERSE;
}
/* Check to see if we can get away with using just the index without
** ever reading the table. If that is the case, then halve the
@@ -82193,13 +83380,15 @@
{
/* Case 5: There is no usable index. We must do a complete
** scan of the entire table.
*/
+ static const u8 aStep[] = { OP_Next, OP_Prev };
+ static const u8 aStart[] = { OP_Rewind, OP_Last };
+ assert( bRev==0 || bRev==1 );
assert( omitTable==0 );
- assert( bRev==0 );
- pLevel->op = OP_Next;
+ pLevel->op = aStep[bRev];
pLevel->p1 = iCur;
- pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, OP_Rewind, iCur, addrBrk);
+ pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
codeRowSetEarly = 0;
}
notReady &= ~getMask(pWC->pMaskSet, iCur);
@@ -82291,9 +83480,9 @@
if( pInfo ){
assert( pInfo->needToFreeIdxStr==0 || db->mallocFailed );
if( pInfo->needToFreeIdxStr ){
sqlite3_free(pInfo->idxStr);
- }
+ }
sqlite3DbFree(db, pInfo);
}
}
whereClauseClear(pWInfo->pWC);
@@ -82398,8 +83587,9 @@
u8 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
int regRowSet /* Register hold RowSet if WHERE_FILL_ROWSET is set */
){
int i; /* Loop counter */
+ int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
WhereInfo *pWInfo; /* Will become the return value of this function */
Vdbe *v = pParse->pVdbe; /* The virtual database engine */
Bitmask notReady; /* Cursors that are not yet positioned */
WhereMaskSet *pMaskSet; /* The expression mask set */
@@ -82423,17 +83613,21 @@
pOrderBy = *ppOrderBy;
}
/* Allocate and initialize the WhereInfo structure that will become the
- ** return value.
+ ** return value. A single allocation is used to store the WhereInfo
+ ** struct, the contents of WhereInfo.a[], the WhereClause structure
+ ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
+ ** field (type Bitmask) it must be aligned on an 8-byte boundary on
+ ** some architectures. Hence the ROUND8() below.
*/
db = pParse->db;
+ nByteWInfo = ROUND8(sizeof(WhereInfo)+(pTabList->nSrc-1)*sizeof(WhereLevel));
pWInfo = sqlite3DbMallocZero(db,
- sizeof(WhereInfo)
- + (pTabList->nSrc-1)*sizeof(WhereLevel)
- + sizeof(WhereClause)
- + sizeof(WhereMaskSet)
- );
+ nByteWInfo +
+ sizeof(WhereClause) +
+ sizeof(WhereMaskSet)
+ );
if( db->mallocFailed ){
goto whereBeginError;
}
pWInfo->nLevel = pTabList->nSrc;
@@ -82440,9 +83634,9 @@
pWInfo->pParse = pParse;
pWInfo->pTabList = pTabList;
pWInfo->iBreak = sqlite3VdbeMakeLabel(v);
pWInfo->regRowSet = (wctrlFlags & WHERE_FILL_ROWSET) ? regRowSet : -1;
- pWInfo->pWC = pWC = (WhereClause*)&pWInfo->a[pWInfo->nLevel];
+ pWInfo->pWC = pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo];
pWInfo->wctrlFlags = wctrlFlags;
pMaskSet = (WhereMaskSet*)&pWC[1];
/* Split the WHERE clause into separate subexpressions where each
@@ -82550,14 +83744,16 @@
if( pVtabIdx && pVtabIdx->orderByConsumed ){
sCost.plan.wsFlags = WHERE_VIRTUALTABLE | WHERE_ORDERBY;
}
sCost.plan.nEq = 0;
- if( (SQLITE_BIG_DBL/2.0)<sCost.rCost ){
+ /* (double)2 In case of SQLITE_OMIT_FLOATING_POINT... */
+ if( (SQLITE_BIG_DBL/((double)2))<sCost.rCost ){
/* The cost is not allowed to be larger than SQLITE_BIG_DBL (the
** inital value of lowestCost in this loop. If it is, then
** the (cost<lowestCost) test below will never be true.
*/
- sCost.rCost = (SQLITE_BIG_DBL/2.0);
+ /* (double)2 In case of SQLITE_OMIT_FLOATING_POINT... */
+ sCost.rCost = (SQLITE_BIG_DBL/((double)2));
}
}else
#endif
{
@@ -82585,9 +83781,9 @@
}else{
pLevel->iIdxCur = -1;
}
notReady &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor);
- pLevel->iFrom = bestJ;
+ pLevel->iFrom = (u8)bestJ;
/* Check that if the table scanned by this loop iteration had an
** INDEXED BY clause attached to it, that the named index is being
** used for the scan. If not, then query compilation has failed.
@@ -82684,9 +83880,9 @@
if( !pWInfo->okOnePass && pTab->nCol<BMS ){
Bitmask b = pTabItem->colUsed;
int n = 0;
for(; b; b=b>>1, n++){}
- sqlite3VdbeChangeP2(v, sqlite3VdbeCurrentAddr(v)-2, n);
+ sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1, SQLITE_INT_TO_PTR(n), P4_INT32);
assert( n<=pTab->nCol );
}
}else{
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
@@ -82697,9 +83893,8 @@
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
int iIdxCur = pLevel->iIdxCur;
assert( pIx->pSchema==pTab->pSchema );
assert( iIdxCur>=0 );
- sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pIx->nColumn+1);
sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIx->tnum, iDb,
(char*)pKey, P4_KEYINFO_HANDOFF);
VdbeComment((v, "%s", pIx->zName));
}
@@ -82984,27 +84179,27 @@
** YYNRULE the number of rules in the grammar
** YYERRORSYMBOL is the code number of the error symbol. If not
** defined, then do no error processing.
*/
-#define YYCODETYPE unsigned char
-#define YYNOCODE 251
+#define YYCODETYPE unsigned short int
+#define YYNOCODE 252
#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 62
+#define YYWILDCARD 65
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite3ParserTOKENTYPE yy0;
- struct LimitVal yy64;
- Expr* yy122;
- Select* yy159;
- IdList* yy180;
- struct {int value; int mask;} yy207;
- struct LikeOp yy318;
- TriggerStep* yy327;
- SrcList* yy347;
- int yy392;
- struct TrigEvent yy410;
- ExprList* yy442;
+ Expr* yy72;
+ TriggerStep* yy145;
+ ExprList* yy148;
+ SrcList* yy185;
+ int yy194;
+ Select* yy243;
+ IdList* yy254;
+ struct TrigEvent yy332;
+ struct LimitVal yy354;
+ struct LikeOp yy392;
+ struct {int value; int mask;} yy497;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
#endif
@@ -83011,10 +84206,10 @@
#define sqlite3ParserARG_SDECL Parse *pParse;
#define sqlite3ParserARG_PDECL ,Parse *pParse
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 610
-#define YYNRULE 319
+#define YYNSTATE 613
+#define YYNRULE 321
#define YYFALLBACK 1
#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
@@ -83071,429 +84266,456 @@
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
*/
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 304, 930, 120, 609, 1, 178, 214, 436, 62, 62,
- /* 10 */ 62, 62, 216, 64, 64, 64, 64, 65, 65, 66,
- /* 20 */ 66, 66, 67, 216, 406, 403, 443, 449, 69, 64,
- /* 30 */ 64, 64, 64, 65, 65, 66, 66, 66, 67, 216,
- /* 40 */ 469, 467, 336, 174, 61, 60, 309, 453, 454, 450,
- /* 50 */ 450, 63, 63, 62, 62, 62, 62, 200, 64, 64,
- /* 60 */ 64, 64, 65, 65, 66, 66, 66, 67, 216, 304,
- /* 70 */ 510, 312, 436, 509, 438, 83, 64, 64, 64, 64,
- /* 80 */ 65, 65, 66, 66, 66, 67, 216, 65, 65, 66,
- /* 90 */ 66, 66, 67, 216, 511, 443, 449, 325, 408, 59,
- /* 100 */ 465, 218, 57, 213, 411, 496, 428, 440, 440, 440,
- /* 110 */ 206, 67, 216, 61, 60, 309, 453, 454, 450, 450,
- /* 120 */ 63, 63, 62, 62, 62, 62, 552, 64, 64, 64,
- /* 130 */ 64, 65, 65, 66, 66, 66, 67, 216, 304, 228,
- /* 140 */ 186, 469, 544, 312, 433, 170, 114, 256, 357, 261,
- /* 150 */ 358, 181, 425, 20, 426, 542, 153, 85, 265, 465,
- /* 160 */ 218, 150, 151, 539, 443, 449, 95, 311, 394, 412,
- /* 170 */ 413, 510, 276, 427, 436, 438, 152, 553, 545, 589,
- /* 180 */ 590, 539, 61, 60, 309, 453, 454, 450, 450, 63,
- /* 190 */ 63, 62, 62, 62, 62, 402, 64, 64, 64, 64,
- /* 200 */ 65, 65, 66, 66, 66, 67, 216, 304, 440, 440,
- /* 210 */ 440, 228, 109, 411, 399, 523, 593, 330, 114, 256,
- /* 220 */ 357, 261, 358, 181, 187, 330, 485, 359, 362, 363,
- /* 230 */ 265, 593, 241, 443, 449, 592, 591, 248, 364, 436,
- /* 240 */ 432, 35, 492, 66, 66, 66, 67, 216, 432, 42,
- /* 250 */ 592, 61, 60, 309, 453, 454, 450, 450, 63, 63,
- /* 260 */ 62, 62, 62, 62, 401, 64, 64, 64, 64, 65,
- /* 270 */ 65, 66, 66, 66, 67, 216, 304, 570, 412, 413,
- /* 280 */ 187, 501, 344, 359, 362, 363, 215, 354, 346, 221,
- /* 290 */ 330, 341, 330, 56, 364, 569, 588, 217, 68, 156,
- /* 300 */ 70, 155, 443, 449, 68, 187, 70, 155, 359, 362,
- /* 310 */ 363, 397, 217, 432, 35, 432, 36, 148, 569, 364,
- /* 320 */ 61, 60, 309, 453, 454, 450, 450, 63, 63, 62,
- /* 330 */ 62, 62, 62, 433, 64, 64, 64, 64, 65, 65,
- /* 340 */ 66, 66, 66, 67, 216, 387, 282, 281, 330, 304,
- /* 350 */ 474, 68, 480, 70, 155, 344, 214, 154, 299, 330,
- /* 360 */ 343, 467, 543, 174, 384, 475, 257, 247, 387, 282,
- /* 370 */ 281, 432, 28, 411, 160, 443, 449, 258, 476, 214,
- /* 380 */ 516, 496, 432, 42, 198, 492, 68, 162, 70, 155,
- /* 390 */ 517, 433, 78, 61, 60, 309, 453, 454, 450, 450,
- /* 400 */ 63, 63, 62, 62, 62, 62, 595, 64, 64, 64,
- /* 410 */ 64, 65, 65, 66, 66, 66, 67, 216, 433, 367,
- /* 420 */ 349, 433, 304, 220, 222, 544, 505, 330, 465, 330,
- /* 430 */ 230, 330, 240, 163, 161, 554, 20, 431, 412, 413,
- /* 440 */ 2, 430, 385, 375, 411, 198, 182, 249, 443, 449,
- /* 450 */ 432, 35, 432, 50, 432, 50, 310, 460, 461, 17,
- /* 460 */ 207, 335, 460, 461, 388, 81, 61, 60, 309, 453,
- /* 470 */ 454, 450, 450, 63, 63, 62, 62, 62, 62, 433,
- /* 480 */ 64, 64, 64, 64, 65, 65, 66, 66, 66, 67,
- /* 490 */ 216, 304, 348, 504, 433, 508, 531, 486, 320, 353,
- /* 500 */ 321, 306, 457, 385, 23, 331, 265, 470, 411, 412,
- /* 510 */ 413, 444, 445, 551, 526, 307, 532, 443, 449, 217,
- /* 520 */ 550, 496, 432, 3, 217, 381, 607, 921, 333, 921,
- /* 530 */ 456, 456, 447, 448, 276, 61, 60, 309, 453, 454,
- /* 540 */ 450, 450, 63, 63, 62, 62, 62, 62, 410, 64,
- /* 550 */ 64, 64, 64, 65, 65, 66, 66, 66, 67, 216,
- /* 560 */ 304, 446, 607, 920, 525, 920, 604, 264, 314, 474,
- /* 570 */ 411, 123, 411, 412, 413, 124, 277, 487, 234, 333,
- /* 580 */ 411, 456, 456, 319, 475, 411, 443, 449, 333, 377,
- /* 590 */ 456, 456, 286, 333, 380, 456, 456, 476, 178, 340,
- /* 600 */ 436, 420, 604, 315, 61, 60, 309, 453, 454, 450,
- /* 610 */ 450, 63, 63, 62, 62, 62, 62, 330, 64, 64,
- /* 620 */ 64, 64, 65, 65, 66, 66, 66, 67, 216, 304,
- /* 630 */ 289, 5, 287, 268, 466, 412, 413, 412, 413, 396,
- /* 640 */ 432, 29, 503, 330, 159, 412, 413, 610, 406, 403,
- /* 650 */ 412, 413, 414, 415, 416, 443, 449, 333, 214, 456,
- /* 660 */ 456, 488, 276, 489, 21, 436, 432, 24, 436, 487,
- /* 670 */ 514, 515, 395, 61, 60, 309, 453, 454, 450, 450,
- /* 680 */ 63, 63, 62, 62, 62, 62, 330, 64, 64, 64,
- /* 690 */ 64, 65, 65, 66, 66, 66, 67, 216, 304, 560,
- /* 700 */ 374, 560, 352, 94, 578, 330, 567, 515, 330, 432,
- /* 710 */ 33, 330, 288, 330, 562, 330, 544, 330, 561, 183,
- /* 720 */ 184, 185, 603, 303, 443, 449, 600, 20, 432, 54,
- /* 730 */ 376, 432, 53, 436, 432, 99, 432, 97, 432, 102,
- /* 740 */ 432, 103, 61, 60, 309, 453, 454, 450, 450, 63,
- /* 750 */ 63, 62, 62, 62, 62, 330, 64, 64, 64, 64,
- /* 760 */ 65, 65, 66, 66, 66, 67, 216, 304, 330, 405,
- /* 770 */ 1, 202, 330, 512, 330, 214, 330, 171, 432, 108,
- /* 780 */ 330, 421, 429, 330, 487, 342, 330, 384, 19, 386,
- /* 790 */ 145, 432, 110, 443, 449, 432, 16, 432, 100, 432,
- /* 800 */ 34, 351, 270, 432, 98, 433, 432, 25, 276, 432,
- /* 810 */ 55, 61, 60, 309, 453, 454, 450, 450, 63, 63,
- /* 820 */ 62, 62, 62, 62, 330, 64, 64, 64, 64, 65,
- /* 830 */ 65, 66, 66, 66, 67, 216, 304, 330, 323, 119,
- /* 840 */ 274, 330, 272, 330, 355, 330, 422, 432, 111, 330,
- /* 850 */ 580, 159, 115, 233, 330, 177, 161, 439, 463, 463,
- /* 860 */ 432, 112, 443, 449, 432, 113, 432, 26, 432, 37,
- /* 870 */ 649, 431, 432, 38, 492, 430, 487, 432, 27, 264,
- /* 880 */ 61, 71, 309, 453, 454, 450, 450, 63, 63, 62,
- /* 890 */ 62, 62, 62, 330, 64, 64, 64, 64, 65, 65,
- /* 900 */ 66, 66, 66, 67, 216, 304, 330, 264, 264, 528,
- /* 910 */ 330, 157, 330, 252, 330, 229, 432, 39, 330, 482,
- /* 920 */ 332, 478, 77, 330, 79, 330, 483, 520, 521, 432,
- /* 930 */ 40, 443, 449, 432, 41, 432, 43, 432, 44, 492,
- /* 940 */ 491, 432, 45, 316, 317, 433, 432, 30, 432, 31,
- /* 950 */ 60, 309, 453, 454, 450, 450, 63, 63, 62, 62,
- /* 960 */ 62, 62, 330, 64, 64, 64, 64, 65, 65, 66,
- /* 970 */ 66, 66, 67, 216, 304, 330, 264, 564, 254, 330,
- /* 980 */ 458, 330, 22, 330, 495, 432, 46, 330, 494, 535,
- /* 990 */ 179, 186, 330, 267, 330, 186, 451, 497, 432, 47,
- /* 1000 */ 443, 449, 432, 48, 432, 49, 432, 32, 182, 262,
- /* 1010 */ 432, 10, 318, 276, 389, 432, 51, 432, 52, 276,
- /* 1020 */ 309, 453, 454, 450, 450, 63, 63, 62, 62, 62,
- /* 1030 */ 62, 276, 64, 64, 64, 64, 65, 65, 66, 66,
- /* 1040 */ 66, 67, 216, 165, 276, 276, 189, 192, 235, 236,
- /* 1050 */ 237, 168, 239, 566, 105, 581, 18, 530, 529, 73,
- /* 1060 */ 337, 582, 4, 306, 605, 527, 308, 211, 366, 294,
- /* 1070 */ 186, 263, 533, 231, 334, 565, 295, 186, 534, 546,
- /* 1080 */ 433, 433, 573, 574, 179, 92, 232, 292, 209, 269,
- /* 1090 */ 569, 339, 271, 853, 208, 273, 275, 210, 585, 195,
- /* 1100 */ 92, 469, 371, 606, 602, 8, 302, 423, 280, 379,
- /* 1110 */ 382, 383, 147, 242, 283, 437, 462, 284, 285, 577,
- /* 1120 */ 338, 76, 75, 587, 293, 296, 297, 599, 481, 464,
- /* 1130 */ 74, 328, 329, 250, 526, 438, 572, 166, 290, 393,
- /* 1140 */ 392, 291, 281, 409, 537, 584, 305, 484, 259, 540,
- /* 1150 */ 417, 214, 418, 214, 536, 326, 538, 419, 361, 167,
- /* 1160 */ 73, 337, 169, 4, 7, 327, 347, 308, 440, 440,
- /* 1170 */ 440, 441, 442, 11, 85, 334, 398, 84, 434, 345,
- /* 1180 */ 243, 58, 244, 73, 337, 80, 4, 245, 435, 246,
- /* 1190 */ 308, 176, 339, 479, 86, 121, 356, 350, 334, 493,
- /* 1200 */ 251, 253, 469, 499, 255, 513, 500, 518, 313, 519,
- /* 1210 */ 260, 523, 125, 522, 226, 339, 219, 524, 368, 190,
- /* 1220 */ 191, 300, 76, 75, 502, 469, 225, 227, 547, 541,
- /* 1230 */ 548, 74, 328, 329, 301, 555, 438, 549, 370, 193,
- /* 1240 */ 372, 194, 557, 89, 196, 76, 75, 278, 378, 117,
- /* 1250 */ 558, 568, 133, 390, 74, 328, 329, 199, 391, 438,
- /* 1260 */ 322, 134, 135, 136, 575, 143, 583, 596, 139, 440,
- /* 1270 */ 440, 440, 441, 442, 11, 597, 598, 601, 137, 142,
- /* 1280 */ 101, 224, 104, 407, 238, 424, 650, 651, 93, 172,
- /* 1290 */ 96, 173, 440, 440, 440, 441, 442, 11, 452, 455,
- /* 1300 */ 72, 471, 459, 468, 472, 144, 158, 6, 473, 490,
- /* 1310 */ 107, 175, 477, 82, 13, 122, 12, 180, 506, 118,
- /* 1320 */ 498, 164, 507, 324, 223, 87, 126, 116, 266, 127,
- /* 1330 */ 88, 128, 188, 258, 360, 369, 146, 556, 129, 373,
- /* 1340 */ 179, 365, 279, 197, 131, 130, 563, 9, 571, 132,
- /* 1350 */ 559, 201, 14, 576, 203, 204, 205, 579, 140, 138,
- /* 1360 */ 141, 15, 586, 594, 212, 106, 400, 298, 149, 404,
- /* 1370 */ 931, 608, 90, 91,
+ /* 0 */ 304, 935, 176, 612, 2, 150, 214, 438, 24, 24,
+ /* 10 */ 24, 24, 487, 26, 26, 26, 26, 27, 27, 28,
+ /* 20 */ 28, 28, 29, 216, 412, 413, 212, 412, 413, 445,
+ /* 30 */ 451, 31, 26, 26, 26, 26, 27, 27, 28, 28,
+ /* 40 */ 28, 29, 216, 30, 482, 32, 134, 23, 22, 308,
+ /* 50 */ 455, 456, 452, 452, 25, 25, 24, 24, 24, 24,
+ /* 60 */ 435, 26, 26, 26, 26, 27, 27, 28, 28, 28,
+ /* 70 */ 29, 216, 304, 216, 311, 438, 511, 489, 45, 26,
+ /* 80 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216,
+ /* 90 */ 412, 413, 415, 416, 156, 415, 416, 360, 363, 364,
+ /* 100 */ 311, 445, 451, 385, 513, 21, 186, 494, 365, 27,
+ /* 110 */ 27, 28, 28, 28, 29, 216, 412, 413, 414, 23,
+ /* 120 */ 22, 308, 455, 456, 452, 452, 25, 25, 24, 24,
+ /* 130 */ 24, 24, 554, 26, 26, 26, 26, 27, 27, 28,
+ /* 140 */ 28, 28, 29, 216, 304, 228, 503, 135, 467, 218,
+ /* 150 */ 438, 145, 132, 256, 358, 261, 359, 153, 415, 416,
+ /* 160 */ 553, 528, 331, 30, 265, 32, 134, 552, 592, 593,
+ /* 170 */ 230, 228, 489, 445, 451, 57, 505, 328, 132, 256,
+ /* 180 */ 358, 261, 359, 153, 415, 416, 434, 78, 407, 404,
+ /* 190 */ 265, 23, 22, 308, 455, 456, 452, 452, 25, 25,
+ /* 200 */ 24, 24, 24, 24, 476, 26, 26, 26, 26, 27,
+ /* 210 */ 27, 28, 28, 28, 29, 216, 304, 572, 438, 546,
+ /* 220 */ 477, 127, 547, 596, 30, 331, 32, 134, 345, 214,
+ /* 230 */ 428, 63, 331, 355, 414, 478, 241, 341, 414, 342,
+ /* 240 */ 328, 387, 193, 595, 594, 445, 451, 328, 299, 434,
+ /* 250 */ 85, 469, 545, 200, 190, 555, 434, 78, 309, 462,
+ /* 260 */ 463, 571, 471, 23, 22, 308, 455, 456, 452, 452,
+ /* 270 */ 25, 25, 24, 24, 24, 24, 435, 26, 26, 26,
+ /* 280 */ 26, 27, 27, 28, 28, 28, 29, 216, 304, 347,
+ /* 290 */ 221, 191, 512, 429, 544, 331, 440, 234, 345, 430,
+ /* 300 */ 324, 409, 541, 344, 591, 217, 213, 541, 112, 331,
+ /* 310 */ 328, 388, 282, 281, 211, 29, 216, 445, 451, 434,
+ /* 320 */ 79, 217, 214, 334, 328, 458, 458, 442, 442, 442,
+ /* 330 */ 571, 270, 4, 434, 85, 23, 22, 308, 455, 456,
+ /* 340 */ 452, 452, 25, 25, 24, 24, 24, 24, 435, 26,
+ /* 350 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216,
+ /* 360 */ 304, 514, 156, 331, 488, 360, 363, 364, 331, 353,
+ /* 370 */ 431, 247, 395, 274, 220, 272, 365, 352, 328, 331,
+ /* 380 */ 388, 282, 281, 328, 412, 413, 307, 434, 93, 445,
+ /* 390 */ 451, 214, 434, 93, 328, 530, 150, 1, 438, 403,
+ /* 400 */ 468, 412, 413, 434, 78, 40, 210, 23, 22, 308,
+ /* 410 */ 455, 456, 452, 452, 25, 25, 24, 24, 24, 24,
+ /* 420 */ 194, 26, 26, 26, 26, 27, 27, 28, 28, 28,
+ /* 430 */ 29, 216, 304, 319, 331, 596, 507, 535, 320, 179,
+ /* 440 */ 435, 489, 467, 156, 192, 349, 360, 363, 364, 328,
+ /* 450 */ 414, 536, 415, 416, 435, 595, 546, 365, 434, 71,
+ /* 460 */ 378, 445, 451, 208, 240, 381, 438, 556, 63, 415,
+ /* 470 */ 416, 414, 28, 28, 28, 29, 216, 43, 435, 23,
+ /* 480 */ 22, 308, 455, 456, 452, 452, 25, 25, 24, 24,
+ /* 490 */ 24, 24, 276, 26, 26, 26, 26, 27, 27, 28,
+ /* 500 */ 28, 28, 29, 216, 304, 354, 209, 414, 510, 412,
+ /* 510 */ 413, 135, 426, 331, 412, 413, 398, 217, 66, 333,
+ /* 520 */ 328, 564, 412, 413, 30, 563, 32, 134, 328, 434,
+ /* 530 */ 8, 546, 484, 445, 451, 400, 489, 434, 72, 377,
+ /* 540 */ 435, 485, 603, 63, 598, 494, 414, 372, 469, 337,
+ /* 550 */ 200, 23, 22, 308, 455, 456, 452, 452, 25, 25,
+ /* 560 */ 24, 24, 24, 24, 386, 26, 26, 26, 26, 27,
+ /* 570 */ 27, 28, 28, 28, 29, 216, 304, 415, 416, 476,
+ /* 580 */ 527, 60, 415, 416, 222, 402, 389, 498, 185, 331,
+ /* 590 */ 415, 416, 385, 242, 331, 477, 331, 506, 453, 336,
+ /* 600 */ 462, 463, 414, 490, 328, 445, 451, 414, 491, 328,
+ /* 610 */ 478, 328, 518, 434, 67, 613, 407, 404, 434, 76,
+ /* 620 */ 434, 97, 519, 23, 22, 308, 455, 456, 452, 452,
+ /* 630 */ 25, 25, 24, 24, 24, 24, 331, 26, 26, 26,
+ /* 640 */ 26, 27, 27, 28, 28, 28, 29, 216, 304, 331,
+ /* 650 */ 310, 328, 268, 368, 64, 331, 397, 439, 438, 233,
+ /* 660 */ 434, 96, 217, 16, 328, 183, 331, 459, 467, 218,
+ /* 670 */ 328, 446, 447, 434, 101, 214, 154, 445, 451, 434,
+ /* 680 */ 99, 328, 464, 154, 566, 466, 334, 396, 458, 458,
+ /* 690 */ 434, 104, 449, 450, 205, 23, 22, 308, 455, 456,
+ /* 700 */ 452, 452, 25, 25, 24, 24, 24, 24, 331, 26,
+ /* 710 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216,
+ /* 720 */ 304, 448, 331, 328, 390, 56, 438, 331, 435, 331,
+ /* 730 */ 248, 306, 434, 105, 516, 517, 472, 328, 306, 39,
+ /* 740 */ 331, 41, 328, 265, 328, 414, 434, 126, 339, 445,
+ /* 750 */ 451, 434, 128, 434, 59, 328, 334, 250, 458, 458,
+ /* 760 */ 196, 569, 517, 568, 434, 102, 483, 23, 22, 308,
+ /* 770 */ 455, 456, 452, 452, 25, 25, 24, 24, 24, 24,
+ /* 780 */ 331, 26, 26, 26, 26, 27, 27, 28, 28, 28,
+ /* 790 */ 29, 216, 304, 331, 435, 328, 562, 375, 562, 331,
+ /* 800 */ 264, 858, 606, 303, 434, 77, 197, 137, 328, 406,
+ /* 810 */ 2, 331, 178, 215, 328, 414, 486, 434, 100, 136,
+ /* 820 */ 18, 445, 451, 434, 68, 334, 328, 458, 458, 610,
+ /* 830 */ 926, 460, 926, 65, 414, 434, 98, 314, 528, 23,
+ /* 840 */ 22, 308, 455, 456, 452, 452, 25, 25, 24, 24,
+ /* 850 */ 24, 24, 331, 26, 26, 26, 26, 27, 27, 28,
+ /* 860 */ 28, 28, 29, 216, 304, 331, 350, 328, 264, 155,
+ /* 870 */ 264, 331, 607, 331, 201, 137, 434, 129, 433, 574,
+ /* 880 */ 328, 414, 432, 414, 331, 414, 328, 498, 328, 434,
+ /* 890 */ 130, 498, 539, 445, 451, 434, 131, 434, 69, 328,
+ /* 900 */ 362, 334, 414, 458, 458, 229, 414, 315, 434, 80,
+ /* 910 */ 259, 23, 33, 308, 455, 456, 452, 452, 25, 25,
+ /* 920 */ 24, 24, 24, 24, 331, 26, 26, 26, 26, 27,
+ /* 930 */ 27, 28, 28, 28, 29, 216, 304, 331, 264, 328,
+ /* 940 */ 164, 264, 356, 331, 417, 418, 419, 525, 434, 81,
+ /* 950 */ 376, 542, 328, 414, 318, 331, 414, 538, 328, 465,
+ /* 960 */ 465, 434, 70, 322, 175, 445, 451, 434, 82, 433,
+ /* 970 */ 328, 610, 925, 432, 925, 316, 540, 494, 317, 434,
+ /* 980 */ 83, 522, 523, 587, 22, 308, 455, 456, 452, 452,
+ /* 990 */ 25, 25, 24, 24, 24, 24, 331, 26, 26, 26,
+ /* 1000 */ 26, 27, 27, 28, 28, 28, 29, 216, 304, 331,
+ /* 1010 */ 209, 328, 257, 249, 607, 331, 252, 202, 203, 204,
+ /* 1020 */ 434, 84, 290, 258, 328, 532, 531, 331, 414, 394,
+ /* 1030 */ 328, 331, 533, 434, 86, 332, 141, 445, 451, 434,
+ /* 1040 */ 87, 47, 328, 496, 435, 151, 328, 537, 410, 155,
+ /* 1050 */ 414, 434, 88, 534, 494, 434, 73, 308, 455, 456,
+ /* 1060 */ 452, 452, 25, 25, 24, 24, 24, 24, 386, 26,
+ /* 1070 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216,
+ /* 1080 */ 35, 338, 286, 3, 331, 411, 331, 327, 413, 423,
+ /* 1090 */ 382, 422, 276, 254, 420, 35, 338, 335, 3, 328,
+ /* 1100 */ 414, 328, 327, 413, 414, 313, 276, 414, 434, 74,
+ /* 1110 */ 434, 89, 335, 331, 421, 340, 424, 331, 425, 331,
+ /* 1120 */ 267, 414, 155, 142, 289, 471, 287, 325, 328, 326,
+ /* 1130 */ 340, 414, 328, 414, 328, 581, 276, 434, 90, 144,
+ /* 1140 */ 471, 434, 91, 434, 92, 38, 37, 15, 331, 277,
+ /* 1150 */ 133, 414, 441, 276, 36, 329, 330, 6, 436, 440,
+ /* 1160 */ 38, 37, 504, 328, 206, 414, 47, 414, 414, 36,
+ /* 1170 */ 329, 330, 434, 75, 440, 198, 367, 214, 155, 583,
+ /* 1180 */ 235, 236, 237, 143, 239, 348, 343, 580, 46, 243,
+ /* 1190 */ 442, 442, 442, 443, 444, 9, 584, 276, 435, 7,
+ /* 1200 */ 172, 414, 294, 331, 288, 442, 442, 442, 443, 444,
+ /* 1210 */ 9, 295, 414, 35, 338, 567, 3, 155, 328, 480,
+ /* 1220 */ 327, 413, 331, 170, 276, 571, 244, 434, 17, 169,
+ /* 1230 */ 335, 19, 171, 245, 414, 412, 413, 328, 331, 414,
+ /* 1240 */ 585, 276, 575, 576, 151, 54, 434, 94, 340, 493,
+ /* 1250 */ 497, 499, 346, 328, 276, 262, 414, 529, 471, 263,
+ /* 1260 */ 246, 20, 434, 95, 414, 414, 414, 231, 548, 414,
+ /* 1270 */ 414, 437, 414, 471, 414, 393, 291, 281, 38, 37,
+ /* 1280 */ 588, 305, 54, 414, 232, 269, 214, 36, 329, 330,
+ /* 1290 */ 219, 271, 440, 188, 189, 273, 275, 292, 42, 280,
+ /* 1300 */ 414, 380, 383, 512, 384, 283, 414, 440, 149, 399,
+ /* 1310 */ 414, 414, 608, 605, 414, 302, 414, 414, 284, 414,
+ /* 1320 */ 414, 285, 579, 442, 442, 442, 443, 444, 9, 48,
+ /* 1330 */ 590, 293, 296, 414, 297, 602, 414, 414, 442, 442,
+ /* 1340 */ 442, 251, 351, 481, 177, 414, 414, 414, 495, 414,
+ /* 1350 */ 414, 501, 253, 255, 609, 502, 357, 312, 521, 515,
+ /* 1360 */ 107, 525, 226, 225, 520, 260, 369, 158, 227, 524,
+ /* 1370 */ 557, 526, 300, 549, 550, 551, 373, 278, 159, 301,
+ /* 1380 */ 543, 371, 160, 51, 207, 559, 560, 161, 140, 379,
+ /* 1390 */ 570, 163, 117, 391, 181, 392, 118, 119, 120, 121,
+ /* 1400 */ 321, 123, 577, 599, 600, 55, 58, 586, 601, 604,
+ /* 1410 */ 62, 323, 408, 103, 224, 111, 174, 238, 427, 199,
+ /* 1420 */ 654, 655, 656, 146, 147, 454, 457, 34, 182, 180,
+ /* 1430 */ 461, 470, 473, 474, 195, 5, 492, 475, 148, 479,
+ /* 1440 */ 44, 106, 10, 11, 138, 508, 509, 500, 223, 49,
+ /* 1450 */ 361, 108, 152, 266, 109, 50, 110, 157, 258, 370,
+ /* 1460 */ 184, 558, 139, 113, 151, 162, 279, 115, 374, 14,
+ /* 1470 */ 573, 116, 165, 52, 12, 366, 166, 53, 578, 167,
+ /* 1480 */ 582, 168, 114, 124, 122, 561, 565, 13, 61, 125,
+ /* 1490 */ 597, 173, 298, 187, 589, 405, 936, 611, 936, 936,
+ /* 1500 */ 401,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 19, 142, 143, 144, 145, 24, 113, 26, 72, 73,
- /* 10 */ 74, 75, 87, 77, 78, 79, 80, 81, 82, 83,
- /* 20 */ 84, 85, 86, 87, 1, 2, 45, 46, 76, 77,
- /* 30 */ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
- /* 40 */ 61, 165, 166, 167, 63, 64, 65, 66, 67, 68,
- /* 50 */ 69, 70, 71, 72, 73, 74, 75, 25, 77, 78,
- /* 60 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 19,
- /* 70 */ 91, 19, 91, 173, 95, 25, 77, 78, 79, 80,
- /* 80 */ 81, 82, 83, 84, 85, 86, 87, 81, 82, 83,
- /* 90 */ 84, 85, 86, 87, 173, 45, 46, 146, 147, 49,
- /* 100 */ 81, 82, 22, 152, 26, 150, 26, 128, 129, 130,
- /* 110 */ 159, 86, 87, 63, 64, 65, 66, 67, 68, 69,
- /* 120 */ 70, 71, 72, 73, 74, 75, 185, 77, 78, 79,
- /* 130 */ 80, 81, 82, 83, 84, 85, 86, 87, 19, 87,
- /* 140 */ 25, 61, 150, 19, 193, 93, 94, 95, 96, 97,
- /* 150 */ 98, 99, 160, 161, 171, 172, 25, 125, 106, 81,
- /* 160 */ 82, 81, 82, 180, 45, 46, 47, 212, 217, 91,
- /* 170 */ 92, 91, 150, 172, 26, 95, 184, 185, 185, 101,
- /* 180 */ 102, 180, 63, 64, 65, 66, 67, 68, 69, 70,
- /* 190 */ 71, 72, 73, 74, 75, 244, 77, 78, 79, 80,
- /* 200 */ 81, 82, 83, 84, 85, 86, 87, 19, 128, 129,
- /* 210 */ 130, 87, 24, 26, 192, 100, 150, 150, 94, 95,
- /* 220 */ 96, 97, 98, 99, 93, 150, 25, 96, 97, 98,
- /* 230 */ 106, 150, 194, 45, 46, 169, 170, 150, 107, 91,
- /* 240 */ 173, 174, 165, 83, 84, 85, 86, 87, 173, 174,
- /* 250 */ 169, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- /* 260 */ 72, 73, 74, 75, 242, 77, 78, 79, 80, 81,
- /* 270 */ 82, 83, 84, 85, 86, 87, 19, 11, 91, 92,
- /* 280 */ 93, 204, 215, 96, 97, 98, 196, 220, 213, 214,
- /* 290 */ 150, 190, 150, 203, 107, 52, 230, 231, 221, 159,
- /* 300 */ 223, 224, 45, 46, 221, 93, 223, 224, 96, 97,
- /* 310 */ 98, 230, 231, 173, 174, 173, 174, 116, 52, 107,
- /* 320 */ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
- /* 330 */ 73, 74, 75, 193, 77, 78, 79, 80, 81, 82,
- /* 340 */ 83, 84, 85, 86, 87, 102, 103, 104, 150, 19,
- /* 350 */ 12, 221, 222, 223, 224, 215, 113, 159, 162, 150,
- /* 360 */ 220, 165, 166, 167, 150, 27, 95, 225, 102, 103,
- /* 370 */ 104, 173, 174, 26, 150, 45, 46, 106, 40, 113,
- /* 380 */ 42, 150, 173, 174, 159, 165, 221, 159, 223, 224,
- /* 390 */ 52, 193, 135, 63, 64, 65, 66, 67, 68, 69,
- /* 400 */ 70, 71, 72, 73, 74, 75, 241, 77, 78, 79,
- /* 410 */ 80, 81, 82, 83, 84, 85, 86, 87, 193, 19,
- /* 420 */ 150, 193, 19, 214, 204, 150, 23, 150, 81, 150,
- /* 430 */ 216, 150, 157, 205, 206, 160, 161, 110, 91, 92,
- /* 440 */ 22, 114, 217, 212, 26, 159, 46, 150, 45, 46,
- /* 450 */ 173, 174, 173, 174, 173, 174, 168, 169, 170, 234,
- /* 460 */ 159, 168, 169, 170, 239, 135, 63, 64, 65, 66,
- /* 470 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 193,
- /* 480 */ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
- /* 490 */ 87, 19, 215, 23, 193, 23, 33, 207, 219, 150,
- /* 500 */ 219, 101, 23, 217, 22, 150, 106, 23, 26, 91,
- /* 510 */ 92, 45, 46, 180, 181, 154, 53, 45, 46, 231,
- /* 520 */ 187, 150, 173, 174, 231, 239, 22, 23, 109, 25,
- /* 530 */ 111, 112, 66, 67, 150, 63, 64, 65, 66, 67,
- /* 540 */ 68, 69, 70, 71, 72, 73, 74, 75, 150, 77,
- /* 550 */ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
- /* 560 */ 19, 95, 22, 23, 23, 25, 62, 150, 105, 12,
- /* 570 */ 26, 23, 26, 91, 92, 23, 192, 25, 148, 109,
- /* 580 */ 26, 111, 112, 212, 27, 26, 45, 46, 109, 228,
- /* 590 */ 111, 112, 17, 109, 233, 111, 112, 40, 24, 42,
- /* 600 */ 26, 150, 62, 186, 63, 64, 65, 66, 67, 68,
- /* 610 */ 69, 70, 71, 72, 73, 74, 75, 150, 77, 78,
- /* 620 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 19,
- /* 630 */ 55, 195, 57, 23, 165, 91, 92, 91, 92, 94,
- /* 640 */ 173, 174, 83, 150, 92, 91, 92, 0, 1, 2,
- /* 650 */ 91, 92, 7, 8, 9, 45, 46, 109, 113, 111,
- /* 660 */ 112, 117, 150, 117, 22, 91, 173, 174, 26, 117,
- /* 670 */ 189, 190, 127, 63, 64, 65, 66, 67, 68, 69,
- /* 680 */ 70, 71, 72, 73, 74, 75, 150, 77, 78, 79,
- /* 690 */ 80, 81, 82, 83, 84, 85, 86, 87, 19, 102,
- /* 700 */ 103, 104, 19, 24, 192, 150, 189, 190, 150, 173,
- /* 710 */ 174, 150, 137, 150, 28, 150, 150, 150, 32, 102,
- /* 720 */ 103, 104, 247, 248, 45, 46, 160, 161, 173, 174,
- /* 730 */ 44, 173, 174, 91, 173, 174, 173, 174, 173, 174,
- /* 740 */ 173, 174, 63, 64, 65, 66, 67, 68, 69, 70,
- /* 750 */ 71, 72, 73, 74, 75, 150, 77, 78, 79, 80,
- /* 760 */ 81, 82, 83, 84, 85, 86, 87, 19, 150, 144,
- /* 770 */ 145, 159, 150, 164, 150, 113, 150, 22, 173, 174,
- /* 780 */ 150, 150, 173, 150, 25, 150, 150, 150, 22, 127,
- /* 790 */ 24, 173, 174, 45, 46, 173, 174, 173, 174, 173,
- /* 800 */ 174, 118, 17, 173, 174, 193, 173, 174, 150, 173,
- /* 810 */ 174, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- /* 820 */ 72, 73, 74, 75, 150, 77, 78, 79, 80, 81,
- /* 830 */ 82, 83, 84, 85, 86, 87, 19, 150, 245, 246,
- /* 840 */ 55, 150, 57, 150, 83, 150, 150, 173, 174, 150,
- /* 850 */ 192, 92, 150, 216, 150, 205, 206, 150, 128, 129,
- /* 860 */ 173, 174, 45, 46, 173, 174, 173, 174, 173, 174,
- /* 870 */ 115, 110, 173, 174, 165, 114, 117, 173, 174, 150,
- /* 880 */ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
- /* 890 */ 73, 74, 75, 150, 77, 78, 79, 80, 81, 82,
- /* 900 */ 83, 84, 85, 86, 87, 19, 150, 150, 150, 182,
- /* 910 */ 150, 159, 150, 204, 150, 186, 173, 174, 150, 30,
- /* 920 */ 19, 150, 134, 150, 136, 150, 37, 7, 8, 173,
- /* 930 */ 174, 45, 46, 173, 174, 173, 174, 173, 174, 165,
- /* 940 */ 150, 173, 174, 186, 186, 193, 173, 174, 173, 174,
- /* 950 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- /* 960 */ 74, 75, 150, 77, 78, 79, 80, 81, 82, 83,
- /* 970 */ 84, 85, 86, 87, 19, 150, 150, 21, 204, 150,
- /* 980 */ 23, 150, 25, 150, 150, 173, 174, 150, 23, 23,
- /* 990 */ 25, 25, 150, 23, 150, 25, 95, 150, 173, 174,
- /* 1000 */ 45, 46, 173, 174, 173, 174, 173, 174, 46, 150,
- /* 1010 */ 173, 174, 186, 150, 58, 173, 174, 173, 174, 150,
- /* 1020 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- /* 1030 */ 75, 150, 77, 78, 79, 80, 81, 82, 83, 84,
- /* 1040 */ 85, 86, 87, 5, 150, 150, 159, 159, 10, 11,
- /* 1050 */ 12, 13, 14, 97, 16, 192, 22, 94, 95, 19,
- /* 1060 */ 20, 192, 22, 101, 23, 150, 26, 29, 23, 31,
- /* 1070 */ 25, 150, 182, 192, 34, 23, 38, 25, 182, 150,
- /* 1080 */ 193, 193, 23, 23, 25, 25, 192, 192, 50, 150,
- /* 1090 */ 52, 51, 150, 137, 56, 150, 150, 59, 23, 235,
- /* 1100 */ 25, 61, 236, 62, 23, 71, 25, 153, 150, 150,
- /* 1110 */ 150, 150, 195, 197, 150, 165, 232, 150, 150, 150,
- /* 1120 */ 227, 81, 82, 150, 150, 150, 150, 150, 176, 232,
- /* 1130 */ 90, 91, 92, 208, 181, 95, 198, 6, 208, 208,
- /* 1140 */ 102, 103, 104, 149, 165, 198, 108, 176, 176, 165,
- /* 1150 */ 149, 113, 149, 113, 176, 149, 176, 13, 177, 151,
- /* 1160 */ 19, 20, 151, 22, 25, 158, 122, 26, 128, 129,
- /* 1170 */ 130, 131, 132, 133, 125, 34, 138, 123, 193, 121,
- /* 1180 */ 198, 124, 199, 19, 20, 134, 22, 200, 202, 201,
- /* 1190 */ 26, 115, 51, 156, 101, 156, 101, 120, 34, 210,
- /* 1200 */ 209, 209, 61, 210, 209, 175, 210, 175, 43, 183,
- /* 1210 */ 175, 100, 22, 177, 87, 51, 226, 175, 18, 155,
- /* 1220 */ 155, 178, 81, 82, 83, 61, 229, 229, 175, 183,
- /* 1230 */ 175, 90, 91, 92, 178, 156, 95, 175, 156, 155,
- /* 1240 */ 41, 156, 156, 134, 155, 81, 82, 237, 156, 63,
- /* 1250 */ 238, 188, 22, 156, 90, 91, 92, 188, 18, 95,
- /* 1260 */ 156, 191, 191, 191, 198, 218, 198, 36, 188, 128,
- /* 1270 */ 129, 130, 131, 132, 133, 156, 156, 140, 191, 218,
- /* 1280 */ 163, 179, 179, 1, 15, 23, 115, 115, 240, 115,
- /* 1290 */ 240, 115, 128, 129, 130, 131, 132, 133, 95, 110,
- /* 1300 */ 22, 11, 23, 23, 23, 22, 22, 119, 23, 117,
- /* 1310 */ 243, 25, 23, 25, 119, 22, 25, 119, 23, 246,
- /* 1320 */ 118, 115, 23, 249, 47, 22, 22, 35, 23, 22,
- /* 1330 */ 22, 22, 99, 106, 47, 19, 24, 20, 101, 39,
- /* 1340 */ 25, 47, 137, 101, 22, 48, 48, 5, 1, 105,
- /* 1350 */ 54, 126, 22, 1, 116, 17, 120, 20, 105, 116,
- /* 1360 */ 126, 22, 127, 23, 15, 17, 60, 139, 22, 3,
- /* 1370 */ 250, 4, 71, 71,
-};
-#define YY_SHIFT_USE_DFLT (-108)
-#define YY_SHIFT_MAX 404
+ /* 0 */ 19, 142, 143, 144, 145, 24, 116, 26, 75, 76,
+ /* 10 */ 77, 78, 25, 80, 81, 82, 83, 84, 85, 86,
+ /* 20 */ 87, 88, 89, 90, 26, 27, 160, 26, 27, 48,
+ /* 30 */ 49, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ /* 40 */ 88, 89, 90, 222, 223, 224, 225, 66, 67, 68,
+ /* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 60 */ 194, 80, 81, 82, 83, 84, 85, 86, 87, 88,
+ /* 70 */ 89, 90, 19, 90, 19, 94, 174, 25, 25, 80,
+ /* 80 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+ /* 90 */ 26, 27, 94, 95, 96, 94, 95, 99, 100, 101,
+ /* 100 */ 19, 48, 49, 150, 174, 52, 119, 166, 110, 84,
+ /* 110 */ 85, 86, 87, 88, 89, 90, 26, 27, 165, 66,
+ /* 120 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
+ /* 130 */ 77, 78, 186, 80, 81, 82, 83, 84, 85, 86,
+ /* 140 */ 87, 88, 89, 90, 19, 90, 205, 95, 84, 85,
+ /* 150 */ 26, 96, 97, 98, 99, 100, 101, 102, 94, 95,
+ /* 160 */ 181, 182, 150, 222, 109, 224, 225, 188, 104, 105,
+ /* 170 */ 217, 90, 120, 48, 49, 50, 86, 165, 97, 98,
+ /* 180 */ 99, 100, 101, 102, 94, 95, 174, 175, 1, 2,
+ /* 190 */ 109, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ /* 200 */ 75, 76, 77, 78, 12, 80, 81, 82, 83, 84,
+ /* 210 */ 85, 86, 87, 88, 89, 90, 19, 11, 94, 150,
+ /* 220 */ 28, 24, 186, 150, 222, 150, 224, 225, 216, 116,
+ /* 230 */ 161, 162, 150, 221, 165, 43, 195, 45, 165, 191,
+ /* 240 */ 165, 128, 160, 170, 171, 48, 49, 165, 163, 174,
+ /* 250 */ 175, 166, 167, 168, 185, 186, 174, 175, 169, 170,
+ /* 260 */ 171, 55, 64, 66, 67, 68, 69, 70, 71, 72,
+ /* 270 */ 73, 74, 75, 76, 77, 78, 194, 80, 81, 82,
+ /* 280 */ 83, 84, 85, 86, 87, 88, 89, 90, 19, 214,
+ /* 290 */ 215, 25, 94, 172, 173, 150, 98, 148, 216, 173,
+ /* 300 */ 146, 147, 181, 221, 231, 232, 152, 181, 154, 150,
+ /* 310 */ 165, 105, 106, 107, 160, 89, 90, 48, 49, 174,
+ /* 320 */ 175, 232, 116, 112, 165, 114, 115, 129, 130, 131,
+ /* 330 */ 55, 16, 196, 174, 175, 66, 67, 68, 69, 70,
+ /* 340 */ 71, 72, 73, 74, 75, 76, 77, 78, 194, 80,
+ /* 350 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+ /* 360 */ 19, 165, 96, 150, 208, 99, 100, 101, 150, 19,
+ /* 370 */ 174, 226, 218, 58, 215, 60, 110, 27, 165, 150,
+ /* 380 */ 105, 106, 107, 165, 26, 27, 155, 174, 175, 48,
+ /* 390 */ 49, 116, 174, 175, 165, 183, 24, 22, 26, 245,
+ /* 400 */ 166, 26, 27, 174, 175, 136, 160, 66, 67, 68,
+ /* 410 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 420 */ 160, 80, 81, 82, 83, 84, 85, 86, 87, 88,
+ /* 430 */ 89, 90, 19, 220, 150, 150, 23, 183, 220, 23,
+ /* 440 */ 194, 25, 84, 96, 160, 216, 99, 100, 101, 165,
+ /* 450 */ 165, 183, 94, 95, 194, 170, 150, 110, 174, 175,
+ /* 460 */ 229, 48, 49, 236, 158, 234, 94, 161, 162, 94,
+ /* 470 */ 95, 165, 86, 87, 88, 89, 90, 136, 194, 66,
+ /* 480 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
+ /* 490 */ 77, 78, 150, 80, 81, 82, 83, 84, 85, 86,
+ /* 500 */ 87, 88, 89, 90, 19, 150, 160, 165, 23, 26,
+ /* 510 */ 27, 95, 153, 150, 26, 27, 231, 232, 22, 19,
+ /* 520 */ 165, 29, 26, 27, 222, 33, 224, 225, 165, 174,
+ /* 530 */ 175, 150, 31, 48, 49, 193, 120, 174, 175, 47,
+ /* 540 */ 194, 40, 161, 162, 242, 166, 165, 237, 166, 167,
+ /* 550 */ 168, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ /* 560 */ 75, 76, 77, 78, 218, 80, 81, 82, 83, 84,
+ /* 570 */ 85, 86, 87, 88, 89, 90, 19, 94, 95, 12,
+ /* 580 */ 23, 235, 94, 95, 205, 243, 240, 150, 196, 150,
+ /* 590 */ 94, 95, 150, 198, 150, 28, 150, 23, 98, 169,
+ /* 600 */ 170, 171, 165, 120, 165, 48, 49, 165, 120, 165,
+ /* 610 */ 43, 165, 45, 174, 175, 0, 1, 2, 174, 175,
+ /* 620 */ 174, 175, 55, 66, 67, 68, 69, 70, 71, 72,
+ /* 630 */ 73, 74, 75, 76, 77, 78, 150, 80, 81, 82,
+ /* 640 */ 83, 84, 85, 86, 87, 88, 89, 90, 19, 150,
+ /* 650 */ 213, 165, 23, 19, 22, 150, 97, 166, 26, 217,
+ /* 660 */ 174, 175, 232, 22, 165, 24, 150, 23, 84, 85,
+ /* 670 */ 165, 48, 49, 174, 175, 116, 49, 48, 49, 174,
+ /* 680 */ 175, 165, 233, 49, 21, 233, 112, 128, 114, 115,
+ /* 690 */ 174, 175, 69, 70, 160, 66, 67, 68, 69, 70,
+ /* 700 */ 71, 72, 73, 74, 75, 76, 77, 78, 150, 80,
+ /* 710 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+ /* 720 */ 19, 98, 150, 165, 61, 24, 94, 150, 194, 150,
+ /* 730 */ 150, 104, 174, 175, 190, 191, 23, 165, 104, 135,
+ /* 740 */ 150, 137, 165, 109, 165, 165, 174, 175, 228, 48,
+ /* 750 */ 49, 174, 175, 174, 175, 165, 112, 209, 114, 115,
+ /* 760 */ 160, 190, 191, 100, 174, 175, 177, 66, 67, 68,
+ /* 770 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 780 */ 150, 80, 81, 82, 83, 84, 85, 86, 87, 88,
+ /* 790 */ 89, 90, 19, 150, 194, 165, 105, 106, 107, 150,
+ /* 800 */ 150, 138, 248, 249, 174, 175, 206, 207, 165, 144,
+ /* 810 */ 145, 150, 23, 197, 165, 165, 177, 174, 175, 150,
+ /* 820 */ 204, 48, 49, 174, 175, 112, 165, 114, 115, 22,
+ /* 830 */ 23, 23, 25, 25, 165, 174, 175, 187, 182, 66,
+ /* 840 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
+ /* 850 */ 77, 78, 150, 80, 81, 82, 83, 84, 85, 86,
+ /* 860 */ 87, 88, 89, 90, 19, 150, 150, 165, 150, 25,
+ /* 870 */ 150, 150, 65, 150, 206, 207, 174, 175, 113, 199,
+ /* 880 */ 165, 165, 117, 165, 150, 165, 165, 150, 165, 174,
+ /* 890 */ 175, 150, 166, 48, 49, 174, 175, 174, 175, 165,
+ /* 900 */ 178, 112, 165, 114, 115, 187, 165, 187, 174, 175,
+ /* 910 */ 177, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ /* 920 */ 75, 76, 77, 78, 150, 80, 81, 82, 83, 84,
+ /* 930 */ 85, 86, 87, 88, 89, 90, 19, 150, 150, 165,
+ /* 940 */ 25, 150, 86, 150, 7, 8, 9, 103, 174, 175,
+ /* 950 */ 213, 166, 165, 165, 213, 150, 165, 177, 165, 129,
+ /* 960 */ 130, 174, 175, 246, 247, 48, 49, 174, 175, 113,
+ /* 970 */ 165, 22, 23, 117, 25, 187, 177, 166, 187, 174,
+ /* 980 */ 175, 7, 8, 199, 67, 68, 69, 70, 71, 72,
+ /* 990 */ 73, 74, 75, 76, 77, 78, 150, 80, 81, 82,
+ /* 1000 */ 83, 84, 85, 86, 87, 88, 89, 90, 19, 150,
+ /* 1010 */ 160, 165, 98, 150, 65, 150, 205, 105, 106, 107,
+ /* 1020 */ 174, 175, 209, 109, 165, 97, 98, 150, 165, 209,
+ /* 1030 */ 165, 150, 35, 174, 175, 150, 6, 48, 49, 174,
+ /* 1040 */ 175, 126, 165, 23, 194, 25, 165, 23, 149, 25,
+ /* 1050 */ 165, 174, 175, 56, 166, 174, 175, 68, 69, 70,
+ /* 1060 */ 71, 72, 73, 74, 75, 76, 77, 78, 218, 80,
+ /* 1070 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+ /* 1080 */ 19, 20, 16, 22, 150, 150, 150, 26, 27, 150,
+ /* 1090 */ 240, 13, 150, 205, 149, 19, 20, 36, 22, 165,
+ /* 1100 */ 165, 165, 26, 27, 165, 108, 150, 165, 174, 175,
+ /* 1110 */ 174, 175, 36, 150, 149, 54, 150, 150, 150, 150,
+ /* 1120 */ 23, 165, 25, 151, 58, 64, 60, 149, 165, 159,
+ /* 1130 */ 54, 165, 165, 165, 165, 193, 150, 174, 175, 151,
+ /* 1140 */ 64, 174, 175, 174, 175, 84, 85, 22, 150, 193,
+ /* 1150 */ 150, 165, 150, 150, 93, 94, 95, 25, 194, 98,
+ /* 1160 */ 84, 85, 86, 165, 160, 165, 126, 165, 165, 93,
+ /* 1170 */ 94, 95, 174, 175, 98, 5, 23, 116, 25, 193,
+ /* 1180 */ 10, 11, 12, 13, 14, 123, 150, 17, 124, 199,
+ /* 1190 */ 129, 130, 131, 132, 133, 134, 193, 150, 194, 74,
+ /* 1200 */ 30, 165, 32, 150, 138, 129, 130, 131, 132, 133,
+ /* 1210 */ 134, 41, 165, 19, 20, 23, 22, 25, 165, 150,
+ /* 1220 */ 26, 27, 150, 53, 150, 55, 200, 174, 175, 59,
+ /* 1230 */ 36, 22, 62, 201, 165, 26, 27, 165, 150, 165,
+ /* 1240 */ 193, 150, 23, 23, 25, 25, 174, 175, 54, 150,
+ /* 1250 */ 150, 150, 122, 165, 150, 150, 165, 150, 64, 150,
+ /* 1260 */ 202, 125, 174, 175, 165, 165, 165, 193, 150, 165,
+ /* 1270 */ 165, 203, 165, 64, 165, 105, 106, 107, 84, 85,
+ /* 1280 */ 23, 111, 25, 165, 193, 150, 116, 93, 94, 95,
+ /* 1290 */ 227, 150, 98, 84, 85, 150, 150, 193, 135, 150,
+ /* 1300 */ 165, 150, 150, 94, 150, 150, 165, 98, 118, 139,
+ /* 1310 */ 165, 165, 23, 23, 165, 25, 165, 165, 150, 165,
+ /* 1320 */ 165, 150, 150, 129, 130, 131, 132, 133, 134, 104,
+ /* 1330 */ 150, 150, 150, 165, 150, 150, 165, 165, 129, 130,
+ /* 1340 */ 131, 210, 121, 157, 157, 165, 165, 165, 211, 165,
+ /* 1350 */ 165, 211, 210, 210, 65, 211, 104, 46, 184, 176,
+ /* 1360 */ 22, 103, 90, 230, 176, 176, 18, 156, 230, 178,
+ /* 1370 */ 157, 176, 179, 176, 176, 176, 44, 238, 156, 179,
+ /* 1380 */ 184, 157, 156, 135, 157, 157, 239, 156, 66, 157,
+ /* 1390 */ 189, 189, 22, 157, 219, 18, 192, 192, 192, 192,
+ /* 1400 */ 157, 189, 199, 39, 157, 241, 241, 199, 157, 37,
+ /* 1410 */ 244, 250, 1, 164, 180, 180, 247, 15, 23, 22,
+ /* 1420 */ 118, 118, 118, 118, 118, 98, 113, 22, 22, 219,
+ /* 1430 */ 23, 23, 11, 23, 22, 34, 120, 23, 25, 23,
+ /* 1440 */ 25, 22, 25, 34, 118, 23, 23, 27, 50, 22,
+ /* 1450 */ 50, 22, 34, 23, 22, 22, 22, 102, 109, 19,
+ /* 1460 */ 24, 20, 38, 104, 25, 104, 138, 22, 42, 5,
+ /* 1470 */ 1, 108, 127, 74, 22, 50, 119, 74, 1, 16,
+ /* 1480 */ 20, 121, 51, 108, 119, 57, 51, 22, 16, 127,
+ /* 1490 */ 23, 15, 140, 22, 128, 3, 251, 4, 251, 251,
+ /* 1500 */ 63,
+};
+#define YY_SHIFT_USE_DFLT (-111)
+#define YY_SHIFT_MAX 405
static const short yy_shift_ofst[] = {
- /* 0 */ 23, 1038, 1040, -19, 1040, 1164, 1164, 187, 78, 243,
- /* 10 */ 119, 1164, 1164, 1164, 1164, 1164, -48, 266, 347, 554,
- /* 20 */ 148, 19, 19, -107, 50, 188, 257, 330, 403, 472,
- /* 30 */ 541, 610, 679, 748, 817, 748, 748, 748, 748, 748,
- /* 40 */ 748, 748, 748, 748, 748, 748, 748, 748, 748, 748,
- /* 50 */ 748, 748, 748, 886, 955, 955, 1141, 1164, 1164, 1164,
- /* 60 */ 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164,
- /* 70 */ 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164,
- /* 80 */ 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164,
- /* 90 */ 1164, 1164, 1164, 1164, 1164, 1164, 1164, -64, -64, -1,
- /* 100 */ -1, 52, 6, 160, 400, 956, 554, 554, 25, 148,
- /* 110 */ -75, -108, -108, -108, 80, 124, 338, 338, 504, 540,
- /* 120 */ 647, 574, 554, 574, 574, 554, 554, 554, 554, 554,
- /* 130 */ 554, 554, 554, 554, 554, 554, 554, 554, 554, 554,
- /* 140 */ 554, 554, 545, 662, -107, -107, -107, -108, -108, -108,
- /* 150 */ -21, -21, 131, 212, 470, 418, 479, 484, 557, 544,
- /* 160 */ 546, 482, 548, 552, 559, 645, 554, 554, 554, 554,
- /* 170 */ 554, 761, 554, 554, 642, 554, 554, 759, 554, 554,
- /* 180 */ 554, 554, 554, 463, 463, 463, 554, 554, 554, 419,
- /* 190 */ 554, 554, 419, 554, 686, 597, 554, 554, 419, 554,
- /* 200 */ 554, 554, 419, 554, 554, 554, 419, 419, 554, 554,
- /* 210 */ 554, 554, 554, 766, 327, 201, 148, 730, 730, 788,
- /* 220 */ 889, 889, 683, 889, 962, 889, 148, 889, 148, 115,
- /* 230 */ 32, 683, 683, 32, 1131, 1131, 1131, 1131, 1144, 1144,
- /* 240 */ 1139, -107, 1049, 1044, 1054, 1058, 1057, 1051, 1076, 1076,
- /* 250 */ 1093, 1077, 1093, 1077, 1093, 1077, 1095, 1095, 1165, 1095,
- /* 260 */ 1111, 1095, 1190, 1127, 1127, 1165, 1095, 1095, 1095, 1190,
- /* 270 */ 1200, 1076, 1200, 1076, 1200, 1076, 1076, 1199, 1109, 1200,
- /* 280 */ 1076, 1186, 1186, 1230, 1049, 1076, 1240, 1240, 1240, 1240,
- /* 290 */ 1049, 1186, 1230, 1076, 1231, 1231, 1076, 1076, 1137, -108,
- /* 300 */ -108, -108, -108, -108, 466, 575, 617, 785, 755, 901,
- /* 310 */ 957, 965, 271, 920, 963, 966, 970, 1045, 1052, 1059,
- /* 320 */ 1060, 1075, 1034, 1081, 1041, 1282, 1269, 1262, 1171, 1172,
- /* 330 */ 1174, 1176, 1203, 1189, 1278, 1279, 1280, 1283, 1290, 1284,
- /* 340 */ 1281, 1286, 1285, 1289, 1288, 1188, 1291, 1195, 1288, 1192,
- /* 350 */ 1293, 1198, 1202, 1206, 1295, 1299, 1292, 1277, 1303, 1287,
- /* 360 */ 1304, 1305, 1307, 1308, 1294, 1309, 1233, 1227, 1316, 1317,
- /* 370 */ 1312, 1237, 1300, 1296, 1297, 1315, 1298, 1205, 1242, 1322,
- /* 380 */ 1342, 1347, 1244, 1301, 1302, 1225, 1330, 1238, 1352, 1338,
- /* 390 */ 1236, 1337, 1243, 1253, 1234, 1339, 1235, 1340, 1348, 1306,
- /* 400 */ 1349, 1228, 1346, 1366, 1367,
-};
-#define YY_REDUCE_USE_DFLT (-142)
+ /* 0 */ 187, 1061, 1170, 1061, 1194, 1194, -2, 64, -19, 1194,
+ /* 10 */ 1194, 1194, 1194, 1194, 275, 358, 1, 125, 1076, 1194,
+ /* 20 */ 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194,
+ /* 30 */ 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194,
+ /* 40 */ 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194,
+ /* 50 */ 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, -48,
+ /* 60 */ 206, 1, 1, 124, 584, 584, -110, 53, 197, 269,
+ /* 70 */ 341, 413, 485, 557, 629, 701, 773, 845, 773, 773,
+ /* 80 */ 773, 773, 773, 773, 773, 773, 773, 773, 773, 773,
+ /* 90 */ 773, 773, 773, 773, 773, 773, 917, 989, 989, -67,
+ /* 100 */ -67, -1, -1, 55, 25, 386, 1, 1, 1, 1,
+ /* 110 */ 1, 634, 663, 1, 1, 1, 1, 1, 1, 1,
+ /* 120 */ 1, 1, 1, 1, 1, 1, 226, 124, -17, -111,
+ /* 130 */ -111, -111, 1209, 81, 375, 483, 488, 496, 90, 567,
+ /* 140 */ 567, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* 150 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* 160 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* 170 */ 1, 1, 1, 1, 807, 949, 615, 372, 372, 372,
+ /* 180 */ 559, 113, -110, -110, -110, -111, -111, -111, 198, 198,
+ /* 190 */ 266, 347, 574, 644, 713, 192, 789, 416, 937, 856,
+ /* 200 */ 632, 52, 997, 997, 997, 211, 211, 492, 691, 211,
+ /* 210 */ 211, 211, 211, 641, 765, -13, 124, 830, 830, 604,
+ /* 220 */ 501, 501, 350, 501, 627, 501, 124, 501, 124, 844,
+ /* 230 */ 915, 350, 350, 915, 1030, 1030, 1030, 1030, 1078, 1078,
+ /* 240 */ 1132, -110, 1040, 1062, 1064, 1130, 1136, 1163, 1190, 1190,
+ /* 250 */ 1225, 1221, 1225, 1221, 1225, 1221, 1252, 1252, 1311, 1252,
+ /* 260 */ 1258, 1252, 1338, 1272, 1272, 1311, 1252, 1252, 1252, 1338,
+ /* 270 */ 1348, 1190, 1348, 1190, 1348, 1190, 1190, 1332, 1248, 1348,
+ /* 280 */ 1190, 1322, 1322, 1370, 1040, 1190, 1377, 1377, 1377, 1377,
+ /* 290 */ 1040, 1322, 1370, 1190, 1364, 1364, 1190, 1190, 1372, -111,
+ /* 300 */ -111, -111, -111, -111, 623, 1066, 912, 315, 500, 808,
+ /* 310 */ 1020, 914, 974, 928, 1024, 1097, 1153, 1192, 1219, 1220,
+ /* 320 */ 1257, 1125, 1290, 1289, 1411, 1402, 1395, 1397, 1302, 1303,
+ /* 330 */ 1304, 1305, 1306, 1327, 1313, 1405, 1407, 1408, 1406, 1421,
+ /* 340 */ 1412, 1410, 1413, 1414, 1416, 1415, 1401, 1417, 1409, 1415,
+ /* 350 */ 1316, 1419, 1418, 1420, 1326, 1422, 1423, 1424, 1398, 1427,
+ /* 360 */ 1400, 1429, 1430, 1432, 1433, 1425, 1434, 1355, 1349, 1440,
+ /* 370 */ 1441, 1436, 1359, 1426, 1428, 1431, 1439, 1435, 1328, 1361,
+ /* 380 */ 1445, 1464, 1469, 1363, 1399, 1403, 1345, 1452, 1357, 1477,
+ /* 390 */ 1463, 1360, 1460, 1365, 1375, 1362, 1465, 1366, 1467, 1472,
+ /* 400 */ 1437, 1476, 1352, 1471, 1492, 1493,
+};
+#define YY_REDUCE_USE_DFLT (-180)
#define YY_REDUCE_MAX 303
static const short yy_reduce_ofst[] = {
- /* 0 */ -141, -49, 140, 77, 198, 67, 75, -8, 66, 225,
- /* 10 */ 165, 142, 209, 277, 279, 281, 130, 286, 81, 275,
- /* 20 */ 196, 288, 293, 228, 83, 83, 83, 83, 83, 83,
- /* 30 */ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- /* 40 */ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- /* 50 */ 83, 83, 83, 83, 83, 83, 349, 467, 493, 536,
- /* 60 */ 555, 558, 561, 563, 565, 567, 605, 618, 622, 624,
- /* 70 */ 626, 630, 633, 636, 674, 687, 691, 693, 695, 699,
- /* 80 */ 704, 743, 756, 760, 762, 764, 768, 773, 775, 812,
- /* 90 */ 825, 829, 831, 833, 837, 842, 844, 83, 83, 83,
- /* 100 */ 83, -17, 83, 83, 333, 361, 22, 566, 83, -124,
- /* 110 */ 83, 83, 83, 83, 609, 1, 481, 517, 475, 475,
- /* 120 */ 625, 220, -45, 709, 774, 417, 729, 757, 758, 384,
- /* 130 */ 231, 826, 214, 371, 512, 658, 863, 869, 881, 894,
- /* 140 */ 637, 895, 301, 612, 752, 887, 888, 90, 650, 593,
- /* 150 */ -100, -79, -59, -7, 38, 87, 38, 38, 101, 224,
- /* 160 */ 270, 297, 38, 290, 355, 430, 398, 451, 631, 696,
- /* 170 */ 702, 436, 355, 707, 469, 635, 771, 290, 790, 834,
- /* 180 */ 847, 859, 915, 727, 890, 896, 921, 929, 939, 38,
- /* 190 */ 942, 945, 38, 946, 864, 866, 958, 959, 38, 960,
- /* 200 */ 961, 964, 38, 967, 968, 969, 38, 38, 973, 974,
- /* 210 */ 975, 976, 977, 954, 917, 916, 950, 884, 897, 893,
- /* 220 */ 952, 971, 925, 972, 953, 978, 979, 980, 984, 981,
- /* 230 */ 938, 930, 931, 947, 994, 1001, 1003, 1006, 1008, 1011,
- /* 240 */ 1007, 985, 982, 983, 987, 988, 986, 990, 1037, 1039,
- /* 250 */ 991, 989, 992, 993, 995, 996, 1030, 1032, 1026, 1035,
- /* 260 */ 1036, 1042, 1043, 997, 998, 1046, 1053, 1055, 1062, 1056,
- /* 270 */ 1064, 1079, 1065, 1082, 1084, 1085, 1086, 1010, 1012, 1089,
- /* 280 */ 1092, 1063, 1069, 1047, 1066, 1097, 1070, 1071, 1072, 1087,
- /* 290 */ 1068, 1080, 1061, 1104, 1048, 1050, 1119, 1120, 1067, 1117,
- /* 300 */ 1102, 1103, 1073, 1074,
+ /* 0 */ -141, 82, 154, 284, 12, 75, 69, 73, -59, 145,
+ /* 10 */ 159, 229, 213, 218, 346, 285, 306, 302, 355, 363,
+ /* 20 */ 439, 444, 446, 486, 499, 505, 516, 558, 572, 577,
+ /* 30 */ 579, 590, 630, 643, 649, 661, 702, 715, 721, 723,
+ /* 40 */ 734, 774, 787, 793, 805, 846, 859, 865, 877, 881,
+ /* 50 */ 934, 936, 963, 967, 969, 998, 1053, 1072, 1088, -179,
+ /* 60 */ 850, 342, 381, 85, 89, 430, 600, 2, 2, 2,
+ /* 70 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ /* 80 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ /* 90 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ /* 100 */ 2, 2, 2, 121, 2, 2, 437, 650, 718, 720,
+ /* 110 */ 788, -21, 231, 956, 737, 791, -47, 741, 942, 986,
+ /* 120 */ 1003, 1047, 1074, 1091, 442, 1104, 2, 382, 2, 2,
+ /* 130 */ 2, 2, 196, 126, 580, 669, 716, 863, 885, 544,
+ /* 140 */ 571, 935, 939, 966, 968, 1000, 885, 1002, 1036, 1069,
+ /* 150 */ 1099, 1100, 1101, 1105, 1107, 1109, 1118, 1135, 1141, 1145,
+ /* 160 */ 1146, 1149, 1151, 1152, 1154, 1155, 1168, 1171, 1172, 1180,
+ /* 170 */ 1181, 1182, 1184, 1185, 554, 554, 665, 379, 811, 888,
+ /* 180 */ -134, 246, 260, 534, 1004, 616, 668, 717, -98, -70,
+ /* 190 */ -54, 36, 41, 41, 41, 48, 41, 156, 149, 136,
+ /* 200 */ 234, 156, 212, 254, 268, 41, 41, 227, 310, 41,
+ /* 210 */ 41, 41, 41, 359, 392, 395, 491, 449, 452, 520,
+ /* 220 */ 589, 639, 548, 733, 656, 780, 726, 799, 785, 722,
+ /* 230 */ 680, 813, 820, 784, 899, 945, 965, 978, 972, 988,
+ /* 240 */ 970, 964, 990, 1026, 1032, 1058, 1068, 1063, 1186, 1187,
+ /* 250 */ 1131, 1137, 1142, 1140, 1143, 1144, 1183, 1188, 1174, 1189,
+ /* 260 */ 1191, 1195, 1193, 1133, 1138, 1196, 1197, 1198, 1199, 1200,
+ /* 270 */ 1211, 1213, 1222, 1224, 1226, 1227, 1228, 1139, 1147, 1231,
+ /* 280 */ 1232, 1201, 1202, 1175, 1203, 1236, 1204, 1205, 1206, 1207,
+ /* 290 */ 1208, 1212, 1210, 1243, 1164, 1165, 1247, 1251, 1166, 1249,
+ /* 300 */ 1234, 1235, 1169, 1161,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 615, 929, 848, 736, 929, 848, 929, 929, 875, 929,
- /* 10 */ 904, 846, 929, 929, 929, 929, 820, 929, 875, 929,
- /* 20 */ 652, 875, 875, 740, 771, 929, 929, 929, 929, 929,
- /* 30 */ 929, 929, 929, 772, 929, 850, 845, 841, 843, 842,
- /* 40 */ 849, 773, 762, 769, 776, 751, 888, 778, 779, 785,
- /* 50 */ 786, 905, 903, 808, 807, 826, 929, 929, 929, 929,
- /* 60 */ 929, 929, 929, 929, 929, 929, 929, 929, 929, 929,
- /* 70 */ 929, 929, 929, 929, 929, 929, 929, 929, 929, 929,
- /* 80 */ 929, 929, 929, 929, 929, 929, 929, 929, 929, 929,
- /* 90 */ 929, 929, 929, 929, 929, 929, 929, 810, 832, 809,
- /* 100 */ 819, 645, 811, 812, 705, 640, 929, 929, 813, 929,
- /* 110 */ 814, 827, 828, 829, 929, 929, 929, 929, 929, 929,
- /* 120 */ 615, 736, 929, 736, 736, 929, 929, 929, 929, 929,
- /* 130 */ 929, 929, 929, 929, 929, 929, 929, 929, 929, 929,
- /* 140 */ 929, 929, 929, 929, 929, 929, 929, 730, 740, 922,
- /* 150 */ 929, 929, 696, 929, 929, 929, 929, 929, 929, 929,
- /* 160 */ 929, 929, 929, 929, 929, 623, 621, 929, 929, 929,
- /* 170 */ 929, 728, 929, 929, 654, 929, 929, 738, 929, 929,
- /* 180 */ 929, 929, 929, 929, 929, 929, 929, 929, 929, 642,
- /* 190 */ 929, 929, 717, 929, 881, 929, 929, 929, 895, 929,
- /* 200 */ 929, 929, 893, 929, 929, 929, 719, 781, 861, 929,
- /* 210 */ 908, 910, 929, 929, 728, 737, 929, 929, 929, 844,
- /* 220 */ 765, 765, 753, 765, 675, 765, 929, 765, 929, 678,
- /* 230 */ 775, 753, 753, 775, 620, 620, 620, 620, 631, 631,
- /* 240 */ 695, 929, 775, 766, 768, 758, 770, 929, 744, 744,
- /* 250 */ 752, 757, 752, 757, 752, 757, 707, 707, 692, 707,
- /* 260 */ 678, 707, 854, 858, 858, 692, 707, 707, 707, 854,
- /* 270 */ 637, 744, 637, 744, 637, 744, 744, 885, 887, 637,
- /* 280 */ 744, 709, 709, 787, 775, 744, 716, 716, 716, 716,
- /* 290 */ 775, 709, 787, 744, 907, 907, 744, 744, 915, 662,
- /* 300 */ 680, 680, 922, 927, 929, 929, 929, 929, 794, 929,
- /* 310 */ 929, 929, 929, 929, 929, 929, 929, 929, 929, 929,
- /* 320 */ 929, 929, 868, 929, 929, 929, 629, 929, 799, 795,
- /* 330 */ 929, 796, 929, 722, 929, 929, 929, 929, 929, 929,
- /* 340 */ 929, 929, 929, 929, 847, 929, 759, 929, 767, 929,
- /* 350 */ 929, 929, 929, 929, 929, 929, 929, 929, 929, 929,
- /* 360 */ 929, 929, 929, 929, 929, 929, 929, 929, 929, 929,
- /* 370 */ 929, 929, 929, 929, 883, 884, 929, 929, 929, 929,
- /* 380 */ 929, 929, 929, 929, 929, 929, 929, 929, 929, 929,
- /* 390 */ 929, 929, 929, 929, 929, 929, 929, 929, 929, 914,
- /* 400 */ 929, 929, 917, 616, 929, 611, 613, 614, 618, 619,
- /* 410 */ 622, 649, 650, 651, 624, 625, 626, 627, 628, 630,
- /* 420 */ 634, 632, 633, 635, 641, 643, 661, 663, 647, 665,
- /* 430 */ 726, 727, 791, 720, 721, 725, 648, 802, 793, 797,
- /* 440 */ 798, 800, 801, 815, 816, 818, 824, 831, 834, 817,
- /* 450 */ 822, 823, 825, 830, 833, 723, 724, 837, 655, 656,
- /* 460 */ 659, 660, 871, 873, 872, 874, 658, 657, 803, 806,
- /* 470 */ 839, 840, 896, 897, 898, 899, 900, 835, 745, 838,
- /* 480 */ 821, 760, 763, 764, 761, 729, 739, 747, 748, 749,
- /* 490 */ 750, 734, 735, 741, 756, 789, 790, 754, 755, 742,
- /* 500 */ 743, 731, 732, 733, 836, 792, 804, 805, 666, 667,
- /* 510 */ 799, 668, 669, 670, 708, 711, 712, 713, 671, 690,
- /* 520 */ 693, 694, 672, 679, 673, 674, 681, 682, 683, 686,
- /* 530 */ 687, 688, 689, 684, 685, 855, 856, 859, 857, 676,
- /* 540 */ 677, 691, 664, 653, 646, 697, 700, 701, 702, 703,
- /* 550 */ 704, 706, 698, 699, 644, 636, 638, 746, 877, 886,
- /* 560 */ 882, 878, 879, 880, 639, 851, 852, 710, 783, 784,
- /* 570 */ 876, 889, 891, 788, 892, 894, 890, 919, 714, 715,
- /* 580 */ 718, 860, 901, 774, 777, 780, 782, 862, 863, 864,
- /* 590 */ 865, 866, 869, 870, 867, 902, 906, 909, 911, 912,
- /* 600 */ 913, 916, 918, 923, 924, 925, 928, 926, 617, 612,
+ /* 0 */ 618, 853, 934, 934, 853, 934, 934, 880, 741, 851,
+ /* 10 */ 934, 934, 934, 934, 934, 880, 934, 909, 934, 934,
+ /* 20 */ 934, 934, 934, 934, 934, 934, 934, 934, 934, 934,
+ /* 30 */ 934, 934, 934, 934, 934, 934, 934, 934, 934, 934,
+ /* 40 */ 934, 934, 934, 934, 934, 934, 934, 934, 934, 934,
+ /* 50 */ 934, 934, 934, 934, 934, 934, 934, 934, 934, 825,
+ /* 60 */ 934, 934, 934, 657, 880, 880, 745, 776, 934, 934,
+ /* 70 */ 934, 934, 934, 934, 934, 934, 777, 934, 855, 850,
+ /* 80 */ 846, 848, 847, 854, 778, 767, 774, 781, 756, 893,
+ /* 90 */ 783, 784, 790, 791, 910, 908, 813, 812, 831, 815,
+ /* 100 */ 837, 814, 824, 649, 816, 817, 934, 934, 934, 934,
+ /* 110 */ 934, 710, 644, 934, 934, 934, 934, 934, 934, 934,
+ /* 120 */ 934, 934, 934, 934, 934, 934, 818, 934, 819, 832,
+ /* 130 */ 833, 834, 934, 934, 934, 934, 934, 934, 934, 934,
+ /* 140 */ 934, 624, 934, 934, 934, 934, 934, 934, 934, 934,
+ /* 150 */ 934, 934, 934, 934, 934, 934, 934, 934, 934, 934,
+ /* 160 */ 934, 934, 934, 934, 934, 934, 934, 934, 934, 866,
+ /* 170 */ 934, 913, 915, 934, 934, 934, 618, 741, 741, 741,
+ /* 180 */ 934, 934, 934, 934, 934, 735, 745, 927, 934, 934,
+ /* 190 */ 701, 934, 934, 934, 934, 934, 934, 934, 626, 733,
+ /* 200 */ 659, 743, 934, 934, 934, 646, 722, 886, 934, 900,
+ /* 210 */ 898, 724, 786, 934, 733, 742, 934, 934, 934, 849,
+ /* 220 */ 770, 770, 758, 770, 680, 770, 934, 770, 934, 683,
+ /* 230 */ 780, 758, 758, 780, 623, 623, 623, 623, 634, 634,
+ /* 240 */ 700, 934, 780, 771, 773, 763, 775, 934, 749, 749,
+ /* 250 */ 757, 762, 757, 762, 757, 762, 712, 712, 697, 712,
+ /* 260 */ 683, 712, 859, 863, 863, 697, 712, 712, 712, 859,
+ /* 270 */ 641, 749, 641, 749, 641, 749, 749, 890, 892, 641,
+ /* 280 */ 749, 714, 714, 792, 780, 749, 721, 721, 721, 721,
+ /* 290 */ 780, 714, 792, 749, 912, 912, 749, 749, 920, 667,
+ /* 300 */ 685, 685, 927, 932, 934, 934, 934, 934, 934, 934,
+ /* 310 */ 934, 934, 934, 934, 934, 934, 934, 934, 934, 934,
+ /* 320 */ 934, 873, 934, 934, 934, 632, 934, 651, 799, 804,
+ /* 330 */ 800, 934, 801, 934, 727, 934, 934, 934, 934, 934,
+ /* 340 */ 934, 934, 934, 934, 934, 852, 934, 764, 934, 772,
+ /* 350 */ 934, 934, 934, 934, 934, 934, 934, 934, 934, 934,
+ /* 360 */ 934, 934, 934, 934, 934, 934, 934, 934, 934, 934,
+ /* 370 */ 934, 934, 934, 934, 934, 888, 889, 934, 934, 934,
+ /* 380 */ 934, 934, 934, 934, 934, 934, 934, 934, 934, 934,
+ /* 390 */ 934, 934, 934, 934, 934, 934, 934, 934, 934, 934,
+ /* 400 */ 919, 934, 934, 922, 619, 934, 614, 616, 617, 621,
+ /* 410 */ 622, 625, 651, 652, 654, 655, 656, 627, 628, 629,
+ /* 420 */ 630, 631, 633, 637, 635, 636, 638, 645, 647, 666,
+ /* 430 */ 668, 670, 731, 732, 796, 725, 726, 730, 653, 807,
+ /* 440 */ 798, 802, 803, 805, 806, 820, 821, 823, 829, 836,
+ /* 450 */ 839, 822, 827, 828, 830, 835, 838, 728, 729, 842,
+ /* 460 */ 660, 661, 664, 665, 876, 878, 877, 879, 663, 662,
+ /* 470 */ 808, 811, 844, 845, 901, 902, 903, 904, 905, 840,
+ /* 480 */ 750, 843, 826, 765, 768, 769, 766, 734, 744, 752,
+ /* 490 */ 753, 754, 755, 739, 740, 746, 761, 794, 795, 759,
+ /* 500 */ 760, 747, 748, 736, 737, 738, 841, 797, 809, 810,
+ /* 510 */ 671, 672, 804, 673, 674, 675, 713, 716, 717, 718,
+ /* 520 */ 676, 695, 698, 699, 677, 684, 678, 679, 686, 687,
+ /* 530 */ 688, 691, 692, 693, 694, 689, 690, 860, 861, 864,
+ /* 540 */ 862, 681, 682, 696, 669, 658, 650, 702, 705, 706,
+ /* 550 */ 707, 708, 709, 711, 703, 704, 648, 639, 642, 751,
+ /* 560 */ 882, 891, 887, 883, 884, 885, 643, 856, 857, 715,
+ /* 570 */ 788, 789, 881, 894, 896, 793, 897, 899, 895, 924,
+ /* 580 */ 640, 719, 720, 723, 865, 906, 779, 782, 785, 787,
+ /* 590 */ 867, 868, 869, 870, 871, 874, 875, 872, 907, 911,
+ /* 600 */ 914, 916, 917, 918, 921, 923, 928, 929, 930, 933,
+ /* 610 */ 931, 620, 615,
};
#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0]))
/* The next table maps tokens into fallback tokens. If a construct
@@ -83519,14 +84741,14 @@
26, /* IMMEDIATE => ID */
26, /* EXCLUSIVE => ID */
0, /* COMMIT => nothing */
26, /* END => ID */
- 0, /* ROLLBACK => nothing */
- 0, /* SAVEPOINT => nothing */
- 0, /* RELEASE => nothing */
+ 26, /* ROLLBACK => ID */
+ 26, /* SAVEPOINT => ID */
+ 26, /* RELEASE => ID */
0, /* TO => nothing */
- 0, /* CREATE => nothing */
0, /* TABLE => nothing */
+ 0, /* CREATE => nothing */
26, /* IF => ID */
0, /* NOT => nothing */
0, /* EXISTS => nothing */
26, /* TEMP => ID */
@@ -83534,16 +84756,19 @@
0, /* RP => nothing */
0, /* AS => nothing */
0, /* COMMA => nothing */
0, /* ID => nothing */
+ 0, /* INDEXED => nothing */
26, /* ABORT => ID */
26, /* AFTER => ID */
26, /* ANALYZE => ID */
26, /* ASC => ID */
26, /* ATTACH => ID */
26, /* BEFORE => ID */
+ 26, /* BY => ID */
26, /* CASCADE => ID */
26, /* CAST => ID */
+ 26, /* COLUMNKW => ID */
26, /* CONFLICT => ID */
26, /* DATABASE => ID */
26, /* DESC => ID */
26, /* DETACH => ID */
@@ -83625,10 +84850,8 @@
0, /* DISTINCT => nothing */
0, /* DOT => nothing */
0, /* FROM => nothing */
0, /* JOIN => nothing */
- 0, /* INDEXED => nothing */
- 0, /* BY => nothing */
0, /* USING => nothing */
0, /* ORDER => nothing */
0, /* GROUP => nothing */
0, /* HAVING => nothing */
@@ -83647,9 +84870,8 @@
0, /* ELSE => nothing */
0, /* INDEX => nothing */
0, /* ALTER => nothing */
0, /* ADD => nothing */
- 0, /* COLUMNKW => nothing */
};
#endif /* YYFALLBACK */
/* The following structure represents a single element of the
@@ -83729,67 +84951,67 @@
"$", "SEMI", "EXPLAIN", "QUERY",
"PLAN", "BEGIN", "TRANSACTION", "DEFERRED",
"IMMEDIATE", "EXCLUSIVE", "COMMIT", "END",
"ROLLBACK", "SAVEPOINT", "RELEASE", "TO",
- "CREATE", "TABLE", "IF", "NOT",
+ "TABLE", "CREATE", "IF", "NOT",
"EXISTS", "TEMP", "LP", "RP",
- "AS", "COMMA", "ID", "ABORT",
- "AFTER", "ANALYZE", "ASC", "ATTACH",
- "BEFORE", "CASCADE", "CAST", "CONFLICT",
- "DATABASE", "DESC", "DETACH", "EACH",
- "FAIL", "FOR", "IGNORE", "INITIALLY",
- "INSTEAD", "LIKE_KW", "MATCH", "KEY",
- "OF", "OFFSET", "PRAGMA", "RAISE",
- "REPLACE", "RESTRICT", "ROW", "TRIGGER",
- "VACUUM", "VIEW", "VIRTUAL", "REINDEX",
- "RENAME", "CTIME_KW", "ANY", "OR",
- "AND", "IS", "BETWEEN", "IN",
- "ISNULL", "NOTNULL", "NE", "EQ",
- "GT", "LE", "LT", "GE",
- "ESCAPE", "BITAND", "BITOR", "LSHIFT",
- "RSHIFT", "PLUS", "MINUS", "STAR",
- "SLASH", "REM", "CONCAT", "COLLATE",
- "UMINUS", "UPLUS", "BITNOT", "STRING",
- "JOIN_KW", "CONSTRAINT", "DEFAULT", "NULL",
- "PRIMARY", "UNIQUE", "CHECK", "REFERENCES",
- "AUTOINCR", "ON", "DELETE", "UPDATE",
- "INSERT", "SET", "DEFERRABLE", "FOREIGN",
- "DROP", "UNION", "ALL", "EXCEPT",
- "INTERSECT", "SELECT", "DISTINCT", "DOT",
- "FROM", "JOIN", "INDEXED", "BY",
- "USING", "ORDER", "GROUP", "HAVING",
- "LIMIT", "WHERE", "INTO", "VALUES",
- "INTEGER", "FLOAT", "BLOB", "REGISTER",
- "VARIABLE", "CASE", "WHEN", "THEN",
- "ELSE", "INDEX", "ALTER", "ADD",
- "COLUMNKW", "error", "input", "cmdlist",
+ "AS", "COMMA", "ID", "INDEXED",
+ "ABORT", "AFTER", "ANALYZE", "ASC",
+ "ATTACH", "BEFORE", "BY", "CASCADE",
+ "CAST", "COLUMNKW", "CONFLICT", "DATABASE",
+ "DESC", "DETACH", "EACH", "FAIL",
+ "FOR", "IGNORE", "INITIALLY", "INSTEAD",
+ "LIKE_KW", "MATCH", "KEY", "OF",
+ "OFFSET", "PRAGMA", "RAISE", "REPLACE",
+ "RESTRICT", "ROW", "TRIGGER", "VACUUM",
+ "VIEW", "VIRTUAL", "REINDEX", "RENAME",
+ "CTIME_KW", "ANY", "OR", "AND",
+ "IS", "BETWEEN", "IN", "ISNULL",
+ "NOTNULL", "NE", "EQ", "GT",
+ "LE", "LT", "GE", "ESCAPE",
+ "BITAND", "BITOR", "LSHIFT", "RSHIFT",
+ "PLUS", "MINUS", "STAR", "SLASH",
+ "REM", "CONCAT", "COLLATE", "UMINUS",
+ "UPLUS", "BITNOT", "STRING", "JOIN_KW",
+ "CONSTRAINT", "DEFAULT", "NULL", "PRIMARY",
+ "UNIQUE", "CHECK", "REFERENCES", "AUTOINCR",
+ "ON", "DELETE", "UPDATE", "INSERT",
+ "SET", "DEFERRABLE", "FOREIGN", "DROP",
+ "UNION", "ALL", "EXCEPT", "INTERSECT",
+ "SELECT", "DISTINCT", "DOT", "FROM",
+ "JOIN", "USING", "ORDER", "GROUP",
+ "HAVING", "LIMIT", "WHERE", "INTO",
+ "VALUES", "INTEGER", "FLOAT", "BLOB",
+ "REGISTER", "VARIABLE", "CASE", "WHEN",
+ "THEN", "ELSE", "INDEX", "ALTER",
+ "ADD", "error", "input", "cmdlist",
"ecmd", "explain", "cmdx", "cmd",
"transtype", "trans_opt", "nm", "savepoint_opt",
- "create_table", "create_table_args", "temp", "ifnotexists",
- "dbnm", "columnlist", "conslist_opt", "select",
- "column", "columnid", "type", "carglist",
- "id", "ids", "typetoken", "typename",
- "signed", "plus_num", "minus_num", "carg",
- "ccons", "term", "expr", "onconf",
- "sortorder", "autoinc", "idxlist_opt", "refargs",
- "defer_subclause", "refarg", "refact", "init_deferred_pred_opt",
- "conslist", "tcons", "idxlist", "defer_subclause_opt",
- "orconf", "resolvetype", "raisetype", "ifexists",
- "fullname", "oneselect", "multiselect_op", "distinct",
- "selcollist", "from", "where_opt", "groupby_opt",
- "having_opt", "orderby_opt", "limit_opt", "sclp",
- "as", "seltablist", "stl_prefix", "joinop",
- "indexed_opt", "on_opt", "using_opt", "joinop2",
- "inscollist", "sortlist", "sortitem", "nexprlist",
- "setlist", "insert_cmd", "inscollist_opt", "itemlist",
- "exprlist", "likeop", "escape", "between_op",
- "in_op", "case_operand", "case_exprlist", "case_else",
- "uniqueflag", "collate", "nmnum", "plus_opt",
- "number", "trigger_decl", "trigger_cmd_list", "trigger_time",
- "trigger_event", "foreach_clause", "when_clause", "trigger_cmd",
- "database_kw_opt", "key_opt", "add_column_fullname", "kwcolumn_opt",
- "create_vtab", "vtabarglist", "vtabarg", "vtabargtoken",
- "lp", "anylist",
+ "create_table", "create_table_args", "createkw", "temp",
+ "ifnotexists", "dbnm", "columnlist", "conslist_opt",
+ "select", "column", "columnid", "type",
+ "carglist", "id", "ids", "typetoken",
+ "typename", "signed", "plus_num", "minus_num",
+ "carg", "ccons", "term", "expr",
+ "onconf", "sortorder", "autoinc", "idxlist_opt",
+ "refargs", "defer_subclause", "refarg", "refact",
+ "init_deferred_pred_opt", "conslist", "tcons", "idxlist",
+ "defer_subclause_opt", "orconf", "resolvetype", "raisetype",
+ "ifexists", "fullname", "oneselect", "multiselect_op",
+ "distinct", "selcollist", "from", "where_opt",
+ "groupby_opt", "having_opt", "orderby_opt", "limit_opt",
+ "sclp", "as", "seltablist", "stl_prefix",
+ "joinop", "indexed_opt", "on_opt", "using_opt",
+ "joinop2", "inscollist", "sortlist", "sortitem",
+ "nexprlist", "setlist", "insert_cmd", "inscollist_opt",
+ "itemlist", "exprlist", "likeop", "escape",
+ "between_op", "in_op", "case_operand", "case_exprlist",
+ "case_else", "uniqueflag", "collate", "nmnum",
+ "plus_opt", "number", "trigger_decl", "trigger_cmd_list",
+ "trigger_time", "trigger_event", "foreach_clause", "when_clause",
+ "trigger_cmd", "database_kw_opt", "key_opt", "add_column_fullname",
+ "kwcolumn_opt", "create_vtab", "vtabarglist", "vtabarg",
+ "vtabargtoken", "lp", "anylist",
};
#endif /* NDEBUG */
#ifndef NDEBUG
@@ -83821,301 +85043,303 @@
/* 22 */ "cmd ::= SAVEPOINT nm",
/* 23 */ "cmd ::= RELEASE savepoint_opt nm",
/* 24 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm",
/* 25 */ "cmd ::= create_table create_table_args",
- /* 26 */ "create_table ::= CREATE temp TABLE ifnotexists nm dbnm",
- /* 27 */ "ifnotexists ::=",
- /* 28 */ "ifnotexists ::= IF NOT EXISTS",
- /* 29 */ "temp ::= TEMP",
- /* 30 */ "temp ::=",
- /* 31 */ "create_table_args ::= LP columnlist conslist_opt RP",
- /* 32 */ "create_table_args ::= AS select",
- /* 33 */ "columnlist ::= columnlist COMMA column",
- /* 34 */ "columnlist ::= column",
- /* 35 */ "column ::= columnid type carglist",
- /* 36 */ "columnid ::= nm",
- /* 37 */ "id ::= ID",
- /* 38 */ "ids ::= ID|STRING",
- /* 39 */ "nm ::= ID",
- /* 40 */ "nm ::= STRING",
- /* 41 */ "nm ::= JOIN_KW",
- /* 42 */ "type ::=",
- /* 43 */ "type ::= typetoken",
- /* 44 */ "typetoken ::= typename",
- /* 45 */ "typetoken ::= typename LP signed RP",
- /* 46 */ "typetoken ::= typename LP signed COMMA signed RP",
- /* 47 */ "typename ::= ids",
- /* 48 */ "typename ::= typename ids",
- /* 49 */ "signed ::= plus_num",
- /* 50 */ "signed ::= minus_num",
- /* 51 */ "carglist ::= carglist carg",
- /* 52 */ "carglist ::=",
- /* 53 */ "carg ::= CONSTRAINT nm ccons",
- /* 54 */ "carg ::= ccons",
- /* 55 */ "ccons ::= DEFAULT term",
- /* 56 */ "ccons ::= DEFAULT LP expr RP",
- /* 57 */ "ccons ::= DEFAULT PLUS term",
- /* 58 */ "ccons ::= DEFAULT MINUS term",
- /* 59 */ "ccons ::= DEFAULT id",
- /* 60 */ "ccons ::= NULL onconf",
- /* 61 */ "ccons ::= NOT NULL onconf",
- /* 62 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
- /* 63 */ "ccons ::= UNIQUE onconf",
- /* 64 */ "ccons ::= CHECK LP expr RP",
- /* 65 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
- /* 66 */ "ccons ::= defer_subclause",
- /* 67 */ "ccons ::= COLLATE ids",
- /* 68 */ "autoinc ::=",
- /* 69 */ "autoinc ::= AUTOINCR",
- /* 70 */ "refargs ::=",
- /* 71 */ "refargs ::= refargs refarg",
- /* 72 */ "refarg ::= MATCH nm",
- /* 73 */ "refarg ::= ON DELETE refact",
- /* 74 */ "refarg ::= ON UPDATE refact",
- /* 75 */ "refarg ::= ON INSERT refact",
- /* 76 */ "refact ::= SET NULL",
- /* 77 */ "refact ::= SET DEFAULT",
- /* 78 */ "refact ::= CASCADE",
- /* 79 */ "refact ::= RESTRICT",
- /* 80 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
- /* 81 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
- /* 82 */ "init_deferred_pred_opt ::=",
- /* 83 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
- /* 84 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
- /* 85 */ "conslist_opt ::=",
- /* 86 */ "conslist_opt ::= COMMA conslist",
- /* 87 */ "conslist ::= conslist COMMA tcons",
- /* 88 */ "conslist ::= conslist tcons",
- /* 89 */ "conslist ::= tcons",
- /* 90 */ "tcons ::= CONSTRAINT nm",
- /* 91 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
- /* 92 */ "tcons ::= UNIQUE LP idxlist RP onconf",
- /* 93 */ "tcons ::= CHECK LP expr RP onconf",
- /* 94 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
- /* 95 */ "defer_subclause_opt ::=",
- /* 96 */ "defer_subclause_opt ::= defer_subclause",
- /* 97 */ "onconf ::=",
- /* 98 */ "onconf ::= ON CONFLICT resolvetype",
- /* 99 */ "orconf ::=",
- /* 100 */ "orconf ::= OR resolvetype",
- /* 101 */ "resolvetype ::= raisetype",
- /* 102 */ "resolvetype ::= IGNORE",
- /* 103 */ "resolvetype ::= REPLACE",
- /* 104 */ "cmd ::= DROP TABLE ifexists fullname",
- /* 105 */ "ifexists ::= IF EXISTS",
- /* 106 */ "ifexists ::=",
- /* 107 */ "cmd ::= CREATE temp VIEW ifnotexists nm dbnm AS select",
- /* 108 */ "cmd ::= DROP VIEW ifexists fullname",
- /* 109 */ "cmd ::= select",
- /* 110 */ "select ::= oneselect",
- /* 111 */ "select ::= select multiselect_op oneselect",
- /* 112 */ "multiselect_op ::= UNION",
- /* 113 */ "multiselect_op ::= UNION ALL",
- /* 114 */ "multiselect_op ::= EXCEPT|INTERSECT",
- /* 115 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
- /* 116 */ "distinct ::= DISTINCT",
- /* 117 */ "distinct ::= ALL",
- /* 118 */ "distinct ::=",
- /* 119 */ "sclp ::= selcollist COMMA",
- /* 120 */ "sclp ::=",
- /* 121 */ "selcollist ::= sclp expr as",
- /* 122 */ "selcollist ::= sclp STAR",
- /* 123 */ "selcollist ::= sclp nm DOT STAR",
- /* 124 */ "as ::= AS nm",
- /* 125 */ "as ::= ids",
- /* 126 */ "as ::=",
- /* 127 */ "from ::=",
- /* 128 */ "from ::= FROM seltablist",
- /* 129 */ "stl_prefix ::= seltablist joinop",
- /* 130 */ "stl_prefix ::=",
- /* 131 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
- /* 132 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
- /* 133 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
- /* 134 */ "dbnm ::=",
- /* 135 */ "dbnm ::= DOT nm",
- /* 136 */ "fullname ::= nm dbnm",
- /* 137 */ "joinop ::= COMMA|JOIN",
- /* 138 */ "joinop ::= JOIN_KW JOIN",
- /* 139 */ "joinop ::= JOIN_KW nm JOIN",
- /* 140 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 141 */ "on_opt ::= ON expr",
- /* 142 */ "on_opt ::=",
- /* 143 */ "indexed_opt ::=",
- /* 144 */ "indexed_opt ::= INDEXED BY nm",
- /* 145 */ "indexed_opt ::= NOT INDEXED",
- /* 146 */ "using_opt ::= USING LP inscollist RP",
- /* 147 */ "using_opt ::=",
- /* 148 */ "orderby_opt ::=",
- /* 149 */ "orderby_opt ::= ORDER BY sortlist",
- /* 150 */ "sortlist ::= sortlist COMMA sortitem sortorder",
- /* 151 */ "sortlist ::= sortitem sortorder",
- /* 152 */ "sortitem ::= expr",
- /* 153 */ "sortorder ::= ASC",
- /* 154 */ "sortorder ::= DESC",
- /* 155 */ "sortorder ::=",
- /* 156 */ "groupby_opt ::=",
- /* 157 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 158 */ "having_opt ::=",
- /* 159 */ "having_opt ::= HAVING expr",
- /* 160 */ "limit_opt ::=",
- /* 161 */ "limit_opt ::= LIMIT expr",
- /* 162 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 163 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 164 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt",
- /* 165 */ "where_opt ::=",
- /* 166 */ "where_opt ::= WHERE expr",
- /* 167 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt",
- /* 168 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 169 */ "setlist ::= nm EQ expr",
- /* 170 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP",
- /* 171 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
- /* 172 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
- /* 173 */ "insert_cmd ::= INSERT orconf",
- /* 174 */ "insert_cmd ::= REPLACE",
- /* 175 */ "itemlist ::= itemlist COMMA expr",
- /* 176 */ "itemlist ::= expr",
- /* 177 */ "inscollist_opt ::=",
- /* 178 */ "inscollist_opt ::= LP inscollist RP",
- /* 179 */ "inscollist ::= inscollist COMMA nm",
- /* 180 */ "inscollist ::= nm",
- /* 181 */ "expr ::= term",
- /* 182 */ "expr ::= LP expr RP",
- /* 183 */ "term ::= NULL",
- /* 184 */ "expr ::= ID",
- /* 185 */ "expr ::= JOIN_KW",
- /* 186 */ "expr ::= nm DOT nm",
- /* 187 */ "expr ::= nm DOT nm DOT nm",
- /* 188 */ "term ::= INTEGER|FLOAT|BLOB",
- /* 189 */ "term ::= STRING",
- /* 190 */ "expr ::= REGISTER",
- /* 191 */ "expr ::= VARIABLE",
- /* 192 */ "expr ::= expr COLLATE ids",
- /* 193 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 194 */ "expr ::= ID LP distinct exprlist RP",
- /* 195 */ "expr ::= ID LP STAR RP",
- /* 196 */ "term ::= CTIME_KW",
- /* 197 */ "expr ::= expr AND expr",
- /* 198 */ "expr ::= expr OR expr",
- /* 199 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 200 */ "expr ::= expr EQ|NE expr",
- /* 201 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 202 */ "expr ::= expr PLUS|MINUS expr",
- /* 203 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 204 */ "expr ::= expr CONCAT expr",
- /* 205 */ "likeop ::= LIKE_KW",
- /* 206 */ "likeop ::= NOT LIKE_KW",
- /* 207 */ "likeop ::= MATCH",
- /* 208 */ "likeop ::= NOT MATCH",
- /* 209 */ "escape ::= ESCAPE expr",
- /* 210 */ "escape ::=",
- /* 211 */ "expr ::= expr likeop expr escape",
- /* 212 */ "expr ::= expr ISNULL|NOTNULL",
- /* 213 */ "expr ::= expr IS NULL",
- /* 214 */ "expr ::= expr NOT NULL",
- /* 215 */ "expr ::= expr IS NOT NULL",
- /* 216 */ "expr ::= NOT expr",
- /* 217 */ "expr ::= BITNOT expr",
- /* 218 */ "expr ::= MINUS expr",
- /* 219 */ "expr ::= PLUS expr",
- /* 220 */ "between_op ::= BETWEEN",
- /* 221 */ "between_op ::= NOT BETWEEN",
- /* 222 */ "expr ::= expr between_op expr AND expr",
- /* 223 */ "in_op ::= IN",
- /* 224 */ "in_op ::= NOT IN",
- /* 225 */ "expr ::= expr in_op LP exprlist RP",
- /* 226 */ "expr ::= LP select RP",
- /* 227 */ "expr ::= expr in_op LP select RP",
- /* 228 */ "expr ::= expr in_op nm dbnm",
- /* 229 */ "expr ::= EXISTS LP select RP",
- /* 230 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 231 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 232 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 233 */ "case_else ::= ELSE expr",
- /* 234 */ "case_else ::=",
- /* 235 */ "case_operand ::= expr",
- /* 236 */ "case_operand ::=",
- /* 237 */ "exprlist ::= nexprlist",
- /* 238 */ "exprlist ::=",
- /* 239 */ "nexprlist ::= nexprlist COMMA expr",
- /* 240 */ "nexprlist ::= expr",
- /* 241 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
- /* 242 */ "uniqueflag ::= UNIQUE",
- /* 243 */ "uniqueflag ::=",
- /* 244 */ "idxlist_opt ::=",
- /* 245 */ "idxlist_opt ::= LP idxlist RP",
- /* 246 */ "idxlist ::= idxlist COMMA nm collate sortorder",
- /* 247 */ "idxlist ::= nm collate sortorder",
- /* 248 */ "collate ::=",
- /* 249 */ "collate ::= COLLATE ids",
- /* 250 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 251 */ "cmd ::= VACUUM",
- /* 252 */ "cmd ::= VACUUM nm",
- /* 253 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 254 */ "cmd ::= PRAGMA nm dbnm EQ ON",
- /* 255 */ "cmd ::= PRAGMA nm dbnm EQ DELETE",
- /* 256 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 257 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 258 */ "cmd ::= PRAGMA nm dbnm",
- /* 259 */ "nmnum ::= plus_num",
- /* 260 */ "nmnum ::= nm",
- /* 261 */ "plus_num ::= plus_opt number",
- /* 262 */ "minus_num ::= MINUS number",
- /* 263 */ "number ::= INTEGER|FLOAT",
- /* 264 */ "plus_opt ::= PLUS",
- /* 265 */ "plus_opt ::=",
- /* 266 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
- /* 267 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 268 */ "trigger_time ::= BEFORE",
- /* 269 */ "trigger_time ::= AFTER",
- /* 270 */ "trigger_time ::= INSTEAD OF",
- /* 271 */ "trigger_time ::=",
- /* 272 */ "trigger_event ::= DELETE|INSERT",
- /* 273 */ "trigger_event ::= UPDATE",
- /* 274 */ "trigger_event ::= UPDATE OF inscollist",
- /* 275 */ "foreach_clause ::=",
- /* 276 */ "foreach_clause ::= FOR EACH ROW",
- /* 277 */ "when_clause ::=",
- /* 278 */ "when_clause ::= WHEN expr",
- /* 279 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 280 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 281 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
- /* 282 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
- /* 283 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
- /* 284 */ "trigger_cmd ::= DELETE FROM nm where_opt",
- /* 285 */ "trigger_cmd ::= select",
- /* 286 */ "expr ::= RAISE LP IGNORE RP",
- /* 287 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 288 */ "raisetype ::= ROLLBACK",
- /* 289 */ "raisetype ::= ABORT",
- /* 290 */ "raisetype ::= FAIL",
- /* 291 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 292 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 293 */ "cmd ::= DETACH database_kw_opt expr",
- /* 294 */ "key_opt ::=",
- /* 295 */ "key_opt ::= KEY expr",
- /* 296 */ "database_kw_opt ::= DATABASE",
- /* 297 */ "database_kw_opt ::=",
- /* 298 */ "cmd ::= REINDEX",
- /* 299 */ "cmd ::= REINDEX nm dbnm",
- /* 300 */ "cmd ::= ANALYZE",
- /* 301 */ "cmd ::= ANALYZE nm dbnm",
- /* 302 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 303 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
- /* 304 */ "add_column_fullname ::= fullname",
- /* 305 */ "kwcolumn_opt ::=",
- /* 306 */ "kwcolumn_opt ::= COLUMNKW",
- /* 307 */ "cmd ::= create_vtab",
- /* 308 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 309 */ "create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm",
- /* 310 */ "vtabarglist ::= vtabarg",
- /* 311 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 312 */ "vtabarg ::=",
- /* 313 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 314 */ "vtabargtoken ::= ANY",
- /* 315 */ "vtabargtoken ::= lp anylist RP",
- /* 316 */ "lp ::= LP",
- /* 317 */ "anylist ::=",
- /* 318 */ "anylist ::= anylist ANY",
+ /* 26 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm",
+ /* 27 */ "createkw ::= CREATE",
+ /* 28 */ "ifnotexists ::=",
+ /* 29 */ "ifnotexists ::= IF NOT EXISTS",
+ /* 30 */ "temp ::= TEMP",
+ /* 31 */ "temp ::=",
+ /* 32 */ "create_table_args ::= LP columnlist conslist_opt RP",
+ /* 33 */ "create_table_args ::= AS select",
+ /* 34 */ "columnlist ::= columnlist COMMA column",
+ /* 35 */ "columnlist ::= column",
+ /* 36 */ "column ::= columnid type carglist",
+ /* 37 */ "columnid ::= nm",
+ /* 38 */ "id ::= ID",
+ /* 39 */ "id ::= INDEXED",
+ /* 40 */ "ids ::= ID|STRING",
+ /* 41 */ "nm ::= id",
+ /* 42 */ "nm ::= STRING",
+ /* 43 */ "nm ::= JOIN_KW",
+ /* 44 */ "type ::=",
+ /* 45 */ "type ::= typetoken",
+ /* 46 */ "typetoken ::= typename",
+ /* 47 */ "typetoken ::= typename LP signed RP",
+ /* 48 */ "typetoken ::= typename LP signed COMMA signed RP",
+ /* 49 */ "typename ::= ids",
+ /* 50 */ "typename ::= typename ids",
+ /* 51 */ "signed ::= plus_num",
+ /* 52 */ "signed ::= minus_num",
+ /* 53 */ "carglist ::= carglist carg",
+ /* 54 */ "carglist ::=",
+ /* 55 */ "carg ::= CONSTRAINT nm ccons",
+ /* 56 */ "carg ::= ccons",
+ /* 57 */ "ccons ::= DEFAULT term",
+ /* 58 */ "ccons ::= DEFAULT LP expr RP",
+ /* 59 */ "ccons ::= DEFAULT PLUS term",
+ /* 60 */ "ccons ::= DEFAULT MINUS term",
+ /* 61 */ "ccons ::= DEFAULT id",
+ /* 62 */ "ccons ::= NULL onconf",
+ /* 63 */ "ccons ::= NOT NULL onconf",
+ /* 64 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
+ /* 65 */ "ccons ::= UNIQUE onconf",
+ /* 66 */ "ccons ::= CHECK LP expr RP",
+ /* 67 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
+ /* 68 */ "ccons ::= defer_subclause",
+ /* 69 */ "ccons ::= COLLATE ids",
+ /* 70 */ "autoinc ::=",
+ /* 71 */ "autoinc ::= AUTOINCR",
+ /* 72 */ "refargs ::=",
+ /* 73 */ "refargs ::= refargs refarg",
+ /* 74 */ "refarg ::= MATCH nm",
+ /* 75 */ "refarg ::= ON DELETE refact",
+ /* 76 */ "refarg ::= ON UPDATE refact",
+ /* 77 */ "refarg ::= ON INSERT refact",
+ /* 78 */ "refact ::= SET NULL",
+ /* 79 */ "refact ::= SET DEFAULT",
+ /* 80 */ "refact ::= CASCADE",
+ /* 81 */ "refact ::= RESTRICT",
+ /* 82 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+ /* 83 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+ /* 84 */ "init_deferred_pred_opt ::=",
+ /* 85 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+ /* 86 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+ /* 87 */ "conslist_opt ::=",
+ /* 88 */ "conslist_opt ::= COMMA conslist",
+ /* 89 */ "conslist ::= conslist COMMA tcons",
+ /* 90 */ "conslist ::= conslist tcons",
+ /* 91 */ "conslist ::= tcons",
+ /* 92 */ "tcons ::= CONSTRAINT nm",
+ /* 93 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
+ /* 94 */ "tcons ::= UNIQUE LP idxlist RP onconf",
+ /* 95 */ "tcons ::= CHECK LP expr RP onconf",
+ /* 96 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
+ /* 97 */ "defer_subclause_opt ::=",
+ /* 98 */ "defer_subclause_opt ::= defer_subclause",
+ /* 99 */ "onconf ::=",
+ /* 100 */ "onconf ::= ON CONFLICT resolvetype",
+ /* 101 */ "orconf ::=",
+ /* 102 */ "orconf ::= OR resolvetype",
+ /* 103 */ "resolvetype ::= raisetype",
+ /* 104 */ "resolvetype ::= IGNORE",
+ /* 105 */ "resolvetype ::= REPLACE",
+ /* 106 */ "cmd ::= DROP TABLE ifexists fullname",
+ /* 107 */ "ifexists ::= IF EXISTS",
+ /* 108 */ "ifexists ::=",
+ /* 109 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select",
+ /* 110 */ "cmd ::= DROP VIEW ifexists fullname",
+ /* 111 */ "cmd ::= select",
+ /* 112 */ "select ::= oneselect",
+ /* 113 */ "select ::= select multiselect_op oneselect",
+ /* 114 */ "multiselect_op ::= UNION",
+ /* 115 */ "multiselect_op ::= UNION ALL",
+ /* 116 */ "multiselect_op ::= EXCEPT|INTERSECT",
+ /* 117 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+ /* 118 */ "distinct ::= DISTINCT",
+ /* 119 */ "distinct ::= ALL",
+ /* 120 */ "distinct ::=",
+ /* 121 */ "sclp ::= selcollist COMMA",
+ /* 122 */ "sclp ::=",
+ /* 123 */ "selcollist ::= sclp expr as",
+ /* 124 */ "selcollist ::= sclp STAR",
+ /* 125 */ "selcollist ::= sclp nm DOT STAR",
+ /* 126 */ "as ::= AS nm",
+ /* 127 */ "as ::= ids",
+ /* 128 */ "as ::=",
+ /* 129 */ "from ::=",
+ /* 130 */ "from ::= FROM seltablist",
+ /* 131 */ "stl_prefix ::= seltablist joinop",
+ /* 132 */ "stl_prefix ::=",
+ /* 133 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+ /* 134 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+ /* 135 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+ /* 136 */ "dbnm ::=",
+ /* 137 */ "dbnm ::= DOT nm",
+ /* 138 */ "fullname ::= nm dbnm",
+ /* 139 */ "joinop ::= COMMA|JOIN",
+ /* 140 */ "joinop ::= JOIN_KW JOIN",
+ /* 141 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 142 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 143 */ "on_opt ::= ON expr",
+ /* 144 */ "on_opt ::=",
+ /* 145 */ "indexed_opt ::=",
+ /* 146 */ "indexed_opt ::= INDEXED BY nm",
+ /* 147 */ "indexed_opt ::= NOT INDEXED",
+ /* 148 */ "using_opt ::= USING LP inscollist RP",
+ /* 149 */ "using_opt ::=",
+ /* 150 */ "orderby_opt ::=",
+ /* 151 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 152 */ "sortlist ::= sortlist COMMA sortitem sortorder",
+ /* 153 */ "sortlist ::= sortitem sortorder",
+ /* 154 */ "sortitem ::= expr",
+ /* 155 */ "sortorder ::= ASC",
+ /* 156 */ "sortorder ::= DESC",
+ /* 157 */ "sortorder ::=",
+ /* 158 */ "groupby_opt ::=",
+ /* 159 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 160 */ "having_opt ::=",
+ /* 161 */ "having_opt ::= HAVING expr",
+ /* 162 */ "limit_opt ::=",
+ /* 163 */ "limit_opt ::= LIMIT expr",
+ /* 164 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 165 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 166 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt",
+ /* 167 */ "where_opt ::=",
+ /* 168 */ "where_opt ::= WHERE expr",
+ /* 169 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt",
+ /* 170 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 171 */ "setlist ::= nm EQ expr",
+ /* 172 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP",
+ /* 173 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
+ /* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
+ /* 175 */ "insert_cmd ::= INSERT orconf",
+ /* 176 */ "insert_cmd ::= REPLACE",
+ /* 177 */ "itemlist ::= itemlist COMMA expr",
+ /* 178 */ "itemlist ::= expr",
+ /* 179 */ "inscollist_opt ::=",
+ /* 180 */ "inscollist_opt ::= LP inscollist RP",
+ /* 181 */ "inscollist ::= inscollist COMMA nm",
+ /* 182 */ "inscollist ::= nm",
+ /* 183 */ "expr ::= term",
+ /* 184 */ "expr ::= LP expr RP",
+ /* 185 */ "term ::= NULL",
+ /* 186 */ "expr ::= id",
+ /* 187 */ "expr ::= JOIN_KW",
+ /* 188 */ "expr ::= nm DOT nm",
+ /* 189 */ "expr ::= nm DOT nm DOT nm",
+ /* 190 */ "term ::= INTEGER|FLOAT|BLOB",
+ /* 191 */ "term ::= STRING",
+ /* 192 */ "expr ::= REGISTER",
+ /* 193 */ "expr ::= VARIABLE",
+ /* 194 */ "expr ::= expr COLLATE ids",
+ /* 195 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 196 */ "expr ::= ID LP distinct exprlist RP",
+ /* 197 */ "expr ::= ID LP STAR RP",
+ /* 198 */ "term ::= CTIME_KW",
+ /* 199 */ "expr ::= expr AND expr",
+ /* 200 */ "expr ::= expr OR expr",
+ /* 201 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 202 */ "expr ::= expr EQ|NE expr",
+ /* 203 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 204 */ "expr ::= expr PLUS|MINUS expr",
+ /* 205 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 206 */ "expr ::= expr CONCAT expr",
+ /* 207 */ "likeop ::= LIKE_KW",
+ /* 208 */ "likeop ::= NOT LIKE_KW",
+ /* 209 */ "likeop ::= MATCH",
+ /* 210 */ "likeop ::= NOT MATCH",
+ /* 211 */ "escape ::= ESCAPE expr",
+ /* 212 */ "escape ::=",
+ /* 213 */ "expr ::= expr likeop expr escape",
+ /* 214 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 215 */ "expr ::= expr IS NULL",
+ /* 216 */ "expr ::= expr NOT NULL",
+ /* 217 */ "expr ::= expr IS NOT NULL",
+ /* 218 */ "expr ::= NOT expr",
+ /* 219 */ "expr ::= BITNOT expr",
+ /* 220 */ "expr ::= MINUS expr",
+ /* 221 */ "expr ::= PLUS expr",
+ /* 222 */ "between_op ::= BETWEEN",
+ /* 223 */ "between_op ::= NOT BETWEEN",
+ /* 224 */ "expr ::= expr between_op expr AND expr",
+ /* 225 */ "in_op ::= IN",
+ /* 226 */ "in_op ::= NOT IN",
+ /* 227 */ "expr ::= expr in_op LP exprlist RP",
+ /* 228 */ "expr ::= LP select RP",
+ /* 229 */ "expr ::= expr in_op LP select RP",
+ /* 230 */ "expr ::= expr in_op nm dbnm",
+ /* 231 */ "expr ::= EXISTS LP select RP",
+ /* 232 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 233 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 234 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 235 */ "case_else ::= ELSE expr",
+ /* 236 */ "case_else ::=",
+ /* 237 */ "case_operand ::= expr",
+ /* 238 */ "case_operand ::=",
+ /* 239 */ "exprlist ::= nexprlist",
+ /* 240 */ "exprlist ::=",
+ /* 241 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 242 */ "nexprlist ::= expr",
+ /* 243 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
+ /* 244 */ "uniqueflag ::= UNIQUE",
+ /* 245 */ "uniqueflag ::=",
+ /* 246 */ "idxlist_opt ::=",
+ /* 247 */ "idxlist_opt ::= LP idxlist RP",
+ /* 248 */ "idxlist ::= idxlist COMMA nm collate sortorder",
+ /* 249 */ "idxlist ::= nm collate sortorder",
+ /* 250 */ "collate ::=",
+ /* 251 */ "collate ::= COLLATE ids",
+ /* 252 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 253 */ "cmd ::= VACUUM",
+ /* 254 */ "cmd ::= VACUUM nm",
+ /* 255 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 256 */ "cmd ::= PRAGMA nm dbnm EQ ON",
+ /* 257 */ "cmd ::= PRAGMA nm dbnm EQ DELETE",
+ /* 258 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 259 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 260 */ "cmd ::= PRAGMA nm dbnm",
+ /* 261 */ "nmnum ::= plus_num",
+ /* 262 */ "nmnum ::= nm",
+ /* 263 */ "plus_num ::= plus_opt number",
+ /* 264 */ "minus_num ::= MINUS number",
+ /* 265 */ "number ::= INTEGER|FLOAT",
+ /* 266 */ "plus_opt ::= PLUS",
+ /* 267 */ "plus_opt ::=",
+ /* 268 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 269 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 270 */ "trigger_time ::= BEFORE",
+ /* 271 */ "trigger_time ::= AFTER",
+ /* 272 */ "trigger_time ::= INSTEAD OF",
+ /* 273 */ "trigger_time ::=",
+ /* 274 */ "trigger_event ::= DELETE|INSERT",
+ /* 275 */ "trigger_event ::= UPDATE",
+ /* 276 */ "trigger_event ::= UPDATE OF inscollist",
+ /* 277 */ "foreach_clause ::=",
+ /* 278 */ "foreach_clause ::= FOR EACH ROW",
+ /* 279 */ "when_clause ::=",
+ /* 280 */ "when_clause ::= WHEN expr",
+ /* 281 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 283 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
+ /* 284 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
+ /* 285 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
+ /* 286 */ "trigger_cmd ::= DELETE FROM nm where_opt",
+ /* 287 */ "trigger_cmd ::= select",
+ /* 288 */ "expr ::= RAISE LP IGNORE RP",
+ /* 289 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 290 */ "raisetype ::= ROLLBACK",
+ /* 291 */ "raisetype ::= ABORT",
+ /* 292 */ "raisetype ::= FAIL",
+ /* 293 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 294 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 295 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 296 */ "key_opt ::=",
+ /* 297 */ "key_opt ::= KEY expr",
+ /* 298 */ "database_kw_opt ::= DATABASE",
+ /* 299 */ "database_kw_opt ::=",
+ /* 300 */ "cmd ::= REINDEX",
+ /* 301 */ "cmd ::= REINDEX nm dbnm",
+ /* 302 */ "cmd ::= ANALYZE",
+ /* 303 */ "cmd ::= ANALYZE nm dbnm",
+ /* 304 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 305 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
+ /* 306 */ "add_column_fullname ::= fullname",
+ /* 307 */ "kwcolumn_opt ::=",
+ /* 308 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 309 */ "cmd ::= create_vtab",
+ /* 310 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 311 */ "create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm",
+ /* 312 */ "vtabarglist ::= vtabarg",
+ /* 313 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 314 */ "vtabarg ::=",
+ /* 315 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 316 */ "vtabargtoken ::= ANY",
+ /* 317 */ "vtabargtoken ::= lp anylist RP",
+ /* 318 */ "lp ::= LP",
+ /* 319 */ "anylist ::=",
+ /* 320 */ "anylist ::= anylist ANY",
};
#endif /* NDEBUG */
@@ -84192,69 +85416,69 @@
** Note: during a reduce, the only symbols destroyed are those
** which appear on the RHS of the rule, but which are not used
** inside the C code.
*/
- case 159: /* select */
- case 193: /* oneselect */
-{
-sqlite3SelectDelete(pParse->db, (yypminor->yy159));
-}
- break;
- case 173: /* term */
- case 174: /* expr */
- case 198: /* where_opt */
- case 200: /* having_opt */
- case 209: /* on_opt */
- case 214: /* sortitem */
- case 222: /* escape */
- case 225: /* case_operand */
- case 227: /* case_else */
- case 238: /* when_clause */
- case 241: /* key_opt */
-{
-sqlite3ExprDelete(pParse->db, (yypminor->yy122));
-}
- break;
- case 178: /* idxlist_opt */
- case 186: /* idxlist */
- case 196: /* selcollist */
- case 199: /* groupby_opt */
- case 201: /* orderby_opt */
- case 203: /* sclp */
- case 213: /* sortlist */
- case 215: /* nexprlist */
- case 216: /* setlist */
- case 219: /* itemlist */
- case 220: /* exprlist */
- case 226: /* case_exprlist */
-{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy442));
-}
- break;
- case 192: /* fullname */
- case 197: /* from */
- case 205: /* seltablist */
- case 206: /* stl_prefix */
-{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy347));
-}
- break;
- case 210: /* using_opt */
- case 212: /* inscollist */
- case 218: /* inscollist_opt */
-{
-sqlite3IdListDelete(pParse->db, (yypminor->yy180));
-}
- break;
- case 234: /* trigger_cmd_list */
- case 239: /* trigger_cmd */
-{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy327));
-}
- break;
- case 236: /* trigger_event */
-{
-sqlite3IdListDelete(pParse->db, (yypminor->yy410).b);
+ case 160: /* select */
+ case 194: /* oneselect */
+{
+sqlite3SelectDelete(pParse->db, (yypminor->yy243));
+}
+ break;
+ case 174: /* term */
+ case 175: /* expr */
+ case 199: /* where_opt */
+ case 201: /* having_opt */
+ case 210: /* on_opt */
+ case 215: /* sortitem */
+ case 223: /* escape */
+ case 226: /* case_operand */
+ case 228: /* case_else */
+ case 239: /* when_clause */
+ case 242: /* key_opt */
+{
+sqlite3ExprDelete(pParse->db, (yypminor->yy72));
+}
+ break;
+ case 179: /* idxlist_opt */
+ case 187: /* idxlist */
+ case 197: /* selcollist */
+ case 200: /* groupby_opt */
+ case 202: /* orderby_opt */
+ case 204: /* sclp */
+ case 214: /* sortlist */
+ case 216: /* nexprlist */
+ case 217: /* setlist */
+ case 220: /* itemlist */
+ case 221: /* exprlist */
+ case 227: /* case_exprlist */
+{
+sqlite3ExprListDelete(pParse->db, (yypminor->yy148));
+}
+ break;
+ case 193: /* fullname */
+ case 198: /* from */
+ case 206: /* seltablist */
+ case 207: /* stl_prefix */
+{
+sqlite3SrcListDelete(pParse->db, (yypminor->yy185));
+}
+ break;
+ case 211: /* using_opt */
+ case 213: /* inscollist */
+ case 219: /* inscollist_opt */
+{
+sqlite3IdListDelete(pParse->db, (yypminor->yy254));
+}
+ break;
+ case 235: /* trigger_cmd_list */
+ case 240: /* trigger_cmd */
+{
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy145));
+}
+ break;
+ case 237: /* trigger_event */
+{
+sqlite3IdListDelete(pParse->db, (yypminor->yy332).b);
}
break;
default: break; /* If no destructor action specified: do nothing */
}
@@ -84512,231 +85736,233 @@
{ 147, 3 },
{ 147, 5 },
{ 147, 2 },
{ 152, 6 },
- { 155, 0 },
- { 155, 3 },
{ 154, 1 },
- { 154, 0 },
+ { 156, 0 },
+ { 156, 3 },
+ { 155, 1 },
+ { 155, 0 },
{ 153, 4 },
{ 153, 2 },
- { 157, 3 },
- { 157, 1 },
- { 160, 3 },
- { 161, 1 },
- { 164, 1 },
+ { 158, 3 },
+ { 158, 1 },
+ { 161, 3 },
+ { 162, 1 },
+ { 165, 1 },
{ 165, 1 },
+ { 166, 1 },
{ 150, 1 },
{ 150, 1 },
{ 150, 1 },
- { 162, 0 },
- { 162, 1 },
- { 166, 1 },
- { 166, 4 },
- { 166, 6 },
+ { 163, 0 },
+ { 163, 1 },
{ 167, 1 },
- { 167, 2 },
+ { 167, 4 },
+ { 167, 6 },
{ 168, 1 },
- { 168, 1 },
- { 163, 2 },
- { 163, 0 },
- { 171, 3 },
- { 171, 1 },
- { 172, 2 },
- { 172, 4 },
+ { 168, 2 },
+ { 169, 1 },
+ { 169, 1 },
+ { 164, 2 },
+ { 164, 0 },
{ 172, 3 },
- { 172, 3 },
- { 172, 2 },
- { 172, 2 },
- { 172, 3 },
- { 172, 5 },
- { 172, 2 },
- { 172, 4 },
- { 172, 4 },
{ 172, 1 },
- { 172, 2 },
- { 177, 0 },
- { 177, 1 },
- { 179, 0 },
- { 179, 2 },
- { 181, 2 },
- { 181, 3 },
- { 181, 3 },
- { 181, 3 },
+ { 173, 2 },
+ { 173, 4 },
+ { 173, 3 },
+ { 173, 3 },
+ { 173, 2 },
+ { 173, 2 },
+ { 173, 3 },
+ { 173, 5 },
+ { 173, 2 },
+ { 173, 4 },
+ { 173, 4 },
+ { 173, 1 },
+ { 173, 2 },
+ { 178, 0 },
+ { 178, 1 },
+ { 180, 0 },
+ { 180, 2 },
{ 182, 2 },
- { 182, 2 },
- { 182, 1 },
- { 182, 1 },
- { 180, 3 },
- { 180, 2 },
- { 183, 0 },
+ { 182, 3 },
+ { 182, 3 },
+ { 182, 3 },
{ 183, 2 },
{ 183, 2 },
- { 158, 0 },
- { 158, 2 },
- { 184, 3 },
+ { 183, 1 },
+ { 183, 1 },
+ { 181, 3 },
+ { 181, 2 },
+ { 184, 0 },
+ { 184, 2 },
{ 184, 2 },
- { 184, 1 },
+ { 159, 0 },
+ { 159, 2 },
+ { 185, 3 },
{ 185, 2 },
- { 185, 7 },
- { 185, 5 },
- { 185, 5 },
- { 185, 10 },
- { 187, 0 },
- { 187, 1 },
- { 175, 0 },
- { 175, 3 },
+ { 185, 1 },
+ { 186, 2 },
+ { 186, 7 },
+ { 186, 5 },
+ { 186, 5 },
+ { 186, 10 },
{ 188, 0 },
- { 188, 2 },
- { 189, 1 },
- { 189, 1 },
- { 189, 1 },
+ { 188, 1 },
+ { 176, 0 },
+ { 176, 3 },
+ { 189, 0 },
+ { 189, 2 },
+ { 190, 1 },
+ { 190, 1 },
+ { 190, 1 },
{ 147, 4 },
- { 191, 2 },
- { 191, 0 },
+ { 192, 2 },
+ { 192, 0 },
{ 147, 8 },
{ 147, 4 },
{ 147, 1 },
- { 159, 1 },
- { 159, 3 },
- { 194, 1 },
- { 194, 2 },
- { 194, 1 },
- { 193, 9 },
+ { 160, 1 },
+ { 160, 3 },
+ { 195, 1 },
+ { 195, 2 },
{ 195, 1 },
- { 195, 1 },
- { 195, 0 },
- { 203, 2 },
- { 203, 0 },
- { 196, 3 },
- { 196, 2 },
- { 196, 4 },
- { 204, 2 },
- { 204, 1 },
+ { 194, 9 },
+ { 196, 1 },
+ { 196, 1 },
+ { 196, 0 },
+ { 204, 2 },
{ 204, 0 },
- { 197, 0 },
+ { 197, 3 },
{ 197, 2 },
- { 206, 2 },
- { 206, 0 },
- { 205, 7 },
- { 205, 7 },
- { 205, 7 },
- { 156, 0 },
- { 156, 2 },
- { 192, 2 },
- { 207, 1 },
+ { 197, 4 },
+ { 205, 2 },
+ { 205, 1 },
+ { 205, 0 },
+ { 198, 0 },
+ { 198, 2 },
{ 207, 2 },
- { 207, 3 },
- { 207, 4 },
- { 209, 2 },
+ { 207, 0 },
+ { 206, 7 },
+ { 206, 7 },
+ { 206, 7 },
+ { 157, 0 },
+ { 157, 2 },
+ { 193, 2 },
+ { 208, 1 },
+ { 208, 2 },
+ { 208, 3 },
+ { 208, 4 },
+ { 210, 2 },
+ { 210, 0 },
{ 209, 0 },
- { 208, 0 },
- { 208, 3 },
- { 208, 2 },
- { 210, 4 },
- { 210, 0 },
- { 201, 0 },
- { 201, 3 },
- { 213, 4 },
- { 213, 2 },
- { 214, 1 },
- { 176, 1 },
- { 176, 1 },
- { 176, 0 },
- { 199, 0 },
- { 199, 3 },
+ { 209, 3 },
+ { 209, 2 },
+ { 211, 4 },
+ { 211, 0 },
+ { 202, 0 },
+ { 202, 3 },
+ { 214, 4 },
+ { 214, 2 },
+ { 215, 1 },
+ { 177, 1 },
+ { 177, 1 },
+ { 177, 0 },
{ 200, 0 },
- { 200, 2 },
- { 202, 0 },
- { 202, 2 },
- { 202, 4 },
- { 202, 4 },
+ { 200, 3 },
+ { 201, 0 },
+ { 201, 2 },
+ { 203, 0 },
+ { 203, 2 },
+ { 203, 4 },
+ { 203, 4 },
{ 147, 5 },
- { 198, 0 },
- { 198, 2 },
+ { 199, 0 },
+ { 199, 2 },
{ 147, 7 },
- { 216, 5 },
- { 216, 3 },
+ { 217, 5 },
+ { 217, 3 },
{ 147, 8 },
{ 147, 5 },
{ 147, 6 },
- { 217, 2 },
- { 217, 1 },
+ { 218, 2 },
+ { 218, 1 },
+ { 220, 3 },
+ { 220, 1 },
+ { 219, 0 },
{ 219, 3 },
- { 219, 1 },
- { 218, 0 },
- { 218, 3 },
- { 212, 3 },
- { 212, 1 },
+ { 213, 3 },
+ { 213, 1 },
+ { 175, 1 },
+ { 175, 3 },
{ 174, 1 },
- { 174, 3 },
- { 173, 1 },
+ { 175, 1 },
+ { 175, 1 },
+ { 175, 3 },
+ { 175, 5 },
{ 174, 1 },
{ 174, 1 },
- { 174, 3 },
- { 174, 5 },
- { 173, 1 },
- { 173, 1 },
- { 174, 1 },
+ { 175, 1 },
+ { 175, 1 },
+ { 175, 3 },
+ { 175, 6 },
+ { 175, 5 },
+ { 175, 4 },
{ 174, 1 },
- { 174, 3 },
- { 174, 6 },
- { 174, 5 },
- { 174, 4 },
- { 173, 1 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 221, 1 },
- { 221, 2 },
- { 221, 1 },
- { 221, 2 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 222, 1 },
+ { 222, 2 },
+ { 222, 1 },
{ 222, 2 },
- { 222, 0 },
- { 174, 4 },
- { 174, 2 },
- { 174, 3 },
- { 174, 3 },
- { 174, 4 },
- { 174, 2 },
- { 174, 2 },
- { 174, 2 },
- { 174, 2 },
- { 223, 1 },
{ 223, 2 },
- { 174, 5 },
+ { 223, 0 },
+ { 175, 4 },
+ { 175, 2 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 4 },
+ { 175, 2 },
+ { 175, 2 },
+ { 175, 2 },
+ { 175, 2 },
{ 224, 1 },
{ 224, 2 },
- { 174, 5 },
- { 174, 3 },
- { 174, 5 },
- { 174, 4 },
- { 174, 4 },
- { 174, 5 },
- { 226, 5 },
- { 226, 4 },
- { 227, 2 },
- { 227, 0 },
+ { 175, 5 },
{ 225, 1 },
- { 225, 0 },
- { 220, 1 },
- { 220, 0 },
- { 215, 3 },
- { 215, 1 },
+ { 225, 2 },
+ { 175, 5 },
+ { 175, 3 },
+ { 175, 5 },
+ { 175, 4 },
+ { 175, 4 },
+ { 175, 5 },
+ { 227, 5 },
+ { 227, 4 },
+ { 228, 2 },
+ { 228, 0 },
+ { 226, 1 },
+ { 226, 0 },
+ { 221, 1 },
+ { 221, 0 },
+ { 216, 3 },
+ { 216, 1 },
{ 147, 11 },
- { 228, 1 },
- { 228, 0 },
- { 178, 0 },
- { 178, 3 },
- { 186, 5 },
- { 186, 3 },
+ { 229, 1 },
{ 229, 0 },
- { 229, 2 },
+ { 179, 0 },
+ { 179, 3 },
+ { 187, 5 },
+ { 187, 3 },
+ { 230, 0 },
+ { 230, 2 },
{ 147, 4 },
{ 147, 1 },
{ 147, 2 },
{ 147, 5 },
@@ -84744,68 +85970,68 @@
{ 147, 5 },
{ 147, 5 },
{ 147, 6 },
{ 147, 3 },
- { 230, 1 },
- { 230, 1 },
- { 169, 2 },
+ { 231, 1 },
+ { 231, 1 },
{ 170, 2 },
+ { 171, 2 },
+ { 233, 1 },
{ 232, 1 },
- { 231, 1 },
- { 231, 0 },
+ { 232, 0 },
{ 147, 5 },
- { 233, 11 },
- { 235, 1 },
- { 235, 1 },
- { 235, 2 },
- { 235, 0 },
+ { 234, 11 },
{ 236, 1 },
{ 236, 1 },
- { 236, 3 },
- { 237, 0 },
+ { 236, 2 },
+ { 236, 0 },
+ { 237, 1 },
+ { 237, 1 },
{ 237, 3 },
{ 238, 0 },
- { 238, 2 },
- { 234, 3 },
- { 234, 2 },
- { 239, 6 },
- { 239, 8 },
- { 239, 5 },
- { 239, 4 },
- { 239, 1 },
- { 174, 4 },
- { 174, 6 },
- { 190, 1 },
- { 190, 1 },
- { 190, 1 },
+ { 238, 3 },
+ { 239, 0 },
+ { 239, 2 },
+ { 235, 3 },
+ { 235, 2 },
+ { 240, 6 },
+ { 240, 8 },
+ { 240, 5 },
+ { 240, 4 },
+ { 240, 1 },
+ { 175, 4 },
+ { 175, 6 },
+ { 191, 1 },
+ { 191, 1 },
+ { 191, 1 },
{ 147, 4 },
{ 147, 6 },
{ 147, 3 },
- { 241, 0 },
- { 241, 2 },
- { 240, 1 },
- { 240, 0 },
+ { 242, 0 },
+ { 242, 2 },
+ { 241, 1 },
+ { 241, 0 },
{ 147, 1 },
{ 147, 3 },
{ 147, 1 },
{ 147, 3 },
{ 147, 6 },
{ 147, 6 },
- { 242, 1 },
- { 243, 0 },
{ 243, 1 },
+ { 244, 0 },
+ { 244, 1 },
{ 147, 1 },
{ 147, 4 },
- { 244, 7 },
- { 245, 1 },
- { 245, 3 },
- { 246, 0 },
- { 246, 2 },
- { 247, 1 },
- { 247, 3 },
+ { 245, 7 },
+ { 246, 1 },
+ { 246, 3 },
+ { 247, 0 },
+ { 247, 2 },
{ 248, 1 },
- { 249, 0 },
- { 249, 2 },
+ { 248, 3 },
+ { 249, 1 },
+ { 250, 0 },
+ { 250, 2 },
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -84869,34 +86095,34 @@
case 12: /* trans_opt ::= TRANSACTION nm */
case 20: /* savepoint_opt ::= SAVEPOINT */
case 21: /* savepoint_opt ::= */
case 25: /* cmd ::= create_table create_table_args */
- case 33: /* columnlist ::= columnlist COMMA column */
- case 34: /* columnlist ::= column */
- case 42: /* type ::= */
- case 49: /* signed ::= plus_num */
- case 50: /* signed ::= minus_num */
- case 51: /* carglist ::= carglist carg */
- case 52: /* carglist ::= */
- case 53: /* carg ::= CONSTRAINT nm ccons */
- case 54: /* carg ::= ccons */
- case 60: /* ccons ::= NULL onconf */
- case 87: /* conslist ::= conslist COMMA tcons */
- case 88: /* conslist ::= conslist tcons */
- case 89: /* conslist ::= tcons */
- case 90: /* tcons ::= CONSTRAINT nm */
- case 264: /* plus_opt ::= PLUS */
- case 265: /* plus_opt ::= */
- case 275: /* foreach_clause ::= */
- case 276: /* foreach_clause ::= FOR EACH ROW */
- case 296: /* database_kw_opt ::= DATABASE */
- case 297: /* database_kw_opt ::= */
- case 305: /* kwcolumn_opt ::= */
- case 306: /* kwcolumn_opt ::= COLUMNKW */
- case 310: /* vtabarglist ::= vtabarg */
- case 311: /* vtabarglist ::= vtabarglist COMMA vtabarg */
- case 313: /* vtabarg ::= vtabarg vtabargtoken */
- case 317: /* anylist ::= */
+ case 34: /* columnlist ::= columnlist COMMA column */
+ case 35: /* columnlist ::= column */
+ case 44: /* type ::= */
+ case 51: /* signed ::= plus_num */
+ case 52: /* signed ::= minus_num */
+ case 53: /* carglist ::= carglist carg */
+ case 54: /* carglist ::= */
+ case 55: /* carg ::= CONSTRAINT nm ccons */
+ case 56: /* carg ::= ccons */
+ case 62: /* ccons ::= NULL onconf */
+ case 89: /* conslist ::= conslist COMMA tcons */
+ case 90: /* conslist ::= conslist tcons */
+ case 91: /* conslist ::= tcons */
+ case 92: /* tcons ::= CONSTRAINT nm */
+ case 266: /* plus_opt ::= PLUS */
+ case 267: /* plus_opt ::= */
+ case 277: /* foreach_clause ::= */
+ case 278: /* foreach_clause ::= FOR EACH ROW */
+ case 298: /* database_kw_opt ::= DATABASE */
+ case 299: /* database_kw_opt ::= */
+ case 307: /* kwcolumn_opt ::= */
+ case 308: /* kwcolumn_opt ::= COLUMNKW */
+ case 312: /* vtabarglist ::= vtabarg */
+ case 313: /* vtabarglist ::= vtabarglist COMMA vtabarg */
+ case 315: /* vtabarg ::= vtabarg vtabargtoken */
+ case 319: /* anylist ::= */
{
}
break;
case 5: /* explain ::= */
@@ -84911,19 +86137,19 @@
case 8: /* cmdx ::= cmd */
{ sqlite3FinishCoding(pParse); }
break;
case 9: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy392);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy194);}
break;
case 13: /* transtype ::= */
-{yygotominor.yy392 = TK_DEFERRED;}
+{yygotominor.yy194 = TK_DEFERRED;}
break;
case 14: /* transtype ::= DEFERRED */
case 15: /* transtype ::= IMMEDIATE */
case 16: /* transtype ::= EXCLUSIVE */
- case 112: /* multiselect_op ::= UNION */
- case 114: /* multiselect_op ::= EXCEPT|INTERSECT */
-{yygotominor.yy392 = yymsp[0].major;}
+ case 114: /* multiselect_op ::= UNION */
+ case 116: /* multiselect_op ::= EXCEPT|INTERSECT */
+{yygotominor.yy194 = yymsp[0].major;}
break;
case 17: /* cmd ::= COMMIT trans_opt */
case 18: /* cmd ::= END trans_opt */
{sqlite3CommitTransaction(pParse);}
@@ -84945,932 +86171,944 @@
{
sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0);
}
break;
- case 26: /* create_table ::= CREATE temp TABLE ifnotexists nm dbnm */
-{
- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy392,0,0,yymsp[-2].minor.yy392);
-}
- break;
- case 27: /* ifnotexists ::= */
- case 30: /* temp ::= */
- case 68: /* autoinc ::= */
- case 82: /* init_deferred_pred_opt ::= */
- case 84: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
- case 95: /* defer_subclause_opt ::= */
- case 106: /* ifexists ::= */
- case 117: /* distinct ::= ALL */
- case 118: /* distinct ::= */
- case 220: /* between_op ::= BETWEEN */
- case 223: /* in_op ::= IN */
-{yygotominor.yy392 = 0;}
- break;
- case 28: /* ifnotexists ::= IF NOT EXISTS */
- case 29: /* temp ::= TEMP */
- case 69: /* autoinc ::= AUTOINCR */
- case 83: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
- case 105: /* ifexists ::= IF EXISTS */
- case 116: /* distinct ::= DISTINCT */
- case 221: /* between_op ::= NOT BETWEEN */
- case 224: /* in_op ::= NOT IN */
-{yygotominor.yy392 = 1;}
- break;
- case 31: /* create_table_args ::= LP columnlist conslist_opt RP */
+ case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+{
+ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy194,0,0,yymsp[-2].minor.yy194);
+}
+ break;
+ case 27: /* createkw ::= CREATE */
+{
+ pParse->db->lookaside.bEnabled = 0;
+ yygotominor.yy0 = yymsp[0].minor.yy0;
+}
+ break;
+ case 28: /* ifnotexists ::= */
+ case 31: /* temp ::= */
+ case 70: /* autoinc ::= */
+ case 84: /* init_deferred_pred_opt ::= */
+ case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+ case 97: /* defer_subclause_opt ::= */
+ case 108: /* ifexists ::= */
+ case 119: /* distinct ::= ALL */
+ case 120: /* distinct ::= */
+ case 222: /* between_op ::= BETWEEN */
+ case 225: /* in_op ::= IN */
+{yygotominor.yy194 = 0;}
+ break;
+ case 29: /* ifnotexists ::= IF NOT EXISTS */
+ case 30: /* temp ::= TEMP */
+ case 71: /* autoinc ::= AUTOINCR */
+ case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ case 107: /* ifexists ::= IF EXISTS */
+ case 118: /* distinct ::= DISTINCT */
+ case 223: /* between_op ::= NOT BETWEEN */
+ case 226: /* in_op ::= NOT IN */
+{yygotominor.yy194 = 1;}
+ break;
+ case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
{
sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0);
}
break;
- case 32: /* create_table_args ::= AS select */
-{
- sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy159);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159);
-}
- break;
- case 35: /* column ::= columnid type carglist */
+ case 33: /* create_table_args ::= AS select */
+{
+ sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy243);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243);
+}
+ break;
+ case 36: /* column ::= columnid type carglist */
{
yygotominor.yy0.z = yymsp[-2].minor.yy0.z;
yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
}
break;
- case 36: /* columnid ::= nm */
+ case 37: /* columnid ::= nm */
{
sqlite3AddColumn(pParse,&yymsp[0].minor.yy0);
yygotominor.yy0 = yymsp[0].minor.yy0;
}
break;
- case 37: /* id ::= ID */
- case 38: /* ids ::= ID|STRING */
- case 39: /* nm ::= ID */
- case 40: /* nm ::= STRING */
- case 41: /* nm ::= JOIN_KW */
- case 44: /* typetoken ::= typename */
- case 47: /* typename ::= ids */
- case 124: /* as ::= AS nm */
- case 125: /* as ::= ids */
- case 135: /* dbnm ::= DOT nm */
- case 144: /* indexed_opt ::= INDEXED BY nm */
- case 249: /* collate ::= COLLATE ids */
- case 259: /* nmnum ::= plus_num */
- case 260: /* nmnum ::= nm */
- case 261: /* plus_num ::= plus_opt number */
- case 262: /* minus_num ::= MINUS number */
- case 263: /* number ::= INTEGER|FLOAT */
+ case 38: /* id ::= ID */
+ case 39: /* id ::= INDEXED */
+ case 40: /* ids ::= ID|STRING */
+ case 41: /* nm ::= id */
+ case 42: /* nm ::= STRING */
+ case 43: /* nm ::= JOIN_KW */
+ case 46: /* typetoken ::= typename */
+ case 49: /* typename ::= ids */
+ case 126: /* as ::= AS nm */
+ case 127: /* as ::= ids */
+ case 137: /* dbnm ::= DOT nm */
+ case 146: /* indexed_opt ::= INDEXED BY nm */
+ case 251: /* collate ::= COLLATE ids */
+ case 261: /* nmnum ::= plus_num */
+ case 262: /* nmnum ::= nm */
+ case 263: /* plus_num ::= plus_opt number */
+ case 264: /* minus_num ::= MINUS number */
+ case 265: /* number ::= INTEGER|FLOAT */
{yygotominor.yy0 = yymsp[0].minor.yy0;}
break;
- case 43: /* type ::= typetoken */
+ case 45: /* type ::= typetoken */
{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
break;
- case 45: /* typetoken ::= typename LP signed RP */
+ case 47: /* typetoken ::= typename LP signed RP */
{
yygotominor.yy0.z = yymsp[-3].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
}
break;
- case 46: /* typetoken ::= typename LP signed COMMA signed RP */
+ case 48: /* typetoken ::= typename LP signed COMMA signed RP */
{
yygotominor.yy0.z = yymsp[-5].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
}
break;
- case 48: /* typename ::= typename ids */
+ case 50: /* typename ::= typename ids */
{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
break;
- case 55: /* ccons ::= DEFAULT term */
- case 57: /* ccons ::= DEFAULT PLUS term */
-{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy122);}
- break;
- case 56: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy122);}
- break;
- case 58: /* ccons ::= DEFAULT MINUS term */
-{
- Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy122, 0, 0);
- sqlite3ExprSpan(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy122->span);
+ case 57: /* ccons ::= DEFAULT term */
+ case 59: /* ccons ::= DEFAULT PLUS term */
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy72);}
+ break;
+ case 58: /* ccons ::= DEFAULT LP expr RP */
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy72);}
+ break;
+ case 60: /* ccons ::= DEFAULT MINUS term */
+{
+ Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy72, 0, 0);
+ sqlite3ExprSpan(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72->span);
sqlite3AddDefaultValue(pParse,p);
}
break;
- case 59: /* ccons ::= DEFAULT id */
+ case 61: /* ccons ::= DEFAULT id */
{
Expr *p = sqlite3PExpr(pParse, TK_STRING, 0, 0, &yymsp[0].minor.yy0);
sqlite3AddDefaultValue(pParse,p);
}
break;
- case 61: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy392);}
- break;
- case 62: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy392,yymsp[0].minor.yy392,yymsp[-2].minor.yy392);}
- break;
- case 63: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy392,0,0,0,0);}
- break;
- case 64: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy122);}
- break;
- case 65: /* ccons ::= REFERENCES nm idxlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy442,yymsp[0].minor.yy392);}
- break;
- case 66: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy392);}
- break;
- case 67: /* ccons ::= COLLATE ids */
+ case 63: /* ccons ::= NOT NULL onconf */
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy194);}
+ break;
+ case 64: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy194,yymsp[0].minor.yy194,yymsp[-2].minor.yy194);}
+ break;
+ case 65: /* ccons ::= UNIQUE onconf */
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy194,0,0,0,0);}
+ break;
+ case 66: /* ccons ::= CHECK LP expr RP */
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy72);}
+ break;
+ case 67: /* ccons ::= REFERENCES nm idxlist_opt refargs */
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy148,yymsp[0].minor.yy194);}
+ break;
+ case 68: /* ccons ::= defer_subclause */
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy194);}
+ break;
+ case 69: /* ccons ::= COLLATE ids */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
- case 70: /* refargs ::= */
-{ yygotominor.yy392 = OE_Restrict * 0x010101; }
- break;
- case 71: /* refargs ::= refargs refarg */
-{ yygotominor.yy392 = (yymsp[-1].minor.yy392 & ~yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; }
- break;
- case 72: /* refarg ::= MATCH nm */
-{ yygotominor.yy207.value = 0; yygotominor.yy207.mask = 0x000000; }
- break;
- case 73: /* refarg ::= ON DELETE refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy392; yygotominor.yy207.mask = 0x0000ff; }
- break;
- case 74: /* refarg ::= ON UPDATE refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy392<<8; yygotominor.yy207.mask = 0x00ff00; }
- break;
- case 75: /* refarg ::= ON INSERT refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy392<<16; yygotominor.yy207.mask = 0xff0000; }
- break;
- case 76: /* refact ::= SET NULL */
-{ yygotominor.yy392 = OE_SetNull; }
- break;
- case 77: /* refact ::= SET DEFAULT */
-{ yygotominor.yy392 = OE_SetDflt; }
- break;
- case 78: /* refact ::= CASCADE */
-{ yygotominor.yy392 = OE_Cascade; }
- break;
- case 79: /* refact ::= RESTRICT */
-{ yygotominor.yy392 = OE_Restrict; }
- break;
- case 80: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
- case 81: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- case 96: /* defer_subclause_opt ::= defer_subclause */
- case 98: /* onconf ::= ON CONFLICT resolvetype */
- case 100: /* orconf ::= OR resolvetype */
- case 101: /* resolvetype ::= raisetype */
- case 173: /* insert_cmd ::= INSERT orconf */
-{yygotominor.yy392 = yymsp[0].minor.yy392;}
- break;
- case 85: /* conslist_opt ::= */
+ case 72: /* refargs ::= */
+{ yygotominor.yy194 = OE_Restrict * 0x010101; }
+ break;
+ case 73: /* refargs ::= refargs refarg */
+{ yygotominor.yy194 = (yymsp[-1].minor.yy194 & ~yymsp[0].minor.yy497.mask) | yymsp[0].minor.yy497.value; }
+ break;
+ case 74: /* refarg ::= MATCH nm */
+{ yygotominor.yy497.value = 0; yygotominor.yy497.mask = 0x000000; }
+ break;
+ case 75: /* refarg ::= ON DELETE refact */
+{ yygotominor.yy497.value = yymsp[0].minor.yy194; yygotominor.yy497.mask = 0x0000ff; }
+ break;
+ case 76: /* refarg ::= ON UPDATE refact */
+{ yygotominor.yy497.value = yymsp[0].minor.yy194<<8; yygotominor.yy497.mask = 0x00ff00; }
+ break;
+ case 77: /* refarg ::= ON INSERT refact */
+{ yygotominor.yy497.value = yymsp[0].minor.yy194<<16; yygotominor.yy497.mask = 0xff0000; }
+ break;
+ case 78: /* refact ::= SET NULL */
+{ yygotominor.yy194 = OE_SetNull; }
+ break;
+ case 79: /* refact ::= SET DEFAULT */
+{ yygotominor.yy194 = OE_SetDflt; }
+ break;
+ case 80: /* refact ::= CASCADE */
+{ yygotominor.yy194 = OE_Cascade; }
+ break;
+ case 81: /* refact ::= RESTRICT */
+{ yygotominor.yy194 = OE_Restrict; }
+ break;
+ case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+ case 83: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ case 98: /* defer_subclause_opt ::= defer_subclause */
+ case 100: /* onconf ::= ON CONFLICT resolvetype */
+ case 102: /* orconf ::= OR resolvetype */
+ case 103: /* resolvetype ::= raisetype */
+ case 175: /* insert_cmd ::= INSERT orconf */
+{yygotominor.yy194 = yymsp[0].minor.yy194;}
+ break;
+ case 87: /* conslist_opt ::= */
{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
break;
- case 86: /* conslist_opt ::= COMMA conslist */
+ case 88: /* conslist_opt ::= COMMA conslist */
{yygotominor.yy0 = yymsp[-1].minor.yy0;}
break;
- case 91: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy442,yymsp[0].minor.yy392,yymsp[-2].minor.yy392,0);}
- break;
- case 92: /* tcons ::= UNIQUE LP idxlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy442,yymsp[0].minor.yy392,0,0,0,0);}
- break;
- case 93: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy122);}
- break;
- case 94: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
-{
- sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy442, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy442, yymsp[-1].minor.yy392);
- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy392);
-}
- break;
- case 97: /* onconf ::= */
- case 99: /* orconf ::= */
-{yygotominor.yy392 = OE_Default;}
- break;
- case 102: /* resolvetype ::= IGNORE */
-{yygotominor.yy392 = OE_Ignore;}
- break;
- case 103: /* resolvetype ::= REPLACE */
- case 174: /* insert_cmd ::= REPLACE */
-{yygotominor.yy392 = OE_Replace;}
- break;
- case 104: /* cmd ::= DROP TABLE ifexists fullname */
-{
- sqlite3DropTable(pParse, yymsp[0].minor.yy347, 0, yymsp[-1].minor.yy392);
-}
- break;
- case 107: /* cmd ::= CREATE temp VIEW ifnotexists nm dbnm AS select */
-{
- sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy159, yymsp[-6].minor.yy392, yymsp[-4].minor.yy392);
-}
- break;
- case 108: /* cmd ::= DROP VIEW ifexists fullname */
-{
- sqlite3DropTable(pParse, yymsp[0].minor.yy347, 1, yymsp[-1].minor.yy392);
-}
- break;
- case 109: /* cmd ::= select */
+ case 93: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy148,yymsp[0].minor.yy194,yymsp[-2].minor.yy194,0);}
+ break;
+ case 94: /* tcons ::= UNIQUE LP idxlist RP onconf */
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy148,yymsp[0].minor.yy194,0,0,0,0);}
+ break;
+ case 95: /* tcons ::= CHECK LP expr RP onconf */
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy72);}
+ break;
+ case 96: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
+{
+ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy148, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, yymsp[-1].minor.yy194);
+ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy194);
+}
+ break;
+ case 99: /* onconf ::= */
+ case 101: /* orconf ::= */
+{yygotominor.yy194 = OE_Default;}
+ break;
+ case 104: /* resolvetype ::= IGNORE */
+{yygotominor.yy194 = OE_Ignore;}
+ break;
+ case 105: /* resolvetype ::= REPLACE */
+ case 176: /* insert_cmd ::= REPLACE */
+{yygotominor.yy194 = OE_Replace;}
+ break;
+ case 106: /* cmd ::= DROP TABLE ifexists fullname */
+{
+ sqlite3DropTable(pParse, yymsp[0].minor.yy185, 0, yymsp[-1].minor.yy194);
+}
+ break;
+ case 109: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
+{
+ sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy243, yymsp[-6].minor.yy194, yymsp[-4].minor.yy194);
+}
+ break;
+ case 110: /* cmd ::= DROP VIEW ifexists fullname */
+{
+ sqlite3DropTable(pParse, yymsp[0].minor.yy185, 1, yymsp[-1].minor.yy194);
+}
+ break;
+ case 111: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0};
- sqlite3Select(pParse, yymsp[0].minor.yy159, &dest);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159);
-}
- break;
- case 110: /* select ::= oneselect */
-{yygotominor.yy159 = yymsp[0].minor.yy159;}
- break;
- case 111: /* select ::= select multiselect_op oneselect */
-{
- if( yymsp[0].minor.yy159 ){
- yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392;
- yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159;
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159);
- }
- yygotominor.yy159 = yymsp[0].minor.yy159;
-}
- break;
- case 113: /* multiselect_op ::= UNION ALL */
-{yygotominor.yy392 = TK_ALL;}
- break;
- case 115: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
-{
- yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy392,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
-}
- break;
- case 119: /* sclp ::= selcollist COMMA */
- case 245: /* idxlist_opt ::= LP idxlist RP */
-{yygotominor.yy442 = yymsp[-1].minor.yy442;}
- break;
- case 120: /* sclp ::= */
- case 148: /* orderby_opt ::= */
- case 156: /* groupby_opt ::= */
- case 238: /* exprlist ::= */
- case 244: /* idxlist_opt ::= */
-{yygotominor.yy442 = 0;}
- break;
- case 121: /* selcollist ::= sclp expr as */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[-1].minor.yy122,yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0);
-}
- break;
- case 122: /* selcollist ::= sclp STAR */
+ sqlite3Select(pParse, yymsp[0].minor.yy243, &dest);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243);
+}
+ break;
+ case 112: /* select ::= oneselect */
+{yygotominor.yy243 = yymsp[0].minor.yy243;}
+ break;
+ case 113: /* select ::= select multiselect_op oneselect */
+{
+ if( yymsp[0].minor.yy243 ){
+ yymsp[0].minor.yy243->op = (u8)yymsp[-1].minor.yy194;
+ yymsp[0].minor.yy243->pPrior = yymsp[-2].minor.yy243;
+ }else{
+ sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy243);
+ }
+ yygotominor.yy243 = yymsp[0].minor.yy243;
+}
+ break;
+ case 115: /* multiselect_op ::= UNION ALL */
+{yygotominor.yy194 = TK_ALL;}
+ break;
+ case 117: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+{
+ yygotominor.yy243 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy148,yymsp[-5].minor.yy185,yymsp[-4].minor.yy72,yymsp[-3].minor.yy148,yymsp[-2].minor.yy72,yymsp[-1].minor.yy148,yymsp[-7].minor.yy194,yymsp[0].minor.yy354.pLimit,yymsp[0].minor.yy354.pOffset);
+}
+ break;
+ case 121: /* sclp ::= selcollist COMMA */
+ case 247: /* idxlist_opt ::= LP idxlist RP */
+{yygotominor.yy148 = yymsp[-1].minor.yy148;}
+ break;
+ case 122: /* sclp ::= */
+ case 150: /* orderby_opt ::= */
+ case 158: /* groupby_opt ::= */
+ case 240: /* exprlist ::= */
+ case 246: /* idxlist_opt ::= */
+{yygotominor.yy148 = 0;}
+ break;
+ case 123: /* selcollist ::= sclp expr as */
+{
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[-1].minor.yy72,yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0);
+}
+ break;
+ case 124: /* selcollist ::= sclp STAR */
{
Expr *p = sqlite3PExpr(pParse, TK_ALL, 0, 0, 0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy442, p, 0);
-}
- break;
- case 123: /* selcollist ::= sclp nm DOT STAR */
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p, 0);
+}
+ break;
+ case 125: /* selcollist ::= sclp nm DOT STAR */
{
Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442, pDot, 0);
-}
- break;
- case 126: /* as ::= */
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot, 0);
+}
+ break;
+ case 128: /* as ::= */
{yygotominor.yy0.n = 0;}
break;
- case 127: /* from ::= */
-{yygotominor.yy347 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy347));}
- break;
- case 128: /* from ::= FROM seltablist */
-{
- yygotominor.yy347 = yymsp[0].minor.yy347;
- sqlite3SrcListShiftJoinType(yygotominor.yy347);
-}
- break;
- case 129: /* stl_prefix ::= seltablist joinop */
-{
- yygotominor.yy347 = yymsp[-1].minor.yy347;
- if( yygotominor.yy347 && yygotominor.yy347->nSrc>0 ) yygotominor.yy347->a[yygotominor.yy347->nSrc-1].jointype = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 130: /* stl_prefix ::= */
-{yygotominor.yy347 = 0;}
- break;
- case 131: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
-{
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
- sqlite3SrcListIndexedBy(pParse, yygotominor.yy347, &yymsp[-2].minor.yy0);
-}
- break;
- case 132: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
-{
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy159,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
- }
- break;
- case 133: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
-{
- if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){
- yygotominor.yy347 = yymsp[-4].minor.yy347;
+ case 129: /* from ::= */
+{yygotominor.yy185 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy185));}
+ break;
+ case 130: /* from ::= FROM seltablist */
+{
+ yygotominor.yy185 = yymsp[0].minor.yy185;
+ sqlite3SrcListShiftJoinType(yygotominor.yy185);
+}
+ break;
+ case 131: /* stl_prefix ::= seltablist joinop */
+{
+ yygotominor.yy185 = yymsp[-1].minor.yy185;
+ if( yygotominor.yy185 && yygotominor.yy185->nSrc>0 ) yygotominor.yy185->a[yygotominor.yy185->nSrc-1].jointype = (u8)yymsp[0].minor.yy194;
+}
+ break;
+ case 132: /* stl_prefix ::= */
+{yygotominor.yy185 = 0;}
+ break;
+ case 133: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+{
+ yygotominor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
+ sqlite3SrcListIndexedBy(pParse, yygotominor.yy185, &yymsp[-2].minor.yy0);
+}
+ break;
+ case 134: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+{
+ yygotominor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy243,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
+ }
+ break;
+ case 135: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+{
+ if( yymsp[-6].minor.yy185==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy72==0 && yymsp[0].minor.yy254==0 ){
+ yygotominor.yy185 = yymsp[-4].minor.yy185;
}else{
Select *pSubquery;
- sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347);
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,0,0,0);
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
- }
- }
- break;
- case 134: /* dbnm ::= */
- case 143: /* indexed_opt ::= */
+ sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy185);
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy185,0,0,0,0,0,0,0);
+ yygotominor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
+ }
+ }
+ break;
+ case 136: /* dbnm ::= */
+ case 145: /* indexed_opt ::= */
{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
break;
- case 136: /* fullname ::= nm dbnm */
-{yygotominor.yy347 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
- break;
- case 137: /* joinop ::= COMMA|JOIN */
-{ yygotominor.yy392 = JT_INNER; }
- break;
- case 138: /* joinop ::= JOIN_KW JOIN */
-{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
- break;
- case 139: /* joinop ::= JOIN_KW nm JOIN */
-{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
- break;
- case 140: /* joinop ::= JOIN_KW nm nm JOIN */
-{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
- break;
- case 141: /* on_opt ::= ON expr */
- case 152: /* sortitem ::= expr */
- case 159: /* having_opt ::= HAVING expr */
- case 166: /* where_opt ::= WHERE expr */
- case 181: /* expr ::= term */
- case 209: /* escape ::= ESCAPE expr */
- case 233: /* case_else ::= ELSE expr */
- case 235: /* case_operand ::= expr */
-{yygotominor.yy122 = yymsp[0].minor.yy122;}
- break;
- case 142: /* on_opt ::= */
- case 158: /* having_opt ::= */
- case 165: /* where_opt ::= */
- case 210: /* escape ::= */
- case 234: /* case_else ::= */
- case 236: /* case_operand ::= */
-{yygotominor.yy122 = 0;}
- break;
- case 145: /* indexed_opt ::= NOT INDEXED */
+ case 138: /* fullname ::= nm dbnm */
+{yygotominor.yy185 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
+ break;
+ case 139: /* joinop ::= COMMA|JOIN */
+{ yygotominor.yy194 = JT_INNER; }
+ break;
+ case 140: /* joinop ::= JOIN_KW JOIN */
+{ yygotominor.yy194 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
+ break;
+ case 141: /* joinop ::= JOIN_KW nm JOIN */
+{ yygotominor.yy194 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
+ break;
+ case 142: /* joinop ::= JOIN_KW nm nm JOIN */
+{ yygotominor.yy194 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
+ break;
+ case 143: /* on_opt ::= ON expr */
+ case 154: /* sortitem ::= expr */
+ case 161: /* having_opt ::= HAVING expr */
+ case 168: /* where_opt ::= WHERE expr */
+ case 183: /* expr ::= term */
+ case 211: /* escape ::= ESCAPE expr */
+ case 235: /* case_else ::= ELSE expr */
+ case 237: /* case_operand ::= expr */
+{yygotominor.yy72 = yymsp[0].minor.yy72;}
+ break;
+ case 144: /* on_opt ::= */
+ case 160: /* having_opt ::= */
+ case 167: /* where_opt ::= */
+ case 212: /* escape ::= */
+ case 236: /* case_else ::= */
+ case 238: /* case_operand ::= */
+{yygotominor.yy72 = 0;}
+ break;
+ case 147: /* indexed_opt ::= NOT INDEXED */
{yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
break;
- case 146: /* using_opt ::= USING LP inscollist RP */
- case 178: /* inscollist_opt ::= LP inscollist RP */
-{yygotominor.yy180 = yymsp[-1].minor.yy180;}
- break;
- case 147: /* using_opt ::= */
- case 177: /* inscollist_opt ::= */
-{yygotominor.yy180 = 0;}
- break;
- case 149: /* orderby_opt ::= ORDER BY sortlist */
- case 157: /* groupby_opt ::= GROUP BY nexprlist */
- case 237: /* exprlist ::= nexprlist */
-{yygotominor.yy442 = yymsp[0].minor.yy442;}
- break;
- case 150: /* sortlist ::= sortlist COMMA sortitem sortorder */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442,yymsp[-1].minor.yy122,0);
- if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 151: /* sortlist ::= sortitem sortorder */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy122,0);
- if( yygotominor.yy442 && yygotominor.yy442->a ) yygotominor.yy442->a[0].sortOrder = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 153: /* sortorder ::= ASC */
- case 155: /* sortorder ::= */
-{yygotominor.yy392 = SQLITE_SO_ASC;}
- break;
- case 154: /* sortorder ::= DESC */
-{yygotominor.yy392 = SQLITE_SO_DESC;}
- break;
- case 160: /* limit_opt ::= */
-{yygotominor.yy64.pLimit = 0; yygotominor.yy64.pOffset = 0;}
- break;
- case 161: /* limit_opt ::= LIMIT expr */
-{yygotominor.yy64.pLimit = yymsp[0].minor.yy122; yygotominor.yy64.pOffset = 0;}
- break;
- case 162: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yygotominor.yy64.pLimit = yymsp[-2].minor.yy122; yygotominor.yy64.pOffset = yymsp[0].minor.yy122;}
- break;
- case 163: /* limit_opt ::= LIMIT expr COMMA expr */
-{yygotominor.yy64.pOffset = yymsp[-2].minor.yy122; yygotominor.yy64.pLimit = yymsp[0].minor.yy122;}
- break;
- case 164: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
-{
- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy347, &yymsp[-1].minor.yy0);
- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy347,yymsp[0].minor.yy122);
-}
- break;
- case 167: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
-{
- sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy347, &yymsp[-3].minor.yy0);
- sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy442,"set list");
- sqlite3Update(pParse,yymsp[-4].minor.yy347,yymsp[-1].minor.yy442,yymsp[0].minor.yy122,yymsp[-5].minor.yy392);
-}
- break;
- case 168: /* setlist ::= setlist COMMA nm EQ expr */
-{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442,yymsp[0].minor.yy122,&yymsp[-2].minor.yy0);}
- break;
- case 169: /* setlist ::= nm EQ expr */
-{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy122,&yymsp[-2].minor.yy0);}
- break;
- case 170: /* cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP */
-{sqlite3Insert(pParse, yymsp[-5].minor.yy347, yymsp[-1].minor.yy442, 0, yymsp[-4].minor.yy180, yymsp[-7].minor.yy392);}
- break;
- case 171: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
-{sqlite3Insert(pParse, yymsp[-2].minor.yy347, 0, yymsp[0].minor.yy159, yymsp[-1].minor.yy180, yymsp[-4].minor.yy392);}
- break;
- case 172: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
-{sqlite3Insert(pParse, yymsp[-3].minor.yy347, 0, 0, yymsp[-2].minor.yy180, yymsp[-5].minor.yy392);}
- break;
- case 175: /* itemlist ::= itemlist COMMA expr */
- case 239: /* nexprlist ::= nexprlist COMMA expr */
-{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy122,0);}
- break;
- case 176: /* itemlist ::= expr */
- case 240: /* nexprlist ::= expr */
-{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy122,0);}
- break;
- case 179: /* inscollist ::= inscollist COMMA nm */
-{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy180,&yymsp[0].minor.yy0);}
- break;
- case 180: /* inscollist ::= nm */
-{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
- break;
- case 182: /* expr ::= LP expr RP */
-{yygotominor.yy122 = yymsp[-1].minor.yy122; sqlite3ExprSpan(yygotominor.yy122,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
- break;
- case 183: /* term ::= NULL */
- case 188: /* term ::= INTEGER|FLOAT|BLOB */
- case 189: /* term ::= STRING */
-{yygotominor.yy122 = sqlite3PExpr(pParse, yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
- break;
- case 184: /* expr ::= ID */
- case 185: /* expr ::= JOIN_KW */
-{yygotominor.yy122 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);}
- break;
- case 186: /* expr ::= nm DOT nm */
+ case 148: /* using_opt ::= USING LP inscollist RP */
+ case 180: /* inscollist_opt ::= LP inscollist RP */
+{yygotominor.yy254 = yymsp[-1].minor.yy254;}
+ break;
+ case 149: /* using_opt ::= */
+ case 179: /* inscollist_opt ::= */
+{yygotominor.yy254 = 0;}
+ break;
+ case 151: /* orderby_opt ::= ORDER BY sortlist */
+ case 159: /* groupby_opt ::= GROUP BY nexprlist */
+ case 239: /* exprlist ::= nexprlist */
+{yygotominor.yy148 = yymsp[0].minor.yy148;}
+ break;
+ case 152: /* sortlist ::= sortlist COMMA sortitem sortorder */
+{
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148,yymsp[-1].minor.yy72,0);
+ if( yygotominor.yy148 ) yygotominor.yy148->a[yygotominor.yy148->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy194;
+}
+ break;
+ case 153: /* sortlist ::= sortitem sortorder */
+{
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy72,0);
+ if( yygotominor.yy148 && yygotominor.yy148->a ) yygotominor.yy148->a[0].sortOrder = (u8)yymsp[0].minor.yy194;
+}
+ break;
+ case 155: /* sortorder ::= ASC */
+ case 157: /* sortorder ::= */
+{yygotominor.yy194 = SQLITE_SO_ASC;}
+ break;
+ case 156: /* sortorder ::= DESC */
+{yygotominor.yy194 = SQLITE_SO_DESC;}
+ break;
+ case 162: /* limit_opt ::= */
+{yygotominor.yy354.pLimit = 0; yygotominor.yy354.pOffset = 0;}
+ break;
+ case 163: /* limit_opt ::= LIMIT expr */
+{yygotominor.yy354.pLimit = yymsp[0].minor.yy72; yygotominor.yy354.pOffset = 0;}
+ break;
+ case 164: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yygotominor.yy354.pLimit = yymsp[-2].minor.yy72; yygotominor.yy354.pOffset = yymsp[0].minor.yy72;}
+ break;
+ case 165: /* limit_opt ::= LIMIT expr COMMA expr */
+{yygotominor.yy354.pOffset = yymsp[-2].minor.yy72; yygotominor.yy354.pLimit = yymsp[0].minor.yy72;}
+ break;
+ case 166: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
+{
+ sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy185, &yymsp[-1].minor.yy0);
+ sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy185,yymsp[0].minor.yy72);
+}
+ break;
+ case 169: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
+{
+ sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy185, &yymsp[-3].minor.yy0);
+ sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy148,"set list");
+ sqlite3Update(pParse,yymsp[-4].minor.yy185,yymsp[-1].minor.yy148,yymsp[0].minor.yy72,yymsp[-5].minor.yy194);
+}
+ break;
+ case 170: /* setlist ::= setlist COMMA nm EQ expr */
+{yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148,yymsp[0].minor.yy72,&yymsp[-2].minor.yy0);}
+ break;
+ case 171: /* setlist ::= nm EQ expr */
+{yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy72,&yymsp[-2].minor.yy0);}
+ break;
+ case 172: /* cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP */
+{sqlite3Insert(pParse, yymsp[-5].minor.yy185, yymsp[-1].minor.yy148, 0, yymsp[-4].minor.yy254, yymsp[-7].minor.yy194);}
+ break;
+ case 173: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
+{sqlite3Insert(pParse, yymsp[-2].minor.yy185, 0, yymsp[0].minor.yy243, yymsp[-1].minor.yy254, yymsp[-4].minor.yy194);}
+ break;
+ case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
+{sqlite3Insert(pParse, yymsp[-3].minor.yy185, 0, 0, yymsp[-2].minor.yy254, yymsp[-5].minor.yy194);}
+ break;
+ case 177: /* itemlist ::= itemlist COMMA expr */
+ case 241: /* nexprlist ::= nexprlist COMMA expr */
+{yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy72,0);}
+ break;
+ case 178: /* itemlist ::= expr */
+ case 242: /* nexprlist ::= expr */
+{yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy72,0);}
+ break;
+ case 181: /* inscollist ::= inscollist COMMA nm */
+{yygotominor.yy254 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
+ break;
+ case 182: /* inscollist ::= nm */
+{yygotominor.yy254 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
+ break;
+ case 184: /* expr ::= LP expr RP */
+{yygotominor.yy72 = yymsp[-1].minor.yy72; sqlite3ExprSpan(yygotominor.yy72,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
+ break;
+ case 185: /* term ::= NULL */
+ case 190: /* term ::= INTEGER|FLOAT|BLOB */
+ case 191: /* term ::= STRING */
+{yygotominor.yy72 = sqlite3PExpr(pParse, yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
+ break;
+ case 186: /* expr ::= id */
+ case 187: /* expr ::= JOIN_KW */
+{yygotominor.yy72 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);}
+ break;
+ case 188: /* expr ::= nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
-}
- break;
- case 187: /* expr ::= nm DOT nm DOT nm */
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
+}
+ break;
+ case 189: /* expr ::= nm DOT nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
-}
- break;
- case 190: /* expr ::= REGISTER */
-{yygotominor.yy122 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
- break;
- case 191: /* expr ::= VARIABLE */
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
+}
+ break;
+ case 192: /* expr ::= REGISTER */
+{yygotominor.yy72 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
+ break;
+ case 193: /* expr ::= VARIABLE */
{
Token *pToken = &yymsp[0].minor.yy0;
- Expr *pExpr = yygotominor.yy122 = sqlite3PExpr(pParse, TK_VARIABLE, 0, 0, pToken);
+ Expr *pExpr = yygotominor.yy72 = sqlite3PExpr(pParse, TK_VARIABLE, 0, 0, pToken);
sqlite3ExprAssignVarNumber(pParse, pExpr);
}
break;
- case 192: /* expr ::= expr COLLATE ids */
-{
- yygotominor.yy122 = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy122, &yymsp[0].minor.yy0);
-}
- break;
- case 193: /* expr ::= CAST LP expr AS typetoken RP */
-{
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy122, 0, &yymsp[-1].minor.yy0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
-}
- break;
- case 194: /* expr ::= ID LP distinct exprlist RP */
-{
- if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>SQLITE_MAX_FUNCTION_ARG ){
+ case 194: /* expr ::= expr COLLATE ids */
+{
+ yygotominor.yy72 = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy72, &yymsp[0].minor.yy0);
+}
+ break;
+ case 195: /* expr ::= CAST LP expr AS typetoken RP */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy72, 0, &yymsp[-1].minor.yy0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
+}
+ break;
+ case 196: /* expr ::= ID LP distinct exprlist RP */
+{
+ if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>SQLITE_MAX_FUNCTION_ARG ){
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
}
- yygotominor.yy122 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
- if( yymsp[-2].minor.yy392 && yygotominor.yy122 ){
- yygotominor.yy122->flags |= EP_Distinct;
- }
-}
- break;
- case 195: /* expr ::= ID LP STAR RP */
-{
- yygotominor.yy122 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
-}
- break;
- case 196: /* term ::= CTIME_KW */
+ yygotominor.yy72 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+ if( yymsp[-2].minor.yy194 && yygotominor.yy72 ){
+ yygotominor.yy72->flags |= EP_Distinct;
+ }
+}
+ break;
+ case 197: /* expr ::= ID LP STAR RP */
+{
+ yygotominor.yy72 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+}
+ break;
+ case 198: /* term ::= CTIME_KW */
{
/* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
** treated as functions that return constants */
- yygotominor.yy122 = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
- if( yygotominor.yy122 ){
- yygotominor.yy122->op = TK_CONST_FUNC;
- yygotominor.yy122->span = yymsp[0].minor.yy0;
- }
-}
- break;
- case 197: /* expr ::= expr AND expr */
- case 198: /* expr ::= expr OR expr */
- case 199: /* expr ::= expr LT|GT|GE|LE expr */
- case 200: /* expr ::= expr EQ|NE expr */
- case 201: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
- case 202: /* expr ::= expr PLUS|MINUS expr */
- case 203: /* expr ::= expr STAR|SLASH|REM expr */
- case 204: /* expr ::= expr CONCAT expr */
-{yygotominor.yy122 = sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy122,yymsp[0].minor.yy122,0);}
- break;
- case 205: /* likeop ::= LIKE_KW */
- case 207: /* likeop ::= MATCH */
-{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.not = 0;}
- break;
- case 206: /* likeop ::= NOT LIKE_KW */
- case 208: /* likeop ::= NOT MATCH */
-{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.not = 1;}
- break;
- case 211: /* expr ::= expr likeop expr escape */
+ yygotominor.yy72 = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
+ if( yygotominor.yy72 ){
+ yygotominor.yy72->op = TK_CONST_FUNC;
+ yygotominor.yy72->span = yymsp[0].minor.yy0;
+ }
+}
+ break;
+ case 199: /* expr ::= expr AND expr */
+ case 200: /* expr ::= expr OR expr */
+ case 201: /* expr ::= expr LT|GT|GE|LE expr */
+ case 202: /* expr ::= expr EQ|NE expr */
+ case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+ case 204: /* expr ::= expr PLUS|MINUS expr */
+ case 205: /* expr ::= expr STAR|SLASH|REM expr */
+ case 206: /* expr ::= expr CONCAT expr */
+{yygotominor.yy72 = sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy72,yymsp[0].minor.yy72,0);}
+ break;
+ case 207: /* likeop ::= LIKE_KW */
+ case 209: /* likeop ::= MATCH */
+{yygotominor.yy392.eOperator = yymsp[0].minor.yy0; yygotominor.yy392.not = 0;}
+ break;
+ case 208: /* likeop ::= NOT LIKE_KW */
+ case 210: /* likeop ::= NOT MATCH */
+{yygotominor.yy392.eOperator = yymsp[0].minor.yy0; yygotominor.yy392.not = 1;}
+ break;
+ case 213: /* expr ::= expr likeop expr escape */
{
ExprList *pList;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[-1].minor.yy122, 0);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-3].minor.yy122, 0);
- if( yymsp[0].minor.yy122 ){
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy122, 0);
- }
- yygotominor.yy122 = sqlite3ExprFunction(pParse, pList, &yymsp[-2].minor.yy318.eOperator);
- if( yymsp[-2].minor.yy318.not ) yygotominor.yy122 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy122, 0, 0);
- sqlite3ExprSpan(yygotominor.yy122, &yymsp[-3].minor.yy122->span, &yymsp[-1].minor.yy122->span);
- if( yygotominor.yy122 ) yygotominor.yy122->flags |= EP_InfixFunc;
-}
- break;
- case 212: /* expr ::= expr ISNULL|NOTNULL */
-{
- yygotominor.yy122 = sqlite3PExpr(pParse, yymsp[0].major, yymsp[-1].minor.yy122, 0, 0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-1].minor.yy122->span,&yymsp[0].minor.yy0);
-}
- break;
- case 213: /* expr ::= expr IS NULL */
-{
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_ISNULL, yymsp[-2].minor.yy122, 0, 0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-2].minor.yy122->span,&yymsp[0].minor.yy0);
-}
- break;
- case 214: /* expr ::= expr NOT NULL */
-{
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-2].minor.yy122, 0, 0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-2].minor.yy122->span,&yymsp[0].minor.yy0);
-}
- break;
- case 215: /* expr ::= expr IS NOT NULL */
-{
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-3].minor.yy122, 0, 0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-3].minor.yy122->span,&yymsp[0].minor.yy0);
-}
- break;
- case 216: /* expr ::= NOT expr */
- case 217: /* expr ::= BITNOT expr */
-{
- yygotominor.yy122 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy122, 0, 0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy122->span);
-}
- break;
- case 218: /* expr ::= MINUS expr */
-{
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy122, 0, 0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy122->span);
-}
- break;
- case 219: /* expr ::= PLUS expr */
-{
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_UPLUS, yymsp[0].minor.yy122, 0, 0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy122->span);
-}
- break;
- case 222: /* expr ::= expr between_op expr AND expr */
-{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy122, 0);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy122, 0);
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy122, 0, 0);
- if( yygotominor.yy122 ){
- yygotominor.yy122->pList = pList;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-1].minor.yy72, 0);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-3].minor.yy72, 0);
+ if( yymsp[0].minor.yy72 ){
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy72, 0);
+ }
+ yygotominor.yy72 = sqlite3ExprFunction(pParse, pList, &yymsp[-2].minor.yy392.eOperator);
+ if( yymsp[-2].minor.yy392.not ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
+ sqlite3ExprSpan(yygotominor.yy72, &yymsp[-3].minor.yy72->span, &yymsp[-1].minor.yy72->span);
+ if( yygotominor.yy72 ) yygotominor.yy72->flags |= EP_InfixFunc;
+}
+ break;
+ case 214: /* expr ::= expr ISNULL|NOTNULL */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, yymsp[0].major, yymsp[-1].minor.yy72, 0, 0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-1].minor.yy72->span,&yymsp[0].minor.yy0);
+}
+ break;
+ case 215: /* expr ::= expr IS NULL */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_ISNULL, yymsp[-2].minor.yy72, 0, 0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-2].minor.yy72->span,&yymsp[0].minor.yy0);
+}
+ break;
+ case 216: /* expr ::= expr NOT NULL */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-2].minor.yy72, 0, 0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-2].minor.yy72->span,&yymsp[0].minor.yy0);
+}
+ break;
+ case 217: /* expr ::= expr IS NOT NULL */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-3].minor.yy72, 0, 0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-3].minor.yy72->span,&yymsp[0].minor.yy0);
+}
+ break;
+ case 218: /* expr ::= NOT expr */
+ case 219: /* expr ::= BITNOT expr */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy72, 0, 0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72->span);
+}
+ break;
+ case 220: /* expr ::= MINUS expr */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy72, 0, 0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72->span);
+}
+ break;
+ case 221: /* expr ::= PLUS expr */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_UPLUS, yymsp[0].minor.yy72, 0, 0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72->span);
+}
+ break;
+ case 224: /* expr ::= expr between_op expr AND expr */
+{
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy72, 0);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy72, 0);
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy72, 0, 0);
+ if( yygotominor.yy72 ){
+ yygotominor.yy72->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- if( yymsp[-3].minor.yy392 ) yygotominor.yy122 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy122, 0, 0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-4].minor.yy122->span,&yymsp[0].minor.yy122->span);
-}
- break;
- case 225: /* expr ::= expr in_op LP exprlist RP */
-{
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy122, 0, 0);
- if( yygotominor.yy122 ){
- yygotominor.yy122->pList = yymsp[-1].minor.yy442;
- sqlite3ExprSetHeight(pParse, yygotominor.yy122);
- }else{
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy442);
- }
- if( yymsp[-3].minor.yy392 ) yygotominor.yy122 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy122, 0, 0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-4].minor.yy122->span,&yymsp[0].minor.yy0);
- }
- break;
- case 226: /* expr ::= LP select RP */
-{
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
- if( yygotominor.yy122 ){
- yygotominor.yy122->pSelect = yymsp[-1].minor.yy159;
- sqlite3ExprSetHeight(pParse, yygotominor.yy122);
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
- }
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
- }
- break;
- case 227: /* expr ::= expr in_op LP select RP */
-{
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy122, 0, 0);
- if( yygotominor.yy122 ){
- yygotominor.yy122->pSelect = yymsp[-1].minor.yy159;
- sqlite3ExprSetHeight(pParse, yygotominor.yy122);
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
- }
- if( yymsp[-3].minor.yy392 ) yygotominor.yy122 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy122, 0, 0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-4].minor.yy122->span,&yymsp[0].minor.yy0);
- }
- break;
- case 228: /* expr ::= expr in_op nm dbnm */
+ if( yymsp[-3].minor.yy194 ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-4].minor.yy72->span,&yymsp[0].minor.yy72->span);
+}
+ break;
+ case 227: /* expr ::= expr in_op LP exprlist RP */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy72, 0, 0);
+ if( yygotominor.yy72 ){
+ yygotominor.yy72->x.pList = yymsp[-1].minor.yy148;
+ sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ }else{
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
+ }
+ if( yymsp[-3].minor.yy194 ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-4].minor.yy72->span,&yymsp[0].minor.yy0);
+ }
+ break;
+ case 228: /* expr ::= LP select RP */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
+ if( yygotominor.yy72 ){
+ yygotominor.yy72->x.pSelect = yymsp[-1].minor.yy243;
+ ExprSetProperty(yygotominor.yy72, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ }else{
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy243);
+ }
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+ }
+ break;
+ case 229: /* expr ::= expr in_op LP select RP */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy72, 0, 0);
+ if( yygotominor.yy72 ){
+ yygotominor.yy72->x.pSelect = yymsp[-1].minor.yy243;
+ ExprSetProperty(yygotominor.yy72, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ }else{
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy243);
+ }
+ if( yymsp[-3].minor.yy194 ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-4].minor.yy72->span,&yymsp[0].minor.yy0);
+ }
+ break;
+ case 230: /* expr ::= expr in_op nm dbnm */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy122, 0, 0);
- if( yygotominor.yy122 ){
- yygotominor.yy122->pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
- sqlite3ExprSetHeight(pParse, yygotominor.yy122);
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy72, 0, 0);
+ if( yygotominor.yy72 ){
+ yygotominor.yy72->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
+ ExprSetProperty(yygotominor.yy72, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy72);
}else{
sqlite3SrcListDelete(pParse->db, pSrc);
}
- if( yymsp[-2].minor.yy392 ) yygotominor.yy122 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy122, 0, 0);
- sqlite3ExprSpan(yygotominor.yy122,&yymsp[-3].minor.yy122->span,yymsp[0].minor.yy0.z?&yymsp[0].minor.yy0:&yymsp[-1].minor.yy0);
- }
- break;
- case 229: /* expr ::= EXISTS LP select RP */
-{
- Expr *p = yygotominor.yy122 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
+ if( yymsp[-2].minor.yy194 ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
+ sqlite3ExprSpan(yygotominor.yy72,&yymsp[-3].minor.yy72->span,yymsp[0].minor.yy0.z?&yymsp[0].minor.yy0:&yymsp[-1].minor.yy0);
+ }
+ break;
+ case 231: /* expr ::= EXISTS LP select RP */
+{
+ Expr *p = yygotominor.yy72 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
- p->pSelect = yymsp[-1].minor.yy159;
+ p->x.pSelect = yymsp[-1].minor.yy243;
+ ExprSetProperty(yygotominor.yy72, EP_xIsSelect);
sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
- sqlite3ExprSetHeight(pParse, yygotominor.yy122);
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
- }
- }
- break;
- case 230: /* expr ::= CASE case_operand case_exprlist case_else END */
-{
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy122, yymsp[-1].minor.yy122, 0);
- if( yygotominor.yy122 ){
- yygotominor.yy122->pList = yymsp[-2].minor.yy442;
- sqlite3ExprSetHeight(pParse, yygotominor.yy122);
- }else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy442);
- }
- sqlite3ExprSpan(yygotominor.yy122, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
-}
- break;
- case 231: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, yymsp[-2].minor.yy122, 0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy122, 0);
-}
- break;
- case 232: /* case_exprlist ::= WHEN expr THEN expr */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy122, 0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy122, 0);
-}
- break;
- case 241: /* cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
+ sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ }else{
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy243);
+ }
+ }
+ break;
+ case 232: /* expr ::= CASE case_operand case_exprlist case_else END */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, yymsp[-1].minor.yy72, 0);
+ if( yygotominor.yy72 ){
+ yygotominor.yy72->x.pList = yymsp[-2].minor.yy148;
+ sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ }else{
+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy148);
+ }
+ sqlite3ExprSpan(yygotominor.yy72, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
+}
+ break;
+ case 233: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+{
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy72, 0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yygotominor.yy148, yymsp[0].minor.yy72, 0);
+}
+ break;
+ case 234: /* case_exprlist ::= WHEN expr THEN expr */
+{
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy72, 0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yygotominor.yy148, yymsp[0].minor.yy72, 0);
+}
+ break;
+ case 243: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
{
sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0,
- sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy442, yymsp[-9].minor.yy392,
- &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy392);
-}
- break;
- case 242: /* uniqueflag ::= UNIQUE */
- case 289: /* raisetype ::= ABORT */
-{yygotominor.yy392 = OE_Abort;}
- break;
- case 243: /* uniqueflag ::= */
-{yygotominor.yy392 = OE_None;}
- break;
- case 246: /* idxlist ::= idxlist COMMA nm collate sortorder */
+ sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy148, yymsp[-9].minor.yy194,
+ &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy194);
+}
+ break;
+ case 244: /* uniqueflag ::= UNIQUE */
+ case 291: /* raisetype ::= ABORT */
+{yygotominor.yy194 = OE_Abort;}
+ break;
+ case 245: /* uniqueflag ::= */
+{yygotominor.yy194 = OE_None;}
+ break;
+ case 248: /* idxlist ::= idxlist COMMA nm collate sortorder */
+{
+ Expr *p = 0;
+ if( yymsp[-1].minor.yy0.n>0 ){
+ p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
+ sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
+ }
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, p, &yymsp[-2].minor.yy0);
+ sqlite3ExprListCheckLength(pParse, yygotominor.yy148, "index");
+ if( yygotominor.yy148 ) yygotominor.yy148->a[yygotominor.yy148->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy194;
+}
+ break;
+ case 249: /* idxlist ::= nm collate sortorder */
{
Expr *p = 0;
if( yymsp[-1].minor.yy0.n>0 ){
p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
}
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p, &yymsp[-2].minor.yy0);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
- if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 247: /* idxlist ::= nm collate sortorder */
-{
- Expr *p = 0;
- if( yymsp[-1].minor.yy0.n>0 ){
- p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
- sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
- }
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p, &yymsp[-2].minor.yy0);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
- if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 248: /* collate ::= */
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,0, p, &yymsp[-2].minor.yy0);
+ sqlite3ExprListCheckLength(pParse, yygotominor.yy148, "index");
+ if( yygotominor.yy148 ) yygotominor.yy148->a[yygotominor.yy148->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy194;
+}
+ break;
+ case 250: /* collate ::= */
{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
break;
- case 250: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy347, yymsp[-1].minor.yy392);}
- break;
- case 251: /* cmd ::= VACUUM */
- case 252: /* cmd ::= VACUUM nm */
+ case 252: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
+ break;
+ case 253: /* cmd ::= VACUUM */
+ case 254: /* cmd ::= VACUUM nm */
{sqlite3Vacuum(pParse);}
break;
- case 253: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
- case 254: /* cmd ::= PRAGMA nm dbnm EQ ON */
- case 255: /* cmd ::= PRAGMA nm dbnm EQ DELETE */
+ case 255: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 256: /* cmd ::= PRAGMA nm dbnm EQ ON */
+ case 257: /* cmd ::= PRAGMA nm dbnm EQ DELETE */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 256: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 258: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{
sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);
}
break;
- case 257: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 259: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 258: /* cmd ::= PRAGMA nm dbnm */
+ case 260: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 266: /* cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END */
+ case 268: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
- sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy327, &all);
-}
- break;
- case 267: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy145, &all);
+}
+ break;
+ case 269: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
- sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy392, yymsp[-4].minor.yy410.a, yymsp[-4].minor.yy410.b, yymsp[-2].minor.yy347, yymsp[0].minor.yy122, yymsp[-10].minor.yy392, yymsp[-8].minor.yy392);
+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy194, yymsp[-4].minor.yy332.a, yymsp[-4].minor.yy332.b, yymsp[-2].minor.yy185, yymsp[0].minor.yy72, yymsp[-10].minor.yy194, yymsp[-8].minor.yy194);
yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
}
break;
- case 268: /* trigger_time ::= BEFORE */
- case 271: /* trigger_time ::= */
-{ yygotominor.yy392 = TK_BEFORE; }
- break;
- case 269: /* trigger_time ::= AFTER */
-{ yygotominor.yy392 = TK_AFTER; }
- break;
- case 270: /* trigger_time ::= INSTEAD OF */
-{ yygotominor.yy392 = TK_INSTEAD;}
- break;
- case 272: /* trigger_event ::= DELETE|INSERT */
- case 273: /* trigger_event ::= UPDATE */
-{yygotominor.yy410.a = yymsp[0].major; yygotominor.yy410.b = 0;}
- break;
- case 274: /* trigger_event ::= UPDATE OF inscollist */
-{yygotominor.yy410.a = TK_UPDATE; yygotominor.yy410.b = yymsp[0].minor.yy180;}
- break;
- case 277: /* when_clause ::= */
- case 294: /* key_opt ::= */
-{ yygotominor.yy122 = 0; }
- break;
- case 278: /* when_clause ::= WHEN expr */
- case 295: /* key_opt ::= KEY expr */
-{ yygotominor.yy122 = yymsp[0].minor.yy122; }
- break;
- case 279: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 270: /* trigger_time ::= BEFORE */
+ case 273: /* trigger_time ::= */
+{ yygotominor.yy194 = TK_BEFORE; }
+ break;
+ case 271: /* trigger_time ::= AFTER */
+{ yygotominor.yy194 = TK_AFTER; }
+ break;
+ case 272: /* trigger_time ::= INSTEAD OF */
+{ yygotominor.yy194 = TK_INSTEAD;}
+ break;
+ case 274: /* trigger_event ::= DELETE|INSERT */
+ case 275: /* trigger_event ::= UPDATE */
+{yygotominor.yy332.a = yymsp[0].major; yygotominor.yy332.b = 0;}
+ break;
+ case 276: /* trigger_event ::= UPDATE OF inscollist */
+{yygotominor.yy332.a = TK_UPDATE; yygotominor.yy332.b = yymsp[0].minor.yy254;}
+ break;
+ case 279: /* when_clause ::= */
+ case 296: /* key_opt ::= */
+{ yygotominor.yy72 = 0; }
+ break;
+ case 280: /* when_clause ::= WHEN expr */
+ case 297: /* key_opt ::= KEY expr */
+{ yygotominor.yy72 = yymsp[0].minor.yy72; }
+ break;
+ case 281: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+{
+/*
+ if( yymsp[-2].minor.yy145 ){
+ yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145;
+ }else{
+ yymsp[-2].minor.yy145 = yymsp[-1].minor.yy145;
+ }
+*/
+ assert( yymsp[-2].minor.yy145!=0 );
+ yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145;
+ yymsp[-2].minor.yy145->pLast = yymsp[-1].minor.yy145;
+ yygotominor.yy145 = yymsp[-2].minor.yy145;
+}
+ break;
+ case 282: /* trigger_cmd_list ::= trigger_cmd SEMI */
+{
+ /* if( yymsp[-1].minor.yy145 ) */
+ assert( yymsp[-1].minor.yy145!=0 );
+ yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145;
+ yygotominor.yy145 = yymsp[-1].minor.yy145;
+}
+ break;
+ case 283: /* trigger_cmd ::= UPDATE orconf nm SET setlist where_opt */
+{ yygotominor.yy145 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy148, yymsp[0].minor.yy72, yymsp[-4].minor.yy194); }
+ break;
+ case 284: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP */
+{yygotominor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy254, yymsp[-1].minor.yy148, 0, yymsp[-7].minor.yy194);}
+ break;
+ case 285: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt select */
+{yygotominor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy254, 0, yymsp[0].minor.yy243, yymsp[-4].minor.yy194);}
+ break;
+ case 286: /* trigger_cmd ::= DELETE FROM nm where_opt */
+{yygotominor.yy145 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-1].minor.yy0, yymsp[0].minor.yy72);}
+ break;
+ case 287: /* trigger_cmd ::= select */
+{yygotominor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); }
+ break;
+ case 288: /* expr ::= RAISE LP IGNORE RP */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
+ if( yygotominor.yy72 ){
+ yygotominor.yy72->affinity = OE_Ignore;
+ sqlite3ExprSpan(yygotominor.yy72, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
+ }
+}
+ break;
+ case 289: /* expr ::= RAISE LP raisetype COMMA nm RP */
+{
+ yygotominor.yy72 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
+ if( yygotominor.yy72 ) {
+ yygotominor.yy72->affinity = (char)yymsp[-3].minor.yy194;
+ sqlite3ExprSpan(yygotominor.yy72, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
+ }
+}
+ break;
+ case 290: /* raisetype ::= ROLLBACK */
+{yygotominor.yy194 = OE_Rollback;}
+ break;
+ case 292: /* raisetype ::= FAIL */
+{yygotominor.yy194 = OE_Fail;}
+ break;
+ case 293: /* cmd ::= DROP TRIGGER ifexists fullname */
{
-/*
- if( yymsp[-2].minor.yy327 ){
- yymsp[-2].minor.yy327->pLast->pNext = yymsp[-1].minor.yy327;
- }else{
- yymsp[-2].minor.yy327 = yymsp[-1].minor.yy327;
- }
-*/
- assert( yymsp[-2].minor.yy327!=0 );
- yymsp[-2].minor.yy327->pLast->pNext = yymsp[-1].minor.yy327;
- yymsp[-2].minor.yy327->pLast = yymsp[-1].minor.yy327;
- yygotominor.yy327 = yymsp[-2].minor.yy327;
-}
- break;
- case 280: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194);
+}
+ break;
+ case 294: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
- /* if( yymsp[-1].minor.yy327 ) */
- assert( yymsp[-1].minor.yy327!=0 );
- yymsp[-1].minor.yy327->pLast = yymsp[-1].minor.yy327;
- yygotominor.yy327 = yymsp[-1].minor.yy327;
-}
- break;
- case 281: /* trigger_cmd ::= UPDATE orconf nm SET setlist where_opt */
-{ yygotominor.yy327 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy442, yymsp[0].minor.yy122, yymsp[-4].minor.yy392); }
- break;
- case 282: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP */
-{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy180, yymsp[-1].minor.yy442, 0, yymsp[-7].minor.yy392);}
- break;
- case 283: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt select */
-{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, 0, yymsp[0].minor.yy159, yymsp[-4].minor.yy392);}
- break;
- case 284: /* trigger_cmd ::= DELETE FROM nm where_opt */
-{yygotominor.yy327 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-1].minor.yy0, yymsp[0].minor.yy122);}
- break;
- case 285: /* trigger_cmd ::= select */
-{yygotominor.yy327 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy159); }
- break;
- case 286: /* expr ::= RAISE LP IGNORE RP */
+ sqlite3Attach(pParse, yymsp[-3].minor.yy72, yymsp[-1].minor.yy72, yymsp[0].minor.yy72);
+}
+ break;
+ case 295: /* cmd ::= DETACH database_kw_opt expr */
{
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
- if( yygotominor.yy122 ){
- yygotominor.yy122->iColumn = OE_Ignore;
- sqlite3ExprSpan(yygotominor.yy122, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
- }
-}
- break;
- case 287: /* expr ::= RAISE LP raisetype COMMA nm RP */
-{
- yygotominor.yy122 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
- if( yygotominor.yy122 ) {
- yygotominor.yy122->iColumn = yymsp[-3].minor.yy392;
- sqlite3ExprSpan(yygotominor.yy122, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
- }
-}
- break;
- case 288: /* raisetype ::= ROLLBACK */
-{yygotominor.yy392 = OE_Rollback;}
- break;
- case 290: /* raisetype ::= FAIL */
-{yygotominor.yy392 = OE_Fail;}
- break;
- case 291: /* cmd ::= DROP TRIGGER ifexists fullname */
-{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy347,yymsp[-1].minor.yy392);
-}
- break;
- case 292: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
-{
- sqlite3Attach(pParse, yymsp[-3].minor.yy122, yymsp[-1].minor.yy122, yymsp[0].minor.yy122);
-}
- break;
- case 293: /* cmd ::= DETACH database_kw_opt expr */
-{
- sqlite3Detach(pParse, yymsp[0].minor.yy122);
-}
- break;
- case 298: /* cmd ::= REINDEX */
+ sqlite3Detach(pParse, yymsp[0].minor.yy72);
+}
+ break;
+ case 300: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 299: /* cmd ::= REINDEX nm dbnm */
+ case 301: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 300: /* cmd ::= ANALYZE */
+ case 302: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 301: /* cmd ::= ANALYZE nm dbnm */
+ case 303: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 302: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 304: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy347,&yymsp[0].minor.yy0);
-}
- break;
- case 303: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0);
+}
+ break;
+ case 305: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
{
sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
}
break;
- case 304: /* add_column_fullname ::= fullname */
+ case 306: /* add_column_fullname ::= fullname */
{
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy347);
-}
- break;
- case 307: /* cmd ::= create_vtab */
+ pParse->db->lookaside.bEnabled = 0;
+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185);
+}
+ break;
+ case 309: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 308: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 310: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
- case 309: /* create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm */
+ case 311: /* create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm */
{
sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 312: /* vtabarg ::= */
+ case 314: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 314: /* vtabargtoken ::= ANY */
- case 315: /* vtabargtoken ::= lp anylist RP */
- case 316: /* lp ::= LP */
- case 318: /* anylist ::= anylist ANY */
+ case 316: /* vtabargtoken ::= ANY */
+ case 317: /* vtabargtoken ::= lp anylist RP */
+ case 318: /* lp ::= LP */
+ case 320: /* anylist ::= anylist ANY */
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
};
yygoto = yyRuleInfo[yyruleno].lhs;
@@ -85885,10 +87123,10 @@
** That gives a significant speed improvement. */
if( yysize ){
yypParser->yyidx++;
yymsp -= yysize-1;
- yymsp->stateno = yyact;
- yymsp->major = yygoto;
+ yymsp->stateno = (YYACTIONTYPE)yyact;
+ yymsp->major = (YYCODETYPE)yygoto;
yymsp->minor = yygotominor;
}else
#endif
{
@@ -86130,9 +87368,9 @@
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
-** $Id: tokenize.c,v 1.152 2008/09/01 15:52:11 drh Exp $
+** $Id: tokenize.c,v 1.155 2009/03/31 03:41:57 shane Exp $
*/
/*
** The charMap() macro maps alphabetic characters into their
@@ -86183,9 +87421,9 @@
/***** This file contains automatically generated code ******
**
** The code in this file has been automatically generated by
**
-** $Header: /sqlite/sqlite/tool/mkkeywordhash.c,v 1.36 2008/12/31 21:52:41 drh Exp $
+** $Header: /sqlite/sqlite/tool/mkkeywordhash.c,v 1.37 2009/02/01 00:00:46 drh Exp $
**
** The code in this file implements a function that determines whether
** or not a given identifier is really an SQL keyword. The same thing
** might be implemented more directly using a hand-written hash table.
@@ -86506,9 +87744,9 @@
SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
int i, c;
switch( *z ){
case ' ': case '\t': case '\n': case '\f': case '\r': {
- for(i=1; isspace(z[i]); i++){}
+ for(i=1; sqlite3Isspace(z[i]); i++){}
*tokenType = TK_SPACE;
return i;
}
case '-': {
@@ -86640,9 +87878,9 @@
}
}
case '.': {
#ifndef SQLITE_OMIT_FLOATING_POINT
- if( !isdigit(z[1]) )
+ if( !sqlite3Isdigit(z[1]) )
#endif
{
*tokenType = TK_DOT;
return 1;
@@ -86652,22 +87890,22 @@
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': {
*tokenType = TK_INTEGER;
- for(i=0; isdigit(z[i]); i++){}
+ for(i=0; sqlite3Isdigit(z[i]); i++){}
#ifndef SQLITE_OMIT_FLOATING_POINT
if( z[i]=='.' ){
i++;
- while( isdigit(z[i]) ){ i++; }
+ while( sqlite3Isdigit(z[i]) ){ i++; }
*tokenType = TK_FLOAT;
}
if( (z[i]=='e' || z[i]=='E') &&
- ( isdigit(z[i+1])
- || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))
+ ( sqlite3Isdigit(z[i+1])
+ || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2]))
)
){
i += 2;
- while( isdigit(z[i]) ){ i++; }
+ while( sqlite3Isdigit(z[i]) ){ i++; }
*tokenType = TK_FLOAT;
}
#endif
while( IdChar(z[i]) ){
@@ -86682,13 +87920,13 @@
return i;
}
case '?': {
*tokenType = TK_VARIABLE;
- for(i=1; isdigit(z[i]); i++){}
+ for(i=1; sqlite3Isdigit(z[i]); i++){}
return i;
}
case '#': {
- for(i=1; isdigit(z[i]); i++){}
+ for(i=1; sqlite3Isdigit(z[i]); i++){}
if( i>1 ){
/* Parameters of the form #NNN (where NNN is a number) are used
** internally by sqlite3NestedParse. */
*tokenType = TK_REGISTER;
@@ -86710,9 +87948,9 @@
#ifndef SQLITE_OMIT_TCL_VARIABLE
}else if( c=='(' && n>0 ){
do{
i++;
- }while( (c=z[i])!=0 && !isspace(c) && c!=')' );
+ }while( (c=z[i])!=0 && !sqlite3Isspace(c) && c!=')' );
if( c==')' ){
i++;
}else{
*tokenType = TK_ILLEGAL;
@@ -86732,9 +87970,9 @@
case 'x': case 'X': {
if( z[1]=='\'' ){
*tokenType = TK_BLOB;
for(i=2; (c=z[i])!=0 && c!='\''; i++){
- if( !isxdigit(c) ){
+ if( !sqlite3Isxdigit(c) ){
*tokenType = TK_ILLEGAL;
}
}
if( i%2 || !c ) *tokenType = TK_ILLEGAL;
@@ -86764,16 +88002,19 @@
** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that
** error message.
*/
SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
- int nErr = 0;
- int i;
- void *pEngine;
- int tokenType;
- int lastTokenParsed = -1;
- sqlite3 *db = pParse->db;
- int mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
-
+ int nErr = 0; /* Number of errors encountered */
+ int i; /* Loop counter */
+ void *pEngine; /* The LEMON-generated LALR(1) parser */
+ int tokenType; /* type of the next token */
+ int lastTokenParsed = -1; /* type of the previous token */
+ u8 enableLookaside; /* Saved value of db->lookaside.bEnabled */
+ sqlite3 *db = pParse->db; /* The database connection */
+ int mxSqlLen; /* Max length of an SQL string */
+
+
+ mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
if( db->activeVdbeCnt==0 ){
db->u1.isInterrupted = 0;
}
pParse->rc = SQLITE_OK;
@@ -86791,8 +88032,10 @@
assert( pParse->nVar==0 );
assert( pParse->nVarExpr==0 );
assert( pParse->nVarExprAlloc==0 );
assert( pParse->apVarExpr==0 );
+ enableLookaside = db->lookaside.bEnabled;
+ if( db->lookaside.pStart ) db->lookaside.bEnabled = 1;
while( !db->mallocFailed && zSql[i]!=0 ){
assert( i>=0 );
pParse->sLastToken.z = (u8*)&zSql[i];
assert( pParse->sLastToken.dyn==0 );
@@ -86845,8 +88088,9 @@
sqlite3ParserStackPeak(pEngine)
);
#endif /* YYDEBUG */
sqlite3ParserFree(pEngine, sqlite3_free);
+ db->lookaside.bEnabled = enableLookaside;
if( db->mallocFailed ){
pParse->rc = SQLITE_NOMEM;
}
if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
@@ -87194,9 +88438,9 @@
** implement the programmer interface to the library. Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.521 2009/01/10 16:15:22 drh Exp $
+** $Id: main.c,v 1.534 2009/03/23 04:33:32 danielk1977 Exp $
*/
#ifdef SQLITE_ENABLE_FTS3
/************** Include fts3.h in the middle of main.c ***********************/
@@ -87458,8 +88702,9 @@
** we don't want to run it too often and soak up CPU cycles for no
** reason. So we run it once during initialization.
*/
#ifndef NDEBUG
+#ifndef SQLITE_OMIT_FLOATING_POINT
/* This section of code's only "output" is via assert() statements. */
if ( rc==SQLITE_OK ){
u64 x = (((u64)1)<<63)-1;
double y;
@@ -87467,8 +88712,9 @@
assert(sizeof(x)==sizeof(y));
memcpy(&y, &x, 8);
assert( sqlite3IsNaN(y) );
}
+#endif
#endif
return rc;
}
@@ -87653,29 +88899,39 @@
void *pStart;
if( db->lookaside.nOut ){
return SQLITE_BUSY;
}
- if( sz<0 ) sz = 0;
+ /* Free any existing lookaside buffer for this handle before
+ ** allocating a new one so we don't have to have space for
+ ** both at the same time.
+ */
+ if( db->lookaside.bMalloced ){
+ sqlite3_free(db->lookaside.pStart);
+ }
+ /* The size of a lookaside slot needs to be larger than a pointer
+ ** to be useful.
+ */
+ if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
if( cnt<0 ) cnt = 0;
- if( pBuf==0 ){
- sz = (sz + 7)&~7;
+ if( sz==0 || cnt==0 ){
+ sz = 0;
+ pStart = 0;
+ }else if( pBuf==0 ){
+ sz = ROUND8(sz);
sqlite3BeginBenignMalloc();
pStart = sqlite3Malloc( sz*cnt );
sqlite3EndBenignMalloc();
}else{
- sz = sz&~7;
- pStart = pBuf;
- }
- if( db->lookaside.bMalloced ){
- sqlite3_free(db->lookaside.pStart);
+ sz = ROUNDDOWN8(sz);
+ pStart = pBuf;
}
db->lookaside.pStart = pStart;
db->lookaside.pFree = 0;
db->lookaside.sz = (u16)sz;
- db->lookaside.bMalloced = pBuf==0 ?1:0;
if( pStart ){
int i;
LookasideSlot *p;
+ assert( sz > sizeof(LookasideSlot*) );
p = (LookasideSlot*)pStart;
for(i=cnt-1; i>=0; i--){
p->pNext = db->lookaside.pFree;
db->lookaside.pFree = p;
@@ -87682,11 +88938,13 @@
p = (LookasideSlot*)&((u8*)p)[sz];
}
db->lookaside.pEnd = p;
db->lookaside.bEnabled = 1;
+ db->lookaside.bMalloced = pBuf==0 ?1:0;
}else{
db->lookaside.pEnd = 0;
db->lookaside.bEnabled = 0;
+ db->lookaside.bMalloced = 0;
}
return SQLITE_OK;
}
@@ -87813,8 +89071,9 @@
db->pSavepoint = pTmp->pNext;
sqlite3DbFree(db, pTmp);
}
db->nSavepoint = 0;
+ db->nStatement = 0;
db->isTransactionSavepoint = 0;
}
/*
@@ -87852,13 +89111,23 @@
/* If there are any outstanding VMs, return SQLITE_BUSY. */
if( db->pVdbe ){
sqlite3Error(db, SQLITE_BUSY,
- "Unable to close due to unfinalised statements");
+ "unable to close due to unfinalised statements");
sqlite3_mutex_leave(db->mutex);
return SQLITE_BUSY;
}
assert( sqlite3SafetyCheckSickOrOk(db) );
+
+ for(j=0; j<db->nDb; j++){
+ Btree *pBt = db->aDb[j].pBt;
+ if( pBt && sqlite3BtreeIsInBackup(pBt) ){
+ sqlite3Error(db, SQLITE_BUSY,
+ "unable to close due to unfinished backup operation");
+ sqlite3_mutex_leave(db->mutex);
+ return SQLITE_BUSY;
+ }
+ }
/* Free any outstanding Savepoint structures. */
sqlite3CloseSavepoints(db);
@@ -87872,8 +89141,14 @@
}
}
}
sqlite3ResetInternalSchema(db, 0);
+
+ /* Tell the code in notify.c that the connection no longer holds any
+ ** locks and does not require any further unlock-notify callbacks.
+ */
+ sqlite3ConnectionClosed(db);
+
assert( db->nDb<=2 );
assert( db->aDb==db->aDbStatic );
for(j=0; j<ArraySize(db->aFunc.a); j++){
FuncDef *pNext, *pHash, *p;
@@ -88198,9 +89473,9 @@
p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
if( p && p->iPrefEnc==enc && p->nArg==nArg ){
if( db->activeVdbeCnt ){
sqlite3Error(db, SQLITE_BUSY,
- "Unable to delete/modify user-function due to active statements");
+ "unable to delete/modify user-function due to active statements");
assert( !db->mallocFailed );
return SQLITE_BUSY;
}else{
sqlite3ExpirePreparedStatements(db);
@@ -88481,17 +89756,17 @@
}
if( !sqlite3SafetyCheckSickOrOk(db) ){
return sqlite3ErrStr(SQLITE_MISUSE);
}
+ sqlite3_mutex_enter(db->mutex);
if( db->mallocFailed ){
- return sqlite3ErrStr(SQLITE_NOMEM);
- }
- sqlite3_mutex_enter(db->mutex);
- assert( !db->mallocFailed );
- z = (char*)sqlite3_value_text(db->pErr);
- assert( !db->mallocFailed );
- if( z==0 ){
- z = sqlite3ErrStr(db->errCode);
+ z = sqlite3ErrStr(SQLITE_NOMEM);
+ }else{
+ z = (char*)sqlite3_value_text(db->pErr);
+ assert( !db->mallocFailed );
+ if( z==0 ){
+ z = sqlite3ErrStr(db->errCode);
+ }
}
sqlite3_mutex_leave(db->mutex);
return z;
}
@@ -88501,48 +89776,44 @@
** Return UTF-16 encoded English language explanation of the most recent
** error.
*/
SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
- /* Because all the characters in the string are in the unicode
- ** range 0x00-0xFF, if we pad the big-endian string with a
- ** zero byte, we can obtain the little-endian string with
- ** &big_endian[1].
- */
- static const char outOfMemBe[] = {
- 0, 'o', 0, 'u', 0, 't', 0, ' ',
- 0, 'o', 0, 'f', 0, ' ',
- 0, 'm', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0, 0, 0
+ static const u16 outOfMem[] = {
+ 'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0
};
- static const char misuseBe [] = {
- 0, 'l', 0, 'i', 0, 'b', 0, 'r', 0, 'a', 0, 'r', 0, 'y', 0, ' ',
- 0, 'r', 0, 'o', 0, 'u', 0, 't', 0, 'i', 0, 'n', 0, 'e', 0, ' ',
- 0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ',
- 0, 'o', 0, 'u', 0, 't', 0, ' ',
- 0, 'o', 0, 'f', 0, ' ',
- 0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0
+ static const u16 misuse[] = {
+ 'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ',
+ 'r', 'o', 'u', 't', 'i', 'n', 'e', ' ',
+ 'c', 'a', 'l', 'l', 'e', 'd', ' ',
+ 'o', 'u', 't', ' ',
+ 'o', 'f', ' ',
+ 's', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 0
};
const void *z;
if( !db ){
- return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
+ return (void *)outOfMem;
}
if( !sqlite3SafetyCheckSickOrOk(db) ){
- return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
+ return (void *)misuse;
}
sqlite3_mutex_enter(db->mutex);
- assert( !db->mallocFailed );
- z = sqlite3_value_text16(db->pErr);
- if( z==0 ){
- sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
- SQLITE_UTF8, SQLITE_STATIC);
+ if( db->mallocFailed ){
+ z = (void *)outOfMem;
+ }else{
z = sqlite3_value_text16(db->pErr);
- }
- /* A malloc() may have failed within the call to sqlite3_value_text16()
- ** above. If this is the case, then the db->mallocFailed flag needs to
- ** be cleared before returning. Do this directly, instead of via
- ** sqlite3ApiExit(), to avoid setting the database handle error message.
- */
- db->mallocFailed = 0;
+ if( z==0 ){
+ sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
+ SQLITE_UTF8, SQLITE_STATIC);
+ z = sqlite3_value_text16(db->pErr);
+ }
+ /* A malloc() may have failed within the call to sqlite3_value_text16()
+ ** above. If this is the case, then the db->mallocFailed flag needs to
+ ** be cleared before returning. Do this directly, instead of via
+ ** sqlite3ApiExit(), to avoid setting the database handle error message.
+ */
+ db->mallocFailed = 0;
+ }
sqlite3_mutex_leave(db->mutex);
return z;
}
#endif /* SQLITE_OMIT_UTF16 */
@@ -88608,9 +89879,9 @@
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, nName, 0);
if( pColl && pColl->xCmp ){
if( db->activeVdbeCnt ){
sqlite3Error(db, SQLITE_BUSY,
- "Unable to delete/modify collation sequence due to active statements");
+ "unable to delete/modify collation sequence due to active statements");
return SQLITE_BUSY;
}
sqlite3ExpirePreparedStatements(db);
@@ -89183,9 +90454,8 @@
sqlite3_mutex_enter(db->mutex);
(void)sqlite3SafetyOn(db);
sqlite3BtreeEnterAll(db);
rc = sqlite3Init(db, &zErrMsg);
- sqlite3BtreeLeaveAll(db);
if( SQLITE_OK!=rc ){
goto error_out;
}
@@ -89239,8 +90509,9 @@
zCollSeq = "BINARY";
}
error_out:
+ sqlite3BtreeLeaveAll(db);
(void)sqlite3SafetyOff(db);
/* Whether the function call succeeded or failed, set the output parameters
** to whatever their local counterparts contain. If an error did occur,
@@ -89393,15 +90664,344 @@
xBenignEnd = va_arg(ap, void_function);
sqlite3BenignMallocHooks(xBenignBegin, xBenignEnd);
break;
}
+
+ /*
+ ** sqlite3_test_control(PENDING_BYTE, unsigned int X)
+ **
+ ** Set the PENDING byte to the value in the argument, if X>0.
+ ** Make no changes if X==0. Return the value of the pending byte
+ ** as it existing before this routine was called.
+ **
+ ** IMPORTANT: Changing the PENDING byte from 0x40000000 results in
+ ** an incompatible database file format. Changing the PENDING byte
+ ** while any database connection is open results in undefined and
+ ** dileterious behavior.
+ */
+ case SQLITE_TESTCTRL_PENDING_BYTE: {
+ unsigned int newVal = va_arg(ap, unsigned int);
+ rc = sqlite3PendingByte;
+ if( newVal ) sqlite3PendingByte = newVal;
+ break;
+ }
}
va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
return rc;
}
/************** End of main.c ************************************************/
+/************** Begin file notify.c ******************************************/
+/*
+** 2009 March 3
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** This file contains the implementation of the sqlite3_unlock_notify()
+** API method and its associated functionality.
+**
+** $Id: notify.c,v 1.2 2009/03/25 16:51:43 drh Exp $
+*/
+
+/* Omit this entire file if SQLITE_ENABLE_UNLOCK_NOTIFY is not defined. */
+#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
+
+/*
+** Public interfaces:
+**
+** sqlite3ConnectionBlocked()
+** sqlite3ConnectionUnlocked()
+** sqlite3ConnectionClosed()
+** sqlite3_unlock_notify()
+*/
+
+#define assertMutexHeld() \
+ assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) )
+
+/*
+** Head of a linked list of all sqlite3 objects created by this process
+** for which either sqlite3.pBlockingConnection or sqlite3.pUnlockConnection
+** is not NULL. This variable may only accessed while the STATIC_MASTER
+** mutex is held.
+*/
+static sqlite3 *SQLITE_WSD sqlite3BlockedList = 0;
+
+#ifndef NDEBUG
+/*
+** This function is a complex assert() that verifies the following
+** properties of the blocked connections list:
+**
+** 1) Each entry in the list has a non-NULL value for either
+** pUnlockConnection or pBlockingConnection, or both.
+**
+** 2) All entries in the list that share a common value for
+** xUnlockNotify are grouped together.
+**
+** 3) If the argument db is not NULL, then none of the entries in the
+** blocked connections list have pUnlockConnection or pBlockingConnection
+** set to db. This is used when closing connection db.
+*/
+static void checkListProperties(sqlite3 *db){
+ sqlite3 *p;
+ for(p=sqlite3BlockedList; p; p=p->pNextBlocked){
+ int seen = 0;
+ sqlite3 *p2;
+
+ /* Verify property (1) */
+ assert( p->pUnlockConnection || p->pBlockingConnection );
+
+ /* Verify property (2) */
+ for(p2=sqlite3BlockedList; p2!=p; p2=p2->pNextBlocked){
+ if( p2->xUnlockNotify==p->xUnlockNotify ) seen = 1;
+ assert( p2->xUnlockNotify==p->xUnlockNotify || !seen );
+ assert( db==0 || p->pUnlockConnection!=db );
+ assert( db==0 || p->pBlockingConnection!=db );
+ }
+ }
+}
+#else
+# define checkListProperties(x)
+#endif
+
+/*
+** Remove connection db from the blocked connections list. If connection
+** db is not currently a part of the list, this function is a no-op.
+*/
+static void removeFromBlockedList(sqlite3 *db){
+ sqlite3 **pp;
+ assertMutexHeld();
+ for(pp=&sqlite3BlockedList; *pp; pp = &(*pp)->pNextBlocked){
+ if( *pp==db ){
+ *pp = (*pp)->pNextBlocked;
+ break;
+ }
+ }
+}
+
+/*
+** Add connection db to the blocked connections list. It is assumed
+** that it is not already a part of the list.
+*/
+static void addToBlockedList(sqlite3 *db){
+ sqlite3 **pp;
+ assertMutexHeld();
+ for(
+ pp=&sqlite3BlockedList;
+ *pp && (*pp)->xUnlockNotify!=db->xUnlockNotify;
+ pp=&(*pp)->pNextBlocked
+ );
+ db->pNextBlocked = *pp;
+ *pp = db;
+}
+
+/*
+** Obtain the STATIC_MASTER mutex.
+*/
+static void enterMutex(){
+ sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+ checkListProperties(0);
+}
+
+/*
+** Release the STATIC_MASTER mutex.
+*/
+static void leaveMutex(){
+ assertMutexHeld();
+ checkListProperties(0);
+ sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+}
+
+/*
+** Register an unlock-notify callback.
+*/
+SQLITE_API int sqlite3_unlock_notify(
+ sqlite3 *db,
+ void (*xNotify)(void **, int),
+ void *pArg
+){
+ int rc = SQLITE_OK;
+
+ sqlite3_mutex_enter(db->mutex);
+ enterMutex();
+
+ if( 0==db->pBlockingConnection ){
+ /* The blocking transaction has been concluded. Or there never was a
+ ** blocking transaction. In either case, invoke the notify callback
+ ** immediately.
+ */
+ xNotify(&pArg, 1);
+ }else{
+ sqlite3 *p;
+
+ for(p=db->pBlockingConnection; p && p!=db; p=p->pUnlockConnection);
+ if( p ){
+ rc = SQLITE_LOCKED; /* Deadlock detected. */
+ }else{
+ db->pUnlockConnection = db->pBlockingConnection;
+ db->xUnlockNotify = xNotify;
+ db->pUnlockArg = pArg;
+ removeFromBlockedList(db);
+ addToBlockedList(db);
+ }
+ }
+
+ leaveMutex();
+ assert( !db->mallocFailed );
+ sqlite3Error(db, rc, (rc?"database is deadlocked":0));
+ sqlite3_mutex_leave(db->mutex);
+ return rc;
+}
+
+/*
+** This function is called while stepping or preparing a statement
+** associated with connection db. The operation will return SQLITE_LOCKED
+** to the user because it requires a lock that will not be available
+** until connection pBlocker concludes its current transaction.
+*/
+SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *db, sqlite3 *pBlocker){
+ enterMutex();
+ if( db->pBlockingConnection==0 && db->pUnlockConnection==0 ){
+ addToBlockedList(db);
+ }
+ db->pBlockingConnection = pBlocker;
+ leaveMutex();
+}
+
+/*
+** The transaction opened by database db has just finished. Locks held
+** by database connection db have been released.
+**
+** This function loops through each entry in the blocked connections
+** list and does the following:
+**
+** 1) If the sqlite3.pBlockingConnection member of a list entry is
+** set to db, then set pBlockingConnection=0.
+**
+** 2) If the sqlite3.pUnlockConnection member of a list entry is
+** set to db, then invoke the configured unlock-notify callback and
+** set pUnlockConnection=0.
+**
+** 3) If the two steps above mean that pBlockingConnection==0 and
+** pUnlockConnection==0, remove the entry from the blocked connections
+** list.
+*/
+SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db){
+ void (*xUnlockNotify)(void **, int) = 0; /* Unlock-notify cb to invoke */
+ int nArg = 0; /* Number of entries in aArg[] */
+ sqlite3 **pp; /* Iterator variable */
+
+ void *aStatic[16];
+ void **aArg = aStatic;
+ void **aDyn = 0;
+
+ enterMutex(); /* Enter STATIC_MASTER mutex */
+
+ /* This loop runs once for each entry in the blocked-connections list. */
+ for(pp=&sqlite3BlockedList; *pp; /* no-op */ ){
+ sqlite3 *p = *pp;
+
+ /* Step 1. */
+ if( p->pBlockingConnection==db ){
+ p->pBlockingConnection = 0;
+ }
+
+ /* Step 2. */
+ if( p->pUnlockConnection==db ){
+ assert( p->xUnlockNotify );
+ if( p->xUnlockNotify!=xUnlockNotify && nArg!=0 ){
+ xUnlockNotify(aArg, nArg);
+ nArg = 0;
+ }
+
+ sqlite3BeginBenignMalloc();
+ assert( aArg==aDyn || (aDyn==0 && aArg==aStatic) );
+ assert( nArg<=(int)ArraySize(aStatic) || aArg==aDyn );
+ if( (!aDyn && nArg==(int)ArraySize(aStatic))
+ || (aDyn && nArg==(int)(sqlite3DbMallocSize(db, aDyn)/sizeof(void*)))
+ ){
+ /* The aArg[] array needs to grow. */
+ void **pNew = (void **)sqlite3Malloc(nArg*sizeof(void *)*2);
+ if( pNew ){
+ memcpy(pNew, aArg, nArg*sizeof(void *));
+ sqlite3_free(aDyn);
+ aDyn = aArg = pNew;
+ }else{
+ /* This occurs when the array of context pointers that need to
+ ** be passed to the unlock-notify callback is larger than the
+ ** aStatic[] array allocated on the stack and the attempt to
+ ** allocate a larger array from the heap has failed.
+ **
+ ** This is a difficult situation to handle. Returning an error
+ ** code to the caller is insufficient, as even if an error code
+ ** is returned the transaction on connection db will still be
+ ** closed and the unlock-notify callbacks on blocked connections
+ ** will go unissued. This might cause the application to wait
+ ** indefinitely for an unlock-notify callback that will never
+ ** arrive.
+ **
+ ** Instead, invoke the unlock-notify callback with the context
+ ** array already accumulated. We can then clear the array and
+ ** begin accumulating any further context pointers without
+ ** requiring any dynamic allocation. This is sub-optimal because
+ ** it means that instead of one callback with a large array of
+ ** context pointers the application will receive two or more
+ ** callbacks with smaller arrays of context pointers, which will
+ ** reduce the applications ability to prioritize multiple
+ ** connections. But it is the best that can be done under the
+ ** circumstances.
+ */
+ xUnlockNotify(aArg, nArg);
+ nArg = 0;
+ }
+ }
+ sqlite3EndBenignMalloc();
+
+ aArg[nArg++] = p->pUnlockArg;
+ xUnlockNotify = p->xUnlockNotify;
+ p->pUnlockConnection = 0;
+ p->xUnlockNotify = 0;
+ p->pUnlockArg = 0;
+ }
+
+ /* Step 3. */
+ if( p->pBlockingConnection==0 && p->pUnlockConnection==0 ){
+ /* Remove connection p from the blocked connections list. */
+ *pp = p->pNextBlocked;
+ p->pNextBlocked = 0;
+ }else{
+ pp = &p->pNextBlocked;
+ }
+ }
+
+ if( nArg!=0 ){
+ xUnlockNotify(aArg, nArg);
+ }
+ sqlite3_free(aDyn);
+ leaveMutex(); /* Leave STATIC_MASTER mutex */
+}
+
+/*
+** This is called when the database connection passed as an argument is
+** being closed. The connection is removed from the blocked list.
+*/
+SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){
+ sqlite3ConnectionUnlocked(db);
+ enterMutex();
+ removeFromBlockedList(db);
+ checkListProperties(db);
+ leaveMutex();
+}
+#endif
+
+/************** End of notify.c **********************************************/
/************** Begin file fts3.c ********************************************/
/*
** 2006 Oct 10
**
@@ -89814,9 +91414,12 @@
** normalized version of the token (i.e. after any case-folding and/or
** stemming has been performed). *pnBytes should be set to the length
** of this buffer in bytes. The input text that generated the token is
** identified by the byte offsets returned in *piStartOffset and
- ** *piEndOffset.
+ ** *piEndOffset. *piStartOffset should be set to the index of the first
+ ** byte of the token in the input buffer. *piEndOffset should be set
+ ** to the index of the first byte just past the end of the token in
+ ** the input buffer.
**
** The buffer *ppToken is set to point at is managed by the tokenizer
** implementation. It is only required to be valid until the next call
** to xNext() or xClose().
@@ -96166,9 +97769,9 @@
readers[i].segment = i;
i++;
}
- /* If we managed to succesfully read them all, optimize them. */
+ /* If we managed to successfully read them all, optimize them. */
if( rc==SQLITE_DONE ){
assert( i==nReaders );
rc = optimizeInternal(v, readers, nReaders, &writer);
}
@@ -96757,9 +98360,9 @@
db, "fts3", &fts3Module, (void *)pHash, hashDestroy
);
}
- /* An error has occured. Delete the hash table and return the error code. */
+ /* An error has occurred. Delete the hash table and return the error code. */
assert( rc!=SQLITE_OK );
if( pHash ){
sqlite3Fts3HashClear(pHash);
sqlite3_free(pHash);
@@ -96923,10 +98526,10 @@
if( !sqlite3_fts3_enable_parentheses && iStart>0 && z[iStart-1]=='-' ){
pRet->pPhrase->isNot = 1;
}
}
- }
- nConsumed = iEnd;
+ nConsumed = iEnd;
+ }
pModule->xClose(pCursor);
}
@@ -96990,10 +98593,8 @@
}
if( ii==0 ){
memset(p, 0, nByte);
p->pPhrase = (Fts3Phrase *)&p[1];
- p->eType = FTSQUERY_PHRASE;
- p->pPhrase->iColumn = pParse->iDefaultCol;
}
p->pPhrase = (Fts3Phrase *)&p[1];
p->pPhrase->nToken = ii+1;
p->pPhrase->aToken[ii].n = nToken;
@@ -97015,21 +98616,27 @@
int jj;
char *zNew;
int nNew = 0;
int nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase);
- nByte += (p->pPhrase->nToken-1) * sizeof(struct PhraseToken);
+ nByte += (p?(p->pPhrase->nToken-1):0) * sizeof(struct PhraseToken);
p = fts3ReallocOrFree(p, nByte + nTemp);
if( !p ){
goto no_mem;
}
- p->pPhrase = (Fts3Phrase *)&p[1];
- zNew = &(((char *)p)[nByte]);
- memcpy(zNew, zTemp, nTemp);
+ if( zTemp ){
+ zNew = &(((char *)p)[nByte]);
+ memcpy(zNew, zTemp, nTemp);
+ }else{
+ memset(p, 0, nByte+nTemp);
+ }
+ p->pPhrase = (Fts3Phrase *)&p[1];
for(jj=0; jj<p->pPhrase->nToken; jj++){
p->pPhrase->aToken[jj].z = &zNew[nNew];
nNew += p->pPhrase->aToken[jj].n;
}
sqlite3_free(zTemp);
+ p->eType = FTSQUERY_PHRASE;
+ p->pPhrase->iColumn = pParse->iDefaultCol;
rc = SQLITE_OK;
}
*ppExpr = p;