From 6d479c3d1347db0f0b32d7532e2b3b35cff76523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96nnerby?= Date: Fri, 18 Apr 2008 07:45:02 +0000 Subject: [PATCH] Merge doep branch to trunk. --- src/3rdparty/include/sqlite/sqlite3.h | 1317 ++- src/3rdparty/include/sqlite/sqlite3ext.h | 18 +- src/3rdparty/src/sqlite/sqlite3.c | 8285 ++++++++++++----- src/contrib/taglib_plugin/TagReaderTaglib.cpp | 3 +- src/core/Library/Base.cpp | 14 +- src/core/PlaybackQueue.cpp | 70 +- src/core/PlaybackQueue.h | 11 +- src/core/Query/Tracks.cpp | 5 + src/core/Track.cpp | 4 + src/core/Track.h | 32 +- src/core/tracklist/IRandomAccess.h | 9 + src/core/tracklist/Standard.cpp | 39 +- src/core/tracklist/Standard.h | 11 +- src/cube/MainWindowController.cpp | 2 - src/cube/TracklistController.cpp | 9 +- src/cube/TracklistController.hpp | 1 + src/cube/TracklistModel.cpp | 21 +- src/cube/TracklistModel.hpp | 3 +- src/cube/TransportController.cpp | 26 +- src/cube/TransportController.hpp | 6 +- src/win32cpp/ListView.cpp | 16 + src/win32cpp/ListView.hpp | 4 + 22 files changed, 7211 insertions(+), 2695 deletions(-) diff --git a/src/3rdparty/include/sqlite/sqlite3.h b/src/3rdparty/include/sqlite/sqlite3.h index cefbcb86c..221fdb108 100644 --- a/src/3rdparty/include/sqlite/sqlite3.h +++ b/src/3rdparty/include/sqlite/sqlite3.h @@ -30,7 +30,7 @@ ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** -** @(#) $Id: sqlite.h.in,v 1.282 2008/01/31 16:36:40 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.305 2008/04/16 00:28:14 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -69,7 +69,7 @@ extern "C" { ** the sqlite3.h file specify the version of SQLite with which ** that header file is associated. ** -** The "version" of SQLite is a strong of the form "X.Y.Z". +** The "version" of SQLite is a string of the form "X.Y.Z". ** The phrase "alpha" or "beta" might be appended after the Z. ** The X value is major version number always 3 in SQLite3. ** The X value only changes when backwards compatibility is @@ -93,8 +93,8 @@ extern "C" { ** 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.5.5" -#define SQLITE_VERSION_NUMBER 3005005 +#define SQLITE_VERSION "3.5.8" +#define SQLITE_VERSION_NUMBER 3005008 /* ** CAPI3REF: Run-Time Library Version Numbers {F10020} @@ -132,7 +132,7 @@ int sqlite3_libversion_number(void); ** ** SQLite can be compiled with or without mutexes. When ** the SQLITE_THREADSAFE C preprocessor macro is true, mutexes -** are enabled and SQLite is threadsafe. When that macro os false, +** are enabled and SQLite is threadsafe. When that macro is false, ** the mutexes are omitted. Without the mutexes, it is not safe ** to use SQLite from more than one thread. ** @@ -334,7 +334,8 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** *errmsg if errmsg is NULL or if there are no errors. ** ** {F12137} The [sqlite3_exec()] function sets the error code and message -** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()]. +** accessible via [sqlite3_errcode()], [sqlite3_errmsg()], and +** [sqlite3_errmsg16()]. ** ** LIMITATIONS: ** @@ -433,7 +434,7 @@ int sqlite3_exec( ** {F10225} Extended result code names contain two or more "_" characters. ** ** {F10226} The numeric value of an extended result code contains the -** numeric value of its corresponding primary result code it +** numeric value of its corresponding primary result code in ** its least significant 8 bits. */ #define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) @@ -452,7 +453,7 @@ int sqlite3_exec( /* ** CAPI3REF: Flags For File Open Operations {F10230} ** -** These bit values are intended for use in then +** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the xOpen method of the ** [sqlite3_vfs] object. @@ -519,12 +520,12 @@ int sqlite3_exec( ** CAPI3REF: Synchronization Type Flags {F10260} ** ** When SQLite invokes the xSync() method of an -** [sqlite3_io_methods] object it uses a combination of the +** [sqlite3_io_methods] object it uses a combination of ** these integer values as the second argument. ** ** When the SQLITE_SYNC_DATAONLY flag is used, it means that the ** sync operation only needs to flush data to mass storage. Inode -** information need not be flushed. The SQLITE_SYNC_NORMAL means +** information need not be flushed. The SQLITE_SYNC_NORMAL flag means ** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means ** to use Mac OS-X style fullsync instead of fsync(). */ @@ -552,7 +553,7 @@ struct sqlite3_file { ** CAPI3REF: OS Interface File Virtual Methods Object {F11120} ** ** Every file opened by the [sqlite3_vfs] xOpen method contains a pointer to -** an instance of the this object. This object defines the +** an instance of this object. This object defines the ** methods used to perform various operations against the open file. ** ** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or @@ -650,7 +651,7 @@ struct sqlite3_io_methods { ** interface. ** ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This -** opcode cases the xFileControl method to write the current state of +** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) ** into an integer that the pArg argument points to. This capability @@ -686,13 +687,13 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** structure used by this VFS. mxPathname is the maximum length of ** a pathname in this VFS. ** -** Registered vfs modules are kept on a linked list formed by +** Registered sqlite3_vfs objects are kept on a linked list formed by ** the pNext pointer. The [sqlite3_vfs_register()] ** and [sqlite3_vfs_unregister()] interfaces manage this list ** in a thread-safe way. The [sqlite3_vfs_find()] interface ** searches the list. ** -** The pNext field is the only fields in the sqlite3_vfs +** The pNext field is the only field in the sqlite3_vfs ** structure that SQLite will ever modify. SQLite will only access ** or modify this field while holding a particular static mutex. ** The application should never modify anything within the sqlite3_vfs @@ -730,12 +731,12 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** ** The file I/O implementation can use the object type flags to ** changes the way it deals with files. For example, an application -** that does not care about crash recovery or rollback, might make -** the open of a journal file a no-op. Writes to this journal are -** also a no-op. Any attempt to read the journal return SQLITE_IOERR. -** Or the implementation might recognize the a database file will -** be doing page-aligned sector reads and writes in a random order -** and set up its I/O subsystem accordingly. +** that does not care about crash recovery or rollback might make +** the open of a journal file a no-op. Writes to this journal would +** also be no-ops, and any attempt to read the journal would return +** SQLITE_IOERR. Or the implementation might recognize that a database +** file will be doing page-aligned sector reads and writes in a random +** order and set up its I/O subsystem accordingly. ** ** SQLite might also add one of the following flags to the xOpen ** method: @@ -752,7 +753,7 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** for exclusive access. This flag is set for all files except ** for the main database file. {END} ** -** {F11148} At least szOsFile bytes of memory is allocated by SQLite +** {F11148} At least szOsFile bytes of memory are allocated by SQLite ** to hold the [sqlite3_file] structure passed as the third ** argument to xOpen. {END} The xOpen method does not have to ** allocate the structure; it should just fill it in. @@ -764,7 +765,7 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** to test to see if a file is at least readable. {END} The file can be a ** directory. ** -** {F11150} SQLite will always allocate at least mxPathname+1 byte for +** {F11150} SQLite will always allocate at least mxPathname+1 bytes for ** the output buffers for xGetTempname and xFullPathname. {F11151} The exact ** size of the output buffer is also passed as a parameter to both ** methods. {END} If the output buffer is not large enough, SQLITE_CANTOPEN @@ -778,7 +779,7 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** The xRandomness() function attempts to return nBytes bytes ** of good-quality randomness into zOut. The return value is ** the actual number of bytes of randomness obtained. The -** xSleep() method cause the calling thread to sleep for at +** xSleep() method causes the calling thread to sleep for at ** least the number of microseconds given. The xCurrentTime() ** method returns a Julian Day Number for the current date and ** time. @@ -813,7 +814,7 @@ struct sqlite3_vfs { ** ** {F11191} These integer constants can be used as the third parameter to ** the xAccess method of an [sqlite3_vfs] object. {END} They determine -** the kind of what kind of permissions the xAccess method is +** what kind of permissions the xAccess method is ** looking for. {F11192} With SQLITE_ACCESS_EXISTS, the xAccess method ** simply checks to see if the file exists. {F11193} With ** SQLITE_ACCESS_READWRITE, the xAccess method checks to see @@ -854,7 +855,7 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff); ** as an undeclared column named ROWID, OID, or _ROWID_ as long as those ** names are not also used by explicitly declared columns. If ** the table has a column of type INTEGER PRIMARY KEY then that column -** is another an alias for the rowid. +** is another alias for the rowid. ** ** This routine returns the rowid of the most recent ** successful INSERT into the database from the database connection @@ -894,7 +895,7 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff); ** ** LIMITATIONS: ** -** {U12232} If separate thread does a new insert on the same +** {U12232} If a separate thread does 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 @@ -914,7 +915,7 @@ sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); ** triggers are not counted. Use the [sqlite3_total_changes()] function ** to find the total number of changes including changes caused by triggers. ** -** A "row changes" is a change to a single row of a single table +** A "row change" is a change to a single row of a single table ** caused by an INSERT, DELETE, or UPDATE statement. Rows that ** are changed as side effects of REPLACE constraint resolution, ** rollback, ABORT processing, DROP TABLE, or by any other @@ -986,7 +987,7 @@ int sqlite3_changes(sqlite3*); ** SQLite implements the command "DELETE FROM table" without ** a WHERE clause by dropping and recreating the table. (This is much ** faster than going -** through and deleting individual elements form the table.) Because of +** through and deleting individual elements from the table.) Because of ** this optimization, the change count for "DELETE FROM table" will be ** zero regardless of the number of elements that were originally in the ** table. To get an accurate count of the number of rows deleted, use @@ -1589,18 +1590,43 @@ void sqlite3_free(void*); sqlite3_int64 sqlite3_memory_used(void); sqlite3_int64 sqlite3_memory_highwater(int resetFlag); +/* +** CAPI3REF: Pseudo-Random Number Generator {F17390} +** +** SQLite contains a high-quality pseudo-random number generator (PRNG) used to +** select random ROWIDs when inserting new records into a table that +** already uses the largest possible ROWID. The PRNG is also used for +** the build-in random() and randomblob() SQL functions. This interface allows +** appliations to access the same PRNG for other purposes. +** +** A call to this routine stores N bytes of randomness into buffer P. +** +** The first time this routine is invoked (either internally or by +** the application) the PRNG is seeded using randomness obtained +** from the xRandomness method of the default [sqlite3_vfs] object. +** On all subsequent invocations, the pseudo-randomness is generated +** internally and without recourse to the [sqlite3_vfs] xRandomness +** method. +** +** INVARIANTS: +** +** {F17392} The [sqlite3_randomness(N,P)] interface writes N bytes of +** high-quality pseudo-randomness into buffer P. +*/ +void sqlite3_randomness(int N, void *P); + /* ** CAPI3REF: Compile-Time Authorization Callbacks {F12500} ** ** This routine registers a authorizer callback with a particular -** database connection, supplied in the first argument. +** [database connection], supplied in the first argument. ** The authorizer callback is invoked as SQL statements are being compiled ** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], ** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. At various ** points during the compilation process, as logic is being created ** to perform various actions, the authorizer callback is invoked to ** see if those actions are allowed. The authorizer callback should -** return SQLITE_OK to allow the action, [SQLITE_IGNORE] to disallow the +** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the ** specific action but allow the SQL statement to continue to be ** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be ** rejected with an error. If the authorizer callback returns @@ -1613,9 +1639,9 @@ sqlite3_int64 sqlite3_memory_highwater(int resetFlag); ** [sqlite3_prepare_v2()] or equivalent call that triggered the ** authorizer will fail with an error message explaining that ** access is denied. If the authorizer code is [SQLITE_READ] -** and the callback returns [SQLITE_IGNORE] then the prepared -** statement is constructed to insert a NULL value in place of -** the table column that would have +** and the callback returns [SQLITE_IGNORE] then the +** [prepared statement] statement is constructed to substitute +** a NULL value in place of the table column that would have ** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] ** return can be used to deny an untrusted user access to individual ** columns of a table. @@ -1628,7 +1654,8 @@ sqlite3_int64 sqlite3_memory_highwater(int resetFlag); ** parameters to the callback are zero-terminated strings that contain ** additional details about the action to be authorized. ** -** An authorizer is used when preparing SQL statements from an untrusted +** An authorizer is used when [sqlite3_prepare | preparing] +** SQL statements from an untrusted ** source, to ensure that the SQL statements do not try to access data ** that they are not allowed to see, or that they do not try to ** execute malicious statements that damage the database. For @@ -1636,8 +1663,13 @@ sqlite3_int64 sqlite3_memory_highwater(int resetFlag); ** SQL queries for evaluation by a database. But the application does ** not want the user to be able to make arbitrary changes to the ** database. An authorizer could then be put in place while the -** user-entered SQL is being prepared that disallows everything -** except SELECT statements. +** user-entered SQL is being [sqlite3_prepare | prepared] that +** disallows everything except [SELECT] statements. +** +** Applications that need to process SQL from untrusted sources +** might also consider lowering resource limits using [sqlite3_limit()] +** and limiting database size using the [max_page_count] [PRAGMA] +** in addition to using an authorizer. ** ** Only a single authorizer can be in place on a database connection ** at a time. Each call to sqlite3_set_authorizer overrides the @@ -1952,6 +1984,9 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** The third options is behavior that is always used for [sqlite3_open()] ** and [sqlite3_open16()]. ** +** If the 4th parameter to [sqlite3_open_v2()] is not one of the +** combinations shown above then the behavior is undefined. +** ** If the filename is ":memory:", then an private ** in-memory database is created for the connection. This in-memory ** database will vanish when the database connection is closed. Future @@ -2030,8 +2065,8 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** Is SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE required ** in sqlite3_open_v2()? ** -** {F12719} If the filename is an empty string, then a private, ephermeral -** on-disk database will be created. +** {F12719} If the filename is NULL or an empty string, then a private, +** ephermeral on-disk database will be created. ** Is SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE required ** in sqlite3_open_v2()? ** @@ -2069,7 +2104,7 @@ int sqlite3_open_v2( ** text that describes the error, as either UTF8 or UTF16 respectively. ** Memory to hold the error message string is managed internally. ** The application does not need to worry with freeing the result. -** However, the error string might be overwritten or deallocated b +** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions. ** ** INVARIANTS: @@ -2077,24 +2112,16 @@ int sqlite3_open_v2( ** {F12801} The [sqlite3_errcode(D)] interface returns the numeric ** [SQLITE_OK | result code] or ** [SQLITE_IOERR_READ | extended result code] -** for the most recent failed interface call associated -** with [sqlite3] handle D. -** -** {U12802} If a prior API call failed but the most recent API call -** succeeded, the return value from [sqlite3_errcode()], -** [sqlite3_errmsg()], and [sqlite3_errmsg16()] are undefined. +** for the most recently failed interface call associated +** with [database connection] D. ** ** {F12803} 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 UTF8 or UTF16 respectively. ** -** {U12804} The strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()] -** are only valid until the next SQLite interface call. -** -** {F12807} Calls to [sqlite3_errcode()], [sqlite3_errmsg()], and -** [sqlite3_errmsg16()] themselves do not affect the -** results of future invocations of these routines. +** {F12807} The strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()] +** are valid until the next SQLite interface call. ** ** {F12808} Calls to API routines that do not return an error code ** (example: [sqlite3_data_count()]) do not @@ -2137,6 +2164,118 @@ const void *sqlite3_errmsg16(sqlite3*); */ typedef struct sqlite3_stmt sqlite3_stmt; +/* +** CAPI3REF: Run-time Limits {F12760} +** +** This interface allows the size of various constructs to be limited +** on a connection by connection basis. The first parameter is the +** [database connection] whose limit is to be set or queried. The +** second parameter is one of the [limit categories] that define a +** 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-preprocess macro named 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 +** 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 +** attach. Developers might also want to use the [sqlite3_set_authorizer()] +** interface to further control untrusted SQL. The size of the database +** created by an untrusted script can be contained using the +** [max_page_count] [PRAGMA]. +** +** This interface is currently considered experimental and is subject +** to change or removal without prior notice. +** +** INVARIANTS: +** +** {F12762} A successful call to [sqlite3_limit(D,C,V)] where V is +** positive changes the +** limit on the size of construct C in [database connection] D +** to the lessor of V and the hard upper bound on the size +** of C that is set at compile-time. +** +** {F12764} A successful call to [sqlite3_limit(D,C,V)] where V is zero +** changes the limit on the size of construct C in +** [database connection] D to be the hard upper bound on the size +** of C that is set at compile-time. +** +** {F12766} A successful call to [sqlite3_limit(D,C,V)] where V is negative +** leaves the state of [database connection] D unchanged. +** +** {F12769} A successful call to [sqlite3_limit(D,C,V)] returns the +** value of the limit on the size of construct C in +** in [database connection] D as it was prior to the call. +*/ +int sqlite3_limit(sqlite3*, int id, int newVal); + +/* +** CAPI3REF: Run-Time Limit Categories {F12790} +** 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: +** +**
+**
SQLITE_LIMIT_LENGTH
+**
The maximum size of any +** string or blob or table row.
+** +**
SQLITE_LIMIT_SQL_LENGTH
+**
The maximum length of an SQL statement.
+** +**
SQLITE_LIMIT_COLUMN
+**
The maximum number of columns in a table definition or in the +** result set of a SELECT or the maximum number of columns in an index +** or in an ORDER BY or GROUP BY clause.
+** +**
SQLITE_LIMIT_EXPR_DEPTH
+**
The maximum depth of the parse tree on any expression.
+** +**
SQLITE_LIMIT_COMPOUND_SELECT
+**
The maximum number of terms in a compound SELECT statement.
+** +**
SQLITE_LIMIT_VDBE_OP
+**
The maximum number of instructions in a virtual machine program +** used to implement an SQL statement.
+** +**
SQLITE_LIMIT_FUNCTION_ARG
+**
The maximum number of arguments on a function.
+** +**
SQLITE_LIMIT_ATTACHED
+**
The maximum number of attached databases.
+** +**
SQLITE_LIMIT_LIKE_PATTERN_LENGTH
+**
The maximum length of the pattern argument to the LIKE or +** GLOB operators.
+** +**
SQLITE_LIMIT_VARIABLE_NUMBER
+**
The maximum number of variables in an SQL statement that can +** be bound.
+**
+*/ +#define SQLITE_LIMIT_LENGTH 0 +#define SQLITE_LIMIT_SQL_LENGTH 1 +#define SQLITE_LIMIT_COLUMN 2 +#define SQLITE_LIMIT_EXPR_DEPTH 3 +#define SQLITE_LIMIT_COMPOUND_SELECT 4 +#define SQLITE_LIMIT_VDBE_OP 5 +#define SQLITE_LIMIT_FUNCTION_ARG 6 +#define SQLITE_LIMIT_ATTACHED 7 +#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 +#define SQLITE_LIMIT_VARIABLE_NUMBER 9 + /* ** CAPI3REF: Compiling An SQL Statement {F13010} ** @@ -2156,7 +2295,11 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** If nByte is non-negative, then it is the maximum number of ** bytes read from zSql. When nByte is non-negative, the ** zSql string ends at either the first '\000' or '\u0000' character or -** until the nByte-th byte, whichever comes first. {END} +** the nByte-th byte, whichever comes first. If the caller knows +** that the supplied string is nul-terminated, then there is a small +** performance advantage to be had by passing an nByte parameter that +** is equal to the number of bytes in the input string including +** the nul-terminator bytes.{END} ** ** *pzTail is made to point to the first byte past the end of the ** first SQL statement in zSql. These routines only compiles the first @@ -2164,7 +2307,7 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** uncompiled. ** ** *ppStmt is left pointing to a compiled [prepared statement] that can be -** executed using [sqlite3_step()]. Or if there is an error, *ppStmt may be +** executed using [sqlite3_step()]. Or if there is an error, *ppStmt is ** set to NULL. If the input text contains no SQL (if the input ** is and empty string or a comment) then *ppStmt is set to NULL. ** {U13018} The calling procedure is responsible for deleting the @@ -2222,7 +2365,7 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** read from zSql is read up to the first zero terminator. ** ** {F13014} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)] -** and its variants is non-negative, then nBytes bytes +** and its variants is non-negative, then at most nBytes bytes ** SQL text is read from zSql. ** ** {F13015} In [sqlite3_prepare_v2(db,zSql,N,P,pzTail)] and its variants @@ -2238,6 +2381,10 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** ** {F13019} The [sqlite3_prepare_v2()] interface and its variants return ** [SQLITE_OK] or an appropriate [error code] upon failure. +** +** {F13021} Before [sqlite3_prepare(db,zSql,nByte,ppStmt,pzTail)] or its +** variants returns an error (any value other than [SQLITE_OK]) +** it first sets *ppStmt to NULL. */ int sqlite3_prepare( sqlite3 *db, /* Database handle */ @@ -2297,12 +2444,39 @@ const char *sqlite3_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Dynamically Typed Value Object {F15000} +** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} ** ** SQLite uses the sqlite3_value object to represent all values -** that are or can be stored in a database table. +** that can be stored in a database table. ** SQLite uses dynamic typing for the values it stores. ** Values stored in sqlite3_value objects can be ** be integers, floating point values, strings, BLOBs, or NULL. +** +** An sqlite3_value object may be either "protected" or "unprotected". +** Some interfaces require a protected sqlite3_value. Other interfaces +** will accept either a protected or an unprotected sqlite3_value. +** Every interface that accepts sqlite3_value arguments specifies +** whether or not it requires a protected sqlite3_value. +** +** The terms "protected" and "unprotected" refer to whether or not +** a mutex is held. A internal mutex is held for a protected +** sqlite3_value object but no mutex is held for an unprotected +** sqlite3_value object. If SQLite is compiled to be single-threaded +** (with SQLITE_THREADSAFE=0 and with [sqlite3_threadsafe()] returning 0) +** then there is no distinction between +** protected and unprotected sqlite3_value objects and they can be +** used interchangable. However, for maximum code portability it +** is recommended that applications make the distinction between +** between protected and unprotected sqlite3_value objects even if +** they are single threaded. +** +** The sqlite3_value objects that are passed as parameters into the +** implementation of application-defined SQL functions are protected. +** The sqlite3_value object returned by +** [sqlite3_column_value()] is unprotected. +** Unprotected sqlite3_value objects may only be used with +** [sqlite3_result_value()] and [sqlite3_bind_value()]. All other +** interfaces that use sqlite3_value require protected sqlite3_value objects. */ typedef struct Mem sqlite3_value; @@ -2348,15 +2522,13 @@ typedef struct sqlite3_context sqlite3_context; ** for "?NNN" parameters is the value of NNN. ** The NNN value must be between 1 and the compile-time ** parameter SQLITE_MAX_VARIABLE_NUMBER (default value: 999). -** See limits.html for additional information. ** ** The third argument is the value to bind to the parameter. ** ** In those ** routines that have a fourth argument, its value is the number of bytes ** in the parameter. To be clear: the value is the number of bytes -** in the value, not the number of characters. The number -** of bytes does not include the zero-terminator at the end of strings. +** in the value, not the number of characters. ** If the fourth parameter is negative, the length of the string is ** number of bytes up to the first zero terminator. ** @@ -2465,6 +2637,10 @@ typedef struct sqlite3_context sqlite3_context; ** ** {F13548} 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. +** +** {F13551} 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. */ int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); int sqlite3_bind_double(sqlite3_stmt*, int, double); @@ -3023,6 +3199,15 @@ int sqlite3_data_count(sqlite3_stmt *pStmt); ** but leaves the result in UTF-16 in native byte order instead of UTF-8. ** The zero terminator is not included in this count. ** +** The object returned by [sqlite3_column_value()] is an +** [unprotected sqlite3_value] object. An unprotected sqlite3_value object +** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()]. +** If the [unprotected sqlite3_value] object returned by +** [sqlite3_column_value()] is used in any other way, including calls +** to routines like +** [sqlite3_value_int()], [sqlite3_value_text()], or [sqlite3_value_bytes()], +** then the behavior is undefined. +** ** These routines attempt to convert the value where appropriate. For ** example, if the internal representation is FLOAT and a text result ** is requested, [sqlite3_snprintf()] is used internally to do the conversion @@ -3138,8 +3323,8 @@ int sqlite3_data_count(sqlite3_stmt *pStmt); ** ** {F13815} The [sqlite3_column_int(S,N)] interface converts the ** Nth column in the current row of the result set for -** [prepared statement] S into a 32-bit signed integer and -** returns a copy of that integer. +** [prepared statement] S into a 64-bit signed integer and +** returns the lower 32 bits of that integer. ** ** {F13818} The [sqlite3_column_int64(S,N)] interface converts the ** Nth column in the current row of the result set for @@ -3164,7 +3349,7 @@ int sqlite3_data_count(sqlite3_stmt *pStmt); ** [prepared statement] S. ** ** {F13830} The [sqlite3_column_value(S,N)] interface returns a -** pointer to the [sqlite3_value] object that for the +** pointer to an [unprotected sqlite3_value] object for the ** Nth column in the current row of the result set for ** [prepared statement] S. */ @@ -3247,11 +3432,10 @@ int sqlite3_reset(sqlite3_stmt *pStmt); ** name of the (scalar) function or aggregate, is encoded in UTF-8 for ** sqlite3_create_function() and UTF-16 for sqlite3_create_function16(). ** -** The first argument is the [database connection] that holds the -** SQL function or aggregate is to be added or redefined. If a single -** program uses more than one database handle internally, then SQL -** functions or aggregates must be added individually to each database -** handle with which they will be used. +** The first parameter is the [database connection] to which the SQL +** function is to be added. If a single +** program uses more than one [database connection] internally, then SQL +** functions must be added individually to each [database connection]. ** ** The second parameter is the name of the SQL function to be created ** or redefined. @@ -3304,7 +3488,63 @@ int sqlite3_reset(sqlite3_stmt *pStmt); ** zero-terminated UTF-16 native byte order instead of as a ** zero-terminated UTF-8. ** -** {F16106} +** {F16106} A successful invocation of +** the [sqlite3_create_function(D,X,N,E,...)] interface registers +** or replaces callback functions in [database connection] D +** used to implement the SQL function named X with N parameters +** and having a perferred text encoding of E. +** +** {F16109} A successful call to [sqlite3_create_function(D,X,N,E,P,F,S,L)] +** replaces the P, F, S, and L values from any prior calls with +** the same D, X, N, and E values. +** +** {F16112} The [sqlite3_create_function(D,X,...)] interface fails with +** a return code of [SQLITE_ERROR] if the SQL function name X is +** longer than 255 bytes exclusive of the zero terminator. +** +** {F16118} Either F must be NULL and S and L are non-NULL or else F +** is non-NULL and S and L are NULL, otherwise +** [sqlite3_create_function(D,X,N,E,P,F,S,L)] returns [SQLITE_ERROR]. +** +** {F16121} The [sqlite3_create_function(D,...)] interface fails with an +** error code of [SQLITE_BUSY] if there exist [prepared statements] +** associated with the [database connection] D. +** +** {F16124} The [sqlite3_create_function(D,X,N,...)] interface fails with an +** error code of [SQLITE_ERROR] if parameter N (specifying the number +** of arguments to the SQL function being registered) is less +** than -1 or greater than 127. +** +** {F16127} When N is non-negative, the [sqlite3_create_function(D,X,N,...)] +** interface causes callbacks to be invoked for the SQL function +** named X when the number of arguments to the SQL function is +** exactly N. +** +** {F16130} When N is -1, the [sqlite3_create_function(D,X,N,...)] +** interface causes callbacks to be invoked for the SQL function +** named X with any number of arguments. +** +** {F16133} 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 is preferred. +** +** {F16136} 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 is preferred. +** +** {F16139} For an aggregate SQL function created using +** [sqlite3_create_function(D,X,N,E,P,0,S,L)] the finializer +** function L will always be invoked exactly once if the +** step function S is called one or more times. +** +** {F16142} 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 are always [protected sqlite3_value] objects. */ int sqlite3_create_function( sqlite3 *db, @@ -3367,14 +3607,18 @@ int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); ** to [sqlite3_create_function()] and [sqlite3_create_function16()] ** define callbacks that implement the SQL functions and aggregates. ** The 4th parameter to these callbacks is an array of pointers to -** [sqlite3_value] objects. There is one [sqlite3_value] object for +** [protected sqlite3_value] objects. There is one [sqlite3_value] object for ** each parameter to the SQL function. These routines are used to ** extract values from the [sqlite3_value] objects. ** +** These routines work only with [protected sqlite3_value] objects. +** Any attempt to use these routines on an [unprotected sqlite3_value] +** object results in undefined behavior. +** ** These routines work just like the corresponding ** [sqlite3_column_blob | sqlite3_column_* routines] except that -** these routines take a single [sqlite3_value*] pointer instead -** of an [sqlite3_stmt*] pointer and an integer column number. +** these routines take a single [protected sqlite3_value] object pointer +** instead of an [sqlite3_stmt*] pointer and an integer column number. ** ** The sqlite3_value_text16() interface extracts a UTF16 string ** in the native byte-order of the host machine. The @@ -3396,11 +3640,70 @@ int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); ** or [sqlite3_value_text16()]. ** ** These routines must be called from the same thread as -** the SQL function that supplied the sqlite3_value* parameters. -** Or, if the sqlite3_value* argument comes from the [sqlite3_column_value()] -** interface, then these routines should be called from the same thread -** that ran [sqlite3_column_value()]. +** the SQL function that supplied the [sqlite3_value*] parameters. ** +** +** INVARIANTS: +** +** {F15103} 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. +** +** {F15106} 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)]. +** +** {F15109} 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)]. +** +** {F15112} 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. +** +** {F15115} 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. +** +** {F15118} 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. +** +** {F15121} 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. +** +** {F15124} 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. +** +** {F15127} 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. +** +** {F15130} 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. +** +** {F15133} 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. +** +** {F15136} 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. */ const void *sqlite3_value_blob(sqlite3_value*); int sqlite3_value_bytes(sqlite3_value*); @@ -3420,16 +3723,16 @@ int sqlite3_value_numeric_type(sqlite3_value*); ** ** The implementation of aggregate SQL functions use this routine to allocate ** a structure for storing their state. -** {F16211} The first time the sqlite3_aggregate_context() routine is +** The first time the sqlite3_aggregate_context() routine is ** is called for a particular aggregate, SQLite allocates nBytes of memory ** zeros that memory, and returns a pointer to it. -** {F16212} On second and subsequent calls to sqlite3_aggregate_context() -** for the same aggregate function index, the same buffer is returned. {END} +** On second and subsequent calls to sqlite3_aggregate_context() +** for the same aggregate function index, the same buffer is returned. ** The implementation ** of the aggregate can use the returned buffer to accumulate data. ** -** {F16213} SQLite automatically frees the allocated buffer when the aggregate -** query concludes. {END} +** SQLite automatically frees the allocated buffer when the aggregate +** query concludes. ** ** The first parameter should be a copy of the ** [sqlite3_context | SQL function context] that is the first @@ -3438,23 +3741,71 @@ int sqlite3_value_numeric_type(sqlite3_value*); ** ** This routine must be called from the same thread in which ** the aggregate SQL function is running. +** +** INVARIANTS: +** +** {F16211} 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 allocation N bytes of memory, +** zero that memory, and return a pointer to the allocationed +** memory. +** +** {F16213} If a memory allocation error occurs during +** [sqlite3_aggregate_context(C,N)] then the function returns 0. +** +** {F16215} 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. +** +** {F16217} 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. */ void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); /* ** CAPI3REF: User Data For Functions {F16240} ** -** {F16241} The sqlite3_user_data() interface returns a copy of +** The sqlite3_user_data() interface returns a copy of ** the pointer that was the pUserData parameter (the 5th parameter) ** of the the [sqlite3_create_function()] ** and [sqlite3_create_function16()] routines that originally ** registered the application defined function. {END} ** -** {U16243} This routine must be called from the same thread in which +** This routine must be called from the same thread in which ** the application-defined function is running. +** +** INVARIANTS: +** +** {F16243} 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. */ void *sqlite3_user_data(sqlite3_context*); +/* +** CAPI3REF: Database Connection For Functions {F16250} +** +** The sqlite3_context_db_handle() interface returns a copy of +** the pointer to the [database connection] (the 1st parameter) +** of the the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +** +** INVARIANTS: +** +** {F16253} 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. +*/ +sqlite3 *sqlite3_context_db_handle(sqlite3_context*); + /* ** CAPI3REF: Function Auxiliary Data {F16270} ** @@ -3469,24 +3820,28 @@ void *sqlite3_user_data(sqlite3_context*); ** invocations of the same function so that the original pattern string ** does not need to be recompiled on each invocation. ** -** {F16271} ** The sqlite3_get_auxdata() interface returns a pointer to the meta-data ** associated by the sqlite3_set_auxdata() function with the Nth argument ** value to the application-defined function. -** {F16272} If no meta-data has been ever been set for the Nth +** If no meta-data has been ever been set for the Nth ** argument of the function, or if the cooresponding function parameter ** has changed since the meta-data was set, then sqlite3_get_auxdata() ** returns a NULL pointer. ** -** {F16275} The sqlite3_set_auxdata() interface saves the meta-data +** The sqlite3_set_auxdata() interface saves the meta-data ** pointed to by its 3rd parameter as the meta-data for the N-th -** argument of the application-defined function. {END} Subsequent +** argument of the application-defined function. Subsequent ** calls to sqlite3_get_auxdata() might return this data, if it has ** not been destroyed. -** {F16277} If it is not NULL, SQLite will invoke the destructor +** If it is not NULL, SQLite will invoke the destructor ** function given by the 4th parameter to sqlite3_set_auxdata() on ** the meta-data when the corresponding function parameter changes -** or when the SQL statement completes, whichever comes first. {END} +** or when the SQL statement completes, whichever comes first. +** +** SQLite is free to call the destructor and drop meta-data on +** any parameter of any function at any time. The only guarantee +** is that the destructor will be called before the metadata is +** dropped. ** ** In practice, meta-data is preserved between function calls for ** expressions that are constant at compile time. This includes literal @@ -3494,6 +3849,33 @@ void *sqlite3_user_data(sqlite3_context*); ** ** These routines must be called from the same thread in which ** the SQL function is running. +** +** INVARIANTS: +** +** {F16272} 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. +** +** {F16274} 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. +** +** {F16276} 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. +** +** {F16277} SQLite ceases to hold metadata for an SQL function parameter +** when the value of that parameter changes. +** +** {F16278} 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. +** +** {F16279} 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. */ void *sqlite3_get_auxdata(sqlite3_context*, int N); void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); @@ -3532,90 +3914,193 @@ typedef void (*sqlite3_destructor_type)(void*); ** [sqlite3_bind_blob | sqlite3_bind_* documentation] for ** additional information. ** -** {F16402} The sqlite3_result_blob() interface sets the result from +** The sqlite3_result_blob() interface sets the result from ** an application defined function to be the BLOB whose content is pointed ** to by the second parameter and which is N bytes long where N is the ** third parameter. -** {F16403} The sqlite3_result_zeroblob() inerfaces set the result of +** The sqlite3_result_zeroblob() inerfaces set the result of ** the application defined function to be a BLOB containing all zero ** bytes and N bytes in size, where N is the value of the 2nd parameter. ** -** {F16407} The sqlite3_result_double() interface sets the result from +** The sqlite3_result_double() interface sets the result from ** an application defined function to be a floating point value specified ** by its 2nd argument. ** -** {F16409} The sqlite3_result_error() and sqlite3_result_error16() functions +** The sqlite3_result_error() and sqlite3_result_error16() functions ** cause the implemented SQL function to throw an exception. -** {F16411} SQLite uses the string pointed to by the +** SQLite uses the string pointed to by the ** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() -** as the text of an error message. {F16412} SQLite interprets the error -** message string from sqlite3_result_error() as UTF8. {F16413} SQLite +** as the text of an error message. SQLite interprets the error +** message string from sqlite3_result_error() as UTF8. SQLite ** interprets the string from sqlite3_result_error16() as UTF16 in native -** byte order. {F16414} If the third parameter to sqlite3_result_error() +** byte order. If the third parameter to sqlite3_result_error() ** or sqlite3_result_error16() is negative then SQLite takes as the error ** message all text up through the first zero character. -** {F16415} If the third parameter to sqlite3_result_error() or +** If the third parameter to sqlite3_result_error() or ** sqlite3_result_error16() is non-negative then SQLite takes that many ** bytes (not characters) from the 2nd parameter as the error message. -** {F16417} The sqlite3_result_error() and sqlite3_result_error16() +** The sqlite3_result_error() and sqlite3_result_error16() ** routines make a copy private copy of the error message text before -** they return. {END} Hence, the calling function can deallocate or +** they return. Hence, the calling function can deallocate or ** modify the text after they return without harm. +** The sqlite3_result_error_code() function changes the error code +** returned by SQLite as a result of an error in a function. By default, +** the error code is SQLITE_ERROR. A subsequent call to sqlite3_result_error() +** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. ** -** {F16421} The sqlite3_result_toobig() interface causes SQLite +** The sqlite3_result_toobig() interface causes SQLite ** to throw an error indicating that a string or BLOB is to long -** to represent. {F16422} The sqlite3_result_nomem() interface +** to represent. The sqlite3_result_nomem() interface ** causes SQLite to throw an exception indicating that the a ** memory allocation failed. ** -** {F16431} The sqlite3_result_int() interface sets the return value +** The sqlite3_result_int() interface sets the return value ** of the application-defined function to be the 32-bit signed integer ** value given in the 2nd argument. -** {F16432} The sqlite3_result_int64() interface sets the return value +** The sqlite3_result_int64() interface sets the return value ** of the application-defined function to be the 64-bit signed integer ** value given in the 2nd argument. ** -** {F16437} The sqlite3_result_null() interface sets the return value +** The sqlite3_result_null() interface sets the return value ** of the application-defined function to be NULL. ** -** {F16441} The sqlite3_result_text(), sqlite3_result_text16(), +** The sqlite3_result_text(), sqlite3_result_text16(), ** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces ** set the return value of the application-defined function to be ** a text string which is represented as UTF-8, UTF-16 native byte order, ** UTF-16 little endian, or UTF-16 big endian, respectively. -** {F16442} SQLite takes the text result from the application from +** SQLite takes the text result from the application from ** the 2nd parameter of the sqlite3_result_text* interfaces. -** {F16444} If the 3rd parameter to the sqlite3_result_text* interfaces +** If the 3rd parameter to the sqlite3_result_text* interfaces ** is negative, then SQLite takes result text from the 2nd parameter ** through the first zero character. -** {F16447} If the 3rd parameter to the sqlite3_result_text* interfaces +** If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined ** function result. -** {F16451} If the 4th parameter to the sqlite3_result_text* interfaces +** If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that ** function as the destructor on the text or blob result when it has ** finished using that result. -** {F16453} If the 4th parameter to the sqlite3_result_text* interfaces +** If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is the special constant SQLITE_STATIC, then ** SQLite assumes that the text or blob result is constant space and ** does not copy the space or call a destructor when it has ** finished using that result. -** {F16454} If the 4th parameter to the sqlite3_result_text* interfaces +** If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT ** then SQLite makes a copy of the result into space obtained from ** from [sqlite3_malloc()] before it returns. ** -** {F16461} The sqlite3_result_value() interface sets the result of -** the application-defined function to be a copy the [sqlite3_value] -** object specified by the 2nd parameter. {F16463} The +** The sqlite3_result_value() interface sets the result of +** the application-defined function to be a copy the +** [unprotected sqlite3_value] object specified by the 2nd parameter. The ** sqlite3_result_value() interface makes a copy of the [sqlite3_value] ** so that [sqlite3_value] specified in the parameter may change or ** be deallocated after sqlite3_result_value() returns without harm. +** A [protected sqlite3_value] object may always be used where an +** [unprotected sqlite3_value] object is required, so either +** kind of [sqlite3_value] object can be used with this interface. ** -** {U16491} These routines are called from within the different thread +** If these routines are called from within the different thread ** than the one containing the application-defined function that recieved ** the [sqlite3_context] pointer, the results are undefined. +** +** INVARIANTS: +** +** {F16403} The default return value from any SQL function is NULL. +** +** {F16406} 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. +** +** {F16409} The [sqlite3_result_double(C,V)] interface changes the +** return value of function C to be the floating point value V. +** +** {F16412} 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 UTF8 error message copied from V up to the +** first zero byte or until N bytes are read if N is positive. +** +** {F16415} 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 UTF16 native byte order error message +** copied from V up to the first zero terminator or until N bytes +** are read if N is positive. +** +** {F16418} 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. +** +** {F16421} 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. +** +** {F16424} 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. +** +** {F16427} The [sqlite3_result_int(C,V)] interface changes the +** return value of function C to be the 32-bit integer value V. +** +** {F16430} The [sqlite3_result_int64(C,V)] interface changes the +** return value of function C to be the 64-bit integer value V. +** +** {F16433} The [sqlite3_result_null(C)] interface changes the +** return value of function C to be NULL. +** +** {F16436} The [sqlite3_result_text(C,V,N,D)] interface changes the +** return value of function C to be the UTF8 string +** V up the first zero if N is negative +** or the first N bytes of V if N is non-negative. +** +** {F16439} The [sqlite3_result_text16(C,V,N,D)] interface changes the +** return value of function C to be the UTF16 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. +** +** {F16442} The [sqlite3_result_text16be(C,V,N,D)] interface changes the +** return value of function C to be the UTF16 big-endian +** string V up to the first zero if N is +** is negative or the first N bytes or V if N is non-negative. +** +** {F16445} The [sqlite3_result_text16le(C,V,N,D)] interface changes the +** return value of function C to be the UTF16 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. +** +** {F16448} The [sqlite3_result_value(C,V)] interface changes the +** return value of function C to be [unprotected sqlite3_value] +** object V. +** +** {F16451} The [sqlite3_result_zeroblob(C,N)] interface changes the +** return value of function C to be an N-byte blob of all zeros. +** +** {F16454} The [sqlite3_result_error()] and [sqlite3_result_error16()] +** interfaces make a copy of their error message strings before +** returning. +** +** {F16457} 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. +** +** {F16460} 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. +** +** {F16463} 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. */ void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); void sqlite3_result_double(sqlite3_context*, double); @@ -3623,6 +4108,7 @@ void sqlite3_result_error(sqlite3_context*, const char*, int); void sqlite3_result_error16(sqlite3_context*, const void*, int); void sqlite3_result_error_toobig(sqlite3_context*); void sqlite3_result_error_nomem(sqlite3_context*); +void sqlite3_result_error_code(sqlite3_context*, int); void sqlite3_result_int(sqlite3_context*, int); void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); void sqlite3_result_null(sqlite3_context*); @@ -3636,35 +4122,30 @@ void sqlite3_result_zeroblob(sqlite3_context*, int n); /* ** CAPI3REF: Define New Collating Sequences {F16600} ** -** {F16601} ** These functions are used to add new collation sequences to the ** [sqlite3*] handle specified as the first argument. ** -** {F16602} ** The name of the new collation sequence is specified as a UTF-8 string ** for sqlite3_create_collation() and sqlite3_create_collation_v2() -** and a UTF-16 string for sqlite3_create_collation16(). {F16603} In all cases +** and a UTF-16 string for sqlite3_create_collation16(). In all cases ** the name is passed as the second function argument. ** -** {F16604} ** The third argument may be one of the constants [SQLITE_UTF8], ** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied ** routine expects to be passed pointers to strings encoded using UTF-8, -** UTF-16 little-endian or UTF-16 big-endian respectively. {F16605} The +** UTF-16 little-endian or UTF-16 big-endian respectively. The ** third argument might also be [SQLITE_UTF16_ALIGNED] to indicate that ** the routine expects pointers to 16-bit word aligned strings ** of UTF16 in the native byte order of the host computer. ** -** {F16607} ** A pointer to the user supplied routine must be passed as the fifth -** argument. {F16609} If it is NULL, this is the same as deleting the collation +** argument. If it is NULL, this is the same as deleting the collation ** sequence (so that SQLite cannot call it anymore). -** {F16611} Each time the application +** Each time the application ** supplied function is invoked, it is passed a copy of the void* passed as ** the fourth argument to sqlite3_create_collation() or ** sqlite3_create_collation16() as its first parameter. ** -** {F16612} ** The remaining arguments to the application-supplied routine are two strings, ** each represented by a (length, data) pair and encoded in the encoding ** that was passed as the third argument when the collation sequence was @@ -3673,15 +4154,63 @@ void sqlite3_result_zeroblob(sqlite3_context*, int n); ** the first string is less than, equal to, or greater than the second ** string. i.e. (STRING1 - STRING2). ** -** {F16615} ** The sqlite3_create_collation_v2() works like sqlite3_create_collation() ** excapt that it takes an extra argument which is a destructor for -** the collation. {F16617} The destructor is called when the collation is +** the collation. The destructor is called when the collation is ** destroyed and is passed a copy of the fourth parameter void* pointer ** of the sqlite3_create_collation_v2(). -** {F16618} Collations are destroyed when +** Collations are destroyed when ** they are overridden by later calls to the collation creation functions ** or when the [sqlite3*] database handle is closed using [sqlite3_close()]. +** +** INVARIANTS: +** +** {F16603} 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 [database connection] B for +** databases having encoding E. +** +** {F16604} 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. +** +** {F16606} 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. +** +** {F16609} 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. +** +** {F16612} A collating function is dropped when it is overloaded. +** +** {F16615} A collating function is dropped when the database connection +** is closed using [sqlite3_close()]. +** +** {F16618} 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. +** +** {F16621} 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. +** +** {F16624} Following a [sqlite3_create_collation_v2(B,X,E,P,F,D)], +** SQLite uses the comparison function F for all text comparison +** operations on [database connection] B on text values that +** use the collating sequence name X. +** +** {F16627} 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. +** +** {F16630} 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. */ int sqlite3_create_collation( sqlite3*, @@ -3709,31 +4238,50 @@ int sqlite3_create_collation16( /* ** CAPI3REF: Collation Needed Callbacks {F16700} ** -** {F16701} ** To avoid having to register all collation sequences before a database ** can be used, a single callback function may be registered with the ** database handle to be called whenever an undefined collation sequence is ** required. ** -** {F16702} ** If the function is registered using the sqlite3_collation_needed() API, ** then it is passed the names of undefined collation sequences as strings ** encoded in UTF-8. {F16703} If sqlite3_collation_needed16() is used, the names -** are passed as UTF-16 in machine native byte order. {F16704} A call to either +** are passed as UTF-16 in machine native byte order. A call to either ** function replaces any existing callback. ** -** {F16705} When the callback is invoked, the first argument passed is a copy +** When the callback is invoked, the first argument passed is a copy ** of the second argument to sqlite3_collation_needed() or -** sqlite3_collation_needed16(). {F16706} The second argument is the database -** handle. {F16707} The third argument is one of [SQLITE_UTF8], +** sqlite3_collation_needed16(). The second argument is the database +** handle. The third argument is one of [SQLITE_UTF8], ** [SQLITE_UTF16BE], or [SQLITE_UTF16LE], indicating the most ** desirable form of the collation sequence function required. -** {F16708} The fourth parameter is the name of the -** required collation sequence. {END} +** The fourth parameter is the name of the +** required collation sequence. ** ** The callback function should register the desired collation using ** [sqlite3_create_collation()], [sqlite3_create_collation16()], or ** [sqlite3_create_collation_v2()]. +** +** INVARIANTS: +** +** {F16702} 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. +** +** {F16704} 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. +** +** {F16706} 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()]. +** +** */ int sqlite3_collation_needed( sqlite3*, @@ -3774,17 +4322,28 @@ int sqlite3_rekey( /* ** CAPI3REF: Suspend Execution For A Short Time {F10530} ** -** {F10531} The sqlite3_sleep() function +** The sqlite3_sleep() function ** causes the current thread to suspend execution ** for at least a number of milliseconds specified in its parameter. ** -** {F10532} If the operating system does not support sleep requests with +** If the operating system does not support sleep requests with ** millisecond time resolution, then the time will be rounded up to -** the nearest second. {F10533} The number of milliseconds of sleep actually +** the nearest second. The number of milliseconds of sleep actually ** requested from the operating system is returned. ** -** {F10534} SQLite implements this interface by calling the xSleep() -** method of the default [sqlite3_vfs] object. {END} +** SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. +** +** INVARIANTS: +** +** {F10533} 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. +** +** {F10536} 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. */ int sqlite3_sleep(int); @@ -3822,8 +4381,8 @@ SQLITE_EXTERN char *sqlite3_temp_directory; ** ** INVARIANTS: ** -** {F12931} The [sqlite3_get_autocommit()] interface returns non-zero or -** zero if the given database connection is or is not in autocommit +** {F12931} The [sqlite3_get_autocommit(D)] interface returns non-zero or +** zero if the [database connection] D is or is not in autocommit ** mode, respectively. ** ** {F12932} Autocommit mode is on by default. @@ -3845,13 +4404,19 @@ int sqlite3_get_autocommit(sqlite3*); /* ** CAPI3REF: Find The Database Handle Of A Prepared Statement {F13120} ** -** {F13121} The sqlite3_db_handle interface +** The sqlite3_db_handle interface ** returns the [sqlite3*] database handle to which a ** [prepared statement] belongs. -** {F13122} the database handle returned by sqlite3_db_handle +** The database handle returned by sqlite3_db_handle ** is the same database handle that was ** the first argument to the [sqlite3_prepare_v2()] or its variants ** that was used to create the statement in the first place. +** +** INVARIANTS: +** +** {F13123} The [sqlite3_db_handle(S)] interface returns a pointer +** to the [database connection] associated with +** [prepared statement] S. */ sqlite3 *sqlite3_db_handle(sqlite3_stmt*); @@ -3859,33 +4424,70 @@ sqlite3 *sqlite3_db_handle(sqlite3_stmt*); /* ** CAPI3REF: Commit And Rollback Notification Callbacks {F12950} ** -** {F12951} The sqlite3_commit_hook() interface registers a callback +** The sqlite3_commit_hook() interface registers a callback ** function to be invoked whenever a transaction is committed. -** {F12952} Any callback set by a previous call to sqlite3_commit_hook() +** Any callback set by a previous call to sqlite3_commit_hook() ** for the same database connection is overridden. -** {F12953} The sqlite3_rollback_hook() interface registers a callback +** The sqlite3_rollback_hook() interface registers a callback ** function to be invoked whenever a transaction is committed. -** {F12954} Any callback set by a previous call to sqlite3_commit_hook() +** Any callback set by a previous call to sqlite3_commit_hook() ** for the same database connection is overridden. -** {F12956} The pArg argument is passed through -** to the callback. {F12957} If the callback on a commit hook function +** The pArg argument is passed through +** to the callback. If the callback on a commit hook function ** returns non-zero, then the commit is converted into a rollback. ** -** {F12958} If another function was previously registered, its +** If another function was previously registered, its ** pArg value is returned. Otherwise NULL is returned. ** -** {F12959} Registering a NULL function disables the callback. +** Registering a NULL function disables the callback. ** -** {F12961} For the purposes of this API, a transaction is said to have been +** For the purposes of this API, a transaction is said to have been ** rolled back if an explicit "ROLLBACK" statement is executed, or ** an error or constraint causes an implicit rollback to occur. -** {F12962} The rollback callback is not invoked if a transaction is +** The rollback callback is not invoked if a transaction is ** automatically rolled back because the database connection is closed. -** {F12964} The rollback callback is not invoked if a transaction is +** The rollback callback is not invoked if a transaction is ** rolled back because a commit callback returned non-zero. -** Check on this {END} +** Check on this ** ** These are experimental interfaces and are subject to change. +** +** INVARIANTS: +** +** {F12951} The [sqlite3_commit_hook(D,F,P)] interface registers the +** callback function F to be invoked with argument P whenever +** a transaction commits on [database connection] D. +** +** {F12952} 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. +** +** {F12953} Each call to [sqlite3_commit_hook()] overwrites the callback +** registered by prior calls. +** +** {F12954} If the F argument to [sqlite3_commit_hook(D,F,P)] is NULL +** then the commit hook callback is cancelled and no callback +** is invoked when a transaction commits. +** +** {F12955} If the commit callback returns non-zero then the commit is +** converted into a rollback. +** +** {F12961} 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 [database connection] D. +** +** {F12962} 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. +** +** {F12963} Each call to [sqlite3_rollback_hook()] overwrites the callback +** registered by prior calls. +** +** {F12964} If the F argument to [sqlite3_rollback_hook(D,F,P)] is NULL +** then the rollback hook callback is cancelled and no callback +** is invoked when a transaction rolls back. */ void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); @@ -3893,32 +4495,63 @@ void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); /* ** CAPI3REF: Data Change Notification Callbacks {F12970} ** -** {F12971} The sqlite3_update_hook() interface +** The sqlite3_update_hook() interface ** registers a callback function with the database connection identified by the ** first argument to be invoked whenever a row is updated, inserted or deleted. -** {F12972} Any callback set by a previous call to this function for the same +** Any callback set by a previous call to this function for the same ** database connection is overridden. ** -** {F12974} The second argument is a pointer to the function to invoke when a +** The second argument is a pointer to the function to invoke when a ** row is updated, inserted or deleted. -** {F12976} The first argument to the callback is +** The first argument to the callback is ** a copy of the third argument to sqlite3_update_hook(). -** {F12977} The second callback +** The second callback ** argument is one of [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], ** depending on the operation that caused the callback to be invoked. -** {F12978} The third and +** The third and ** fourth arguments to the callback contain pointers to the database and ** table name containing the affected row. -** {F12979} The final callback parameter is +** The final callback parameter is ** the rowid of the row. -** {F12981} In the case of an update, this is the rowid after +** In the case of an update, this is the rowid after ** the update takes place. ** -** {F12983} The update hook is not invoked when internal system tables are +** The update hook is not invoked when internal system tables are ** modified (i.e. sqlite_master and sqlite_sequence). ** -** {F12984} If another function was previously registered, its pArg value -** is returned. {F12985} Otherwise NULL is returned. +** If another function was previously registered, its pArg value +** is returned. Otherwise NULL is returned. +** +** INVARIANTS: +** +** {F12971} The [sqlite3_update_hook(D,F,P)] interface causes callback +** function F to be invoked with first parameter P whenever +** a table row is modified, inserted, or deleted on +** [database connection] D. +** +** {F12973} 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. +** +** {F12975} If the update hook callback F in [sqlite3_update_hook(D,F,P)] +** is NULL then the no update callbacks are made. +** +** {F12977} Each call to [sqlite3_update_hook(D,F,P)] overrides prior calls +** to the same interface on the same [database connection] D. +** +** {F12979} The update hook callback is not invoked when internal system +** tables such as sqlite_master and sqlite_sequence are modified. +** +** {F12981} 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. +** +** {F12983} 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. + +** {F12985} The final callback parameter is the rowid of the row after +** the change occurs. */ void *sqlite3_update_hook( sqlite3*, @@ -3929,83 +4562,131 @@ void *sqlite3_update_hook( /* ** CAPI3REF: Enable Or Disable Shared Pager Cache {F10330} ** -** {F10331} ** This routine enables or disables the sharing of the database cache ** and schema data structures between connections to the same database. -** {F10332} ** Sharing is enabled if the argument is true and disabled if the argument ** is false. ** -** {F10333} Cache sharing is enabled and disabled +** Cache sharing is enabled and disabled ** for an entire process. {END} 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. ** -** {F10334} ** The cache sharing mode set by this interface effects all subsequent ** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. -** {F10335} Existing database connections continue use the sharing mode -** that was in effect at the time they were opened. {END} +** Existing database connections continue use the sharing mode +** that was in effect at the time they were opened. ** -** Virtual tables cannot be used with a shared cache. {F10336} When shared +** Virtual tables cannot be used with a shared cache. When shared ** cache is enabled, the [sqlite3_create_module()] API used to register -** virtual tables will always return an error. {END} +** virtual tables will always return an error. ** -** {F10337} This routine returns [SQLITE_OK] if shared cache was -** enabled or disabled successfully. {F10338} An [error code] -** is returned otherwise. {END} +** This routine returns [SQLITE_OK] if shared cache was +** enabled or disabled successfully. An [error code] +** is returned otherwise. ** -** {F10339} Shared cache is disabled by default. {END} But this might change in +** 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: +** +** {F10331} 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. +** +** {F10336} When shared cache is enabled, the [sqlite3_create_module()] +** interface will always return an error. +** +** {F10337} The [sqlite3_enable_shared_cache(B)] interface returns +** [SQLITE_OK] if shared cache was enabled or disabled successfully. +** +** {F10339} Shared cache is disabled by default. */ int sqlite3_enable_shared_cache(int); /* ** CAPI3REF: Attempt To Free Heap Memory {F17340} ** -** {F17341} The sqlite3_release_memory() interface attempts to +** The sqlite3_release_memory() interface attempts to ** free N bytes of heap memory by deallocating non-essential memory ** allocations held by the database labrary. {END} Memory used ** to cache database pages to improve performance is an example of -** non-essential memory. {F16342} sqlite3_release_memory() returns +** non-essential memory. Sqlite3_release_memory() returns ** the number of bytes actually freed, which might be more or less ** than the amount requested. +** +** INVARIANTS: +** +** {F17341} The [sqlite3_release_memory(N)] interface attempts to +** free N bytes of heap memory by deallocating non-essential +** memory allocations held by the database labrary. +** +** {F16342} The [sqlite3_release_memory(N)] returns the number +** of bytes actually freed, which might be more or less +** than the amount requested. */ int sqlite3_release_memory(int); /* ** CAPI3REF: Impose A Limit On Heap Size {F17350} ** -** {F16351} The sqlite3_soft_heap_limit() interface +** The sqlite3_soft_heap_limit() interface ** places a "soft" limit on the amount of heap memory that may be allocated -** by SQLite. {F16352} If an internal allocation is requested +** by SQLite. If an internal allocation is requested ** that would exceed the soft heap limit, [sqlite3_release_memory()] is ** invoked one or more times to free up some space before the allocation -** is made. {END} +** is made. ** -** {F16353} The limit is called "soft", because if +** The limit is called "soft", because if ** [sqlite3_release_memory()] cannot ** free sufficient memory to prevent the limit from being exceeded, ** the memory is allocated anyway and the current operation proceeds. ** -** {F16354} ** A negative or zero value for N means that there is no soft heap limit and ** [sqlite3_release_memory()] will only be called when memory is exhausted. -** {F16355} The default value for the soft heap limit is zero. +** The default value for the soft heap limit is zero. ** ** SQLite makes a best effort to honor the soft heap limit. -** {F16356} But if the soft heap limit cannot honored, execution will -** continue without error or notification. {END} This is why the limit is +** But if the soft heap limit cannot honored, execution will +** continue without error or notification. This is why the limit is ** called a "soft" limit. It is advisory only. ** ** Prior to SQLite version 3.5.0, this routine only constrained the memory ** allocated by a single thread - the same thread in which this routine ** runs. Beginning with SQLite version 3.5.0, the soft heap limit is -** applied to all threads. {F16357} The value specified for the soft heap limit -** is an upper bound on the total memory allocation for all threads. {END} In +** applied to all threads. The value specified for the soft heap limit +** is an upper bound on the total memory allocation for all threads. In ** version 3.5.0 there is no mechanism for limiting the heap usage for ** individual threads. +** +** INVARIANTS: +** +** {F16351} 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. +** +** {F16352} 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. +** +** {F16353} 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. +** +** {F16354} 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. +** +** {F16355} The default value for the soft heap limit is zero. +** +** {F16358} Each call to [sqlite3_soft_heap_limit(N)] overrides the +** values set by all prior calls. */ void sqlite3_soft_heap_limit(int); @@ -4195,6 +4876,9 @@ typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; typedef struct sqlite3_module sqlite3_module; /* +** CAPI3REF: Virtual Table Object {F18000} +** KEYWORDS: sqlite3_module +** ** A module is a class of virtual tables. Each module is defined ** by an instance of the following structure. This structure consists ** mostly of methods for the module. @@ -4231,6 +4915,9 @@ struct sqlite3_module { }; /* +** CAPI3REF: Virtual Table Indexing Information {F18100} +** KEYWORDS: sqlite3_index_info +** ** The sqlite3_index_info structure and its substructures is used to ** pass information into and receive the reply from the xBestIndex ** method of an sqlite3_module. The fields under **Inputs** are the @@ -4311,6 +4998,8 @@ struct sqlite3_index_info { #define SQLITE_INDEX_CONSTRAINT_MATCH 64 /* +** CAPI3REF: Register A Virtual Table Implementation {F18200} +** ** This routine is used to register a new module name with an SQLite ** connection. Module names must be registered before creating new ** virtual tables on the module, or before using preexisting virtual @@ -4324,6 +5013,8 @@ int sqlite3_create_module( ); /* +** CAPI3REF: Register A Virtual Table Implementation {F18210} +** ** This routine is identical to the sqlite3_create_module() method above, ** except that it allows a destructor function to be specified. It is ** even more experimental than the rest of the virtual tables API. @@ -4337,6 +5028,9 @@ int sqlite3_create_module_v2( ); /* +** CAPI3REF: Virtual Table Instance Object {F18010} +** KEYWORDS: sqlite3_vtab +** ** Every module implementation uses a subclass of the following structure ** to describe a particular instance of the module. Each subclass will ** be tailored to the specific needs of the module implementation. The @@ -4360,7 +5054,11 @@ struct sqlite3_vtab { /* Virtual table implementations will typically add additional fields */ }; -/* Every module implementation uses a subclass of the following structure +/* +** CAPI3REF: Virtual Table Cursor Object {F18020} +** KEYWORDS: sqlite3_vtab_cursor +** +** Every module implementation uses a subclass of the following structure ** to describe cursors that point into the virtual table and are used ** to loop through the virtual table. Cursors are created using the ** xOpen method of the module. Each module implementation will define @@ -4375,6 +5073,8 @@ struct sqlite3_vtab_cursor { }; /* +** CAPI3REF: Declare The Schema Of A Virtual Table {F18280} +** ** The xCreate and xConnect methods of a module use the following API ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. @@ -4382,6 +5082,8 @@ struct sqlite3_vtab_cursor { int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); /* +** CAPI3REF: Overload A Function For A Virtual Table {F18300} +** ** Virtual tables can provide alternative implementations of functions ** using the xFindFunction method. But global versions of those functions ** must exist in order to be overloaded. @@ -4414,8 +5116,9 @@ int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); /* ** CAPI3REF: A Handle To An Open BLOB {F17800} ** -** An instance of the following opaque structure is used to -** represent an blob-handle. A blob-handle is created by +** An instance of this object represents an open BLOB on which +** incremental I/O can be preformed. +** Objects of this type are created by ** [sqlite3_blob_open()] and destroyed by [sqlite3_blob_close()]. ** The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces ** can be used to read or write small subsections of the blob. @@ -4427,26 +5130,52 @@ typedef struct sqlite3_blob sqlite3_blob; /* ** CAPI3REF: Open A BLOB For Incremental I/O {F17810} ** -** {F17811} This interfaces opens a handle to the blob located -** in row iRow,, column zColumn, table zTable in database zDb; +** This interfaces opens a handle to the blob located +** in row iRow, column zColumn, table zTable in database zDb; ** in other words, the same blob that would be selected by: ** **
 **     SELECT zColumn FROM zDb.zTable WHERE rowid = iRow;
 ** 
{END} ** -** {F17812} If the flags parameter is non-zero, the blob is opened for +** If the flags parameter is non-zero, the blob is opened for ** read and write access. If it is zero, the blob is opened for read -** access. {END} +** access. ** -** {F17813} On success, [SQLITE_OK] is returned and the new +** Note that the database name is not the filename that contains +** the database but rather the symbolic name of the database that +** is assigned when the database is connected using [ATTACH]. +** For the main database file, the database name is "main". For +** TEMP tables, the database name is "temp". +** +** On success, [SQLITE_OK] is returned and the new ** [sqlite3_blob | blob handle] is written to *ppBlob. -** {F17814} Otherwise an error code is returned and +** Otherwise an error code is returned and ** any value written to *ppBlob should not be used by the caller. -** {F17815} This function sets the database-handle error code and message +** This function sets the database-handle error code and message ** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()]. -** We should go through and mark all interfaces that behave this -** way with a similar statement +** +** INVARIANTS: +** +** {F17813} A successful invocation of the [sqlite3_blob_open(D,B,T,C,R,F,P)] +** interface opens an [sqlite3_blob] object P on the blob +** in column C of table T in database B on [database connection] D. +** +** {F17814} A successful invocation of [sqlite3_blob_open(D,...)] starts +** a new transaction on [database connection] D if that connection +** is not already in a transaction. +** +** {F17816} The [sqlite3_blob_open(D,B,T,C,R,F,P)] interface opens the blob +** for read and write access if and only if the F parameter +** is non-zero. +** +** {F17819} The [sqlite3_blob_open()] interface returns [SQLITE_OK] on +** success and an appropriate [error code] on failure. +** +** {F17821} If an error occurs during evaluation of [sqlite3_blob_open(D,...)] +** then subsequent calls to [sqlite3_errcode(D)], +** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] will return +** information approprate for that error. */ int sqlite3_blob_open( sqlite3*, @@ -4463,26 +5192,50 @@ int sqlite3_blob_open( ** ** Close an open [sqlite3_blob | blob handle]. ** -** {F17831} Closing a BLOB shall cause the current transaction to commit +** Closing a BLOB shall cause the current transaction to commit ** if there are no other BLOBs, no pending prepared statements, and the ** database connection is in autocommit mode. -** {F17832} If any writes were made to the BLOB, they might be held in cache +** If any writes were made to the BLOB, they might be held in cache ** until the close operation if they will fit. {END} ** Closing the BLOB often forces the changes ** out to disk and so if any I/O errors occur, they will likely occur ** at the time when the BLOB is closed. {F17833} Any errors that occur during ** closing are reported as a non-zero return value. ** -** {F17839} The BLOB is closed unconditionally. Even if this routine returns +** The BLOB is closed unconditionally. Even if this routine returns ** an error code, the BLOB is still closed. +** +** INVARIANTS: +** +** {F17833} The [sqlite3_blob_close(P)] interface closes an +** [sqlite3_blob] object P previously opened using +** [sqlite3_blob_open()]. +** +** {F17836} 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 +** [sqlite3_get_autocommit | autocommit mode]. +** +** {F17839} The [sqlite3_blob_close(P)] interfaces closes the +** [sqlite3_blob] object P unconditionally, even if +** [sqlite3_blob_close(P)] returns something other than [SQLITE_OK]. +** */ int sqlite3_blob_close(sqlite3_blob *); /* -** CAPI3REF: Return The Size Of An Open BLOB {F17805} +** CAPI3REF: Return The Size Of An Open BLOB {F17840} ** -** {F16806} Return the size in bytes of the blob accessible via the open -** [sqlite3_blob | blob-handle] passed as an argument. +** Return the size in bytes of the blob accessible via the open +** [sqlite3_blob] object in its only argument. +** +** INVARIANTS: +** +** {F17843} The [sqlite3_blob_bytes(P)] interface returns the size +** in bytes of the BLOB that the [sqlite3_blob] object P +** refers to. */ int sqlite3_blob_bytes(sqlite3_blob *); @@ -4491,38 +5244,96 @@ int sqlite3_blob_bytes(sqlite3_blob *); ** ** This function is used to read data from an open ** [sqlite3_blob | blob-handle] into a caller supplied buffer. -** {F17851} n bytes of data are copied into buffer -** z from the open blob, starting at offset iOffset. +** N bytes of data are copied into buffer +** Z from the open blob, starting at offset iOffset. ** -** {F17852} If offset iOffset is less than n bytes from the end of the blob, -** [SQLITE_ERROR] is returned and no data is read. {F17853} If n is +** If offset iOffset is less than N bytes from the end of the blob, +** [SQLITE_ERROR] is returned and no data is read. If N or iOffset is ** less than zero [SQLITE_ERROR] is returned and no data is read. ** -** {F17854} On success, SQLITE_OK is returned. Otherwise, an +** On success, SQLITE_OK is returned. Otherwise, an ** [error code] or an [extended error code] is returned. +** +** INVARIANTS: +** +** {F17853} The [sqlite3_blob_read(P,Z,N,X)] interface reads N bytes +** beginning at offset X from +** the blob that [sqlite3_blob] object P refers to +** and writes those N bytes into buffer Z. +** +** {F17856} In [sqlite3_blob_read(P,Z,N,X)] if the size of the blob +** is less than N+X bytes, then the function returns [SQLITE_ERROR] +** and nothing is read from the blob. +** +** {F17859} In [sqlite3_blob_read(P,Z,N,X)] if X or N is less than zero +** then the function returns [SQLITE_ERROR] +** and nothing is read from the blob. +** +** {F17862} The [sqlite3_blob_read(P,Z,N,X)] interface returns [SQLITE_OK] +** if N bytes where successfully read into buffer Z. +** +** {F17865} If the requested read could not be completed, +** the [sqlite3_blob_read(P,Z,N,X)] interface returns an +** appropriate [error code] or [extended error code]. +** +** {F17868} If an error occurs during evaluation of [sqlite3_blob_read(D,...)] +** then subsequent calls to [sqlite3_errcode(D)], +** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] will return +** information approprate for that error. */ -int sqlite3_blob_read(sqlite3_blob *, void *z, int n, int iOffset); +int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); /* ** CAPI3REF: Write Data Into A BLOB Incrementally {F17870} ** ** This function is used to write data into an open ** [sqlite3_blob | blob-handle] from a user supplied buffer. -** {F17871} n bytes of data are copied from the buffer +** n bytes of data are copied from the buffer ** pointed to by z into the open blob, starting at offset iOffset. ** -** {F17872} If the [sqlite3_blob | blob-handle] passed as the first argument +** If the [sqlite3_blob | blob-handle] passed as the first argument ** was not opened for writing (the flags parameter to [sqlite3_blob_open()] *** was zero), this function returns [SQLITE_READONLY]. ** -** {F17873} This function may only modify the contents of the blob; it is +** This function may only modify the contents of the blob; it is ** not possible to increase the size of a blob using this API. -** {F17874} If offset iOffset is less than n bytes from the end of the blob, -** [SQLITE_ERROR] is returned and no data is written. {F17875} If n is +** If offset iOffset is less than n bytes from the end of the blob, +** [SQLITE_ERROR] is returned and no data is written. If n is ** less than zero [SQLITE_ERROR] is returned and no data is written. ** -** {F17876} On success, SQLITE_OK is returned. Otherwise, an +** On success, SQLITE_OK is returned. Otherwise, an ** [error code] or an [extended error code] is returned. +** +** INVARIANTS: +** +** {F17873} The [sqlite3_blob_write(P,Z,N,X)] interface writes N bytes +** from buffer Z into +** the blob that [sqlite3_blob] object P refers to +** beginning at an offset of X into the blob. +** +** {F17875} The [sqlite3_blob_write(P,Z,N,X)] interface returns +** [SQLITE_READONLY] if the [sqlite3_blob] object P was +** [sqlite3_blob_open | opened] for reading only. +** +** {F17876} In [sqlite3_blob_write(P,Z,N,X)] if the size of the blob +** is less than N+X bytes, then the function returns [SQLITE_ERROR] +** and nothing is written into the blob. +** +** {F17879} In [sqlite3_blob_write(P,Z,N,X)] if X or N is less than zero +** then the function returns [SQLITE_ERROR] +** and nothing is written into the blob. +** +** {F17882} The [sqlite3_blob_write(P,Z,N,X)] interface returns [SQLITE_OK] +** if N bytes where successfully written into blob. +** +** {F17885} If the requested write could not be completed, +** the [sqlite3_blob_write(P,Z,N,X)] interface returns an +** appropriate [error code] or [extended error code]. +** +** {F17888} If an error occurs during evaluation of [sqlite3_blob_write(D,...)] +** then subsequent calls to [sqlite3_errcode(D)], +** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] will return +** information approprate for that error. */ int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); @@ -4531,30 +5342,57 @@ int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); ** ** A virtual filesystem (VFS) is an [sqlite3_vfs] object ** that SQLite uses to interact -** with the underlying operating system. Most builds come with a +** with the underlying operating system. Most SQLite builds come with a ** single default VFS that is appropriate for the host computer. ** New VFSes can be registered and existing VFSes can be unregistered. ** The following interfaces are provided. ** -** {F11201} The sqlite3_vfs_find() interface returns a pointer to -** a VFS given its name. {F11202} Names are case sensitive. -** {F11203} Names are zero-terminated UTF-8 strings. -** {F11204} If there is no match, a NULL -** pointer is returned. {F11205} If zVfsName is NULL then the default -** VFS is returned. {END} +** The sqlite3_vfs_find() interface returns a pointer to +** a VFS given its name. Names are case sensitive. +** Names are zero-terminated UTF-8 strings. +** If there is no match, a NULL +** pointer is returned. If zVfsName is NULL then the default +** VFS is returned. ** -** {F11210} New VFSes are registered with sqlite3_vfs_register(). -** {F11211} Each new VFS becomes the default VFS if the makeDflt flag is set. -** {F11212} The same VFS can be registered multiple times without injury. -** {F11213} To make an existing VFS into the default VFS, register it again -** with the makeDflt flag set. {U11214} If two different VFSes with the -** same name are registered, the behavior is undefined. {U11215} If a +** New VFSes are registered with sqlite3_vfs_register(). +** Each new VFS becomes the default VFS if the makeDflt flag is set. +** The same VFS can be registered multiple times without injury. +** To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a ** VFS is registered with a name that is NULL or an empty string, ** then the behavior is undefined. ** -** {F11220} Unregister a VFS with the sqlite3_vfs_unregister() interface. -** {F11221} If the default VFS is unregistered, another VFS is chosen as +** 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: +** +** {F11203} 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. +** +** {F11206} 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. +** +** {F11209} 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. +** +** {F11212} Using the [sqlite3_vfs_register(P,F)] interface to register +** the same [sqlite3_vfs] object multiple times is a harmless no-op. +** +** {F11215} The [sqlite3_vfs_register(P,F)] interface makes the +** the [sqlite3_vfs] object P the default [sqlite3_vfs] object +** if F is non-zero. +** +** {F11218} 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()]. */ sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); @@ -4609,6 +5447,7 @@ int sqlite3_vfs_unregister(sqlite3_vfs*); **
  • SQLITE_MUTEX_STATIC_MEM2 **
  • SQLITE_MUTEX_STATIC_PRNG **
  • SQLITE_MUTEX_STATIC_LRU +**
  • SQLITE_MUTEX_STATIC_LRU2 ** {END} ** ** {F17015} The first two constants cause sqlite3_mutex_alloc() to create @@ -4721,6 +5560,7 @@ int sqlite3_mutex_notheld(sqlite3_mutex*); #define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */ #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 */ /* ** CAPI3REF: Low-Level Control Of Database Files {F11300} @@ -4782,9 +5622,10 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_FAULT_FAILURES 2 #define SQLITE_TESTCTRL_FAULT_BENIGN_FAILURES 3 #define SQLITE_TESTCTRL_FAULT_PENDING 4 - - - +#define SQLITE_TESTCTRL_PRNG_SAVE 5 +#define SQLITE_TESTCTRL_PRNG_RESTORE 6 +#define SQLITE_TESTCTRL_PRNG_RESET 7 +#define SQLITE_TESTCTRL_BITVEC_TEST 8 /* diff --git a/src/3rdparty/include/sqlite/sqlite3ext.h b/src/3rdparty/include/sqlite/sqlite3ext.h index 5d4c2dec9..6c538ffe0 100644 --- a/src/3rdparty/include/sqlite/sqlite3ext.h +++ b/src/3rdparty/include/sqlite/sqlite3ext.h @@ -15,7 +15,7 @@ ** as extensions by SQLite should #include this file instead of ** sqlite3.h. ** -** @(#) $Id: sqlite3ext.h,v 1.17 2007/08/31 16:11:36 drh Exp $ +** @(#) $Id: sqlite3ext.h,v 1.21 2008/03/19 21:45:51 drh Exp $ */ #ifndef _SQLITE3EXT_H_ #define _SQLITE3EXT_H_ @@ -24,13 +24,13 @@ typedef struct sqlite3_api_routines sqlite3_api_routines; /* -** The following structure hold pointers to all of the SQLite API +** The following structure holds pointers to all of the SQLite API ** routines. ** ** WARNING: In order to maintain backwards compatibility, add new ** interfaces to the end of this structure only. If you insert new ** interfaces in the middle of this structure, then older different -** versions of SQLite will not be able to load each others shared +** versions of SQLite will not be able to load each others' shared ** libraries! */ struct sqlite3_api_routines { @@ -182,6 +182,12 @@ struct sqlite3_api_routines { sqlite3_vfs *(*vfs_find)(const char*); int (*vfs_register)(sqlite3_vfs*,int); int (*vfs_unregister)(sqlite3_vfs*); + int (*xthreadsafe)(void); + void (*result_zeroblob)(sqlite3_context*,int); + void (*result_error_code)(sqlite3_context*,int); + int (*test_control)(int, ...); + void (*randomness)(int,void*); + sqlite3 *(*context_db_handle)(sqlite3_context*); }; /* @@ -342,6 +348,12 @@ struct sqlite3_api_routines { #define sqlite3_vfs_find sqlite3_api->vfs_find #define sqlite3_vfs_register sqlite3_api->vfs_register #define sqlite3_vfs_unregister sqlite3_api->vfs_unregister +#define sqlite3_threadsafe sqlite3_api->xthreadsafe +#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob +#define sqlite3_result_error_code sqlite3_api->result_error_code +#define sqlite3_test_control sqlite3_api->test_control +#define sqlite3_randomness sqlite3_api->randomness +#define sqlite3_context_db_handle sqlite3_api->context_db_handle #endif /* SQLITE_CORE */ #define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api; diff --git a/src/3rdparty/src/sqlite/sqlite3.c b/src/3rdparty/src/sqlite/sqlite3.c index 9dcdf846d..bda4124da 100644 --- a/src/3rdparty/src/sqlite/sqlite3.c +++ b/src/3rdparty/src/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.5.5. By combining all the individual C code files into this +** version 3.5.8. 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 @@ -11,13 +11,13 @@ ** 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 -** 4801 lines past this header comment.) Additional code files may be +** 5642 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 2008-01-31 16:37:58 UTC. +** This amalgamation was generated on 2008-04-16 15:43:25 UTC. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -41,54 +41,41 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.658 2008/01/30 16:14:23 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.693 2008/04/15 14:36:42 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* -** The macro unlikely() is a hint that surrounds a boolean -** expression that is usually false. Macro likely() surrounds -** a boolean expression that is usually true. GCC is able to -** use these hints to generate better code, sometimes. +** Include the configuration header output by 'configure' if it was run +** (otherwise we get an empty default). */ -#if defined(__GNUC__) && 0 -# define likely(X) __builtin_expect((X),1) -# define unlikely(X) __builtin_expect((X),0) -#else -# define likely(X) !!(X) -# define unlikely(X) !!(X) -#endif - - +/************** Include config.h in the middle of sqliteInt.h ****************/ +/************** Begin file config.h ******************************************/ /* -** These #defines should enable >2GB file support on Posix if the -** underlying operating system supports it. If the OS lacks -** large file support, or if the OS is windows, these should be no-ops. +** 2008 March 6 ** -** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any -** system #includes. Hence, this block of code must be the very first -** code in all source files. +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: ** -** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch -** on the compiler command line. This is necessary if you are compiling -** on a recent machine (ex: RedHat 7.2) but you want your code to work -** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2 -** without this option, LFS is enable. But LFS does not exist in the kernel -** in RedHat 6.0, so the code won't work. Hence, for maximum binary -** portability you should omit LFS. +** 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. ** -** Similar is true for MacOS. LFS is only supported on MacOS 9 and later. +************************************************************************* +** Default configuration header in case the 'configure' script is not used +** +** @(#) $Id: config.h,v 1.1 2008/03/20 02:25:35 mlcreech Exp $ */ -#ifndef SQLITE_DISABLE_LFS -# define _LARGE_FILE 1 -# ifndef _FILE_OFFSET_BITS -# define _FILE_OFFSET_BITS 64 -# endif -# define _LARGEFILE_SOURCE 1 +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +/* We do nothing here, since no assumptions are made by default */ + #endif - +/************** End of config.h **********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ /************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/ /************** Begin file sqliteLimit.h *************************************/ /* @@ -105,7 +92,7 @@ ** ** This file defines various limits of what SQLite can process. ** -** @(#) $Id: sqliteLimit.h,v 1.6 2007/12/17 16:20:07 drh Exp $ +** @(#) $Id: sqliteLimit.h,v 1.8 2008/03/26 15:56:22 drh Exp $ */ /* @@ -142,18 +129,24 @@ /* ** The maximum length of a single SQL statement in bytes. -** A value of zero means there is no limit. +** +** It used to be the case that setting this value to zero would +** turn the limit off. That is no longer true. It is not possible +** to turn this limit off. */ #ifndef SQLITE_MAX_SQL_LENGTH -# define SQLITE_MAX_SQL_LENGTH 0 +# define SQLITE_MAX_SQL_LENGTH 1000000000 #endif /* ** The maximum depth of an expression tree. This is limited to ** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might ** want to place more severe limits on the complexity of an -** expression. A value of 0 (the default) means do not enforce -** any limitation on expression tree depth. +** expression. +** +** A value of 0 used to mean that the limit was not enforced. +** But that is no longer true. The limit is now strictly enforced +** at all times. */ #ifndef SQLITE_MAX_EXPR_DEPTH # define SQLITE_MAX_EXPR_DEPTH 1000 @@ -198,11 +191,9 @@ #endif /* -** The maximum number of attached databases. This must be at least 2 -** in order to support the main database file (0) and the file used to -** hold temporary tables (1). And it must be less than 32 because -** we use a bitmask of databases with a u32 in places (for example -** the Parse.cookieMask field). +** The maximum number of attached databases. This must be between 0 +** and 30. The upper bound on 30 is because a 32-bit integer bitmap +** is used internally to track attached databases. */ #ifndef SQLITE_MAX_ATTACHED # define SQLITE_MAX_ATTACHED 10 @@ -274,46 +265,95 @@ /************** End of sqliteLimit.h *****************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ +/* Disable nuisance warnings on Borland compilers */ +#if defined(__BORLANDC__) +#pragma warn -rch /* unreachable code */ +#pragma warn -ccc /* Condition is always true or false */ +#pragma warn -aus /* Assigned value is never used */ +#pragma warn -csu /* Comparing signed and unsigned */ +#pragma warn -spa /* Suspicous pointer arithmetic */ +#endif + +/* Needed for various definitions... */ +#define _GNU_SOURCE + /* -** For testing purposes, the various size limit constants are really -** variables that we can modify in the testfixture. +** Include standard header files as necessary */ -#ifdef SQLITE_TEST - #undef SQLITE_MAX_LENGTH - #undef SQLITE_MAX_COLUMN - #undef SQLITE_MAX_SQL_LENGTH - #undef SQLITE_MAX_EXPR_DEPTH - #undef SQLITE_MAX_COMPOUND_SELECT - #undef SQLITE_MAX_VDBE_OP - #undef SQLITE_MAX_FUNCTION_ARG - #undef SQLITE_MAX_VARIABLE_NUMBER - #undef SQLITE_MAX_PAGE_SIZE - #undef SQLITE_MAX_PAGE_COUNT - #undef SQLITE_MAX_LIKE_PATTERN_LENGTH +#ifdef HAVE_STDINT_H +#include +#endif +#ifdef HAVE_INTTYPES_H +#include +#endif - #define SQLITE_MAX_LENGTH sqlite3MAX_LENGTH - #define SQLITE_MAX_COLUMN sqlite3MAX_COLUMN - #define SQLITE_MAX_SQL_LENGTH sqlite3MAX_SQL_LENGTH - #define SQLITE_MAX_EXPR_DEPTH sqlite3MAX_EXPR_DEPTH - #define SQLITE_MAX_COMPOUND_SELECT sqlite3MAX_COMPOUND_SELECT - #define SQLITE_MAX_VDBE_OP sqlite3MAX_VDBE_OP - #define SQLITE_MAX_FUNCTION_ARG sqlite3MAX_FUNCTION_ARG - #define SQLITE_MAX_VARIABLE_NUMBER sqlite3MAX_VARIABLE_NUMBER - #define SQLITE_MAX_PAGE_SIZE sqlite3MAX_PAGE_SIZE - #define SQLITE_MAX_PAGE_COUNT sqlite3MAX_PAGE_COUNT - #define SQLITE_MAX_LIKE_PATTERN_LENGTH sqlite3MAX_LIKE_PATTERN_LENGTH +/* +** If possible, use the C99 intptr_t type to define an integral type of +** equivalent size to a pointer. (Technically it's >= sizeof(void *), but +** practically it's == sizeof(void *)). We fall back to an int if this type +** isn't defined. +*/ +#ifdef HAVE_INTPTR_T + typedef intptr_t sqlite3_intptr_t; +#else + typedef int sqlite3_intptr_t; +#endif - extern int sqlite3MAX_LENGTH; - extern int sqlite3MAX_COLUMN; - extern int sqlite3MAX_SQL_LENGTH; - extern int sqlite3MAX_EXPR_DEPTH; - extern int sqlite3MAX_COMPOUND_SELECT; - extern int sqlite3MAX_VDBE_OP; - extern int sqlite3MAX_FUNCTION_ARG; - extern int sqlite3MAX_VARIABLE_NUMBER; - extern int sqlite3MAX_PAGE_SIZE; - extern int sqlite3MAX_PAGE_COUNT; - extern int sqlite3MAX_LIKE_PATTERN_LENGTH; +/* +** A macro used to aid in coverage testing. When doing coverage +** testing, the condition inside the argument must be evaluated +** both true and false in order to get full branch coverage. +** This macro can be inserted to ensure adequate test coverage +** in places where simple condition/decision coverage is inadequate. +*/ +#ifdef SQLITE_COVERAGE_TEST +SQLITE_PRIVATE void sqlite3Coverage(int); +# define testcase(X) if( X ){ sqlite3Coverage(__LINE__); } +#else +# define testcase(X) +#endif + + +/* +** The macro unlikely() is a hint that surrounds a boolean +** expression that is usually false. Macro likely() surrounds +** a boolean expression that is usually true. GCC is able to +** use these hints to generate better code, sometimes. +*/ +#if defined(__GNUC__) && 0 +# define likely(X) __builtin_expect((X),1) +# define unlikely(X) __builtin_expect((X),0) +#else +# define likely(X) !!(X) +# define unlikely(X) !!(X) +#endif + + +/* +** These #defines should enable >2GB file support on Posix if the +** underlying operating system supports it. If the OS lacks +** large file support, or if the OS is windows, these should be no-ops. +** +** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any +** system #includes. Hence, this block of code must be the very first +** code in all source files. +** +** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch +** on the compiler command line. This is necessary if you are compiling +** on a recent machine (ex: RedHat 7.2) but you want your code to work +** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2 +** without this option, LFS is enable. But LFS does not exist in the kernel +** in RedHat 6.0, so the code won't work. Hence, for maximum binary +** portability you should omit LFS. +** +** Similar is true for MacOS. LFS is only supported on MacOS 9 and later. +*/ +#ifndef SQLITE_DISABLE_LFS +# define _LARGE_FILE 1 +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif +# define _LARGEFILE_SOURCE 1 #endif @@ -330,6 +370,40 @@ #endif #endif +/* +** Exactly one of the following macros must be defined in order to +** specify which memory allocation subsystem to use. +** +** SQLITE_SYSTEM_MALLOC // Use normal system malloc() +** SQLITE_MEMDEBUG // Debugging version of system malloc() +** SQLITE_MEMORY_SIZE // internal allocator #1 +** SQLITE_MMAP_HEAP_SIZE // internal mmap() allocator +** SQLITE_POW2_MEMORY_SIZE // internal power-of-two allocator +** +** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as +** the default. +*/ +#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_MEMDEBUG)+\ + defined(SQLITE_MEMORY_SIZE)+defined(SQLITE_MMAP_HEAP_SIZE)+\ + defined(SQLITE_POW2_MEMORY_SIZE)>1 +# error "At most one of the following compile-time configuration options\ + is allows: SQLITE_SYSTEM_MALLOC, SQLITE_MEMDEBUG, SQLITE_MEMORY_SIZE,\ + SQLITE_MMAP_HEAP_SIZE, SQLITE_POW2_MEMORY_SIZE" +#endif +#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_MEMDEBUG)+\ + defined(SQLITE_MEMORY_SIZE)+defined(SQLITE_MMAP_HEAP_SIZE)+\ + defined(SQLITE_POW2_MEMORY_SIZE)==0 +# define SQLITE_SYSTEM_MALLOC 1 +#endif + +/* +** If SQLITE_MALLOC_SOFT_LIMIT is defined, then try to keep the +** sizes of memory allocations below this value where possible. +*/ +#if defined(SQLITE_POW2_MEMORY_SIZE) && !defined(SQLITE_MALLOC_SOFT_LIMIT) +# define SQLITE_MALLOC_SOFT_LIMIT 1024 +#endif + /* ** We need to define _XOPEN_SOURCE as follows in order to enable ** recursive mutexes on most unix systems. But Mac OS X is different. @@ -396,7 +470,7 @@ ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** -** @(#) $Id: sqlite.h.in,v 1.282 2008/01/31 16:36:40 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.305 2008/04/16 00:28:14 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -435,7 +509,7 @@ extern "C" { ** the sqlite3.h file specify the version of SQLite with which ** that header file is associated. ** -** The "version" of SQLite is a strong of the form "X.Y.Z". +** The "version" of SQLite is a string of the form "X.Y.Z". ** The phrase "alpha" or "beta" might be appended after the Z. ** The X value is major version number always 3 in SQLite3. ** The X value only changes when backwards compatibility is @@ -459,8 +533,8 @@ extern "C" { ** 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.5.5" -#define SQLITE_VERSION_NUMBER 3005005 +#define SQLITE_VERSION "3.5.8" +#define SQLITE_VERSION_NUMBER 3005008 /* ** CAPI3REF: Run-Time Library Version Numbers {F10020} @@ -489,7 +563,7 @@ extern "C" { ** {F10023} The [sqlite3_libversion()] function returns ** a pointer to the [sqlite3_version] string constant. */ -SQLITE_EXTERN const char sqlite3_version[]; +SQLITE_API const char sqlite3_version[]; SQLITE_API const char *sqlite3_libversion(void); SQLITE_API int sqlite3_libversion_number(void); @@ -498,7 +572,7 @@ SQLITE_API int sqlite3_libversion_number(void); ** ** SQLite can be compiled with or without mutexes. When ** the SQLITE_THREADSAFE C preprocessor macro is true, mutexes -** are enabled and SQLite is threadsafe. When that macro os false, +** are enabled and SQLite is threadsafe. When that macro is false, ** the mutexes are omitted. Without the mutexes, it is not safe ** to use SQLite from more than one thread. ** @@ -700,7 +774,8 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** *errmsg if errmsg is NULL or if there are no errors. ** ** {F12137} The [sqlite3_exec()] function sets the error code and message -** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()]. +** accessible via [sqlite3_errcode()], [sqlite3_errmsg()], and +** [sqlite3_errmsg16()]. ** ** LIMITATIONS: ** @@ -799,7 +874,7 @@ SQLITE_API int sqlite3_exec( ** {F10225} Extended result code names contain two or more "_" characters. ** ** {F10226} The numeric value of an extended result code contains the -** numeric value of its corresponding primary result code it +** numeric value of its corresponding primary result code in ** its least significant 8 bits. */ #define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) @@ -818,7 +893,7 @@ SQLITE_API int sqlite3_exec( /* ** CAPI3REF: Flags For File Open Operations {F10230} ** -** These bit values are intended for use in then +** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the xOpen method of the ** [sqlite3_vfs] object. @@ -885,12 +960,12 @@ SQLITE_API int sqlite3_exec( ** CAPI3REF: Synchronization Type Flags {F10260} ** ** When SQLite invokes the xSync() method of an -** [sqlite3_io_methods] object it uses a combination of the +** [sqlite3_io_methods] object it uses a combination of ** these integer values as the second argument. ** ** When the SQLITE_SYNC_DATAONLY flag is used, it means that the ** sync operation only needs to flush data to mass storage. Inode -** information need not be flushed. The SQLITE_SYNC_NORMAL means +** information need not be flushed. The SQLITE_SYNC_NORMAL flag means ** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means ** to use Mac OS-X style fullsync instead of fsync(). */ @@ -918,7 +993,7 @@ struct sqlite3_file { ** CAPI3REF: OS Interface File Virtual Methods Object {F11120} ** ** Every file opened by the [sqlite3_vfs] xOpen method contains a pointer to -** an instance of the this object. This object defines the +** an instance of this object. This object defines the ** methods used to perform various operations against the open file. ** ** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or @@ -1016,7 +1091,7 @@ struct sqlite3_io_methods { ** interface. ** ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This -** opcode cases the xFileControl method to write the current state of +** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) ** into an integer that the pArg argument points to. This capability @@ -1052,13 +1127,13 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** structure used by this VFS. mxPathname is the maximum length of ** a pathname in this VFS. ** -** Registered vfs modules are kept on a linked list formed by +** Registered sqlite3_vfs objects are kept on a linked list formed by ** the pNext pointer. The [sqlite3_vfs_register()] ** and [sqlite3_vfs_unregister()] interfaces manage this list ** in a thread-safe way. The [sqlite3_vfs_find()] interface ** searches the list. ** -** The pNext field is the only fields in the sqlite3_vfs +** The pNext field is the only field in the sqlite3_vfs ** structure that SQLite will ever modify. SQLite will only access ** or modify this field while holding a particular static mutex. ** The application should never modify anything within the sqlite3_vfs @@ -1096,12 +1171,12 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** ** The file I/O implementation can use the object type flags to ** changes the way it deals with files. For example, an application -** that does not care about crash recovery or rollback, might make -** the open of a journal file a no-op. Writes to this journal are -** also a no-op. Any attempt to read the journal return SQLITE_IOERR. -** Or the implementation might recognize the a database file will -** be doing page-aligned sector reads and writes in a random order -** and set up its I/O subsystem accordingly. +** that does not care about crash recovery or rollback might make +** the open of a journal file a no-op. Writes to this journal would +** also be no-ops, and any attempt to read the journal would return +** SQLITE_IOERR. Or the implementation might recognize that a database +** file will be doing page-aligned sector reads and writes in a random +** order and set up its I/O subsystem accordingly. ** ** SQLite might also add one of the following flags to the xOpen ** method: @@ -1118,7 +1193,7 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** for exclusive access. This flag is set for all files except ** for the main database file. {END} ** -** {F11148} At least szOsFile bytes of memory is allocated by SQLite +** {F11148} At least szOsFile bytes of memory are allocated by SQLite ** to hold the [sqlite3_file] structure passed as the third ** argument to xOpen. {END} The xOpen method does not have to ** allocate the structure; it should just fill it in. @@ -1130,7 +1205,7 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** to test to see if a file is at least readable. {END} The file can be a ** directory. ** -** {F11150} SQLite will always allocate at least mxPathname+1 byte for +** {F11150} SQLite will always allocate at least mxPathname+1 bytes for ** the output buffers for xGetTempname and xFullPathname. {F11151} The exact ** size of the output buffer is also passed as a parameter to both ** methods. {END} If the output buffer is not large enough, SQLITE_CANTOPEN @@ -1144,7 +1219,7 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** The xRandomness() function attempts to return nBytes bytes ** of good-quality randomness into zOut. The return value is ** the actual number of bytes of randomness obtained. The -** xSleep() method cause the calling thread to sleep for at +** xSleep() method causes the calling thread to sleep for at ** least the number of microseconds given. The xCurrentTime() ** method returns a Julian Day Number for the current date and ** time. @@ -1179,7 +1254,7 @@ struct sqlite3_vfs { ** ** {F11191} These integer constants can be used as the third parameter to ** the xAccess method of an [sqlite3_vfs] object. {END} They determine -** the kind of what kind of permissions the xAccess method is +** what kind of permissions the xAccess method is ** looking for. {F11192} With SQLITE_ACCESS_EXISTS, the xAccess method ** simply checks to see if the file exists. {F11193} With ** SQLITE_ACCESS_READWRITE, the xAccess method checks to see @@ -1220,7 +1295,7 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); ** as an undeclared column named ROWID, OID, or _ROWID_ as long as those ** names are not also used by explicitly declared columns. If ** the table has a column of type INTEGER PRIMARY KEY then that column -** is another an alias for the rowid. +** is another alias for the rowid. ** ** This routine returns the rowid of the most recent ** successful INSERT into the database from the database connection @@ -1260,7 +1335,7 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); ** ** LIMITATIONS: ** -** {U12232} If separate thread does a new insert on the same +** {U12232} If a separate thread does 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 @@ -1280,7 +1355,7 @@ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); ** triggers are not counted. Use the [sqlite3_total_changes()] function ** to find the total number of changes including changes caused by triggers. ** -** A "row changes" is a change to a single row of a single table +** A "row change" is a change to a single row of a single table ** caused by an INSERT, DELETE, or UPDATE statement. Rows that ** are changed as side effects of REPLACE constraint resolution, ** rollback, ABORT processing, DROP TABLE, or by any other @@ -1352,7 +1427,7 @@ SQLITE_API int sqlite3_changes(sqlite3*); ** SQLite implements the command "DELETE FROM table" without ** a WHERE clause by dropping and recreating the table. (This is much ** faster than going -** through and deleting individual elements form the table.) Because of +** through and deleting individual elements from the table.) Because of ** this optimization, the change count for "DELETE FROM table" will be ** zero regardless of the number of elements that were originally in the ** table. To get an accurate count of the number of rows deleted, use @@ -1955,18 +2030,43 @@ SQLITE_API void sqlite3_free(void*); SQLITE_API sqlite3_int64 sqlite3_memory_used(void); SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); +/* +** CAPI3REF: Pseudo-Random Number Generator {F17390} +** +** SQLite contains a high-quality pseudo-random number generator (PRNG) used to +** select random ROWIDs when inserting new records into a table that +** already uses the largest possible ROWID. The PRNG is also used for +** the build-in random() and randomblob() SQL functions. This interface allows +** appliations to access the same PRNG for other purposes. +** +** A call to this routine stores N bytes of randomness into buffer P. +** +** The first time this routine is invoked (either internally or by +** the application) the PRNG is seeded using randomness obtained +** from the xRandomness method of the default [sqlite3_vfs] object. +** On all subsequent invocations, the pseudo-randomness is generated +** internally and without recourse to the [sqlite3_vfs] xRandomness +** method. +** +** INVARIANTS: +** +** {F17392} The [sqlite3_randomness(N,P)] interface writes N bytes of +** high-quality pseudo-randomness into buffer P. +*/ +SQLITE_API void sqlite3_randomness(int N, void *P); + /* ** CAPI3REF: Compile-Time Authorization Callbacks {F12500} ** ** This routine registers a authorizer callback with a particular -** database connection, supplied in the first argument. +** [database connection], supplied in the first argument. ** The authorizer callback is invoked as SQL statements are being compiled ** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], ** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. At various ** points during the compilation process, as logic is being created ** to perform various actions, the authorizer callback is invoked to ** see if those actions are allowed. The authorizer callback should -** return SQLITE_OK to allow the action, [SQLITE_IGNORE] to disallow the +** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the ** specific action but allow the SQL statement to continue to be ** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be ** rejected with an error. If the authorizer callback returns @@ -1979,9 +2079,9 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); ** [sqlite3_prepare_v2()] or equivalent call that triggered the ** authorizer will fail with an error message explaining that ** access is denied. If the authorizer code is [SQLITE_READ] -** and the callback returns [SQLITE_IGNORE] then the prepared -** statement is constructed to insert a NULL value in place of -** the table column that would have +** and the callback returns [SQLITE_IGNORE] then the +** [prepared statement] statement is constructed to substitute +** a NULL value in place of the table column that would have ** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] ** return can be used to deny an untrusted user access to individual ** columns of a table. @@ -1994,7 +2094,8 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); ** parameters to the callback are zero-terminated strings that contain ** additional details about the action to be authorized. ** -** An authorizer is used when preparing SQL statements from an untrusted +** An authorizer is used when [sqlite3_prepare | preparing] +** SQL statements from an untrusted ** source, to ensure that the SQL statements do not try to access data ** that they are not allowed to see, or that they do not try to ** execute malicious statements that damage the database. For @@ -2002,8 +2103,13 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); ** SQL queries for evaluation by a database. But the application does ** not want the user to be able to make arbitrary changes to the ** database. An authorizer could then be put in place while the -** user-entered SQL is being prepared that disallows everything -** except SELECT statements. +** user-entered SQL is being [sqlite3_prepare | prepared] that +** disallows everything except [SELECT] statements. +** +** Applications that need to process SQL from untrusted sources +** might also consider lowering resource limits using [sqlite3_limit()] +** and limiting database size using the [max_page_count] [PRAGMA] +** in addition to using an authorizer. ** ** Only a single authorizer can be in place on a database connection ** at a time. Each call to sqlite3_set_authorizer overrides the @@ -2318,6 +2424,9 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** The third options is behavior that is always used for [sqlite3_open()] ** and [sqlite3_open16()]. ** +** If the 4th parameter to [sqlite3_open_v2()] is not one of the +** combinations shown above then the behavior is undefined. +** ** If the filename is ":memory:", then an private ** in-memory database is created for the connection. This in-memory ** database will vanish when the database connection is closed. Future @@ -2396,8 +2505,8 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** Is SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE required ** in sqlite3_open_v2()? ** -** {F12719} If the filename is an empty string, then a private, ephermeral -** on-disk database will be created. +** {F12719} If the filename is NULL or an empty string, then a private, +** ephermeral on-disk database will be created. ** Is SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE required ** in sqlite3_open_v2()? ** @@ -2435,7 +2544,7 @@ SQLITE_API int sqlite3_open_v2( ** text that describes the error, as either UTF8 or UTF16 respectively. ** Memory to hold the error message string is managed internally. ** The application does not need to worry with freeing the result. -** However, the error string might be overwritten or deallocated b +** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions. ** ** INVARIANTS: @@ -2443,24 +2552,16 @@ SQLITE_API int sqlite3_open_v2( ** {F12801} The [sqlite3_errcode(D)] interface returns the numeric ** [SQLITE_OK | result code] or ** [SQLITE_IOERR_READ | extended result code] -** for the most recent failed interface call associated -** with [sqlite3] handle D. -** -** {U12802} If a prior API call failed but the most recent API call -** succeeded, the return value from [sqlite3_errcode()], -** [sqlite3_errmsg()], and [sqlite3_errmsg16()] are undefined. +** for the most recently failed interface call associated +** with [database connection] D. ** ** {F12803} 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 UTF8 or UTF16 respectively. ** -** {U12804} The strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()] -** are only valid until the next SQLite interface call. -** -** {F12807} Calls to [sqlite3_errcode()], [sqlite3_errmsg()], and -** [sqlite3_errmsg16()] themselves do not affect the -** results of future invocations of these routines. +** {F12807} The strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()] +** are valid until the next SQLite interface call. ** ** {F12808} Calls to API routines that do not return an error code ** (example: [sqlite3_data_count()]) do not @@ -2503,6 +2604,118 @@ SQLITE_API const void *sqlite3_errmsg16(sqlite3*); */ typedef struct sqlite3_stmt sqlite3_stmt; +/* +** CAPI3REF: Run-time Limits {F12760} +** +** This interface allows the size of various constructs to be limited +** on a connection by connection basis. The first parameter is the +** [database connection] whose limit is to be set or queried. The +** second parameter is one of the [limit categories] that define a +** 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-preprocess macro named 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 +** 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 +** attach. Developers might also want to use the [sqlite3_set_authorizer()] +** interface to further control untrusted SQL. The size of the database +** created by an untrusted script can be contained using the +** [max_page_count] [PRAGMA]. +** +** This interface is currently considered experimental and is subject +** to change or removal without prior notice. +** +** INVARIANTS: +** +** {F12762} A successful call to [sqlite3_limit(D,C,V)] where V is +** positive changes the +** limit on the size of construct C in [database connection] D +** to the lessor of V and the hard upper bound on the size +** of C that is set at compile-time. +** +** {F12764} A successful call to [sqlite3_limit(D,C,V)] where V is zero +** changes the limit on the size of construct C in +** [database connection] D to be the hard upper bound on the size +** of C that is set at compile-time. +** +** {F12766} A successful call to [sqlite3_limit(D,C,V)] where V is negative +** leaves the state of [database connection] D unchanged. +** +** {F12769} A successful call to [sqlite3_limit(D,C,V)] returns the +** value of the limit on the size of construct C in +** in [database connection] D as it was prior to the call. +*/ +SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + +/* +** CAPI3REF: Run-Time Limit Categories {F12790} +** 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: +** +**
    +**
    SQLITE_LIMIT_LENGTH
    +**
    The maximum size of any +** string or blob or table row.
    +** +**
    SQLITE_LIMIT_SQL_LENGTH
    +**
    The maximum length of an SQL statement.
    +** +**
    SQLITE_LIMIT_COLUMN
    +**
    The maximum number of columns in a table definition or in the +** result set of a SELECT or the maximum number of columns in an index +** or in an ORDER BY or GROUP BY clause.
    +** +**
    SQLITE_LIMIT_EXPR_DEPTH
    +**
    The maximum depth of the parse tree on any expression.
    +** +**
    SQLITE_LIMIT_COMPOUND_SELECT
    +**
    The maximum number of terms in a compound SELECT statement.
    +** +**
    SQLITE_LIMIT_VDBE_OP
    +**
    The maximum number of instructions in a virtual machine program +** used to implement an SQL statement.
    +** +**
    SQLITE_LIMIT_FUNCTION_ARG
    +**
    The maximum number of arguments on a function.
    +** +**
    SQLITE_LIMIT_ATTACHED
    +**
    The maximum number of attached databases.
    +** +**
    SQLITE_LIMIT_LIKE_PATTERN_LENGTH
    +**
    The maximum length of the pattern argument to the LIKE or +** GLOB operators.
    +** +**
    SQLITE_LIMIT_VARIABLE_NUMBER
    +**
    The maximum number of variables in an SQL statement that can +** be bound.
    +**
    +*/ +#define SQLITE_LIMIT_LENGTH 0 +#define SQLITE_LIMIT_SQL_LENGTH 1 +#define SQLITE_LIMIT_COLUMN 2 +#define SQLITE_LIMIT_EXPR_DEPTH 3 +#define SQLITE_LIMIT_COMPOUND_SELECT 4 +#define SQLITE_LIMIT_VDBE_OP 5 +#define SQLITE_LIMIT_FUNCTION_ARG 6 +#define SQLITE_LIMIT_ATTACHED 7 +#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 +#define SQLITE_LIMIT_VARIABLE_NUMBER 9 + /* ** CAPI3REF: Compiling An SQL Statement {F13010} ** @@ -2522,7 +2735,11 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** If nByte is non-negative, then it is the maximum number of ** bytes read from zSql. When nByte is non-negative, the ** zSql string ends at either the first '\000' or '\u0000' character or -** until the nByte-th byte, whichever comes first. {END} +** the nByte-th byte, whichever comes first. If the caller knows +** that the supplied string is nul-terminated, then there is a small +** performance advantage to be had by passing an nByte parameter that +** is equal to the number of bytes in the input string including +** the nul-terminator bytes.{END} ** ** *pzTail is made to point to the first byte past the end of the ** first SQL statement in zSql. These routines only compiles the first @@ -2530,7 +2747,7 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** uncompiled. ** ** *ppStmt is left pointing to a compiled [prepared statement] that can be -** executed using [sqlite3_step()]. Or if there is an error, *ppStmt may be +** executed using [sqlite3_step()]. Or if there is an error, *ppStmt is ** set to NULL. If the input text contains no SQL (if the input ** is and empty string or a comment) then *ppStmt is set to NULL. ** {U13018} The calling procedure is responsible for deleting the @@ -2588,7 +2805,7 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** read from zSql is read up to the first zero terminator. ** ** {F13014} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)] -** and its variants is non-negative, then nBytes bytes +** and its variants is non-negative, then at most nBytes bytes ** SQL text is read from zSql. ** ** {F13015} In [sqlite3_prepare_v2(db,zSql,N,P,pzTail)] and its variants @@ -2604,6 +2821,10 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** ** {F13019} The [sqlite3_prepare_v2()] interface and its variants return ** [SQLITE_OK] or an appropriate [error code] upon failure. +** +** {F13021} Before [sqlite3_prepare(db,zSql,nByte,ppStmt,pzTail)] or its +** variants returns an error (any value other than [SQLITE_OK]) +** it first sets *ppStmt to NULL. */ SQLITE_API int sqlite3_prepare( sqlite3 *db, /* Database handle */ @@ -2663,12 +2884,39 @@ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Dynamically Typed Value Object {F15000} +** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} ** ** SQLite uses the sqlite3_value object to represent all values -** that are or can be stored in a database table. +** that can be stored in a database table. ** SQLite uses dynamic typing for the values it stores. ** Values stored in sqlite3_value objects can be ** be integers, floating point values, strings, BLOBs, or NULL. +** +** An sqlite3_value object may be either "protected" or "unprotected". +** Some interfaces require a protected sqlite3_value. Other interfaces +** will accept either a protected or an unprotected sqlite3_value. +** Every interface that accepts sqlite3_value arguments specifies +** whether or not it requires a protected sqlite3_value. +** +** The terms "protected" and "unprotected" refer to whether or not +** a mutex is held. A internal mutex is held for a protected +** sqlite3_value object but no mutex is held for an unprotected +** sqlite3_value object. If SQLite is compiled to be single-threaded +** (with SQLITE_THREADSAFE=0 and with [sqlite3_threadsafe()] returning 0) +** then there is no distinction between +** protected and unprotected sqlite3_value objects and they can be +** used interchangable. However, for maximum code portability it +** is recommended that applications make the distinction between +** between protected and unprotected sqlite3_value objects even if +** they are single threaded. +** +** The sqlite3_value objects that are passed as parameters into the +** implementation of application-defined SQL functions are protected. +** The sqlite3_value object returned by +** [sqlite3_column_value()] is unprotected. +** Unprotected sqlite3_value objects may only be used with +** [sqlite3_result_value()] and [sqlite3_bind_value()]. All other +** interfaces that use sqlite3_value require protected sqlite3_value objects. */ typedef struct Mem sqlite3_value; @@ -2714,15 +2962,13 @@ typedef struct sqlite3_context sqlite3_context; ** for "?NNN" parameters is the value of NNN. ** The NNN value must be between 1 and the compile-time ** parameter SQLITE_MAX_VARIABLE_NUMBER (default value: 999). -** See limits.html for additional information. ** ** The third argument is the value to bind to the parameter. ** ** In those ** routines that have a fourth argument, its value is the number of bytes ** in the parameter. To be clear: the value is the number of bytes -** in the value, not the number of characters. The number -** of bytes does not include the zero-terminator at the end of strings. +** in the value, not the number of characters. ** If the fourth parameter is negative, the length of the string is ** number of bytes up to the first zero terminator. ** @@ -2831,6 +3077,10 @@ typedef struct sqlite3_context sqlite3_context; ** ** {F13548} 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. +** +** {F13551} 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. */ 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); @@ -3389,6 +3639,15 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** but leaves the result in UTF-16 in native byte order instead of UTF-8. ** The zero terminator is not included in this count. ** +** The object returned by [sqlite3_column_value()] is an +** [unprotected sqlite3_value] object. An unprotected sqlite3_value object +** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()]. +** If the [unprotected sqlite3_value] object returned by +** [sqlite3_column_value()] is used in any other way, including calls +** to routines like +** [sqlite3_value_int()], [sqlite3_value_text()], or [sqlite3_value_bytes()], +** then the behavior is undefined. +** ** These routines attempt to convert the value where appropriate. For ** example, if the internal representation is FLOAT and a text result ** is requested, [sqlite3_snprintf()] is used internally to do the conversion @@ -3504,8 +3763,8 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** ** {F13815} The [sqlite3_column_int(S,N)] interface converts the ** Nth column in the current row of the result set for -** [prepared statement] S into a 32-bit signed integer and -** returns a copy of that integer. +** [prepared statement] S into a 64-bit signed integer and +** returns the lower 32 bits of that integer. ** ** {F13818} The [sqlite3_column_int64(S,N)] interface converts the ** Nth column in the current row of the result set for @@ -3530,7 +3789,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** [prepared statement] S. ** ** {F13830} The [sqlite3_column_value(S,N)] interface returns a -** pointer to the [sqlite3_value] object that for the +** pointer to an [unprotected sqlite3_value] object for the ** Nth column in the current row of the result set for ** [prepared statement] S. */ @@ -3613,11 +3872,10 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** name of the (scalar) function or aggregate, is encoded in UTF-8 for ** sqlite3_create_function() and UTF-16 for sqlite3_create_function16(). ** -** The first argument is the [database connection] that holds the -** SQL function or aggregate is to be added or redefined. If a single -** program uses more than one database handle internally, then SQL -** functions or aggregates must be added individually to each database -** handle with which they will be used. +** The first parameter is the [database connection] to which the SQL +** function is to be added. If a single +** program uses more than one [database connection] internally, then SQL +** functions must be added individually to each [database connection]. ** ** The second parameter is the name of the SQL function to be created ** or redefined. @@ -3670,7 +3928,63 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** zero-terminated UTF-16 native byte order instead of as a ** zero-terminated UTF-8. ** -** {F16106} +** {F16106} A successful invocation of +** the [sqlite3_create_function(D,X,N,E,...)] interface registers +** or replaces callback functions in [database connection] D +** used to implement the SQL function named X with N parameters +** and having a perferred text encoding of E. +** +** {F16109} A successful call to [sqlite3_create_function(D,X,N,E,P,F,S,L)] +** replaces the P, F, S, and L values from any prior calls with +** the same D, X, N, and E values. +** +** {F16112} The [sqlite3_create_function(D,X,...)] interface fails with +** a return code of [SQLITE_ERROR] if the SQL function name X is +** longer than 255 bytes exclusive of the zero terminator. +** +** {F16118} Either F must be NULL and S and L are non-NULL or else F +** is non-NULL and S and L are NULL, otherwise +** [sqlite3_create_function(D,X,N,E,P,F,S,L)] returns [SQLITE_ERROR]. +** +** {F16121} The [sqlite3_create_function(D,...)] interface fails with an +** error code of [SQLITE_BUSY] if there exist [prepared statements] +** associated with the [database connection] D. +** +** {F16124} The [sqlite3_create_function(D,X,N,...)] interface fails with an +** error code of [SQLITE_ERROR] if parameter N (specifying the number +** of arguments to the SQL function being registered) is less +** than -1 or greater than 127. +** +** {F16127} When N is non-negative, the [sqlite3_create_function(D,X,N,...)] +** interface causes callbacks to be invoked for the SQL function +** named X when the number of arguments to the SQL function is +** exactly N. +** +** {F16130} When N is -1, the [sqlite3_create_function(D,X,N,...)] +** interface causes callbacks to be invoked for the SQL function +** named X with any number of arguments. +** +** {F16133} 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 is preferred. +** +** {F16136} 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 is preferred. +** +** {F16139} For an aggregate SQL function created using +** [sqlite3_create_function(D,X,N,E,P,0,S,L)] the finializer +** function L will always be invoked exactly once if the +** step function S is called one or more times. +** +** {F16142} 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 are always [protected sqlite3_value] objects. */ SQLITE_API int sqlite3_create_function( sqlite3 *db, @@ -3733,14 +4047,18 @@ SQLITE_API int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlit ** to [sqlite3_create_function()] and [sqlite3_create_function16()] ** define callbacks that implement the SQL functions and aggregates. ** The 4th parameter to these callbacks is an array of pointers to -** [sqlite3_value] objects. There is one [sqlite3_value] object for +** [protected sqlite3_value] objects. There is one [sqlite3_value] object for ** each parameter to the SQL function. These routines are used to ** extract values from the [sqlite3_value] objects. ** +** These routines work only with [protected sqlite3_value] objects. +** Any attempt to use these routines on an [unprotected sqlite3_value] +** object results in undefined behavior. +** ** These routines work just like the corresponding ** [sqlite3_column_blob | sqlite3_column_* routines] except that -** these routines take a single [sqlite3_value*] pointer instead -** of an [sqlite3_stmt*] pointer and an integer column number. +** these routines take a single [protected sqlite3_value] object pointer +** instead of an [sqlite3_stmt*] pointer and an integer column number. ** ** The sqlite3_value_text16() interface extracts a UTF16 string ** in the native byte-order of the host machine. The @@ -3762,11 +4080,70 @@ SQLITE_API int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlit ** or [sqlite3_value_text16()]. ** ** These routines must be called from the same thread as -** the SQL function that supplied the sqlite3_value* parameters. -** Or, if the sqlite3_value* argument comes from the [sqlite3_column_value()] -** interface, then these routines should be called from the same thread -** that ran [sqlite3_column_value()]. +** the SQL function that supplied the [sqlite3_value*] parameters. ** +** +** INVARIANTS: +** +** {F15103} 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. +** +** {F15106} 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)]. +** +** {F15109} 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)]. +** +** {F15112} 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. +** +** {F15115} 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. +** +** {F15118} 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. +** +** {F15121} 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. +** +** {F15124} 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. +** +** {F15127} 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. +** +** {F15130} 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. +** +** {F15133} 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. +** +** {F15136} 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. */ SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); SQLITE_API int sqlite3_value_bytes(sqlite3_value*); @@ -3786,16 +4163,16 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); ** ** The implementation of aggregate SQL functions use this routine to allocate ** a structure for storing their state. -** {F16211} The first time the sqlite3_aggregate_context() routine is +** The first time the sqlite3_aggregate_context() routine is ** is called for a particular aggregate, SQLite allocates nBytes of memory ** zeros that memory, and returns a pointer to it. -** {F16212} On second and subsequent calls to sqlite3_aggregate_context() -** for the same aggregate function index, the same buffer is returned. {END} +** On second and subsequent calls to sqlite3_aggregate_context() +** for the same aggregate function index, the same buffer is returned. ** The implementation ** of the aggregate can use the returned buffer to accumulate data. ** -** {F16213} SQLite automatically frees the allocated buffer when the aggregate -** query concludes. {END} +** SQLite automatically frees the allocated buffer when the aggregate +** query concludes. ** ** The first parameter should be a copy of the ** [sqlite3_context | SQL function context] that is the first @@ -3804,23 +4181,71 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); ** ** This routine must be called from the same thread in which ** the aggregate SQL function is running. +** +** INVARIANTS: +** +** {F16211} 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 allocation N bytes of memory, +** zero that memory, and return a pointer to the allocationed +** memory. +** +** {F16213} If a memory allocation error occurs during +** [sqlite3_aggregate_context(C,N)] then the function returns 0. +** +** {F16215} 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. +** +** {F16217} 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. */ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); /* ** CAPI3REF: User Data For Functions {F16240} ** -** {F16241} The sqlite3_user_data() interface returns a copy of +** The sqlite3_user_data() interface returns a copy of ** the pointer that was the pUserData parameter (the 5th parameter) ** of the the [sqlite3_create_function()] ** and [sqlite3_create_function16()] routines that originally ** registered the application defined function. {END} ** -** {U16243} This routine must be called from the same thread in which +** This routine must be called from the same thread in which ** the application-defined function is running. +** +** INVARIANTS: +** +** {F16243} 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. */ SQLITE_API void *sqlite3_user_data(sqlite3_context*); +/* +** CAPI3REF: Database Connection For Functions {F16250} +** +** The sqlite3_context_db_handle() interface returns a copy of +** the pointer to the [database connection] (the 1st parameter) +** of the the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +** +** INVARIANTS: +** +** {F16253} 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. +*/ +SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); + /* ** CAPI3REF: Function Auxiliary Data {F16270} ** @@ -3835,24 +4260,28 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context*); ** invocations of the same function so that the original pattern string ** does not need to be recompiled on each invocation. ** -** {F16271} ** The sqlite3_get_auxdata() interface returns a pointer to the meta-data ** associated by the sqlite3_set_auxdata() function with the Nth argument ** value to the application-defined function. -** {F16272} If no meta-data has been ever been set for the Nth +** If no meta-data has been ever been set for the Nth ** argument of the function, or if the cooresponding function parameter ** has changed since the meta-data was set, then sqlite3_get_auxdata() ** returns a NULL pointer. ** -** {F16275} The sqlite3_set_auxdata() interface saves the meta-data +** The sqlite3_set_auxdata() interface saves the meta-data ** pointed to by its 3rd parameter as the meta-data for the N-th -** argument of the application-defined function. {END} Subsequent +** argument of the application-defined function. Subsequent ** calls to sqlite3_get_auxdata() might return this data, if it has ** not been destroyed. -** {F16277} If it is not NULL, SQLite will invoke the destructor +** If it is not NULL, SQLite will invoke the destructor ** function given by the 4th parameter to sqlite3_set_auxdata() on ** the meta-data when the corresponding function parameter changes -** or when the SQL statement completes, whichever comes first. {END} +** or when the SQL statement completes, whichever comes first. +** +** SQLite is free to call the destructor and drop meta-data on +** any parameter of any function at any time. The only guarantee +** is that the destructor will be called before the metadata is +** dropped. ** ** In practice, meta-data is preserved between function calls for ** expressions that are constant at compile time. This includes literal @@ -3860,6 +4289,33 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context*); ** ** These routines must be called from the same thread in which ** the SQL function is running. +** +** INVARIANTS: +** +** {F16272} 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. +** +** {F16274} 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. +** +** {F16276} 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. +** +** {F16277} SQLite ceases to hold metadata for an SQL function parameter +** when the value of that parameter changes. +** +** {F16278} 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. +** +** {F16279} 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. */ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); @@ -3898,90 +4354,193 @@ typedef void (*sqlite3_destructor_type)(void*); ** [sqlite3_bind_blob | sqlite3_bind_* documentation] for ** additional information. ** -** {F16402} The sqlite3_result_blob() interface sets the result from +** The sqlite3_result_blob() interface sets the result from ** an application defined function to be the BLOB whose content is pointed ** to by the second parameter and which is N bytes long where N is the ** third parameter. -** {F16403} The sqlite3_result_zeroblob() inerfaces set the result of +** The sqlite3_result_zeroblob() inerfaces set the result of ** the application defined function to be a BLOB containing all zero ** bytes and N bytes in size, where N is the value of the 2nd parameter. ** -** {F16407} The sqlite3_result_double() interface sets the result from +** The sqlite3_result_double() interface sets the result from ** an application defined function to be a floating point value specified ** by its 2nd argument. ** -** {F16409} The sqlite3_result_error() and sqlite3_result_error16() functions +** The sqlite3_result_error() and sqlite3_result_error16() functions ** cause the implemented SQL function to throw an exception. -** {F16411} SQLite uses the string pointed to by the +** SQLite uses the string pointed to by the ** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() -** as the text of an error message. {F16412} SQLite interprets the error -** message string from sqlite3_result_error() as UTF8. {F16413} SQLite +** as the text of an error message. SQLite interprets the error +** message string from sqlite3_result_error() as UTF8. SQLite ** interprets the string from sqlite3_result_error16() as UTF16 in native -** byte order. {F16414} If the third parameter to sqlite3_result_error() +** byte order. If the third parameter to sqlite3_result_error() ** or sqlite3_result_error16() is negative then SQLite takes as the error ** message all text up through the first zero character. -** {F16415} If the third parameter to sqlite3_result_error() or +** If the third parameter to sqlite3_result_error() or ** sqlite3_result_error16() is non-negative then SQLite takes that many ** bytes (not characters) from the 2nd parameter as the error message. -** {F16417} The sqlite3_result_error() and sqlite3_result_error16() +** The sqlite3_result_error() and sqlite3_result_error16() ** routines make a copy private copy of the error message text before -** they return. {END} Hence, the calling function can deallocate or +** they return. Hence, the calling function can deallocate or ** modify the text after they return without harm. +** The sqlite3_result_error_code() function changes the error code +** returned by SQLite as a result of an error in a function. By default, +** the error code is SQLITE_ERROR. A subsequent call to sqlite3_result_error() +** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. ** -** {F16421} The sqlite3_result_toobig() interface causes SQLite +** The sqlite3_result_toobig() interface causes SQLite ** to throw an error indicating that a string or BLOB is to long -** to represent. {F16422} The sqlite3_result_nomem() interface +** to represent. The sqlite3_result_nomem() interface ** causes SQLite to throw an exception indicating that the a ** memory allocation failed. ** -** {F16431} The sqlite3_result_int() interface sets the return value +** The sqlite3_result_int() interface sets the return value ** of the application-defined function to be the 32-bit signed integer ** value given in the 2nd argument. -** {F16432} The sqlite3_result_int64() interface sets the return value +** The sqlite3_result_int64() interface sets the return value ** of the application-defined function to be the 64-bit signed integer ** value given in the 2nd argument. ** -** {F16437} The sqlite3_result_null() interface sets the return value +** The sqlite3_result_null() interface sets the return value ** of the application-defined function to be NULL. ** -** {F16441} The sqlite3_result_text(), sqlite3_result_text16(), +** The sqlite3_result_text(), sqlite3_result_text16(), ** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces ** set the return value of the application-defined function to be ** a text string which is represented as UTF-8, UTF-16 native byte order, ** UTF-16 little endian, or UTF-16 big endian, respectively. -** {F16442} SQLite takes the text result from the application from +** SQLite takes the text result from the application from ** the 2nd parameter of the sqlite3_result_text* interfaces. -** {F16444} If the 3rd parameter to the sqlite3_result_text* interfaces +** If the 3rd parameter to the sqlite3_result_text* interfaces ** is negative, then SQLite takes result text from the 2nd parameter ** through the first zero character. -** {F16447} If the 3rd parameter to the sqlite3_result_text* interfaces +** If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined ** function result. -** {F16451} If the 4th parameter to the sqlite3_result_text* interfaces +** If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that ** function as the destructor on the text or blob result when it has ** finished using that result. -** {F16453} If the 4th parameter to the sqlite3_result_text* interfaces +** If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is the special constant SQLITE_STATIC, then ** SQLite assumes that the text or blob result is constant space and ** does not copy the space or call a destructor when it has ** finished using that result. -** {F16454} If the 4th parameter to the sqlite3_result_text* interfaces +** If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT ** then SQLite makes a copy of the result into space obtained from ** from [sqlite3_malloc()] before it returns. ** -** {F16461} The sqlite3_result_value() interface sets the result of -** the application-defined function to be a copy the [sqlite3_value] -** object specified by the 2nd parameter. {F16463} The +** The sqlite3_result_value() interface sets the result of +** the application-defined function to be a copy the +** [unprotected sqlite3_value] object specified by the 2nd parameter. The ** sqlite3_result_value() interface makes a copy of the [sqlite3_value] ** so that [sqlite3_value] specified in the parameter may change or ** be deallocated after sqlite3_result_value() returns without harm. +** A [protected sqlite3_value] object may always be used where an +** [unprotected sqlite3_value] object is required, so either +** kind of [sqlite3_value] object can be used with this interface. ** -** {U16491} These routines are called from within the different thread +** If these routines are called from within the different thread ** than the one containing the application-defined function that recieved ** the [sqlite3_context] pointer, the results are undefined. +** +** INVARIANTS: +** +** {F16403} The default return value from any SQL function is NULL. +** +** {F16406} 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. +** +** {F16409} The [sqlite3_result_double(C,V)] interface changes the +** return value of function C to be the floating point value V. +** +** {F16412} 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 UTF8 error message copied from V up to the +** first zero byte or until N bytes are read if N is positive. +** +** {F16415} 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 UTF16 native byte order error message +** copied from V up to the first zero terminator or until N bytes +** are read if N is positive. +** +** {F16418} 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. +** +** {F16421} 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. +** +** {F16424} 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. +** +** {F16427} The [sqlite3_result_int(C,V)] interface changes the +** return value of function C to be the 32-bit integer value V. +** +** {F16430} The [sqlite3_result_int64(C,V)] interface changes the +** return value of function C to be the 64-bit integer value V. +** +** {F16433} The [sqlite3_result_null(C)] interface changes the +** return value of function C to be NULL. +** +** {F16436} The [sqlite3_result_text(C,V,N,D)] interface changes the +** return value of function C to be the UTF8 string +** V up the first zero if N is negative +** or the first N bytes of V if N is non-negative. +** +** {F16439} The [sqlite3_result_text16(C,V,N,D)] interface changes the +** return value of function C to be the UTF16 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. +** +** {F16442} The [sqlite3_result_text16be(C,V,N,D)] interface changes the +** return value of function C to be the UTF16 big-endian +** string V up to the first zero if N is +** is negative or the first N bytes or V if N is non-negative. +** +** {F16445} The [sqlite3_result_text16le(C,V,N,D)] interface changes the +** return value of function C to be the UTF16 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. +** +** {F16448} The [sqlite3_result_value(C,V)] interface changes the +** return value of function C to be [unprotected sqlite3_value] +** object V. +** +** {F16451} The [sqlite3_result_zeroblob(C,N)] interface changes the +** return value of function C to be an N-byte blob of all zeros. +** +** {F16454} The [sqlite3_result_error()] and [sqlite3_result_error16()] +** interfaces make a copy of their error message strings before +** returning. +** +** {F16457} 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. +** +** {F16460} 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. +** +** {F16463} 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. */ SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); SQLITE_API void sqlite3_result_double(sqlite3_context*, double); @@ -3989,6 +4548,7 @@ SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); +SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int); SQLITE_API void sqlite3_result_int(sqlite3_context*, int); SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); SQLITE_API void sqlite3_result_null(sqlite3_context*); @@ -4002,35 +4562,30 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); /* ** CAPI3REF: Define New Collating Sequences {F16600} ** -** {F16601} ** These functions are used to add new collation sequences to the ** [sqlite3*] handle specified as the first argument. ** -** {F16602} ** The name of the new collation sequence is specified as a UTF-8 string ** for sqlite3_create_collation() and sqlite3_create_collation_v2() -** and a UTF-16 string for sqlite3_create_collation16(). {F16603} In all cases +** and a UTF-16 string for sqlite3_create_collation16(). In all cases ** the name is passed as the second function argument. ** -** {F16604} ** The third argument may be one of the constants [SQLITE_UTF8], ** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied ** routine expects to be passed pointers to strings encoded using UTF-8, -** UTF-16 little-endian or UTF-16 big-endian respectively. {F16605} The +** UTF-16 little-endian or UTF-16 big-endian respectively. The ** third argument might also be [SQLITE_UTF16_ALIGNED] to indicate that ** the routine expects pointers to 16-bit word aligned strings ** of UTF16 in the native byte order of the host computer. ** -** {F16607} ** A pointer to the user supplied routine must be passed as the fifth -** argument. {F16609} If it is NULL, this is the same as deleting the collation +** argument. If it is NULL, this is the same as deleting the collation ** sequence (so that SQLite cannot call it anymore). -** {F16611} Each time the application +** Each time the application ** supplied function is invoked, it is passed a copy of the void* passed as ** the fourth argument to sqlite3_create_collation() or ** sqlite3_create_collation16() as its first parameter. ** -** {F16612} ** The remaining arguments to the application-supplied routine are two strings, ** each represented by a (length, data) pair and encoded in the encoding ** that was passed as the third argument when the collation sequence was @@ -4039,15 +4594,63 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); ** the first string is less than, equal to, or greater than the second ** string. i.e. (STRING1 - STRING2). ** -** {F16615} ** The sqlite3_create_collation_v2() works like sqlite3_create_collation() ** excapt that it takes an extra argument which is a destructor for -** the collation. {F16617} The destructor is called when the collation is +** the collation. The destructor is called when the collation is ** destroyed and is passed a copy of the fourth parameter void* pointer ** of the sqlite3_create_collation_v2(). -** {F16618} Collations are destroyed when +** Collations are destroyed when ** they are overridden by later calls to the collation creation functions ** or when the [sqlite3*] database handle is closed using [sqlite3_close()]. +** +** INVARIANTS: +** +** {F16603} 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 [database connection] B for +** databases having encoding E. +** +** {F16604} 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. +** +** {F16606} 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. +** +** {F16609} 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. +** +** {F16612} A collating function is dropped when it is overloaded. +** +** {F16615} A collating function is dropped when the database connection +** is closed using [sqlite3_close()]. +** +** {F16618} 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. +** +** {F16621} 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. +** +** {F16624} Following a [sqlite3_create_collation_v2(B,X,E,P,F,D)], +** SQLite uses the comparison function F for all text comparison +** operations on [database connection] B on text values that +** use the collating sequence name X. +** +** {F16627} 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. +** +** {F16630} 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. */ SQLITE_API int sqlite3_create_collation( sqlite3*, @@ -4075,31 +4678,50 @@ SQLITE_API int sqlite3_create_collation16( /* ** CAPI3REF: Collation Needed Callbacks {F16700} ** -** {F16701} ** To avoid having to register all collation sequences before a database ** can be used, a single callback function may be registered with the ** database handle to be called whenever an undefined collation sequence is ** required. ** -** {F16702} ** If the function is registered using the sqlite3_collation_needed() API, ** then it is passed the names of undefined collation sequences as strings ** encoded in UTF-8. {F16703} If sqlite3_collation_needed16() is used, the names -** are passed as UTF-16 in machine native byte order. {F16704} A call to either +** are passed as UTF-16 in machine native byte order. A call to either ** function replaces any existing callback. ** -** {F16705} When the callback is invoked, the first argument passed is a copy +** When the callback is invoked, the first argument passed is a copy ** of the second argument to sqlite3_collation_needed() or -** sqlite3_collation_needed16(). {F16706} The second argument is the database -** handle. {F16707} The third argument is one of [SQLITE_UTF8], +** sqlite3_collation_needed16(). The second argument is the database +** handle. The third argument is one of [SQLITE_UTF8], ** [SQLITE_UTF16BE], or [SQLITE_UTF16LE], indicating the most ** desirable form of the collation sequence function required. -** {F16708} The fourth parameter is the name of the -** required collation sequence. {END} +** The fourth parameter is the name of the +** required collation sequence. ** ** The callback function should register the desired collation using ** [sqlite3_create_collation()], [sqlite3_create_collation16()], or ** [sqlite3_create_collation_v2()]. +** +** INVARIANTS: +** +** {F16702} 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. +** +** {F16704} 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. +** +** {F16706} 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()]. +** +** */ SQLITE_API int sqlite3_collation_needed( sqlite3*, @@ -4140,17 +4762,28 @@ SQLITE_API int sqlite3_rekey( /* ** CAPI3REF: Suspend Execution For A Short Time {F10530} ** -** {F10531} The sqlite3_sleep() function +** The sqlite3_sleep() function ** causes the current thread to suspend execution ** for at least a number of milliseconds specified in its parameter. ** -** {F10532} If the operating system does not support sleep requests with +** If the operating system does not support sleep requests with ** millisecond time resolution, then the time will be rounded up to -** the nearest second. {F10533} The number of milliseconds of sleep actually +** the nearest second. The number of milliseconds of sleep actually ** requested from the operating system is returned. ** -** {F10534} SQLite implements this interface by calling the xSleep() -** method of the default [sqlite3_vfs] object. {END} +** SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. +** +** INVARIANTS: +** +** {F10533} 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. +** +** {F10536} 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. */ SQLITE_API int sqlite3_sleep(int); @@ -4168,7 +4801,7 @@ SQLITE_API int sqlite3_sleep(int); ** as part of process initialization and before any SQLite interface ** routines have been call and remain unchanged thereafter. */ -SQLITE_EXTERN char *sqlite3_temp_directory; +SQLITE_API char *sqlite3_temp_directory; /* ** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode {F12930} @@ -4188,8 +4821,8 @@ SQLITE_EXTERN char *sqlite3_temp_directory; ** ** INVARIANTS: ** -** {F12931} The [sqlite3_get_autocommit()] interface returns non-zero or -** zero if the given database connection is or is not in autocommit +** {F12931} The [sqlite3_get_autocommit(D)] interface returns non-zero or +** zero if the [database connection] D is or is not in autocommit ** mode, respectively. ** ** {F12932} Autocommit mode is on by default. @@ -4211,13 +4844,19 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3*); /* ** CAPI3REF: Find The Database Handle Of A Prepared Statement {F13120} ** -** {F13121} The sqlite3_db_handle interface +** The sqlite3_db_handle interface ** returns the [sqlite3*] database handle to which a ** [prepared statement] belongs. -** {F13122} the database handle returned by sqlite3_db_handle +** The database handle returned by sqlite3_db_handle ** is the same database handle that was ** the first argument to the [sqlite3_prepare_v2()] or its variants ** that was used to create the statement in the first place. +** +** INVARIANTS: +** +** {F13123} The [sqlite3_db_handle(S)] interface returns a pointer +** to the [database connection] associated with +** [prepared statement] S. */ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); @@ -4225,33 +4864,70 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); /* ** CAPI3REF: Commit And Rollback Notification Callbacks {F12950} ** -** {F12951} The sqlite3_commit_hook() interface registers a callback +** The sqlite3_commit_hook() interface registers a callback ** function to be invoked whenever a transaction is committed. -** {F12952} Any callback set by a previous call to sqlite3_commit_hook() +** Any callback set by a previous call to sqlite3_commit_hook() ** for the same database connection is overridden. -** {F12953} The sqlite3_rollback_hook() interface registers a callback +** The sqlite3_rollback_hook() interface registers a callback ** function to be invoked whenever a transaction is committed. -** {F12954} Any callback set by a previous call to sqlite3_commit_hook() +** Any callback set by a previous call to sqlite3_commit_hook() ** for the same database connection is overridden. -** {F12956} The pArg argument is passed through -** to the callback. {F12957} If the callback on a commit hook function +** The pArg argument is passed through +** to the callback. If the callback on a commit hook function ** returns non-zero, then the commit is converted into a rollback. ** -** {F12958} If another function was previously registered, its +** If another function was previously registered, its ** pArg value is returned. Otherwise NULL is returned. ** -** {F12959} Registering a NULL function disables the callback. +** Registering a NULL function disables the callback. ** -** {F12961} For the purposes of this API, a transaction is said to have been +** For the purposes of this API, a transaction is said to have been ** rolled back if an explicit "ROLLBACK" statement is executed, or ** an error or constraint causes an implicit rollback to occur. -** {F12962} The rollback callback is not invoked if a transaction is +** The rollback callback is not invoked if a transaction is ** automatically rolled back because the database connection is closed. -** {F12964} The rollback callback is not invoked if a transaction is +** The rollback callback is not invoked if a transaction is ** rolled back because a commit callback returned non-zero. -** Check on this {END} +** Check on this ** ** These are experimental interfaces and are subject to change. +** +** INVARIANTS: +** +** {F12951} The [sqlite3_commit_hook(D,F,P)] interface registers the +** callback function F to be invoked with argument P whenever +** a transaction commits on [database connection] D. +** +** {F12952} 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. +** +** {F12953} Each call to [sqlite3_commit_hook()] overwrites the callback +** registered by prior calls. +** +** {F12954} If the F argument to [sqlite3_commit_hook(D,F,P)] is NULL +** then the commit hook callback is cancelled and no callback +** is invoked when a transaction commits. +** +** {F12955} If the commit callback returns non-zero then the commit is +** converted into a rollback. +** +** {F12961} 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 [database connection] D. +** +** {F12962} 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. +** +** {F12963} Each call to [sqlite3_rollback_hook()] overwrites the callback +** registered by prior calls. +** +** {F12964} If the F argument to [sqlite3_rollback_hook(D,F,P)] is NULL +** then the rollback hook callback is cancelled and no callback +** is invoked when a transaction rolls back. */ SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); @@ -4259,32 +4935,63 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); /* ** CAPI3REF: Data Change Notification Callbacks {F12970} ** -** {F12971} The sqlite3_update_hook() interface +** The sqlite3_update_hook() interface ** registers a callback function with the database connection identified by the ** first argument to be invoked whenever a row is updated, inserted or deleted. -** {F12972} Any callback set by a previous call to this function for the same +** Any callback set by a previous call to this function for the same ** database connection is overridden. ** -** {F12974} The second argument is a pointer to the function to invoke when a +** The second argument is a pointer to the function to invoke when a ** row is updated, inserted or deleted. -** {F12976} The first argument to the callback is +** The first argument to the callback is ** a copy of the third argument to sqlite3_update_hook(). -** {F12977} The second callback +** The second callback ** argument is one of [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], ** depending on the operation that caused the callback to be invoked. -** {F12978} The third and +** The third and ** fourth arguments to the callback contain pointers to the database and ** table name containing the affected row. -** {F12979} The final callback parameter is +** The final callback parameter is ** the rowid of the row. -** {F12981} In the case of an update, this is the rowid after +** In the case of an update, this is the rowid after ** the update takes place. ** -** {F12983} The update hook is not invoked when internal system tables are +** The update hook is not invoked when internal system tables are ** modified (i.e. sqlite_master and sqlite_sequence). ** -** {F12984} If another function was previously registered, its pArg value -** is returned. {F12985} Otherwise NULL is returned. +** If another function was previously registered, its pArg value +** is returned. Otherwise NULL is returned. +** +** INVARIANTS: +** +** {F12971} The [sqlite3_update_hook(D,F,P)] interface causes callback +** function F to be invoked with first parameter P whenever +** a table row is modified, inserted, or deleted on +** [database connection] D. +** +** {F12973} 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. +** +** {F12975} If the update hook callback F in [sqlite3_update_hook(D,F,P)] +** is NULL then the no update callbacks are made. +** +** {F12977} Each call to [sqlite3_update_hook(D,F,P)] overrides prior calls +** to the same interface on the same [database connection] D. +** +** {F12979} The update hook callback is not invoked when internal system +** tables such as sqlite_master and sqlite_sequence are modified. +** +** {F12981} 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. +** +** {F12983} 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. + +** {F12985} The final callback parameter is the rowid of the row after +** the change occurs. */ SQLITE_API void *sqlite3_update_hook( sqlite3*, @@ -4295,83 +5002,131 @@ SQLITE_API void *sqlite3_update_hook( /* ** CAPI3REF: Enable Or Disable Shared Pager Cache {F10330} ** -** {F10331} ** This routine enables or disables the sharing of the database cache ** and schema data structures between connections to the same database. -** {F10332} ** Sharing is enabled if the argument is true and disabled if the argument ** is false. ** -** {F10333} Cache sharing is enabled and disabled +** Cache sharing is enabled and disabled ** for an entire process. {END} 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. ** -** {F10334} ** The cache sharing mode set by this interface effects all subsequent ** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. -** {F10335} Existing database connections continue use the sharing mode -** that was in effect at the time they were opened. {END} +** Existing database connections continue use the sharing mode +** that was in effect at the time they were opened. ** -** Virtual tables cannot be used with a shared cache. {F10336} When shared +** Virtual tables cannot be used with a shared cache. When shared ** cache is enabled, the [sqlite3_create_module()] API used to register -** virtual tables will always return an error. {END} +** virtual tables will always return an error. ** -** {F10337} This routine returns [SQLITE_OK] if shared cache was -** enabled or disabled successfully. {F10338} An [error code] -** is returned otherwise. {END} +** This routine returns [SQLITE_OK] if shared cache was +** enabled or disabled successfully. An [error code] +** is returned otherwise. ** -** {F10339} Shared cache is disabled by default. {END} But this might change in +** 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: +** +** {F10331} 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. +** +** {F10336} When shared cache is enabled, the [sqlite3_create_module()] +** interface will always return an error. +** +** {F10337} The [sqlite3_enable_shared_cache(B)] interface returns +** [SQLITE_OK] if shared cache was enabled or disabled successfully. +** +** {F10339} Shared cache is disabled by default. */ SQLITE_API int sqlite3_enable_shared_cache(int); /* ** CAPI3REF: Attempt To Free Heap Memory {F17340} ** -** {F17341} The sqlite3_release_memory() interface attempts to +** The sqlite3_release_memory() interface attempts to ** free N bytes of heap memory by deallocating non-essential memory ** allocations held by the database labrary. {END} Memory used ** to cache database pages to improve performance is an example of -** non-essential memory. {F16342} sqlite3_release_memory() returns +** non-essential memory. Sqlite3_release_memory() returns ** the number of bytes actually freed, which might be more or less ** than the amount requested. +** +** INVARIANTS: +** +** {F17341} The [sqlite3_release_memory(N)] interface attempts to +** free N bytes of heap memory by deallocating non-essential +** memory allocations held by the database labrary. +** +** {F16342} The [sqlite3_release_memory(N)] returns the number +** of bytes actually freed, which might be more or less +** than the amount requested. */ SQLITE_API int sqlite3_release_memory(int); /* ** CAPI3REF: Impose A Limit On Heap Size {F17350} ** -** {F16351} The sqlite3_soft_heap_limit() interface +** The sqlite3_soft_heap_limit() interface ** places a "soft" limit on the amount of heap memory that may be allocated -** by SQLite. {F16352} If an internal allocation is requested +** by SQLite. If an internal allocation is requested ** that would exceed the soft heap limit, [sqlite3_release_memory()] is ** invoked one or more times to free up some space before the allocation -** is made. {END} +** is made. ** -** {F16353} The limit is called "soft", because if +** The limit is called "soft", because if ** [sqlite3_release_memory()] cannot ** free sufficient memory to prevent the limit from being exceeded, ** the memory is allocated anyway and the current operation proceeds. ** -** {F16354} ** A negative or zero value for N means that there is no soft heap limit and ** [sqlite3_release_memory()] will only be called when memory is exhausted. -** {F16355} The default value for the soft heap limit is zero. +** The default value for the soft heap limit is zero. ** ** SQLite makes a best effort to honor the soft heap limit. -** {F16356} But if the soft heap limit cannot honored, execution will -** continue without error or notification. {END} This is why the limit is +** But if the soft heap limit cannot honored, execution will +** continue without error or notification. This is why the limit is ** called a "soft" limit. It is advisory only. ** ** Prior to SQLite version 3.5.0, this routine only constrained the memory ** allocated by a single thread - the same thread in which this routine ** runs. Beginning with SQLite version 3.5.0, the soft heap limit is -** applied to all threads. {F16357} The value specified for the soft heap limit -** is an upper bound on the total memory allocation for all threads. {END} In +** applied to all threads. The value specified for the soft heap limit +** is an upper bound on the total memory allocation for all threads. In ** version 3.5.0 there is no mechanism for limiting the heap usage for ** individual threads. +** +** INVARIANTS: +** +** {F16351} 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. +** +** {F16352} 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. +** +** {F16353} 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. +** +** {F16354} 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. +** +** {F16355} The default value for the soft heap limit is zero. +** +** {F16358} Each call to [sqlite3_soft_heap_limit(N)] overrides the +** values set by all prior calls. */ SQLITE_API void sqlite3_soft_heap_limit(int); @@ -4561,6 +5316,9 @@ typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; typedef struct sqlite3_module sqlite3_module; /* +** CAPI3REF: Virtual Table Object {F18000} +** KEYWORDS: sqlite3_module +** ** A module is a class of virtual tables. Each module is defined ** by an instance of the following structure. This structure consists ** mostly of methods for the module. @@ -4597,6 +5355,9 @@ struct sqlite3_module { }; /* +** CAPI3REF: Virtual Table Indexing Information {F18100} +** KEYWORDS: sqlite3_index_info +** ** The sqlite3_index_info structure and its substructures is used to ** pass information into and receive the reply from the xBestIndex ** method of an sqlite3_module. The fields under **Inputs** are the @@ -4677,6 +5438,8 @@ struct sqlite3_index_info { #define SQLITE_INDEX_CONSTRAINT_MATCH 64 /* +** CAPI3REF: Register A Virtual Table Implementation {F18200} +** ** This routine is used to register a new module name with an SQLite ** connection. Module names must be registered before creating new ** virtual tables on the module, or before using preexisting virtual @@ -4690,6 +5453,8 @@ SQLITE_API int sqlite3_create_module( ); /* +** CAPI3REF: Register A Virtual Table Implementation {F18210} +** ** This routine is identical to the sqlite3_create_module() method above, ** except that it allows a destructor function to be specified. It is ** even more experimental than the rest of the virtual tables API. @@ -4703,6 +5468,9 @@ SQLITE_API int sqlite3_create_module_v2( ); /* +** CAPI3REF: Virtual Table Instance Object {F18010} +** KEYWORDS: sqlite3_vtab +** ** Every module implementation uses a subclass of the following structure ** to describe a particular instance of the module. Each subclass will ** be tailored to the specific needs of the module implementation. The @@ -4726,7 +5494,11 @@ struct sqlite3_vtab { /* Virtual table implementations will typically add additional fields */ }; -/* Every module implementation uses a subclass of the following structure +/* +** CAPI3REF: Virtual Table Cursor Object {F18020} +** KEYWORDS: sqlite3_vtab_cursor +** +** Every module implementation uses a subclass of the following structure ** to describe cursors that point into the virtual table and are used ** to loop through the virtual table. Cursors are created using the ** xOpen method of the module. Each module implementation will define @@ -4741,6 +5513,8 @@ struct sqlite3_vtab_cursor { }; /* +** CAPI3REF: Declare The Schema Of A Virtual Table {F18280} +** ** The xCreate and xConnect methods of a module use the following API ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. @@ -4748,6 +5522,8 @@ struct sqlite3_vtab_cursor { SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); /* +** CAPI3REF: Overload A Function For A Virtual Table {F18300} +** ** Virtual tables can provide alternative implementations of functions ** using the xFindFunction method. But global versions of those functions ** must exist in order to be overloaded. @@ -4780,8 +5556,9 @@ SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nA /* ** CAPI3REF: A Handle To An Open BLOB {F17800} ** -** An instance of the following opaque structure is used to -** represent an blob-handle. A blob-handle is created by +** An instance of this object represents an open BLOB on which +** incremental I/O can be preformed. +** Objects of this type are created by ** [sqlite3_blob_open()] and destroyed by [sqlite3_blob_close()]. ** The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces ** can be used to read or write small subsections of the blob. @@ -4793,26 +5570,52 @@ typedef struct sqlite3_blob sqlite3_blob; /* ** CAPI3REF: Open A BLOB For Incremental I/O {F17810} ** -** {F17811} This interfaces opens a handle to the blob located -** in row iRow,, column zColumn, table zTable in database zDb; +** This interfaces opens a handle to the blob located +** in row iRow, column zColumn, table zTable in database zDb; ** in other words, the same blob that would be selected by: ** **
     **     SELECT zColumn FROM zDb.zTable WHERE rowid = iRow;
     ** 
    {END} ** -** {F17812} If the flags parameter is non-zero, the blob is opened for +** If the flags parameter is non-zero, the blob is opened for ** read and write access. If it is zero, the blob is opened for read -** access. {END} +** access. ** -** {F17813} On success, [SQLITE_OK] is returned and the new +** Note that the database name is not the filename that contains +** the database but rather the symbolic name of the database that +** is assigned when the database is connected using [ATTACH]. +** For the main database file, the database name is "main". For +** TEMP tables, the database name is "temp". +** +** On success, [SQLITE_OK] is returned and the new ** [sqlite3_blob | blob handle] is written to *ppBlob. -** {F17814} Otherwise an error code is returned and +** Otherwise an error code is returned and ** any value written to *ppBlob should not be used by the caller. -** {F17815} This function sets the database-handle error code and message +** This function sets the database-handle error code and message ** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()]. -** We should go through and mark all interfaces that behave this -** way with a similar statement +** +** INVARIANTS: +** +** {F17813} A successful invocation of the [sqlite3_blob_open(D,B,T,C,R,F,P)] +** interface opens an [sqlite3_blob] object P on the blob +** in column C of table T in database B on [database connection] D. +** +** {F17814} A successful invocation of [sqlite3_blob_open(D,...)] starts +** a new transaction on [database connection] D if that connection +** is not already in a transaction. +** +** {F17816} The [sqlite3_blob_open(D,B,T,C,R,F,P)] interface opens the blob +** for read and write access if and only if the F parameter +** is non-zero. +** +** {F17819} The [sqlite3_blob_open()] interface returns [SQLITE_OK] on +** success and an appropriate [error code] on failure. +** +** {F17821} If an error occurs during evaluation of [sqlite3_blob_open(D,...)] +** then subsequent calls to [sqlite3_errcode(D)], +** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] will return +** information approprate for that error. */ SQLITE_API int sqlite3_blob_open( sqlite3*, @@ -4829,26 +5632,50 @@ SQLITE_API int sqlite3_blob_open( ** ** Close an open [sqlite3_blob | blob handle]. ** -** {F17831} Closing a BLOB shall cause the current transaction to commit +** Closing a BLOB shall cause the current transaction to commit ** if there are no other BLOBs, no pending prepared statements, and the ** database connection is in autocommit mode. -** {F17832} If any writes were made to the BLOB, they might be held in cache +** If any writes were made to the BLOB, they might be held in cache ** until the close operation if they will fit. {END} ** Closing the BLOB often forces the changes ** out to disk and so if any I/O errors occur, they will likely occur ** at the time when the BLOB is closed. {F17833} Any errors that occur during ** closing are reported as a non-zero return value. ** -** {F17839} The BLOB is closed unconditionally. Even if this routine returns +** The BLOB is closed unconditionally. Even if this routine returns ** an error code, the BLOB is still closed. +** +** INVARIANTS: +** +** {F17833} The [sqlite3_blob_close(P)] interface closes an +** [sqlite3_blob] object P previously opened using +** [sqlite3_blob_open()]. +** +** {F17836} 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 +** [sqlite3_get_autocommit | autocommit mode]. +** +** {F17839} The [sqlite3_blob_close(P)] interfaces closes the +** [sqlite3_blob] object P unconditionally, even if +** [sqlite3_blob_close(P)] returns something other than [SQLITE_OK]. +** */ SQLITE_API int sqlite3_blob_close(sqlite3_blob *); /* -** CAPI3REF: Return The Size Of An Open BLOB {F17805} +** CAPI3REF: Return The Size Of An Open BLOB {F17840} ** -** {F16806} Return the size in bytes of the blob accessible via the open -** [sqlite3_blob | blob-handle] passed as an argument. +** Return the size in bytes of the blob accessible via the open +** [sqlite3_blob] object in its only argument. +** +** INVARIANTS: +** +** {F17843} The [sqlite3_blob_bytes(P)] interface returns the size +** in bytes of the BLOB that the [sqlite3_blob] object P +** refers to. */ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); @@ -4857,38 +5684,96 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); ** ** This function is used to read data from an open ** [sqlite3_blob | blob-handle] into a caller supplied buffer. -** {F17851} n bytes of data are copied into buffer -** z from the open blob, starting at offset iOffset. +** N bytes of data are copied into buffer +** Z from the open blob, starting at offset iOffset. ** -** {F17852} If offset iOffset is less than n bytes from the end of the blob, -** [SQLITE_ERROR] is returned and no data is read. {F17853} If n is +** If offset iOffset is less than N bytes from the end of the blob, +** [SQLITE_ERROR] is returned and no data is read. If N or iOffset is ** less than zero [SQLITE_ERROR] is returned and no data is read. ** -** {F17854} On success, SQLITE_OK is returned. Otherwise, an +** On success, SQLITE_OK is returned. Otherwise, an ** [error code] or an [extended error code] is returned. +** +** INVARIANTS: +** +** {F17853} The [sqlite3_blob_read(P,Z,N,X)] interface reads N bytes +** beginning at offset X from +** the blob that [sqlite3_blob] object P refers to +** and writes those N bytes into buffer Z. +** +** {F17856} In [sqlite3_blob_read(P,Z,N,X)] if the size of the blob +** is less than N+X bytes, then the function returns [SQLITE_ERROR] +** and nothing is read from the blob. +** +** {F17859} In [sqlite3_blob_read(P,Z,N,X)] if X or N is less than zero +** then the function returns [SQLITE_ERROR] +** and nothing is read from the blob. +** +** {F17862} The [sqlite3_blob_read(P,Z,N,X)] interface returns [SQLITE_OK] +** if N bytes where successfully read into buffer Z. +** +** {F17865} If the requested read could not be completed, +** the [sqlite3_blob_read(P,Z,N,X)] interface returns an +** appropriate [error code] or [extended error code]. +** +** {F17868} If an error occurs during evaluation of [sqlite3_blob_read(D,...)] +** then subsequent calls to [sqlite3_errcode(D)], +** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] will return +** information approprate for that error. */ -SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *z, int n, int iOffset); +SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); /* ** CAPI3REF: Write Data Into A BLOB Incrementally {F17870} ** ** This function is used to write data into an open ** [sqlite3_blob | blob-handle] from a user supplied buffer. -** {F17871} n bytes of data are copied from the buffer +** n bytes of data are copied from the buffer ** pointed to by z into the open blob, starting at offset iOffset. ** -** {F17872} If the [sqlite3_blob | blob-handle] passed as the first argument +** If the [sqlite3_blob | blob-handle] passed as the first argument ** was not opened for writing (the flags parameter to [sqlite3_blob_open()] *** was zero), this function returns [SQLITE_READONLY]. ** -** {F17873} This function may only modify the contents of the blob; it is +** This function may only modify the contents of the blob; it is ** not possible to increase the size of a blob using this API. -** {F17874} If offset iOffset is less than n bytes from the end of the blob, -** [SQLITE_ERROR] is returned and no data is written. {F17875} If n is +** If offset iOffset is less than n bytes from the end of the blob, +** [SQLITE_ERROR] is returned and no data is written. If n is ** less than zero [SQLITE_ERROR] is returned and no data is written. ** -** {F17876} On success, SQLITE_OK is returned. Otherwise, an +** On success, SQLITE_OK is returned. Otherwise, an ** [error code] or an [extended error code] is returned. +** +** INVARIANTS: +** +** {F17873} The [sqlite3_blob_write(P,Z,N,X)] interface writes N bytes +** from buffer Z into +** the blob that [sqlite3_blob] object P refers to +** beginning at an offset of X into the blob. +** +** {F17875} The [sqlite3_blob_write(P,Z,N,X)] interface returns +** [SQLITE_READONLY] if the [sqlite3_blob] object P was +** [sqlite3_blob_open | opened] for reading only. +** +** {F17876} In [sqlite3_blob_write(P,Z,N,X)] if the size of the blob +** is less than N+X bytes, then the function returns [SQLITE_ERROR] +** and nothing is written into the blob. +** +** {F17879} In [sqlite3_blob_write(P,Z,N,X)] if X or N is less than zero +** then the function returns [SQLITE_ERROR] +** and nothing is written into the blob. +** +** {F17882} The [sqlite3_blob_write(P,Z,N,X)] interface returns [SQLITE_OK] +** if N bytes where successfully written into blob. +** +** {F17885} If the requested write could not be completed, +** the [sqlite3_blob_write(P,Z,N,X)] interface returns an +** appropriate [error code] or [extended error code]. +** +** {F17888} If an error occurs during evaluation of [sqlite3_blob_write(D,...)] +** then subsequent calls to [sqlite3_errcode(D)], +** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] will return +** information approprate for that error. */ SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); @@ -4897,30 +5782,57 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOff ** ** A virtual filesystem (VFS) is an [sqlite3_vfs] object ** that SQLite uses to interact -** with the underlying operating system. Most builds come with a +** with the underlying operating system. Most SQLite builds come with a ** single default VFS that is appropriate for the host computer. ** New VFSes can be registered and existing VFSes can be unregistered. ** The following interfaces are provided. ** -** {F11201} The sqlite3_vfs_find() interface returns a pointer to -** a VFS given its name. {F11202} Names are case sensitive. -** {F11203} Names are zero-terminated UTF-8 strings. -** {F11204} If there is no match, a NULL -** pointer is returned. {F11205} If zVfsName is NULL then the default -** VFS is returned. {END} +** The sqlite3_vfs_find() interface returns a pointer to +** a VFS given its name. Names are case sensitive. +** Names are zero-terminated UTF-8 strings. +** If there is no match, a NULL +** pointer is returned. If zVfsName is NULL then the default +** VFS is returned. ** -** {F11210} New VFSes are registered with sqlite3_vfs_register(). -** {F11211} Each new VFS becomes the default VFS if the makeDflt flag is set. -** {F11212} The same VFS can be registered multiple times without injury. -** {F11213} To make an existing VFS into the default VFS, register it again -** with the makeDflt flag set. {U11214} If two different VFSes with the -** same name are registered, the behavior is undefined. {U11215} If a +** New VFSes are registered with sqlite3_vfs_register(). +** Each new VFS becomes the default VFS if the makeDflt flag is set. +** The same VFS can be registered multiple times without injury. +** To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a ** VFS is registered with a name that is NULL or an empty string, ** then the behavior is undefined. ** -** {F11220} Unregister a VFS with the sqlite3_vfs_unregister() interface. -** {F11221} If the default VFS is unregistered, another VFS is chosen as +** 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: +** +** {F11203} 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. +** +** {F11206} 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. +** +** {F11209} 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. +** +** {F11212} Using the [sqlite3_vfs_register(P,F)] interface to register +** the same [sqlite3_vfs] object multiple times is a harmless no-op. +** +** {F11215} The [sqlite3_vfs_register(P,F)] interface makes the +** the [sqlite3_vfs] object P the default [sqlite3_vfs] object +** if F is non-zero. +** +** {F11218} 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()]. */ SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); @@ -4975,6 +5887,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); **
  • SQLITE_MUTEX_STATIC_MEM2 **
  • SQLITE_MUTEX_STATIC_PRNG **
  • SQLITE_MUTEX_STATIC_LRU +**
  • SQLITE_MUTEX_STATIC_LRU2 ** {END} ** ** {F17015} The first two constants cause sqlite3_mutex_alloc() to create @@ -5087,6 +6000,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); #define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */ #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 */ /* ** CAPI3REF: Low-Level Control Of Database Files {F11300} @@ -5148,9 +6062,10 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_FAULT_FAILURES 2 #define SQLITE_TESTCTRL_FAULT_BENIGN_FAILURES 3 #define SQLITE_TESTCTRL_FAULT_PENDING 4 - - - +#define SQLITE_TESTCTRL_PRNG_SAVE 5 +#define SQLITE_TESTCTRL_PRNG_RESTORE 6 +#define SQLITE_TESTCTRL_PRNG_RESET 7 +#define SQLITE_TESTCTRL_BITVEC_TEST 8 /* @@ -5536,19 +6451,39 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); ** cc '-DUINTPTR_TYPE=long long int' ... */ #ifndef UINT32_TYPE -# define UINT32_TYPE unsigned int +# ifdef HAVE_UINT32_T +# define UINT32_TYPE uint32_t +# else +# define UINT32_TYPE unsigned int +# endif #endif #ifndef UINT16_TYPE -# define UINT16_TYPE unsigned short int +# ifdef HAVE_UINT16_T +# define UINT16_TYPE uint16_t +# else +# define UINT16_TYPE unsigned short int +# endif #endif #ifndef INT16_TYPE -# define INT16_TYPE short int +# ifdef HAVE_INT16_T +# define INT16_TYPE int16_t +# else +# define INT16_TYPE short int +# endif #endif #ifndef UINT8_TYPE -# define UINT8_TYPE unsigned char +# ifdef HAVE_UINT8_T +# define UINT8_TYPE uint8_t +# else +# define UINT8_TYPE unsigned char +# endif #endif #ifndef INT8_TYPE -# define INT8_TYPE signed char +# ifdef HAVE_INT8_T +# define INT8_TYPE int8_t +# else +# define INT8_TYPE signed char +# endif #endif #ifndef LONGDOUBLE_TYPE # define LONGDOUBLE_TYPE long double @@ -5566,7 +6501,7 @@ typedef UINT8_TYPE i8; /* 1-byte signed integer */ ** evaluated at runtime. */ #ifdef SQLITE_AMALGAMATION -SQLITE_PRIVATE const int sqlite3One; +SQLITE_PRIVATE const int sqlite3one; #else SQLITE_PRIVATE const int sqlite3one; #endif @@ -5625,6 +6560,7 @@ struct BusyHandler { */ typedef struct AggInfo AggInfo; typedef struct AuthContext AuthContext; +typedef struct Bitvec Bitvec; typedef struct CollSeq CollSeq; typedef struct Column Column; typedef struct Db Db; @@ -5674,7 +6610,7 @@ typedef struct WhereLevel WhereLevel; ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** -** @(#) $Id: btree.h,v 1.94 2007/12/07 18:55:28 drh Exp $ +** @(#) $Id: btree.h,v 1.97 2008/03/25 17:23:33 drh Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ @@ -5788,17 +6724,26 @@ SQLITE_PRIVATE int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue); SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int); +struct UnpackedRecord; /* Forward declaration. Definition in vdbeaux.c. */ + SQLITE_PRIVATE int sqlite3BtreeCursor( Btree*, /* BTree containing table to open */ int iTable, /* Index of root page */ int wrFlag, /* 1 for writing. 0 for read-only */ - int(*)(void*,int,const void*,int,const void*), /* Key comparison function */ - void*, /* First argument to compare function */ - BtCursor **ppCursor /* Returned cursor */ + struct KeyInfo*, /* First argument to compare function */ + BtCursor *pCursor /* Space to write cursor structure */ ); +SQLITE_PRIVATE int sqlite3BtreeCursorSize(); SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*); -SQLITE_PRIVATE int sqlite3BtreeMoveto(BtCursor*,const void *pKey,i64 nKey,int bias,int *pRes); +SQLITE_PRIVATE int sqlite3BtreeMoveto( + BtCursor*, + const void *pKey, + struct UnpackedRecord *pUnKey, + i64 nKey, + int bias, + int *pRes +); SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*); SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, const void *pData, int nData, @@ -5884,7 +6829,7 @@ SQLITE_PRIVATE void sqlite3BtreeMutexArrayInsert(BtreeMutexArray*, Btree*); ** 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.125 2008/01/17 17:27:31 drh Exp $ +** $Id: vdbe.h,v 1.130 2008/04/11 14:56:53 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -5902,6 +6847,7 @@ typedef struct Vdbe Vdbe; */ typedef struct VdbeFunc VdbeFunc; typedef struct Mem Mem; +typedef struct UnpackedRecord UnpackedRecord; /* ** A single instruction of the virtual machine has an opcode @@ -5911,7 +6857,7 @@ typedef struct Mem Mem; struct VdbeOp { u8 opcode; /* What operation to perform */ signed char p4type; /* One of the P4_xxx constants for p4 */ - u8 flags; /* Flags for internal use */ + u8 opflags; /* Not currently used */ u8 p5; /* Fifth parameter is an unsigned character */ int p1; /* First operand */ int p2; /* Second parameter (often the jump destination) */ @@ -5987,7 +6933,15 @@ typedef struct VdbeOpList VdbeOpList; #define COLNAME_DATABASE 2 #define COLNAME_TABLE 3 #define COLNAME_COLUMN 4 -#define COLNAME_N 5 /* Number of COLNAME_xxx symbols */ +#ifdef SQLITE_ENABLE_COLUMN_METADATA +# define COLNAME_N 5 /* Number of COLNAME_xxx symbols */ +#else +# ifdef SQLITE_OMIT_DECLTYPE +# define COLNAME_N 1 /* Store only the name */ +# else +# define COLNAME_N 2 /* Store the name and decltype */ +# endif +#endif /* ** The following macro converts a relative address in the p2 field @@ -6162,14 +7116,14 @@ typedef struct VdbeOpList VdbeOpList; #define OPFLG_IN3 0x0010 /* in3: P3 is an input */ #define OPFLG_OUT3 0x0020 /* out3: P3 is an output */ #define OPFLG_INITIALIZER {\ -/* 0 */ 0x00, 0x01, 0x00, 0x10, 0x02, 0x11, 0x02, 0x00,\ +/* 0 */ 0x00, 0x01, 0x00, 0x10, 0x02, 0x11, 0x00, 0x00,\ /* 8 */ 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 16 */ 0x04, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,\ /* 24 */ 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00,\ /* 32 */ 0x02, 0x11, 0x11, 0x02, 0x05, 0x00, 0x02, 0x11,\ -/* 40 */ 0x04, 0x00, 0x02, 0x0c, 0x11, 0x01, 0x02, 0x01,\ +/* 40 */ 0x04, 0x00, 0x00, 0x0c, 0x11, 0x01, 0x02, 0x01,\ /* 48 */ 0x00, 0x02, 0x01, 0x01, 0x02, 0x00, 0x04, 0x00,\ -/* 56 */ 0x00, 0x00, 0x11, 0x08, 0x2c, 0x2c, 0x00, 0x11,\ +/* 56 */ 0x00, 0x00, 0x11, 0x00, 0x2c, 0x2c, 0x00, 0x11,\ /* 64 */ 0x05, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\ /* 72 */ 0x15, 0x00, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,\ /* 80 */ 0x2c, 0x2c, 0x2c, 0x2c, 0x00, 0x00, 0x00, 0x04,\ @@ -6214,7 +7168,7 @@ SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*); #endif SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); -SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*, int); SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int); SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); @@ -6222,6 +7176,12 @@ SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n); SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeReleaseMemory(int); +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,void*,int); +SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*); +SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); + + #ifndef NDEBUG SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...); # define VdbeComment(X) sqlite3VdbeComment X @@ -6250,7 +7210,7 @@ SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...); ** 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.68 2007/11/28 16:19:56 drh Exp $ +** @(#) $Id: pager.h,v 1.70 2008/03/20 11:04:21 danielk1977 Exp $ */ #ifndef _PAGER_H_ @@ -6310,7 +7270,7 @@ SQLITE_PRIVATE int sqlite3PagerOverwrite(Pager *pPager, Pgno pgno, void*); SQLITE_PRIVATE int sqlite3PagerPagecount(Pager*); SQLITE_PRIVATE int sqlite3PagerTruncate(Pager*,Pgno); SQLITE_PRIVATE int sqlite3PagerBegin(DbPage*, int exFlag); -SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, Pgno); +SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, Pgno, int); SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*); SQLITE_PRIVATE int sqlite3PagerRollback(Pager*); SQLITE_PRIVATE int sqlite3PagerIsreadonly(Pager*); @@ -6332,6 +7292,7 @@ SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *); SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *); SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int); SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); +SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager); #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO) SQLITE_PRIVATE int sqlite3PagerReleaseMemory(int); @@ -6349,7 +7310,6 @@ SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage*); #ifdef SQLITE_TEST SQLITE_PRIVATE int *sqlite3PagerStats(Pager*); SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*); - int pager3_refinfo_enable; #endif #ifdef SQLITE_TEST @@ -6453,6 +7413,7 @@ void enable_simulated_io_errors(void); # define INCL_DOSMODULEMGR # define INCL_DOSSEMAPHORES # include +# include # define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP) #else # define SQLITE_TEMPNAME_SIZE 200 @@ -6635,11 +7596,7 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *); ** register one or more VFS structures using sqlite3_vfs_register() ** before attempting to use SQLite. */ -#if OS_UNIX || OS_WIN || OS_OS2 SQLITE_PRIVATE sqlite3_vfs *sqlite3OsDefaultVfs(void); -#else -# define sqlite3OsDefaultVfs(X) 0 -#endif #endif /* _SQLITE_OS_H_ */ @@ -6733,6 +7690,7 @@ SQLITE_PRIVATE sqlite3_vfs *sqlite3OsDefaultVfs(void); /************** End of mutex.h ***********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ + /* ** Each database file to be accessed by the system is an instance ** of the following structure. There are normally two of these structures @@ -6800,6 +7758,11 @@ struct Schema { #define DB_UnresetViews 0x0002 /* Some views have defined column names */ #define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */ +/* +** The number of different kinds of things that can be limited +** using the sqlite3_limit() interface. +*/ +#define SQLITE_N_LIMIT (SQLITE_LIMIT_VARIABLE_NUMBER+1) /* ** Each database is an instance of the following structure. @@ -6839,6 +7802,7 @@ struct sqlite3 { u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ + int nextPagesize; /* Pagesize after VACUUM if >0 */ int nTable; /* Number of tables in the database */ CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ i64 lastRowid; /* ROWID of most recent insert (see above) */ @@ -6847,6 +7811,7 @@ struct sqlite3 { int nChange; /* Value returned by sqlite3_changes() */ int nTotalChange; /* Value returned by sqlite3_total_changes() */ sqlite3_mutex *mutex; /* Connection mutex */ + int aLimit[SQLITE_N_LIMIT]; /* Limits */ struct sqlite3InitInfo { /* Information used during initialization */ int iDb; /* When back is being initialized */ int newTnum; /* Rootpage of table being initialized */ @@ -7436,15 +8401,17 @@ struct Expr { /* ** The following are the meanings of bits in the Expr.flags field. */ -#define EP_FromJoin 0x01 /* Originated in ON or USING clause of a join */ -#define EP_Agg 0x02 /* Contains one or more aggregate functions */ -#define EP_Resolved 0x04 /* IDs have been resolved to COLUMNs */ -#define EP_Error 0x08 /* Expression contains one or more errors */ -#define EP_Distinct 0x10 /* Aggregate function with DISTINCT keyword */ -#define EP_VarSelect 0x20 /* pSelect is correlated, not constant */ -#define EP_Dequoted 0x40 /* True if the string has been dequoted */ -#define EP_InfixFunc 0x80 /* True for an infix function: LIKE, GLOB, etc */ -#define EP_ExpCollate 0x100 /* Collating sequence specified explicitly */ +#define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */ +#define EP_Agg 0x0002 /* Contains one or more aggregate functions */ +#define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */ +#define EP_Error 0x0008 /* Expression contains one or more errors */ +#define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */ +#define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */ +#define EP_Dequoted 0x0040 /* True if the string has been dequoted */ +#define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */ +#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 */ /* ** These macros can be used to test, set, or clear bits in the @@ -7601,9 +8568,13 @@ struct WhereLevel { sqlite3_index_info *pIdxInfo; /* Index info for n-th source table */ }; -#define ORDERBY_NORMAL 0 -#define ORDERBY_MIN 1 -#define ORDERBY_MAX 2 +/* +** Flags appropriate for the wflags parameter of sqlite3WhereBegin(). +*/ +#define WHERE_ORDERBY_NORMAL 0 /* No-op */ +#define WHERE_ORDERBY_MIN 1 /* ORDER BY processing for min() func */ +#define WHERE_ORDERBY_MAX 2 /* ORDER BY processing for max() func */ +#define WHERE_ONEPASS_DESIRED 4 /* Want to do one-pass UPDATE/DELETE */ /* ** The WHERE clause processing routine has two halves. The @@ -7613,7 +8584,8 @@ struct WhereLevel { ** into the second half to give some continuity. */ struct WhereInfo { - Parse *pParse; + Parse *pParse; /* Parsing and code generating context */ + u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE or DELETE */ SrcList *pTabList; /* List of tables in the join */ int iTop; /* The very beginning of the WHERE loop */ int iContinue; /* Jump here to continue with next record */ @@ -7729,6 +8701,7 @@ struct SelectDest { u8 affinity; /* Affinity used when eDest==SRT_Set */ int iParm; /* A parameter used by the eDest disposal method */ int iMem; /* Base register where results are written */ + int nMem; /* Number of registers allocated */ }; /* @@ -7767,6 +8740,15 @@ struct Parse { int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ int ckBase; /* Base register of data during check constraints */ + int disableColCache; /* True to disable adding to column cache */ + int nColCache; /* Number of entries in the column cache */ + int iColCache; /* Next entry of the cache to replace */ + struct yColCache { + int iTable; /* Table cursor number */ + int iColumn; /* Table column number */ + char affChange; /* True if this register has had an affinity change */ + int iReg; /* Register holding value of this column */ + } aColCache[10]; /* One for each valid column cache entry */ u32 writeMask; /* Start a write transaction on these databases */ u32 cookieMask; /* Bitmask of schema verified databases */ int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ @@ -7775,12 +8757,12 @@ struct Parse { int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ #endif + int regRowid; /* Register holding rowid of CREATE TABLE entry */ + int regRoot; /* Register holding root page number for new objects */ /* Above is constant between recursions. Below is reset before and after ** each recursion */ - int regRowid; /* Register holding rowid of CREATE TABLE entry */ - int regRoot; /* Register holding root page number for new objects */ int nVar; /* Number of '?' variables seen in the SQL so far */ int nVarExpr; /* Number of used slots in apVarExpr[] */ int nVarExprAlloc; /* Number of allocated slots in apVarExpr[] */ @@ -7983,6 +8965,7 @@ struct StrAccum { char *zText; /* The string collected so far */ int nChar; /* Length of the string so far */ int nAlloc; /* Amount of space allocated in zText */ + int mxAlloc; /* Maximum allowed string length */ u8 mallocFailed; /* Becomes true if any memory allocation fails */ u8 useMalloc; /* True if zText is enlargable using realloc */ u8 tooBig; /* Becomes true if string size exceeds limits */ @@ -8040,6 +9023,7 @@ SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*); SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, int); SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, int); SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, int); +SQLITE_PRIVATE int sqlite3MallocSize(void *); SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); @@ -8089,6 +9073,13 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*); SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,Select*); +SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32); +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 int sqlite3BitvecBuiltinTest(int,int*); + SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int); #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) @@ -8117,7 +9108,6 @@ SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*, Select*, int, int SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, Expr*,ExprList*,int,Expr*,Expr*); SQLITE_PRIVATE void sqlite3SelectDelete(Select*); -SQLITE_PRIVATE void sqlite3SelectMask(Parse *, Select *, u32); SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int); SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); @@ -8125,11 +9115,18 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**, u8); SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); -SQLITE_PRIVATE void sqlite3ExprCodeGetColumn(Vdbe*, Table*, int, int, int); +SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, int); +SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int); +SQLITE_PRIVATE void sqlite3ExprClearColumnCache(Parse*, int); +SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int); +SQLITE_PRIVATE int sqlite3ExprWritableRegister(Parse*,int,int); +SQLITE_PRIVATE void sqlite3ExprHardCopy(Parse*,int,int); SQLITE_PRIVATE int sqlite3ExprCode(Parse*, Expr*, int); SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*); +SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int); SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse*, Expr*, int); -SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int); +SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse*, Expr*); +SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int); SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int); SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int); SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*); @@ -8146,7 +9143,9 @@ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*); SQLITE_PRIVATE Expr *sqlite3CreateIdExpr(Parse *, const char*); -SQLITE_PRIVATE void sqlite3Randomness(int, void*); +SQLITE_PRIVATE void sqlite3PrngSaveState(void); +SQLITE_PRIVATE void sqlite3PrngRestoreState(void); +SQLITE_PRIVATE void sqlite3PrngResetState(void); SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*); SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int); SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int); @@ -8159,7 +9158,7 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*); SQLITE_PRIVATE int sqlite3IsRowid(const char*); SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int); SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*); -SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int); +SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int); SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int, int*,int,int,int,int); SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*,int,int,int,int); @@ -8184,6 +9183,7 @@ SQLITE_PRIVATE int sqlite3SafetyOff(sqlite3*); SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); +SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Select*, Expr*, int); #ifndef SQLITE_OMIT_TRIGGER SQLITE_PRIVATE void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, @@ -8242,7 +9242,8 @@ SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *, int); SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); SQLITE_PRIVATE int sqlite3Utf8Read(const u8*, const u8*, const u8**); -SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *, u64); +SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64); +SQLITE_PRIVATE int sqlite3PutVarint32(unsigned char*, u32); SQLITE_PRIVATE int sqlite3GetVarint(const unsigned char *, u64 *); SQLITE_PRIVATE int sqlite3GetVarint32(const unsigned char *, u32 *); SQLITE_PRIVATE int sqlite3VarintLen(u64 v); @@ -8322,12 +9323,11 @@ SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t)); SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*)); SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*); +SQLITE_PRIVATE int sqlite3AutoLoadExtensions(sqlite3*); #ifndef SQLITE_OMIT_LOAD_EXTENSION SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3*); -SQLITE_PRIVATE int sqlite3AutoLoadExtensions(sqlite3*); #else # define sqlite3CloseExtensions(X) -# define sqlite3AutoLoadExtensions(X) SQLITE_OK #endif #ifndef SQLITE_OMIT_SHARED_CACHE @@ -8364,7 +9364,7 @@ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, sqlite3_vtab *); SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); -SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, int, const char*); +SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); @@ -8379,7 +9379,7 @@ SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); ** mechanism is disabled at compile-time then set up macros so that no ** unnecessary code is generated. */ -#ifndef SQLITE_OMIT_FAULTINJECTOR +#ifndef SQLITE_OMIT_BUILTIN_TEST SQLITE_PRIVATE void sqlite3FaultConfig(int,int,int); SQLITE_PRIVATE int sqlite3FaultFailures(int); SQLITE_PRIVATE int sqlite3FaultBenignFailures(int); @@ -8430,17 +9430,17 @@ SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *); /* ** If the SQLITE_ENABLE IOTRACE exists then the global variable -** sqlite3_io_trace is a pointer to a printf-like routine used to +** sqlite3IoTrace is a pointer to a printf-like routine used to ** print I/O tracing messages. */ #ifdef SQLITE_ENABLE_IOTRACE -# define IOTRACE(A) if( sqlite3_io_trace ){ sqlite3_io_trace A; } +# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; } SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*); #else # define IOTRACE(A) # define sqlite3VdbeIOTraceSql(X) #endif -SQLITE_EXTERN void (*sqlite3_io_trace)(const char*,...); +SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*,...); #endif @@ -8464,7 +9464,7 @@ SQLITE_EXTERN void (*sqlite3_io_trace)(const char*,...); ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: date.c,v 1.75 2008/01/17 22:27:54 drh Exp $ +** $Id: date.c,v 1.79 2008/03/20 14:03:29 drh Exp $ ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon @@ -8576,23 +9576,32 @@ end_getDigits: ** ** (+/-)HH:MM ** +** Or the "zulu" notation: +** +** Z +** ** If the parse is successful, write the number of minutes -** of change in *pnMin and return 0. If a parser error occurs, -** return 0. +** of change in p->tz and return 0. If a parser error occurs, +** return non-zero. ** ** A missing specifier is not considered an error. */ static int parseTimezone(const char *zDate, DateTime *p){ int sgn = 0; int nHr, nMn; + int c; while( isspace(*(u8*)zDate) ){ zDate++; } p->tz = 0; - if( *zDate=='-' ){ + c = *zDate; + if( c=='-' ){ sgn = -1; - }else if( *zDate=='+' ){ + }else if( c=='+' ){ sgn = +1; + }else if( c=='Z' || c=='z' ){ + zDate++; + goto zulu_time; }else{ - return *zDate!=0; + return c!=0; } zDate++; if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){ @@ -8600,6 +9609,7 @@ static int parseTimezone(const char *zDate, DateTime *p){ } zDate += 5; p->tz = sgn*(nMn + nHr*60); +zulu_time: while( isspace(*(u8*)zDate) ){ zDate++; } return *zDate!=0; } @@ -8759,7 +9769,8 @@ static int parseDateOrTime( return 0; }else if( sqlite3StrICmp(zDate,"now")==0){ double r; - sqlite3OsCurrentTime((sqlite3_vfs *)sqlite3_user_data(context), &r); + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3OsCurrentTime(db->pVfs, &r); p->rJD = r; p->validJD = 1; return 0; @@ -9274,7 +10285,7 @@ static void strftimeFunc( } if( nSQLITE_MAX_LENGTH ){ + }else if( n>sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH] ){ sqlite3_result_error_toobig(context); return; }else{ @@ -9405,18 +10416,13 @@ static void currentTimeFunc( ){ time_t t; char *zFormat = (char *)sqlite3_user_data(context); + sqlite3 *db; + double rT; char zBuf[20]; - time(&t); -#ifdef SQLITE_TEST - { - extern int sqlite3_current_time; /* See os_XXX.c */ - if( sqlite3_current_time ){ - t = sqlite3_current_time; - } - } -#endif - + db = sqlite3_context_db_handle(context); + sqlite3OsCurrentTime(db->pVfs, &rT); + t = 86400.0*(rT - 2440587.5) + 0.5; #ifdef HAVE_GMTIME_R { struct tm sNow; @@ -9462,7 +10468,7 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(sqlite3 *db){ for(i=0; ipVfs), aFuncs[i].xFunc, 0, 0); + SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0); } #else static const struct { @@ -9484,7 +10490,7 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(sqlite3 *db){ /************** End of date.c ************************************************/ /************** Begin file os.c **********************************************/ - /* +/* ** 2005 November 29 ** ** The author disclaims copyright to this source code. In place of @@ -9600,7 +10606,15 @@ SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dir return pVfs->xDelete(pVfs, zPath, dirSync); } SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ - return pVfs->xAccess(pVfs, zPath, flags); + int rc; +#ifdef SQLITE_TEST + void *pTstAlloc = sqlite3_malloc(10); + if (!pTstAlloc) return -1; + sqlite3_free(pTstAlloc); +#endif + rc = pVfs->xAccess(pVfs, zPath, flags); + assert( rc==0 || rc==1 ); + return rc; } SQLITE_PRIVATE int sqlite3OsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){ return pVfs->xGetTempname(pVfs, nBufOut, zBufOut); @@ -9657,10 +10671,9 @@ SQLITE_PRIVATE int sqlite3OsOpenMalloc( } SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *pFile){ int rc = SQLITE_OK; - if( pFile ){ - rc = sqlite3OsClose(pFile); - sqlite3_free(pFile); - } + assert( pFile ); + rc = sqlite3OsClose(pFile); + sqlite3_free(pFile); return rc; } @@ -9751,6 +10764,14 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ return SQLITE_OK; } +/* +** Provide a default sqlite3OsDefaultVfs() implementation in the +** cases where none of the standard backends are used. +*/ +#if !OS_UNIX && !OS_WIN && !OS_OS2 +SQLITE_PRIVATE sqlite3_vfs *sqlite3OsDefaultVfs(void){ return 0; } +#endif + /************** End of os.c **************************************************/ /************** Begin file fault.c *******************************************/ /* @@ -9774,7 +10795,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ ** allocation failures or I/O errors. ** ** The fault injector is omitted from the code if SQLite is -** compiled with -DSQLITE_OMIT_FAULTINJECTOR=1. There is a very +** compiled with -DSQLITE_OMIT_BUILTIN_TEST=1. There is a very ** small performance hit for leaving the fault injector in the code. ** Commerical products will probably want to omit the fault injector ** from production builds. But safety-critical systems who work @@ -9782,7 +10803,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ ** choose to leave the fault injector enabled even in production. */ -#ifndef SQLITE_OMIT_FAULTINJECTOR +#ifndef SQLITE_OMIT_BUILTIN_TEST /* ** There can be various kinds of faults. For example, there can be @@ -9796,7 +10817,7 @@ static struct FaultInjector { int nBenign; /* Number of benign failures seen since last config */ int nFail; /* Number of failures seen since last config */ u8 enable; /* True if enabled */ - u8 benign; /* Ture if next failure will be benign */ + u8 benign; /* True if next failure will be benign */ } aFault[SQLITE_FAULTINJECTOR_COUNT]; /* @@ -9859,8 +10880,14 @@ SQLITE_PRIVATE int sqlite3FaultPending(int id){ ** a hash table resize is a benign fault. */ SQLITE_PRIVATE void sqlite3FaultBenign(int id, int enable){ - assert( id>=0 && id=0 && id=mem.alarmThreshold ){ sqlite3MemsysAlarm(nBytes); } - p = malloc(nBytes+8); - if( p==0 ){ - sqlite3MemsysAlarm(nBytes); + if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){ + p = 0; + }else{ p = malloc(nBytes+8); + if( p==0 ){ + sqlite3MemsysAlarm(nBytes); + p = malloc(nBytes+8); + } } if( p ){ p[0] = nBytes; @@ -10092,6 +11108,16 @@ SQLITE_API void sqlite3_free(void *pPrior){ sqlite3_mutex_leave(mem.mutex); } +/* +** Return the number of bytes allocated at p. +*/ +SQLITE_PRIVATE int sqlite3MallocSize(void *p){ + sqlite3_int64 *pInt; + if( !p ) return 0; + pInt = p; + return pInt[-1]; +} + /* ** Change the size of an existing memory allocation */ @@ -10113,12 +11139,16 @@ SQLITE_API void *sqlite3_realloc(void *pPrior, int nBytes){ if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){ sqlite3MemsysAlarm(nBytes-nOld); } - p = realloc(p, nBytes+8); - if( p==0 ){ - sqlite3MemsysAlarm(nBytes); - p = pPrior; - p--; + if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){ + p = 0; + }else{ p = realloc(p, nBytes+8); + if( p==0 ){ + sqlite3MemsysAlarm(nBytes); + p = pPrior; + p--; + p = realloc(p, nBytes+8); + } } if( p ){ p[0] = nBytes; @@ -10132,7 +11162,7 @@ SQLITE_API void *sqlite3_realloc(void *pPrior, int nBytes){ return (void*)p; } -#endif /* !SQLITE_MEMDEBUG && !SQLITE_OMIT_MEMORY_ALLOCATION */ +#endif /* SQLITE_SYSTEM_MALLOC */ /************** End of mem1.c ************************************************/ /************** Begin file mem2.c ********************************************/ @@ -10150,36 +11180,14 @@ SQLITE_API void *sqlite3_realloc(void *pPrior, int nBytes){ ** This file contains the C functions that implement a memory ** allocation subsystem for use by SQLite. ** -** $Id: mem2.c,v 1.19 2008/01/22 21:30:53 drh Exp $ +** $Id: mem2.c,v 1.26 2008/04/10 14:57:25 drh Exp $ */ /* ** This version of the memory allocator is used only if the -** SQLITE_MEMDEBUG macro is defined and SQLITE_OMIT_MEMORY_ALLOCATION -** is not defined. -*/ -#if defined(SQLITE_MEMDEBUG) - -/* -** We will eventually construct multiple memory allocation subsystems -** suitable for use in various contexts: -** -** * Normal multi-threaded builds -** * Normal single-threaded builds -** * Debugging builds -** -** This version is suitable for use in debugging builds. -** -** Features: -** -** * Every allocate has guards at both ends. -** * New allocations are initialized with randomness -** * Allocations are overwritten with randomness when freed -** * Optional logs of malloc activity generated -** * Summary of outstanding allocations with backtraces to the -** point of allocation. -** * The ability to simulate memory allocation failure +** SQLITE_MEMDEBUG macro is defined */ +#ifdef SQLITE_MEMDEBUG /* ** The backtrace functionality is only available with GLIBC @@ -10206,8 +11214,8 @@ SQLITE_API void *sqlite3_realloc(void *pPrior, int nBytes){ ** MemBlockHdr. */ struct MemBlockHdr { + i64 iSize; /* Size of this allocation */ struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */ - int iSize; /* Size of this allocation */ char nBacktrace; /* Number of backtraces on this alloc */ char nBacktraceSlots; /* Available backtrace slots */ short nTitle; /* Bytes of title; includes '\0' */ @@ -10265,6 +11273,7 @@ static struct { ** The number of levels of backtrace to save in new allocations. */ int nBacktrace; + void (*xBacktrace)(int, int, void **); /* ** Title text to insert in front of each block @@ -10369,16 +11378,34 @@ static void sqlite3MemsysAlarm(int nByte){ static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){ struct MemBlockHdr *p; int *pInt; + u8 *pU8; + int nReserve; p = (struct MemBlockHdr*)pAllocation; p--; assert( p->iForeGuard==FOREGUARD ); - assert( (p->iSize & 3)==0 ); + nReserve = (p->iSize+7)&~7; pInt = (int*)pAllocation; - assert( pInt[p->iSize/sizeof(int)]==REARGUARD ); + pU8 = (u8*)pAllocation; + assert( pInt[nReserve/sizeof(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 ); return p; } +/* +** Return the number of bytes currently allocated at address p. +*/ +SQLITE_PRIVATE int sqlite3MallocSize(void *p){ + struct MemBlockHdr *pHdr; + if( !p ){ + return 0; + } + pHdr = sqlite3MemsysGetHeader(p); + return pHdr->iSize; +} + /* ** Allocate nByte bytes of memory. */ @@ -10391,18 +11418,19 @@ SQLITE_API void *sqlite3_malloc(int nByte){ int totalSize; if( nByte>0 ){ + int nReserve; enterMem(); assert( mem.disallow==0 ); if( mem.alarmCallback!=0 && mem.nowUsed+nByte>=mem.alarmThreshold ){ sqlite3MemsysAlarm(nByte); } - nByte = (nByte+3)&~3; - if( nByte/8>NCSIZE-1 ){ + nReserve = (nByte+7)&~7; + if( nReserve/8>NCSIZE-1 ){ mem.sizeCnt[NCSIZE-1]++; }else{ - mem.sizeCnt[nByte/8]++; + mem.sizeCnt[nReserve/8]++; } - totalSize = nByte + sizeof(*pHdr) + sizeof(int) + + totalSize = nReserve + sizeof(*pHdr) + sizeof(int) + mem.nBacktrace*sizeof(void*) + mem.nTitle; if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){ p = 0; @@ -10432,6 +11460,9 @@ SQLITE_API void *sqlite3_malloc(int nByte){ void *aAddr[40]; pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1; memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*)); + if( mem.xBacktrace ){ + mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]); + } }else{ pHdr->nBacktrace = 0; } @@ -10440,8 +11471,8 @@ SQLITE_API void *sqlite3_malloc(int nByte){ } pHdr->iSize = nByte; pInt = (int*)&pHdr[1]; - pInt[nByte/sizeof(int)] = REARGUARD; - memset(pInt, 0x65, nByte); + pInt[nReserve/sizeof(int)] = REARGUARD; + memset(pInt, 0x65, nReserve); mem.nowUsed += nByte; if( mem.nowUsed>mem.mxUsed ){ mem.mxUsed = mem.nowUsed; @@ -10528,31 +11559,44 @@ SQLITE_API void *sqlite3_realloc(void *pPrior, int nByte){ ** A value of zero turns of backtracing. The number is always rounded ** up to a multiple of 2. */ -SQLITE_API void sqlite3_memdebug_backtrace(int depth){ +SQLITE_PRIVATE void sqlite3MemdebugBacktrace(int depth){ if( depth<0 ){ depth = 0; } if( depth>20 ){ depth = 20; } depth = (depth+1)&0xfe; mem.nBacktrace = depth; } +SQLITE_PRIVATE void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){ + mem.xBacktrace = xBacktrace; +} + /* ** Set the title string for subsequent allocations. */ -SQLITE_API void sqlite3_memdebug_settitle(const char *zTitle){ +SQLITE_PRIVATE void sqlite3MemdebugSettitle(const char *zTitle){ int n = strlen(zTitle) + 1; enterMem(); if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1; memcpy(mem.zTitle, zTitle, n); mem.zTitle[n] = 0; - mem.nTitle = (n+3)&~3; + mem.nTitle = (n+7)&~7; sqlite3_mutex_leave(mem.mutex); } +SQLITE_PRIVATE void sqlite3MemdebugSync(){ + struct MemBlockHdr *pHdr; + for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ + void **pBt = (void**)pHdr; + pBt -= pHdr->nBacktraceSlots; + mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); + } +} + /* ** Open the file indicated and write a log of all unfreed memory ** allocations into that log. */ -SQLITE_API void sqlite3_memdebug_dump(const char *zFilename){ +SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){ FILE *out; struct MemBlockHdr *pHdr; void **pBt; @@ -10566,7 +11610,7 @@ SQLITE_API void sqlite3_memdebug_dump(const char *zFilename){ for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ char *z = (char*)pHdr; z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle; - fprintf(out, "**** %d bytes at %p from %s ****\n", + fprintf(out, "**** %lld bytes at %p from %s ****\n", pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???"); if( pHdr->nBacktrace ){ fflush(out); @@ -10588,8 +11632,20 @@ SQLITE_API void sqlite3_memdebug_dump(const char *zFilename){ fclose(out); } +/* +** Return the number of times sqlite3_malloc() has been called. +*/ +SQLITE_PRIVATE int sqlite3MemdebugMallocCount(){ + int i; + int nTotal = 0; + for(i=0; i=nOld-128 ){ return pPrior; } @@ -11172,7 +12228,7 @@ SQLITE_API void *sqlite3_realloc(void *pPrior, int nBytes){ ** Open the file indicated and write a log of all unfreed memory ** allocations into that log. */ -SQLITE_API void sqlite3_memdebug_dump(const char *zFilename){ +SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){ #ifdef SQLITE_DEBUG FILE *out; int i, j; @@ -11247,6 +12303,519 @@ SQLITE_API void sqlite3_memdebug_dump(const char *zFilename){ #endif /* !SQLITE_MEMORY_SIZE */ /************** End of mem3.c ************************************************/ +/************** Begin file mem5.c ********************************************/ +/* +** 2007 October 14 +** +** 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 C functions that implement a memory +** allocation subsystem for use by SQLite. +** +** This version of the memory allocation subsystem omits all +** use of malloc(). All dynamically allocatable memory is +** contained in a static array, mem.aPool[]. The size of this +** fixed memory pool is SQLITE_POW2_MEMORY_SIZE bytes. +** +** This version of the memory allocation subsystem is used if +** and only if SQLITE_POW2_MEMORY_SIZE is defined. +** +** $Id: mem5.c,v 1.4 2008/02/19 15:15:16 drh Exp $ +*/ + +/* +** This version of the memory allocator is used only when +** SQLITE_POW2_MEMORY_SIZE is defined. +*/ +#ifdef SQLITE_POW2_MEMORY_SIZE + +/* +** Log2 of the minimum size of an allocation. For example, if +** 4 then all allocations will be rounded up to at least 16 bytes. +** If 5 then all allocations will be rounded up to at least 32 bytes. +*/ +#ifndef SQLITE_POW2_LOGMIN +# define SQLITE_POW2_LOGMIN 6 +#endif +#define POW2_MIN (1<=0 && i=0 && iLogsize=0 ){ + mem.aPool[next].u.list.prev = prev; + } +} + +/* +** Link the chunk at mem.aPool[i] so that is on the iLogsize +** free list. +*/ +static void memsys5Link(int i, int iLogsize){ + int x; + assert( sqlite3_mutex_held(mem.mutex) ); + assert( i>=0 && i=0 && iLogsize=0 ){ + assert( x=POW2_MAX ); + mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); + sqlite3_mutex_enter(mem.mutex); + for(i=0; i=0 && i=0 && iLogsize=0 ); + while( i>0 ){ + if( imem.maxRequest ){ + mem.maxRequest = nByte; + } + + /* Simulate a memory allocation fault */ + if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ) return 0; + + /* Round nByte up to the next valid power of two */ + if( nByte>POW2_MAX ) return 0; + for(iFullSz=POW2_MIN, iLogsize=0; iFullSz=mem.alarmThreshold ){ + memsys5Alarm(iFullSz); + } + + /* Make sure mem.aiFreelist[iLogsize] contains at least one free + ** block. If not, then split a block of the next larger power of + ** two in order to create a new free block of size iLogsize. + */ + for(iBin=iLogsize; mem.aiFreelist[iBin]<0 && iBin=NSIZE ) return 0; + i = memsys5UnlinkFirst(iBin); + while( iBin>iLogsize ){ + int newSize; + + iBin--; + newSize = 1 << iBin; + mem.aCtrl[i+newSize] = CTRL_FREE | iBin; + memsys5Link(i+newSize, iBin); + } + mem.aCtrl[i] = iLogsize; + + /* Update allocator performance statistics. */ + mem.nAlloc++; + mem.totalAlloc += iFullSz; + mem.totalExcess += iFullSz - nByte; + mem.currentCount++; + mem.currentOut += iFullSz; + if( mem.maxCount=0 && i0 ); + assert( mem.currentOut>=0 ); + mem.currentCount--; + mem.currentOut -= size*POW2_MIN; + assert( mem.currentOut>0 || mem.currentCount==0 ); + assert( mem.currentCount>0 || mem.currentOut==0 ); + + mem.aCtrl[i] = CTRL_FREE | iLogsize; + while( iLogsize>iLogsize) & 1 ){ + iBuddy = i - size; + }else{ + iBuddy = i + size; + } + assert( iBuddy>=0 && iBuddy0 ){ + memsys5Enter(); + p = memsys5Malloc(nBytes); + sqlite3_mutex_leave(mem.mutex); + } + return (void*)p; +} + +/* +** Free memory. +*/ +SQLITE_API void sqlite3_free(void *pPrior){ + if( pPrior==0 ){ + return; + } + assert( mem.mutex!=0 ); + sqlite3_mutex_enter(mem.mutex); + memsys5Free(pPrior); + sqlite3_mutex_leave(mem.mutex); +} + +/* +** Change the size of an existing memory allocation +*/ +SQLITE_API void *sqlite3_realloc(void *pPrior, int nBytes){ + int nOld; + void *p; + if( pPrior==0 ){ + return sqlite3_malloc(nBytes); + } + if( nBytes<=0 ){ + sqlite3_free(pPrior); + return 0; + } + assert( mem.mutex!=0 ); + nOld = sqlite3MallocSize(pPrior); + if( nBytes<=nOld ){ + return pPrior; + } + sqlite3_mutex_enter(mem.mutex); + p = memsys5Malloc(nBytes); + if( p ){ + memcpy(p, pPrior, nOld); + memsys5Free(pPrior); + } + sqlite3_mutex_leave(mem.mutex); + return p; +} + +/* +** Open the file indicated and write a log of all unfreed memory +** allocations into that log. +*/ +SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){ +#ifdef SQLITE_DEBUG + FILE *out; + int i, j, n; + + if( zFilename==0 || zFilename[0]==0 ){ + out = stdout; + }else{ + out = fopen(zFilename, "w"); + if( out==0 ){ + fprintf(stderr, "** Unable to output memory debug output log: %s **\n", + zFilename); + return; + } + } + memsys5Enter(); + for(i=0; i=0; j = mem.aPool[j].u.list.next, n++){} + fprintf(out, "freelist items of size %d: %d\n", POW2_MIN << i, n); + } + fprintf(out, "mem.nAlloc = %llu\n", mem.nAlloc); + fprintf(out, "mem.totalAlloc = %llu\n", mem.totalAlloc); + fprintf(out, "mem.totalExcess = %llu\n", mem.totalExcess); + fprintf(out, "mem.currentOut = %u\n", mem.currentOut); + fprintf(out, "mem.currentCount = %u\n", mem.currentCount); + fprintf(out, "mem.maxOut = %u\n", mem.maxOut); + fprintf(out, "mem.maxCount = %u\n", mem.maxCount); + fprintf(out, "mem.maxRequest = %u\n", mem.maxRequest); + sqlite3_mutex_leave(mem.mutex); + if( out==stdout ){ + fflush(stdout); + }else{ + fclose(out); + } +#endif +} + + +#endif /* !SQLITE_POW2_MEMORY_SIZE */ + +/************** End of mem5.c ************************************************/ /************** Begin file mutex.c *******************************************/ /* ** 2007 August 14 @@ -11269,7 +12838,7 @@ SQLITE_API void sqlite3_memdebug_dump(const char *zFilename){ ** implementation is suitable for testing. ** debugging purposes ** -** $Id: mutex.c,v 1.16 2007/09/10 16:13:00 danielk1977 Exp $ +** $Id: mutex.c,v 1.17 2008/03/26 18:34:43 danielk1977 Exp $ */ #ifdef SQLITE_MUTEX_NOOP_DEBUG @@ -11293,7 +12862,7 @@ struct sqlite3_mutex { ** that means that a mutex could not be allocated. */ SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){ - static sqlite3_mutex aStatic[5]; + static sqlite3_mutex aStatic[6]; sqlite3_mutex *pNew = 0; switch( id ){ case SQLITE_MUTEX_FAST: @@ -11389,7 +12958,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ ************************************************************************* ** This file contains the C functions that implement mutexes for OS/2 ** -** $Id: mutex_os2.c,v 1.4 2007/12/30 23:29:07 pweilbacher Exp $ +** $Id: mutex_os2.c,v 1.6 2008/03/26 18:34:43 danielk1977 Exp $ */ /* @@ -11408,13 +12977,14 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ ** Each recursive mutex is an instance of the following structure. */ struct sqlite3_mutex { - PSZ mutexName; /* Mutex name controlling the lock */ HMTX mutex; /* Mutex controlling the lock */ int id; /* Mutex type */ int nRef; /* Number of references */ TID owner; /* Thread holding this mutex */ }; +#define OS2_MUTEX_INITIALIZER 0,0,0,0 + /* ** The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL @@ -11455,46 +13025,56 @@ struct sqlite3_mutex { ** the same type number. */ SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int iType){ - PSZ mutex_name = "\\SEM32\\SQLITE\\MUTEX"; - int mutex_name_len = strlen(mutex_name) + 1; /* name length + null byte */ - sqlite3_mutex *p; - + sqlite3_mutex *p = NULL; switch( iType ){ case SQLITE_MUTEX_FAST: case SQLITE_MUTEX_RECURSIVE: { p = sqlite3MallocZero( sizeof(*p) ); if( p ){ - p->mutexName = (PSZ)malloc(mutex_name_len); - sqlite3_snprintf(mutex_name_len, p->mutexName, "%s", mutex_name); p->id = iType; - DosCreateMutexSem(p->mutexName, &p->mutex, 0, FALSE); - DosOpenMutexSem(p->mutexName, &p->mutex); + if( DosCreateMutexSem( 0, &p->mutex, 0, FALSE ) != NO_ERROR ){ + sqlite3_free( p ); + p = NULL; + } } break; } default: { - static sqlite3_mutex staticMutexes[5]; - static int isInit = 0; - while( !isInit ) { - static long lock = 0; - DosEnterCritSec(); - lock++; - if( lock == 1 ) { - int i; - DosExitCritSec(); - for(i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++) { - staticMutexes[i].mutexName = (PSZ)malloc(mutex_name_len + 1); - sqlite3_snprintf(mutex_name_len + 1, /* one more for the number */ - staticMutexes[i].mutexName, "%s%1d", mutex_name, i); - DosCreateMutexSem(staticMutexes[i].mutexName, - &staticMutexes[i].mutex, 0, FALSE); - DosOpenMutexSem(staticMutexes[i].mutexName, - &staticMutexes[i].mutex); + static volatile int isInit = 0; + static sqlite3_mutex staticMutexes[] = { + { OS2_MUTEX_INITIALIZER, }, + { OS2_MUTEX_INITIALIZER, }, + { OS2_MUTEX_INITIALIZER, }, + { OS2_MUTEX_INITIALIZER, }, + { OS2_MUTEX_INITIALIZER, }, + { OS2_MUTEX_INITIALIZER, }, + }; + if ( !isInit ){ + APIRET rc; + PTIB ptib; + PPIB ppib; + HMTX mutex; + char name[32]; + DosGetInfoBlocks( &ptib, &ppib ); + sqlite3_snprintf( sizeof(name), name, "\\SEM32\\SQLITE%04x", + ppib->pib_ulpid ); + while( !isInit ){ + mutex = 0; + rc = DosCreateMutexSem( name, &mutex, 0, FALSE); + if( rc == NO_ERROR ){ + int i; + if( !isInit ){ + for( i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++ ){ + DosCreateMutexSem( 0, &staticMutexes[i].mutex, 0, FALSE ); + } + isInit = 1; + } + DosCloseMutexSem( mutex ); + }else if( rc == ERROR_DUPLICATE_NAME ){ + DosSleep( 1 ); + }else{ + return p; } - isInit = 1; - } else { - DosExitCritSec(); - DosSleep(1); } } assert( iType-2 >= 0 ); @@ -11516,9 +13096,8 @@ SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){ assert( p ); assert( p->nRef==0 ); assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); - DosCloseMutexSem(p->mutex); - free(p->mutexName); - sqlite3_free(p); + DosCloseMutexSem( p->mutex ); + sqlite3_free( p ); } /* @@ -11627,7 +13206,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ ************************************************************************* ** This file contains the C functions that implement mutexes for pthreads ** -** $Id: mutex_unix.c,v 1.5 2007/11/28 14:04:57 drh Exp $ +** $Id: mutex_unix.c,v 1.7 2008/03/29 12:47:27 rse Exp $ */ /* @@ -11654,6 +13233,11 @@ struct sqlite3_mutex { int trace; /* True to trace changes */ #endif }; +#ifdef SQLITE_DEBUG +#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 } +#else +#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0 } +#endif /* ** The sqlite3_mutex_alloc() routine allocates a new @@ -11698,11 +13282,12 @@ struct sqlite3_mutex { */ SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int iType){ static sqlite3_mutex staticMutexes[] = { - { PTHREAD_MUTEX_INITIALIZER, }, - { PTHREAD_MUTEX_INITIALIZER, }, - { PTHREAD_MUTEX_INITIALIZER, }, - { PTHREAD_MUTEX_INITIALIZER, }, - { PTHREAD_MUTEX_INITIALIZER, }, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER }; sqlite3_mutex *p; switch( iType ){ @@ -11927,7 +13512,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ ************************************************************************* ** This file contains the C functions that implement mutexes for win32 ** -** $Id: mutex_w32.c,v 1.5 2007/10/05 15:08:01 drh Exp $ +** $Id: mutex_w32.c,v 1.6 2008/03/26 18:34:43 danielk1977 Exp $ */ /* @@ -12026,7 +13611,7 @@ SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int iType){ break; } default: { - static sqlite3_mutex staticMutexes[5]; + static sqlite3_mutex staticMutexes[6]; static int isInit = 0; while( !isInit ){ static long lock = 0; @@ -12149,7 +13734,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ ** Memory allocation functions used throughout sqlite. ** ** -** $Id: malloc.c,v 1.14 2007/10/20 16:36:31 drh Exp $ +** $Id: malloc.c,v 1.15 2008/03/26 18:34:43 danielk1977 Exp $ */ /* @@ -12193,7 +13778,9 @@ SQLITE_API void sqlite3_soft_heap_limit(int n){ */ SQLITE_API int sqlite3_release_memory(int n){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - return sqlite3PagerReleaseMemory(n); + int nRet = sqlite3VdbeReleaseMemory(n); + nRet += sqlite3PagerReleaseMemory(n-nRet); + return nRet; #else return SQLITE_OK; #endif @@ -13110,14 +14697,17 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ return; } }else{ - p->nAlloc += p->nAlloc + N + 1; - if( p->nAlloc > SQLITE_MAX_LENGTH ){ - p->nAlloc = SQLITE_MAX_LENGTH; - if( p->nChar+N >= p->nAlloc ){ + i64 szNew = p->nAlloc; + szNew += N + 1; + if( szNew > p->mxAlloc ){ + p->nAlloc = p->mxAlloc; + if( ((i64)p->nChar)+((i64)N) >= p->nAlloc ){ sqlite3StrAccumReset(p); p->tooBig = 1; return; } + }else{ + p->nAlloc = szNew; } zNew = sqlite3_malloc( p->nAlloc ); if( zNew ){ @@ -13168,10 +14758,11 @@ SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){ /* ** Initialize a string accumulator */ -static void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n){ +static void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){ p->zText = p->zBase = zBase; p->nChar = 0; p->nAlloc = n; + p->mxAlloc = mx; p->useMalloc = 1; p->tooBig = 0; p->mallocFailed = 0; @@ -13185,7 +14776,8 @@ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list a char *z; char zBase[SQLITE_PRINT_BUF_SIZE]; StrAccum acc; - sqlite3StrAccumInit(&acc, zBase, sizeof(zBase)); + sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), + db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH); vxprintf(&acc, 1, zFormat, ap); z = sqlite3StrAccumFinish(&acc); if( acc.mallocFailed && db ){ @@ -13215,7 +14807,7 @@ SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){ char *z; char zBase[SQLITE_PRINT_BUF_SIZE]; StrAccum acc; - sqlite3StrAccumInit(&acc, zBase, sizeof(zBase)); + sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); vxprintf(&acc, 0, zFormat, ap); z = sqlite3StrAccumFinish(&acc); return z; @@ -13248,7 +14840,7 @@ SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ if( n<=0 ){ return zBuf; } - sqlite3StrAccumInit(&acc, zBuf, n); + sqlite3StrAccumInit(&acc, zBuf, n, 0); acc.useMalloc = 0; va_start(ap,zFormat); vxprintf(&acc, 0, zFormat, ap); @@ -13267,7 +14859,7 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){ va_list ap; StrAccum acc; char zBuf[500]; - sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf)); + sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0); acc.useMalloc = 0; va_start(ap,zFormat); vxprintf(&acc, 0, zFormat, ap); @@ -13297,7 +14889,7 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){ ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** -** $Id: random.c,v 1.21 2008/01/16 17:46:38 drh Exp $ +** $Id: random.c,v 1.23 2008/03/21 16:45:47 drh Exp $ */ @@ -13371,7 +14963,7 @@ static int randomByte(void){ /* ** Return N random bytes. */ -SQLITE_PRIVATE void sqlite3Randomness(int N, void *pBuf){ +SQLITE_API void sqlite3_randomness(int N, void *pBuf){ unsigned char *zBuf = pBuf; static sqlite3_mutex *mutex = 0; if( mutex==0 ){ @@ -13384,22 +14976,24 @@ SQLITE_PRIVATE void sqlite3Randomness(int N, void *pBuf){ sqlite3_mutex_leave(mutex); } -#ifdef SQLITE_TEST +#ifndef SQLITE_OMIT_BUILTIN_TEST /* ** For testing purposes, we sometimes want to preserve the state of ** PRNG and restore the PRNG to its saved state at a later time. +** The sqlite3_test_control() interface calls these routines to +** control the PRNG. */ static struct sqlite3PrngType sqlite3SavedPrng; -SQLITE_PRIVATE void sqlite3SavePrngState(void){ +SQLITE_PRIVATE void sqlite3PrngSaveState(void){ memcpy(&sqlite3SavedPrng, &sqlite3Prng, sizeof(sqlite3Prng)); } -SQLITE_PRIVATE void sqlite3RestorePrngState(void){ +SQLITE_PRIVATE void sqlite3PrngRestoreState(void){ memcpy(&sqlite3Prng, &sqlite3SavedPrng, sizeof(sqlite3Prng)); } -SQLITE_PRIVATE void sqlite3ResetPrngState(void){ +SQLITE_PRIVATE void sqlite3PrngResetState(void){ sqlite3Prng.isInit = 0; } -#endif /* SQLITE_TEST */ +#endif /* SQLITE_OMIT_BUILTIN_TEST */ /************** End of random.c **********************************************/ /************** Begin file utf.c *********************************************/ @@ -13417,7 +15011,7 @@ SQLITE_PRIVATE void sqlite3ResetPrngState(void){ ** This file contains routines used to translate between UTF-8, ** UTF-16, UTF-16BE, and UTF-16LE. ** -** $Id: utf.c,v 1.59 2007/10/03 08:46:45 danielk1977 Exp $ +** $Id: utf.c,v 1.61 2008/03/28 15:44:10 danielk1977 Exp $ ** ** Notes on UTF-8: ** @@ -13509,6 +15103,7 @@ struct Cursor { 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 */ Bool isIndex; /* True if an index containing keys only - no data */ @@ -13538,13 +15133,6 @@ struct Cursor { }; typedef struct Cursor Cursor; -/* -** Number of bytes of string storage space available to each stack -** layer without having to malloc. NBFS is short for Number of Bytes -** For Strings. -*/ -#define NBFS 32 - /* ** A value for Cursor.cacheValid that means the cache is always invalid. */ @@ -13574,7 +15162,7 @@ struct Mem { u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */ u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ void (*xDel)(void *); /* If not null, call this function to delete Mem.z */ - char zShort[NBFS]; /* Space for short strings */ + char *zMalloc; /* Dynamic buffer allocated by sqlite3_malloc() */ }; /* One or more of the following flags are set to indicate the validOK @@ -13598,6 +15186,9 @@ struct Mem { #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ +#define MemSetTypeFlag(p, f) \ + ((p)->flags = ((p)->flags&~(MEM_Int|MEM_Real|MEM_Null|MEM_Blob|MEM_Str))|f) + /* Whenever Mem contains a valid string or blob representation, one of ** the following flags must be set to determine the memory management ** policy for Mem.z. The MEM_Term flag tells us whether or not the @@ -13607,7 +15198,6 @@ struct Mem { #define MEM_Dyn 0x0040 /* Need to call sqliteFree() on Mem.z */ #define MEM_Static 0x0080 /* Mem.z points to a static string */ #define MEM_Ephem 0x0100 /* Mem.z points to an ephemeral string */ -#define MEM_Short 0x0200 /* Mem.z points to Mem.zShort */ #define MEM_Agg 0x0400 /* Mem.z points to an agg function context */ #define MEM_Zero 0x0800 /* Mem.i contains count of 0s appended to blob */ @@ -13653,7 +15243,7 @@ struct sqlite3_context { VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */ Mem s; /* The return value is stored here */ Mem *pMem; /* Memory cell used to store aggregate context */ - u8 isError; /* Set to true for an error */ + int isError; /* Error code returned by the function. */ CollSeq *pColl; /* Collating sequence */ }; @@ -13783,6 +15373,32 @@ struct Vdbe { int fetchId; /* Statement number used by sqlite3_fetch_statement */ int lru; /* Counter used for LRU cache replacement */ #endif +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + Vdbe *pLruPrev; + Vdbe *pLruNext; +#endif +}; + +/* +** An instance of the following structure holds information about a +** single index record that has already been parsed out into individual +** values. +** +** A record is an object that contains one or more fields of data. +** Records are used to store the content of a table row and to store +** the key of an index. A blob encoding of a record is created by +** the OP_MakeRecord opcode of the VDBE and is disassemblied by the +** OP_Column opcode. +** +** This structure holds a record that has already been disassembled +** into its constitutent fields. +*/ +struct UnpackedRecord { + KeyInfo *pKeyInfo; /* Collation and sort-order information */ + u16 nField; /* Number of entries in apMem[] */ + u8 needFree; /* True if memory obtained from sqlite3_malloc() */ + u8 needDestroy; /* True if apMem[]s should be destroyed on close */ + Mem *aMem; /* Values */ }; /* @@ -13812,7 +15428,6 @@ int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(Cursor*,int,const unsigned char*,int*); SQLITE_PRIVATE int sqlite3VdbeIdxRowid(BtCursor *, i64 *); SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); -SQLITE_PRIVATE int sqlite3VdbeRecordCompare(void*,int,const void*,int, const void*); SQLITE_PRIVATE int sqlite3VdbeIdxRowidLen(const u8*); SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); @@ -13839,9 +15454,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*); SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); +SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p); SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); SQLITE_PRIVATE const char *sqlite3OpcodeName(int); SQLITE_PRIVATE int sqlite3VdbeOpcodeHasProperty(int, int); +SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); +SQLITE_PRIVATE int sqlite3VdbeReleaseBuffers(Vdbe *p); #ifndef NDEBUG SQLITE_PRIVATE void sqlite3VdbeMemSanity(Mem*); @@ -14017,7 +15635,6 @@ SQLITE_PRIVATE int sqlite3Utf8Read( ** encoding, or if *pMem does not contain a string value. */ SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ - unsigned char zShort[NBFS]; /* Temporary short output buffer */ int len; /* Maximum length of output string in bytes */ unsigned char *zOut; /* Output buffer */ unsigned char *zIn; /* Input iterator */ @@ -14083,19 +15700,14 @@ SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ /* Set zIn to point at the start of the input buffer and zTerm to point 1 ** byte past the end. ** - ** Variable zOut is set to point at the output buffer. This may be space - ** obtained from sqlite3_malloc(), or Mem.zShort, if it large enough and - ** not in use, or the zShort array on the stack (see above). + ** Variable zOut is set to point at the output buffer, space obtained + ** from sqlite3_malloc(). */ zIn = (u8*)pMem->z; zTerm = &zIn[pMem->n]; - if( len>NBFS ){ - zOut = sqlite3DbMallocRaw(pMem->db, len); - if( !zOut ){ - return SQLITE_NOMEM; - } - }else{ - zOut = zShort; + zOut = sqlite3DbMallocRaw(pMem->db, len); + if( !zOut ){ + return SQLITE_NOMEM; } z = zOut; @@ -14137,16 +15749,11 @@ SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len ); sqlite3VdbeMemRelease(pMem); - pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short); + pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem); pMem->enc = desiredEnc; - if( zOut==zShort ){ - memcpy(pMem->zShort, zOut, len); - zOut = (u8*)pMem->zShort; - pMem->flags |= (MEM_Term|MEM_Short); - }else{ - pMem->flags |= (MEM_Term|MEM_Dyn); - } + pMem->flags |= (MEM_Term|MEM_Dyn); pMem->z = (char*)zOut; + pMem->zMalloc = pMem->z; translate_out: #if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) @@ -14184,24 +15791,14 @@ SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem){ } if( bom ){ - /* This function is called as soon as a string is stored in a Mem*, - ** from within sqlite3VdbeMemSetStr(). At that point it is not possible - ** for the string to be stored in Mem.zShort, or for it to be stored - ** in dynamic memory with no destructor. - */ - assert( !(pMem->flags&MEM_Short) ); - assert( !(pMem->flags&MEM_Dyn) || pMem->xDel ); - if( pMem->flags & MEM_Dyn ){ - void (*xDel)(void*) = pMem->xDel; - char *z = pMem->z; - pMem->z = 0; - pMem->xDel = 0; - rc = sqlite3VdbeMemSetStr(pMem, &z[2], pMem->n-2, bom, - SQLITE_TRANSIENT); - xDel(z); - }else{ - rc = sqlite3VdbeMemSetStr(pMem, &pMem->z[2], pMem->n-2, bom, - SQLITE_TRANSIENT); + rc = sqlite3VdbeMemMakeWriteable(pMem); + if( rc==SQLITE_OK ){ + pMem->n -= 2; + memmove(pMem->z, &pMem->z[2], pMem->n); + pMem->z[pMem->n] = '\0'; + pMem->z[pMem->n+1] = '\0'; + pMem->flags |= MEM_Term; + pMem->enc = bom; } } return rc; @@ -14391,7 +15988,7 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(){ ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.216 2008/01/23 03:03:05 drh Exp $ +** $Id: util.c,v 1.222 2008/04/16 00:49:12 drh Exp $ */ @@ -14871,6 +16468,24 @@ SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){ return n; } +/* +** This routine is a faster version of sqlite3PutVarint() that only +** works for 32-bit positive integers and which is optimized for +** the common case of small integers. +*/ +SQLITE_PRIVATE int sqlite3PutVarint32(unsigned char *p, u32 v){ + if( (v & ~0x7f)==0 ){ + p[0] = v; + return 1; + }else if( (v & ~0x3fff)==0 ){ + p[0] = (v>>7) | 0x80; + p[1] = v & 0x7f; + return 2; + }else{ + return sqlite3PutVarint(p, v); + } +} + /* ** Read a 64-bit variable-length integer from memory starting at p[0]. ** Return the number of bytes read. The value is stored in *v. @@ -14968,22 +16583,23 @@ SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){ -#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) \ - || defined(SQLITE_TEST) +#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) /* ** Translate a single byte of Hex into an integer. +** This routinen only works if h really is a valid hexadecimal +** character: 0..9a..fA..F */ static int hexToInt(int h){ - if( h>='0' && h<='9' ){ - return h - '0'; - }else if( h>='a' && h<='f' ){ - return h - 'a' + 10; - }else{ - assert( h>='A' && h<='F' ); - return h - 'A' + 10; - } + assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); +#ifdef SQLITE_ASCII + h += 9*(1&(h>>6)); +#endif +#ifdef SQLITE_EBCDIC + h += 9*(1&~(h>>4)); +#endif + return h & 0xf; } -#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC || SQLITE_TEST */ +#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */ #if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) /* @@ -15038,6 +16654,7 @@ SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ SQLITE_PRIVATE int sqlite3SafetyOn(sqlite3 *db){ if( db->magic==SQLITE_MAGIC_OPEN ){ db->magic = SQLITE_MAGIC_BUSY; + assert( sqlite3_mutex_held(db->mutex) ); return 0; }else if( db->magic==SQLITE_MAGIC_BUSY ){ db->magic = SQLITE_MAGIC_ERROR; @@ -15056,6 +16673,7 @@ SQLITE_PRIVATE int sqlite3SafetyOn(sqlite3 *db){ SQLITE_PRIVATE int sqlite3SafetyOff(sqlite3 *db){ if( db->magic==SQLITE_MAGIC_BUSY ){ db->magic = SQLITE_MAGIC_OPEN; + assert( sqlite3_mutex_held(db->mutex) ); return 0; }else{ db->magic = SQLITE_MAGIC_ERROR; @@ -15113,7 +16731,7 @@ SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ ** This is the implementation of generic hash-tables ** used in SQLite. ** -** $Id: hash.c,v 1.25 2008/01/22 21:30:53 drh Exp $ +** $Id: hash.c,v 1.27 2008/04/02 18:33:08 drh Exp $ */ /* Turn bulk memory into a hash table object by initializing the @@ -15152,7 +16770,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){ assert( pH!=0 ); elem = pH->first; pH->first = 0; - if( pH->ht ) sqlite3_free(pH->ht); + sqlite3_free(pH->ht); pH->ht = 0; pH->htsize = 0; while( elem ){ @@ -15320,7 +16938,12 @@ static void rehash(Hash *pH, int new_size){ HashElem *elem, *next_elem; /* For looping over existing elements */ int (*xHash)(const void*,int); /* The hash function */ - assert( (new_size & (new_size-1))==0 ); +#ifdef SQLITE_MALLOC_SOFT_LIMIT + if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){ + new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht); + } + if( new_size==pH->htsize ) return; +#endif /* There is a call to sqlite3_malloc() inside rehash(). If there is ** already an allocation at pH->ht, then if this malloc() fails it @@ -15332,7 +16955,7 @@ static void rehash(Hash *pH, int new_size){ sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, 0); if( new_ht==0 ) return; - if( pH->ht ) sqlite3_free(pH->ht); + sqlite3_free(pH->ht); pH->ht = new_ht; pH->htsize = new_size; xHash = hashFunction(pH->keyClass); @@ -15423,8 +17046,7 @@ SQLITE_PRIVATE HashElem *sqlite3HashFindElem(const Hash *pH, const void *pKey, i xHash = hashFunction(pH->keyClass); assert( xHash!=0 ); h = (*xHash)(pKey,nKey); - assert( (pH->htsize & (pH->htsize-1))==0 ); - elem = findElementGivenHash(pH,pKey,nKey, h & (pH->htsize-1)); + elem = findElementGivenHash(pH,pKey,nKey, h % pH->htsize); return elem; } @@ -15464,21 +17086,22 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, voi xHash = hashFunction(pH->keyClass); assert( xHash!=0 ); hraw = (*xHash)(pKey, nKey); - assert( (pH->htsize & (pH->htsize-1))==0 ); - h = hraw & (pH->htsize-1); - elem = findElementGivenHash(pH,pKey,nKey,h); - if( elem ){ - void *old_data = elem->data; - if( data==0 ){ - removeElementGivenHash(pH,elem,h); - }else{ - elem->data = data; - if( !pH->copyKey ){ - elem->pKey = (void *)pKey; + if( pH->htsize ){ + h = hraw % pH->htsize; + elem = findElementGivenHash(pH,pKey,nKey,h); + if( elem ){ + void *old_data = elem->data; + if( data==0 ){ + removeElementGivenHash(pH,elem,h); + }else{ + elem->data = data; + if( !pH->copyKey ){ + elem->pKey = (void *)pKey; + } + assert(nKey==elem->nKey); } - assert(nKey==elem->nKey); + return old_data; } - return old_data; } if( data==0 ) return 0; new_elem = (HashElem*)sqlite3_malloc( sizeof(HashElem) ); @@ -15496,7 +17119,7 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, voi new_elem->nKey = nKey; pH->count++; if( pH->htsize==0 ){ - rehash(pH,8); + rehash(pH, 128/sizeof(pH->ht[0])); if( pH->htsize==0 ){ pH->count = 0; if( pH->copyKey ){ @@ -15510,8 +17133,7 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, voi rehash(pH,pH->htsize*2); } assert( pH->htsize>0 ); - assert( (pH->htsize & (pH->htsize-1))==0 ); - h = hraw & (pH->htsize-1); + h = hraw % pH->htsize; insertElement(pH, &pH->ht[h], new_elem); new_elem->data = data; return 0; @@ -15768,16 +17390,16 @@ SQLITE_API unsigned int sqlite3_pending_byte = 0x40000000; #endif #ifdef SQLITE_DEBUG -SQLITE_API int sqlite3_os_trace = 0; -#define OSTRACE1(X) if( sqlite3_os_trace ) sqlite3DebugPrintf(X) -#define OSTRACE2(X,Y) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y) -#define OSTRACE3(X,Y,Z) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z) -#define OSTRACE4(X,Y,Z,A) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A) -#define OSTRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B) +SQLITE_PRIVATE int sqlite3OSTrace = 0; +#define OSTRACE1(X) if( sqlite3OSTrace ) sqlite3DebugPrintf(X) +#define OSTRACE2(X,Y) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y) +#define OSTRACE3(X,Y,Z) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z) +#define OSTRACE4(X,Y,Z,A) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A) +#define OSTRACE5(X,Y,Z,A,B) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A,B) #define OSTRACE6(X,Y,Z,A,B,C) \ - if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C) + if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C) #define OSTRACE7(X,Y,Z,A,B,C,D) \ - if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D) + if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D) #else #define OSTRACE1(X) #define OSTRACE2(X,Y) @@ -15817,19 +17439,22 @@ static unsigned int elapse; ** is used for testing the I/O recovery logic. */ #ifdef SQLITE_TEST -SQLITE_API int sqlite3_io_error_hit = 0; -SQLITE_API int sqlite3_io_error_pending = 0; -SQLITE_API int sqlite3_io_error_persist = 0; +SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ +SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ +SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ +SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ +SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ SQLITE_API int sqlite3_diskfull_pending = 0; SQLITE_API int sqlite3_diskfull = 0; +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) #define SimulateIOError(CODE) \ - if( sqlite3_io_error_pending || sqlite3_io_error_hit ) \ - if( sqlite3_io_error_pending-- == 1 \ - || (sqlite3_io_error_persist && sqlite3_io_error_hit) ) \ - { local_ioerr(); CODE; } + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ + || sqlite3_io_error_pending-- == 1 ) \ + { local_ioerr(); CODE; } static void local_ioerr(){ IOTRACE(("IOERR\n")); - sqlite3_io_error_hit = 1; + sqlite3_io_error_hit++; + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; } #define SimulateDiskfullError(CODE) \ if( sqlite3_diskfull_pending ){ \ @@ -15843,6 +17468,7 @@ static void local_ioerr(){ } \ } #else +#define SimulateIOErrorBenign(X) #define SimulateIOError(A) #define SimulateDiskfullError(A) #endif @@ -15970,15 +17596,10 @@ int os2Write( */ int os2Truncate( sqlite3_file *id, i64 nByte ){ APIRET rc = NO_ERROR; - ULONG filePosition = 0L; os2File *pFile = (os2File*)id; OSTRACE3( "TRUNCATE %d %lld\n", pFile->h, nByte ); SimulateIOError( return SQLITE_IOERR_TRUNCATE ); - rc = DosSetFilePtr( pFile->h, nByte, FILE_BEGIN, &filePosition ); - if( rc != NO_ERROR ){ - return SQLITE_IOERR; - } - rc = DosSetFilePtr( pFile->h, 0L, FILE_END, &filePosition ); + rc = DosSetFileSize( pFile->h, nByte ); return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; } @@ -16101,7 +17722,7 @@ int os2Lock( sqlite3_file *id, int locktype ){ /* If there is already a lock of this type or more restrictive on the ** os2File, do nothing. Don't use the end_lock: exit path, as - ** sqlite3OsEnterMutex() hasn't been called yet. + ** sqlite3_mutex_enter() hasn't been called yet. */ if( pFile->locktype>=locktype ){ OSTRACE3( "LOCK %d %d ok (already held)\n", pFile->h, locktype ); @@ -16232,15 +17853,16 @@ int os2Lock( sqlite3_file *id, int locktype ){ ** non-zero, otherwise zero. */ int os2CheckReservedLock( sqlite3_file *id ){ - APIRET rc = NO_ERROR; + int r = 0; os2File *pFile = (os2File*)id; assert( pFile!=0 ); if( pFile->locktype>=RESERVED_LOCK ){ - rc = 1; - OSTRACE3( "TEST WR-LOCK %d %d (local)\n", pFile->h, rc ); + r = 1; + OSTRACE3( "TEST WR-LOCK %d %d (local)\n", pFile->h, r ); }else{ FILELOCK LockArea, UnlockArea; + APIRET rc = NO_ERROR; memset(&LockArea, 0, sizeof(LockArea)); memset(&UnlockArea, 0, sizeof(UnlockArea)); LockArea.lOffset = RESERVED_BYTE; @@ -16250,17 +17872,18 @@ int os2CheckReservedLock( sqlite3_file *id ){ rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); OSTRACE3( "TEST WR-LOCK %d lock reserved byte rc=%d\n", pFile->h, rc ); if( rc == NO_ERROR ){ - int r; + APIRET rcu = NO_ERROR; /* return code for unlocking */ LockArea.lOffset = 0L; LockArea.lRange = 0L; UnlockArea.lOffset = RESERVED_BYTE; UnlockArea.lRange = 1L; - r = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); - OSTRACE3( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, r ); + rcu = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + OSTRACE3( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, rcu ); } - OSTRACE3( "TEST WR-LOCK %d %d (remote)\n", pFile->h, rc ); + r = !(rc == NO_ERROR); + OSTRACE3( "TEST WR-LOCK %d %d (remote)\n", pFile->h, r ); } - return rc; + return r; } /* @@ -16361,6 +17984,66 @@ static int os2DeviceCharacteristics(sqlite3_file *id){ return 0; } +/* +** Helper function to convert UTF-8 filenames to local OS/2 codepage. +** The two-step process: first convert the incoming UTF-8 string +** into UCS-2 and then from UCS-2 to the current codepage. +** The returned char pointer has to be freed. +*/ +char *convertUtf8PathToCp(const char *in) +{ + UconvObject uconv; + UniChar ucsUtf8Cp[12], + tempPath[CCHMAXPATH]; + char *out; + int rc = 0; + + out = (char *)calloc(CCHMAXPATH, 1); + + /* determine string for the conversion of UTF-8 which is CP1208 */ + rc = UniMapCpToUcsCp(1208, ucsUtf8Cp, 12); + rc = UniCreateUconvObject(ucsUtf8Cp, &uconv); + rc = UniStrToUcs(uconv, tempPath, (char *)in, CCHMAXPATH); + rc = UniFreeUconvObject(uconv); + + /* conversion for current codepage which can be used for paths */ + rc = UniCreateUconvObject((UniChar *)L"@path=yes", &uconv); + rc = UniStrFromUcs(uconv, out, tempPath, CCHMAXPATH); + rc = UniFreeUconvObject(uconv); + + return out; +} + +/* +** Helper function to convert filenames from local codepage to UTF-8. +** The two-step process: first convert the incoming codepage-specific +** string into UCS-2 and then from UCS-2 to the codepage of UTF-8. +** The returned char pointer has to be freed. +*/ +char *convertCpPathToUtf8(const char *in) +{ + UconvObject uconv; + UniChar ucsUtf8Cp[12], + tempPath[CCHMAXPATH]; + char *out; + int rc = 0; + + out = (char *)calloc(CCHMAXPATH, 1); + + /* conversion for current codepage which can be used for paths */ + rc = UniCreateUconvObject((UniChar *)L"@path=yes", &uconv); + rc = UniStrToUcs(uconv, tempPath, (char *)in, CCHMAXPATH); + rc = UniFreeUconvObject(uconv); + + /* determine string for the conversion of UTF-8 which is CP1208 */ + rc = UniMapCpToUcsCp(1208, ucsUtf8Cp, 12); + rc = UniCreateUconvObject(ucsUtf8Cp, &uconv); + rc = UniStrFromUcs(uconv, out, tempPath, CCHMAXPATH); + rc = UniFreeUconvObject(uconv); + + return out; +} + /* ** This vector defines all the methods that can operate on an ** sqlite3_file for os2. @@ -16405,7 +18088,7 @@ static int os2Open( APIRET rc = NO_ERROR; ULONG ulAction; - memset(pFile, 0, sizeof(*pFile)); + memset( pFile, 0, sizeof(*pFile) ); OSTRACE2( "OPEN want %d\n", flags ); @@ -16451,18 +18134,12 @@ static int os2Open( OSTRACE1( "OPEN normal file attribute\n" ); } - //ulOpenMode |= flags & (SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_TEMP_DB) ? - // OPEN_FLAGS_RANDOM : OPEN_FLAGS_SEQUENTIAL; - if( flags & (SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_TEMP_DB) ){ - ulOpenMode |= OPEN_FLAGS_RANDOM; - OSTRACE1( "OPEN random access\n" ); - }else{ - ulOpenMode |= OPEN_FLAGS_SEQUENTIAL; - OSTRACE1( "OPEN sequential access\n" ); - } + /* always open in random access mode for possibly better speed */ + ulOpenMode |= OPEN_FLAGS_RANDOM; ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR; - rc = DosOpen( (PSZ)zName, + char *zNameCp = convertUtf8PathToCp( zName ); + rc = DosOpen( (PSZ)zNameCp, &h, &ulAction, 0L, @@ -16470,6 +18147,7 @@ static int os2Open( ulOpenFlags, ulOpenMode, (PEAOP2)NULL ); + free( zNameCp ); if( rc != NO_ERROR ){ OSTRACE7( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n", rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode ); @@ -16504,7 +18182,9 @@ int os2Delete( ){ APIRET rc = NO_ERROR; SimulateIOError(return SQLITE_IOERR_DELETE); - rc = DosDelete( (PSZ)zFilename ); + char *zFilenameCp = convertUtf8PathToCp( zFilename ); + rc = DosDelete( (PSZ)zFilenameCp ); + free( zFilenameCp ); OSTRACE2( "DELETE \"%s\"\n", zFilename ); return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; } @@ -16520,9 +18200,11 @@ static int os2Access( FILESTATUS3 fsts3ConfigInfo; APIRET rc = NO_ERROR; - memset(&fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo)); - rc = DosQueryPathInfo( (PSZ)zFilename, FIL_STANDARD, + memset( &fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo) ); + char *zFilenameCp = convertUtf8PathToCp( zFilename ); + rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD, &fsts3ConfigInfo, sizeof(FILESTATUS3) ); + free( zFilenameCp ); OSTRACE4( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n", fsts3ConfigInfo.attrFile, flags, rc ); switch( flags ){ @@ -16554,6 +18236,7 @@ static int os2GetTempname( sqlite3_vfs *pVfs, int nBuf, char *zBuf ){ int i, j; char zTempPathBuf[3]; PSZ zTempPath = (PSZ)&zTempPathBuf; + char *zTempPathUTF; if( DosScanEnv( (PSZ)"TEMP", &zTempPath ) ){ if( DosScanEnv( (PSZ)"TMP", &zTempPath ) ){ if( DosScanEnv( (PSZ)"TMPDIR", &zTempPath ) ){ @@ -16570,11 +18253,12 @@ static int os2GetTempname( sqlite3_vfs *pVfs, int nBuf, char *zBuf ){ j--; } zTempPath[j] = '\0'; - assert( nBuf>=pVfs->mxPathname ); - sqlite3_snprintf( pVfs->mxPathname-30, zBuf, - "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath ); + zTempPathUTF = convertCpPathToUtf8( zTempPath ); + sqlite3_snprintf( nBuf-30, zBuf, + "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPathUTF ); + free( zTempPathUTF ); j = strlen( zBuf ); - sqlite3Randomness( 20, &zBuf[j] ); + sqlite3_randomness( 20, &zBuf[j] ); for( i = 0; i < 20; i++, j++ ){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } @@ -16595,24 +18279,16 @@ static int os2FullPathname( int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ - if( strchr(zRelative, ':') ){ - sqlite3_snprintf( nFull, zFull, "%s", zRelative ); - }else{ - ULONG ulDriveNum = 0; - ULONG ulDriveMap = 0; - ULONG cbzBufLen = SQLITE_TEMPNAME_SIZE; - char *zBuff = (char*)malloc( cbzBufLen ); - if( zBuff == 0 ){ - return SQLITE_NOMEM; - } - DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ); - if( DosQueryCurrentDir( ulDriveNum, (PBYTE)zBuff, &cbzBufLen ) == NO_ERROR ){ - sqlite3_snprintf( nFull, zFull, "%c:\\%s\\%s", - (char)('A' + ulDriveNum - 1), zBuff, zRelative); - } - free( zBuff ); - } - return SQLITE_OK; + char *zRelativeCp = convertUtf8PathToCp( zRelative ); + char zFullCp[CCHMAXPATH]; + char *zFullUTF; + APIRET rc = DosQueryPathInfo( zRelativeCp, FIL_QUERYFULLNAME, zFullCp, + CCHMAXPATH ); + free( zRelativeCp ); + zFullUTF = convertCpPathToUtf8( zFullCp ); + sqlite3_snprintf( nFull, zFull, zFullUTF ); + free( zFullUTF ); + return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; } #ifndef SQLITE_OMIT_LOAD_EXTENSION @@ -16628,7 +18304,9 @@ static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){ UCHAR loadErr[256]; HMODULE hmod; APIRET rc; - rc = DosLoadModule((PSZ)loadErr, sizeof(loadErr), zFilename, &hmod); + char *zFilenameCp = convertUtf8PathToCp(zFilename); + rc = DosLoadModule((PSZ)loadErr, sizeof(loadErr), zFilenameCp, &hmod); + free(zFilenameCp); return rc != NO_ERROR ? 0 : (void*)hmod; } /* @@ -16962,16 +18640,16 @@ SQLITE_API unsigned int sqlite3_pending_byte = 0x40000000; #endif #ifdef SQLITE_DEBUG -SQLITE_API int sqlite3_os_trace = 0; -#define OSTRACE1(X) if( sqlite3_os_trace ) sqlite3DebugPrintf(X) -#define OSTRACE2(X,Y) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y) -#define OSTRACE3(X,Y,Z) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z) -#define OSTRACE4(X,Y,Z,A) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A) -#define OSTRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B) +SQLITE_PRIVATE int sqlite3OSTrace = 0; +#define OSTRACE1(X) if( sqlite3OSTrace ) sqlite3DebugPrintf(X) +#define OSTRACE2(X,Y) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y) +#define OSTRACE3(X,Y,Z) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z) +#define OSTRACE4(X,Y,Z,A) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A) +#define OSTRACE5(X,Y,Z,A,B) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A,B) #define OSTRACE6(X,Y,Z,A,B,C) \ - if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C) + if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C) #define OSTRACE7(X,Y,Z,A,B,C,D) \ - if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D) + if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D) #else #define OSTRACE1(X) #define OSTRACE2(X,Y) @@ -17011,19 +18689,22 @@ static unsigned int elapse; ** is used for testing the I/O recovery logic. */ #ifdef SQLITE_TEST -SQLITE_API int sqlite3_io_error_hit = 0; -SQLITE_API int sqlite3_io_error_pending = 0; -SQLITE_API int sqlite3_io_error_persist = 0; +SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ +SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ +SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ +SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ +SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ SQLITE_API int sqlite3_diskfull_pending = 0; SQLITE_API int sqlite3_diskfull = 0; +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) #define SimulateIOError(CODE) \ - if( sqlite3_io_error_pending || sqlite3_io_error_hit ) \ - if( sqlite3_io_error_pending-- == 1 \ - || (sqlite3_io_error_persist && sqlite3_io_error_hit) ) \ - { local_ioerr(); CODE; } + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ + || sqlite3_io_error_pending-- == 1 ) \ + { local_ioerr(); CODE; } static void local_ioerr(){ IOTRACE(("IOERR\n")); - sqlite3_io_error_hit = 1; + sqlite3_io_error_hit++; + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; } #define SimulateDiskfullError(CODE) \ if( sqlite3_diskfull_pending ){ \ @@ -17037,6 +18718,7 @@ static void local_ioerr(){ } \ } #else +#define SimulateIOErrorBenign(X) #define SimulateIOError(A) #define SimulateDiskfullError(A) #endif @@ -17299,12 +18981,12 @@ static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0}; ** file systems that are known to be unsupported */ typedef enum { - posixLockingStyle = 0, /* standard posix-advisory locks */ - afpLockingStyle, /* use afp locks */ - flockLockingStyle, /* use flock() */ - dotlockLockingStyle, /* use .lock files */ - noLockingStyle, /* useful for read-only file system */ - unsupportedLockingStyle /* indicates unsupported file system */ + posixLockingStyle = 0, /* standard posix-advisory locks */ + afpLockingStyle, /* use afp locks */ + flockLockingStyle, /* use flock() */ + dotlockLockingStyle, /* use .lock files */ + noLockingStyle, /* useful for read-only file system */ + unsupportedLockingStyle /* indicates unsupported file system */ } sqlite3LockingStyle; #endif /* SQLITE_ENABLE_LOCKING_STYLE */ @@ -17528,31 +19210,31 @@ static sqlite3LockingStyle sqlite3DetectLockingStyle( #else struct statfs fsInfo; - if (statfs(filePath, &fsInfo) == -1) + if( statfs(filePath, &fsInfo) == -1 ){ return sqlite3TestLockingStyle(filePath, fd); - - if (fsInfo.f_flags & MNT_RDONLY) + } + if( fsInfo.f_flags & MNT_RDONLY ){ return noLockingStyle; - - if( (!strcmp(fsInfo.f_fstypename, "hfs")) || - (!strcmp(fsInfo.f_fstypename, "ufs")) ) - return posixLockingStyle; - - if(!strcmp(fsInfo.f_fstypename, "afpfs")) + } + if( strcmp(fsInfo.f_fstypename, "hfs")==0 || + strcmp(fsInfo.f_fstypename, "ufs")==0 ){ + return posixLockingStyle; + } + if( strcmp(fsInfo.f_fstypename, "afpfs")==0 ){ return afpLockingStyle; - - if(!strcmp(fsInfo.f_fstypename, "nfs")) + } + if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){ return sqlite3TestLockingStyle(filePath, fd); - - if(!strcmp(fsInfo.f_fstypename, "smbfs")) + } + if( strcmp(fsInfo.f_fstypename, "smbfs")==0 ){ return flockLockingStyle; - - if(!strcmp(fsInfo.f_fstypename, "msdos")) + } + if( strcmp(fsInfo.f_fstypename, "msdos")==0 ){ return dotlockLockingStyle; - - if(!strcmp(fsInfo.f_fstypename, "webdav")) + } + if( strcmp(fsInfo.f_fstypename, "webdav")==0 ){ return unsupportedLockingStyle; - + } return sqlite3TestLockingStyle(filePath, fd); #endif /* SQLITE_FIXED_LOCKING_STYLE */ } @@ -18273,6 +19955,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){ struct flock lock; int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; + int h; assert( pFile ); OSTRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", pFile->h, locktype, @@ -18286,17 +19969,20 @@ static int unixUnlock(sqlite3_file *id, int locktype){ return SQLITE_MISUSE; } enterMutex(); + h = pFile->h; pLock = pFile->pLock; assert( pLock->cnt!=0 ); if( pFile->locktype>SHARED_LOCK ){ assert( pLock->locktype==pFile->locktype ); + SimulateIOErrorBenign(1); + SimulateIOError( h=(-1) ) + SimulateIOErrorBenign(0); if( locktype==SHARED_LOCK ){ lock.l_type = F_RDLCK; lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; - if( fcntl(pFile->h, F_SETLK, &lock)==(-1) ){ - /* This should never happen */ + if( fcntl(h, F_SETLK, &lock)==(-1) ){ rc = SQLITE_IOERR_RDLOCK; } } @@ -18304,10 +19990,10 @@ static int unixUnlock(sqlite3_file *id, int locktype){ lock.l_whence = SEEK_SET; lock.l_start = PENDING_BYTE; lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); - if( fcntl(pFile->h, F_SETLK, &lock)!=(-1) ){ + if( fcntl(h, F_SETLK, &lock)!=(-1) ){ pLock->locktype = SHARED_LOCK; }else{ - rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ + rc = SQLITE_IOERR_UNLOCK; } } if( locktype==NO_LOCK ){ @@ -18322,10 +20008,14 @@ static int unixUnlock(sqlite3_file *id, int locktype){ lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = lock.l_len = 0L; - if( fcntl(pFile->h, F_SETLK, &lock)!=(-1) ){ + SimulateIOErrorBenign(1); + SimulateIOError( h=(-1) ) + SimulateIOErrorBenign(0); + if( fcntl(h, F_SETLK, &lock)!=(-1) ){ pLock->locktype = NO_LOCK; }else{ - rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ + rc = SQLITE_IOERR_UNLOCK; + pLock->cnt = 1; } } @@ -18333,21 +20023,23 @@ static int unixUnlock(sqlite3_file *id, int locktype){ ** count reaches zero, close any other file descriptors whose close ** was deferred because of outstanding locks. */ - pOpen = pFile->pOpen; - pOpen->nLock--; - assert( pOpen->nLock>=0 ); - if( pOpen->nLock==0 && pOpen->nPending>0 ){ - int i; - for(i=0; inPending; i++){ - close(pOpen->aPending[i]); + 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; inPending; i++){ + close(pOpen->aPending[i]); + } + free(pOpen->aPending); + pOpen->nPending = 0; + pOpen->aPending = 0; } - free(pOpen->aPending); - pOpen->nPending = 0; - pOpen->aPending = 0; } } leaveMutex(); - pFile->locktype = locktype; + if( rc==SQLITE_OK ) pFile->locktype = locktype; return rc; } @@ -18402,7 +20094,7 @@ static int unixClose(sqlite3_file *id){ typedef struct afpLockingContext afpLockingContext; struct afpLockingContext { unsigned long long sharedLockByte; - char *filePath; + const char *filePath; }; struct ByteRangeLockPB2 @@ -18489,8 +20181,7 @@ static int afpUnixCheckReservedLock(sqlite3_file *id){ /* AFP-style locking following the behavior of unixLock, see the unixLock ** function comments for details of lock management. */ -static int afpUnixLock(sqlite3_file *id, int locktype) -{ +static int afpUnixLock(sqlite3_file *id, int locktype){ int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; @@ -18498,11 +20189,12 @@ static int afpUnixLock(sqlite3_file *id, int locktype) assert( pFile ); OSTRACE5("LOCK %d %s was %s pid=%d\n", pFile->h, - locktypeName(locktype), locktypeName(pFile->locktype), getpid()); + locktypeName(locktype), locktypeName(pFile->locktype), getpid()); + /* If there is already a lock of this type or more restrictive on the - ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as - ** enterMutex() hasn't been called yet. - */ + ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as + ** enterMutex() hasn't been called yet. + */ if( pFile->locktype>=locktype ){ OSTRACE3("LOCK %d %s ok (already held)\n", pFile->h, locktypeName(locktype)); @@ -18510,17 +20202,17 @@ static int afpUnixLock(sqlite3_file *id, int locktype) } /* Make sure the locking sequence is correct - */ + */ assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); assert( locktype!=PENDING_LOCK ); assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); /* This mutex is needed because pFile->pLock is shared across threads - */ + */ enterMutex(); /* Make sure the current thread owns the pFile. - */ + */ rc = transferOwnership(pFile); if( rc!=SQLITE_OK ){ leaveMutex(); @@ -18528,14 +20220,14 @@ static int afpUnixLock(sqlite3_file *id, int locktype) } /* A PENDING lock is needed before acquiring a SHARED lock and before - ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will - ** be released. - */ + ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will + ** be released. + */ if( locktype==SHARED_LOCK || (locktype==EXCLUSIVE_LOCK && pFile->locktypefilePath, pFile->h, - PENDING_BYTE, 1, 1); + ){ + int failed; + failed = _AFPFSSetLock(context->filePath, pFile->h, PENDING_BYTE, 1, 1); if (failed) { rc = SQLITE_BUSY; goto afp_end_lock; @@ -18543,8 +20235,8 @@ static int afpUnixLock(sqlite3_file *id, int locktype) } /* If control gets to this point, then actually go ahead and make - ** operating system calls for the specified lock. - */ + ** operating system calls for the specified lock. + */ if( locktype==SHARED_LOCK ){ int lk, failed; int tries = 0; @@ -18610,19 +20302,19 @@ static int afpUnixLock(sqlite3_file *id, int locktype) } afp_end_lock: - leaveMutex(); + leaveMutex(); OSTRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype), rc==SQLITE_OK ? "ok" : "failed"); return rc; } /* - ** Lower the locking level on file descriptor pFile to locktype. locktype - ** must be either NO_LOCK or SHARED_LOCK. - ** - ** If the locking level of the file descriptor is already at or below - ** the requested locking level, this routine is a no-op. - */ +** Lower the locking level on file descriptor pFile to locktype. locktype +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ static int afpUnixUnlock(sqlite3_file *id, int locktype) { struct flock lock; int rc = SQLITE_OK; @@ -18689,25 +20381,22 @@ static int afpUnixUnlock(sqlite3_file *id, int locktype) { } /* - ** Close a file & cleanup AFP specific locking context - */ +** Close a file & cleanup AFP specific locking context +*/ static int afpUnixClose(sqlite3_file *id) { - unixFile *pFile = (unixFile*)pId; + unixFile *pFile = (unixFile*)id; if( !pFile ) return SQLITE_OK; - afpUnixUnlock(*pId, NO_LOCK); - /* free the AFP locking structure */ - if (pFile->lockingContext != NULL) { - if (((afpLockingContext *)pFile->lockingContext)->filePath != NULL) - sqlite3_free(((afpLockingContext*)pFile->lockingContext)->filePath); - sqlite3_free(pFile->lockingContext); - } - + afpUnixUnlock(id, NO_LOCK); + sqlite3_free(pFile->lockingContext); if( pFile->dirfd>=0 ) close(pFile->dirfd); pFile->dirfd = -1; + enterMutex(); close(pFile->h); + leaveMutex(); OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); + memset(pFile, 0, sizeof(unixFile)); return SQLITE_OK; } @@ -18715,11 +20404,11 @@ static int afpUnixClose(sqlite3_file *id) { #pragma mark flock() style locking /* - ** The flockLockingContext is not used - */ +** The flockLockingContext is not used +*/ typedef void flockLockingContext; -static int flockUnixCheckReservedLock(sqlite3_file *id) { +static int flockUnixCheckReservedLock(sqlite3_file *id){ unixFile *pFile = (unixFile*)id; if (pFile->locktype == RESERVED_LOCK) { @@ -18785,31 +20474,32 @@ static int flockUnixUnlock(sqlite3_file *id, int locktype) { } /* - ** Close a file. - */ -static int flockUnixClose(sqlite3_file *pId) { - unixFile *pFile = (unixFile*)*pId; +** Close a file. +*/ +static int flockUnixClose(sqlite3_file *id) { + unixFile *pFile = (unixFile*)id; if( !pFile ) return SQLITE_OK; - flockUnixUnlock(*pId, NO_LOCK); + flockUnixUnlock(id, NO_LOCK); if( pFile->dirfd>=0 ) close(pFile->dirfd); pFile->dirfd = -1; + enterMutex(); - close(pFile->h); leaveMutex(); OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); + memset(pFile, 0, sizeof(unixFile)); return SQLITE_OK; } #pragma mark Old-School .lock file based locking /* - ** The dotlockLockingContext structure contains all dotlock (.lock) lock - ** specific state - */ +** The dotlockLockingContext structure contains all dotlock (.lock) lock +** specific state +*/ typedef struct dotlockLockingContext dotlockLockingContext; struct dotlockLockingContext { char *lockPath; @@ -18818,26 +20508,29 @@ struct dotlockLockingContext { static int dotlockUnixCheckReservedLock(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; - dotlockLockingContext *context = - (dotlockLockingContext *) pFile->lockingContext; - + dotlockLockingContext *context; + + context = (dotlockLockingContext*)pFile->lockingContext; if (pFile->locktype == RESERVED_LOCK) { return 1; /* already have a reserved lock */ } else { struct stat statBuf; - if (lstat(context->lockPath,&statBuf) == 0) + if (lstat(context->lockPath,&statBuf) == 0){ /* file exists, someone else has the lock */ return 1; - else + }else{ /* file does not exist, we could have it if we want it */ return 0; + } } } static int dotlockUnixLock(sqlite3_file *id, int locktype) { unixFile *pFile = (unixFile*)id; - dotlockLockingContext *context = - (dotlockLockingContext *) pFile->lockingContext; + dotlockLockingContext *context; + int fd; + + context = (dotlockLockingContext*)pFile->lockingContext; /* if we already have a lock, it is exclusive. ** Just adjust level and punt on outta here. */ @@ -18856,8 +20549,8 @@ static int dotlockUnixLock(sqlite3_file *id, int locktype) { } /* grab an exclusive lock */ - int fd = open(context->lockPath,O_RDONLY|O_CREAT|O_EXCL,0600); - if (fd < 0) { + fd = open(context->lockPath,O_RDONLY|O_CREAT|O_EXCL,0600); + if( fd<0 ){ /* failed to open/create the file, someone else may have stolen the lock */ return SQLITE_BUSY; } @@ -18870,8 +20563,9 @@ static int dotlockUnixLock(sqlite3_file *id, int locktype) { static int dotlockUnixUnlock(sqlite3_file *id, int locktype) { unixFile *pFile = (unixFile*)id; - dotlockLockingContext *context = - (dotlockLockingContext *) pFile->lockingContext; + dotlockLockingContext *context; + + context = (dotlockLockingContext*)pFile->lockingContext; assert( locktype<=SHARED_LOCK ); @@ -18899,24 +20593,16 @@ static int dotlockUnixClose(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; if( !pFile ) return SQLITE_OK; - dotlockUnixUnlock(*pId, NO_LOCK); - /* free the dotlock locking structure */ - if (pFile->lockingContext != NULL) { - if (((dotlockLockingContext *)pFile->lockingContext)->lockPath != NULL) - sqlite3_free( ( (dotlockLockingContext *) - pFile->lockingContext)->lockPath); - sqlite3_free(pFile->lockingContext); - } - + dotlockUnixUnlock(id, NO_LOCK); + sqlite3_free(pFile->lockingContext); if( pFile->dirfd>=0 ) close(pFile->dirfd); pFile->dirfd = -1; - enterMutex(); - + enterMutex(); close(pFile->h); - leaveMutex(); OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); + memset(pFile, 0, sizeof(unixFile)); return SQLITE_OK; } @@ -18924,8 +20610,8 @@ static int dotlockUnixClose(sqlite3_file *id) { #pragma mark No locking /* - ** The nolockLockingContext is void - */ +** The nolockLockingContext is void +*/ typedef void nolockLockingContext; static int nolockUnixCheckReservedLock(sqlite3_file *id) { @@ -18941,8 +20627,8 @@ static int nolockUnixUnlock(sqlite3_file *id, int locktype) { } /* - ** Close a file. - */ +** Close a file. +*/ static int nolockUnixClose(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; @@ -18950,12 +20636,11 @@ static int nolockUnixClose(sqlite3_file *id) { if( pFile->dirfd>=0 ) close(pFile->dirfd); pFile->dirfd = -1; enterMutex(); - close(pFile->h); - leaveMutex(); OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); + memset(pFile, 0, sizeof(unixFile)); return SQLITE_OK; } @@ -19023,7 +20708,7 @@ static const sqlite3_io_methods sqlite3UnixIoMethod = { */ static const sqlite3_io_methods sqlite3AFPLockingUnixIoMethod = { 1, /* iVersion */ - unixClose, + afpUnixClose, unixRead, unixWrite, unixTruncate, @@ -19079,7 +20764,7 @@ static const sqlite3_io_methods sqlite3DotlockLockingUnixIoMethod = { /* ** This vector defines all the methods that can operate on an sqlite3_file -** for unix with dotlock style file locking. +** for unix with nolock style file locking. */ static const sqlite3_io_methods sqlite3NolockLockingUnixIoMethod = { 1, /* iVersion */ @@ -19114,22 +20799,25 @@ static const sqlite3_io_methods sqlite3NolockLockingUnixIoMethod = { static int fillInUnixFile( int h, /* Open file descriptor of file being opened */ int dirfd, /* Directory file descriptor */ - sqlite3_file *pId, /* Write completed initialization here */ - const char *zFilename, /* Name of the file being opened */ + sqlite3_file *pId, /* Write to the unixFile structure here */ + const char *zFilename /* Name of the file being opened */ ){ sqlite3LockingStyle lockingStyle; unixFile *pNew = (unixFile *)pId; int rc; - memset(pNew, 0, sizeof(unixFile)); +#ifdef FD_CLOEXEC + fcntl(h, F_SETFD, fcntl(h, F_GETFD, 0) | FD_CLOEXEC); +#endif + lockingStyle = sqlite3DetectLockingStyle(zFilename, h); - if ( lockingStyle == posixLockingStyle ) { + if ( lockingStyle==posixLockingStyle ){ enterMutex(); rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen); leaveMutex(); if( rc ){ + if( dirfd>=0 ) close(dirfd); close(h); - unlink(zFilename); return SQLITE_NOMEM; } } else { @@ -19137,65 +20825,67 @@ static int fillInUnixFile( pNew->pLock = NULL; pNew->pOpen = NULL; } + + OSTRACE3("OPEN %-3d %s\n", h, zFilename); pNew->dirfd = -1; pNew->h = h; + pNew->dirfd = dirfd; SET_THREADID(pNew); - pNew = sqlite3_malloc( sizeof(unixFile) ); - if( pNew==0 ){ - close(h); - enterMutex(); - releaseLockInfo(pNew->pLock); - releaseOpenCnt(pNew->pOpen); - leaveMutex(); - return SQLITE_NOMEM; - }else{ - switch(lockingStyle) { - case afpLockingStyle: { - /* afp locking uses the file path so it needs to be included in - ** the afpLockingContext */ - int nFilename; - pNew->pMethod = &sqlite3AFPLockingUnixIoMethod; - pNew->lockingContext = - sqlite3_malloc(sizeof(afpLockingContext)); - nFilename = strlen(zFilename)+1; - ((afpLockingContext *)pNew->lockingContext)->filePath = - sqlite3_malloc(nFilename); - memcpy(((afpLockingContext *)pNew->lockingContext)->filePath, - zFilename, nFilename); - srandomdev(); - break; + + switch(lockingStyle) { + case afpLockingStyle: { + /* afp locking uses the file path so it needs to be included in + ** the afpLockingContext */ + afpLockingContext *context; + pNew->pMethod = &sqlite3AFPLockingUnixIoMethod; + pNew->lockingContext = context = sqlite3_malloc( sizeof(*context) ); + if( context==0 ){ + close(h); + if( dirfd>=0 ) close(dirfd); + return SQLITE_NOMEM; } - case flockLockingStyle: - /* flock locking doesn't need additional lockingContext information */ - pNew->pMethod = &sqlite3FlockLockingUnixIoMethod; - break; - case dotlockLockingStyle: { - /* dotlock locking uses the file path so it needs to be included in - ** the dotlockLockingContext */ - int nFilename; - pNew->pMethod = &sqlite3DotlockLockingUnixIoMethod; - pNew->lockingContext = sqlite3_malloc( - sizeof(dotlockLockingContext)); - nFilename = strlen(zFilename) + 6; - ((dotlockLockingContext *)pNew->lockingContext)->lockPath = - sqlite3_malloc( nFilename ); - sqlite3_snprintf(nFilename, - ((dotlockLockingContext *)pNew->lockingContext)->lockPath, - "%s.lock", zFilename); - break; - } - case posixLockingStyle: - /* posix locking doesn't need additional lockingContext information */ - pNew->pMethod = &sqlite3UnixIoMethod; - break; - case noLockingStyle: - case unsupportedLockingStyle: - default: - pNew->pMethod = &sqlite3NolockLockingUnixIoMethod; + + /* NB: zFilename exists and remains valid until the file is closed + ** according to requirement F11141. So we do not need to make a + ** copy of the filename. */ + context->filePath = zFilename; + srandomdev(); + break; } - OpenCounter(+1); - return SQLITE_OK; + case flockLockingStyle: + /* flock locking doesn't need additional lockingContext information */ + pNew->pMethod = &sqlite3FlockLockingUnixIoMethod; + break; + case dotlockLockingStyle: { + /* dotlock locking uses the file path so it needs to be included in + ** the dotlockLockingContext */ + dotlockLockingContext *context; + int nFilename; + nFilename = strlen(zFilename); + pNew->pMethod = &sqlite3DotlockLockingUnixIoMethod; + pNew->lockingContext = context = + sqlite3_malloc( sizeof(*context) + nFilename + 6 ); + if( context==0 ){ + close(h); + if( dirfd>=0 ) close(dirfd); + return SQLITE_NOMEM; + } + context->lockPath = (char*)&context[1]; + sqlite3_snprintf(nFilename, context->lockPath, + "%s.lock", zFilename); + break; + } + case posixLockingStyle: + /* posix locking doesn't need additional lockingContext information */ + pNew->pMethod = &sqlite3UnixIoMethod; + break; + case noLockingStyle: + case unsupportedLockingStyle: + default: + pNew->pMethod = &sqlite3NolockLockingUnixIoMethod; } + OpenCounter(+1); + return SQLITE_OK; } #else /* SQLITE_ENABLE_LOCKING_STYLE */ static int fillInUnixFile( @@ -19466,7 +21156,7 @@ static int unixGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ assert( pVfs->mxPathname==MAX_PATHNAME ); sqlite3_snprintf(nBuf-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir); j = strlen(zBuf); - sqlite3Randomness(15, &zBuf[j]); + sqlite3_randomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } @@ -19806,16 +21496,16 @@ SQLITE_API unsigned int sqlite3_pending_byte = 0x40000000; #endif #ifdef SQLITE_DEBUG -SQLITE_API int sqlite3_os_trace = 0; -#define OSTRACE1(X) if( sqlite3_os_trace ) sqlite3DebugPrintf(X) -#define OSTRACE2(X,Y) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y) -#define OSTRACE3(X,Y,Z) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z) -#define OSTRACE4(X,Y,Z,A) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A) -#define OSTRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B) +SQLITE_PRIVATE int sqlite3OSTrace = 0; +#define OSTRACE1(X) if( sqlite3OSTrace ) sqlite3DebugPrintf(X) +#define OSTRACE2(X,Y) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y) +#define OSTRACE3(X,Y,Z) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z) +#define OSTRACE4(X,Y,Z,A) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A) +#define OSTRACE5(X,Y,Z,A,B) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A,B) #define OSTRACE6(X,Y,Z,A,B,C) \ - if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C) + if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C) #define OSTRACE7(X,Y,Z,A,B,C,D) \ - if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D) + if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D) #else #define OSTRACE1(X) #define OSTRACE2(X,Y) @@ -19855,19 +21545,22 @@ static unsigned int elapse; ** is used for testing the I/O recovery logic. */ #ifdef SQLITE_TEST -SQLITE_API int sqlite3_io_error_hit = 0; -SQLITE_API int sqlite3_io_error_pending = 0; -SQLITE_API int sqlite3_io_error_persist = 0; +SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ +SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ +SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ +SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ +SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ SQLITE_API int sqlite3_diskfull_pending = 0; SQLITE_API int sqlite3_diskfull = 0; +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) #define SimulateIOError(CODE) \ - if( sqlite3_io_error_pending || sqlite3_io_error_hit ) \ - if( sqlite3_io_error_pending-- == 1 \ - || (sqlite3_io_error_persist && sqlite3_io_error_hit) ) \ - { local_ioerr(); CODE; } + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ + || sqlite3_io_error_pending-- == 1 ) \ + { local_ioerr(); CODE; } static void local_ioerr(){ IOTRACE(("IOERR\n")); - sqlite3_io_error_hit = 1; + sqlite3_io_error_hit++; + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; } #define SimulateDiskfullError(CODE) \ if( sqlite3_diskfull_pending ){ \ @@ -19881,6 +21574,7 @@ static void local_ioerr(){ } \ } #else +#define SimulateIOErrorBenign(X) #define SimulateIOError(A) #define SimulateDiskfullError(A) #endif @@ -20443,9 +22137,17 @@ static int winClose(sqlite3_file *id){ rc = CloseHandle(pFile->h); }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); #if OS_WINCE +#define WINCE_DELETION_ATTEMPTS 3 winceDestroyLock(pFile); if( pFile->zDeleteOnClose ){ - DeleteFileW(pFile->zDeleteOnClose); + int cnt = 0; + while( + DeleteFileW(pFile->zDeleteOnClose)==0 + && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff + && cnt++ < WINCE_DELETION_ATTEMPTS + ){ + Sleep(100); /* Wait a little before trying again */ + } free(pFile->zDeleteOnClose); } #endif @@ -20609,7 +22311,7 @@ static int getReadLock(winFile *pFile){ 0, SHARED_SIZE, 0, &ovlp); }else{ int lk; - sqlite3Randomness(sizeof(lk), &lk); + sqlite3_randomness(sizeof(lk), &lk); pFile->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1); res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); } @@ -21143,7 +22845,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ sqlite3_snprintf(nBuf-30, zBuf, "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); j = strlen(zBuf); - sqlite3Randomness(20, &zBuf[j]); + sqlite3_randomness(20, &zBuf[j]); for(i=0; i<20; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } @@ -21394,6 +23096,333 @@ SQLITE_PRIVATE sqlite3_vfs *sqlite3OsDefaultVfs(void){ #endif /* OS_WIN */ /************** End of os_win.c **********************************************/ +/************** Begin file bitvec.c ******************************************/ +/* +** 2008 February 16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements an object that represents a fixed-length +** bitmap. Bits are numbered starting with 1. +** +** A bitmap is used to record what pages a database file have been +** journalled during a transaction. Usually only a few pages are +** journalled. So the bitmap is usually sparse and has low cardinality. +** But sometimes (for example when during a DROP of a large table) most +** or all of the pages get journalled. In those cases, the bitmap becomes +** dense. The algorithm needs to handle both cases well. +** +** The size of the bitmap is fixed when the object is created. +** +** All bits are clear when the bitmap is created. Individual bits +** may be set or cleared one at a time. +** +** Test operations are about 100 times more common that set operations. +** Clear operations are exceedingly rare. There are usually between +** 5 and 500 set operations per Bitvec object, though the number of sets can +** sometimes grow into tens of thousands or larger. The size of the +** 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.4 2008/04/14 01:00:58 drh Exp $ +*/ + +#define BITVEC_SZ 512 +/* Round the union size down to the nearest pointer boundary, since that's how +** it will be aligned within the Bitvec struct. */ +#define BITVEC_USIZE (((BITVEC_SZ-12)/sizeof(Bitvec*))*sizeof(Bitvec*)) +#define BITVEC_NCHAR BITVEC_USIZE +#define BITVEC_NBIT (BITVEC_NCHAR*8) +#define BITVEC_NINT (BITVEC_USIZE/4) +#define BITVEC_MXHASH (BITVEC_NINT/2) +#define BITVEC_NPTR (BITVEC_USIZE/sizeof(Bitvec *)) + +#define BITVEC_HASH(X) (((X)*37)%BITVEC_NINT) + +/* +** A bitmap is an instance of the following structure. +** +** This bitmap records the existance of zero or more bits +** with values between 1 and iSize, inclusive. +** +** There are three possible representations of the bitmap. +** If iSize<=BITVEC_NBIT, then Bitvec.u.aBitmap[] is a straight +** bitmap. The least significant bit is bit 1. +** +** If iSize>BITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is +** a hash table that will hold up to BITVEC_MXHASH distinct values. +** +** Otherwise, the value i is redirected into one of BITVEC_NPTR +** sub-bitmaps pointed to by Bitvec.u.apSub[]. Each subbitmap +** handles up to iDivisor separate values of i. apSub[0] holds +** values between 1 and iDivisor. apSub[1] holds values between +** iDivisor+1 and 2*iDivisor. apSub[N] holds values between +** N*iDivisor+1 and (N+1)*iDivisor. Each subbitmap is normalized +** to hold deal with values between 1 and iDivisor. +*/ +struct Bitvec { + u32 iSize; /* Maximum bit index */ + u32 nSet; /* Number of bits that are set */ + u32 iDivisor; /* Number of bits handled by each apSub[] entry */ + union { + u8 aBitmap[BITVEC_NCHAR]; /* Bitmap representation */ + u32 aHash[BITVEC_NINT]; /* Hash table representation */ + Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */ + } u; +}; + +/* +** Create a new bitmap object able to handle bits between 0 and iSize, +** inclusive. Return a pointer to the new object. Return NULL if +** malloc fails. +*/ +SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){ + Bitvec *p; + assert( sizeof(*p)==BITVEC_SZ ); + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ + p->iSize = iSize; + } + return p; +} + +/* +** Check to see if the i-th bit is set. Return true or false. +** If p is NULL (if the bitmap has not been created) or if +** i is out of range, then return false. +*/ +SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){ + if( p==0 ) return 0; + if( i>p->iSize || i==0 ) return 0; + if( p->iSize<=BITVEC_NBIT ){ + i--; + return (p->u.aBitmap[i/8] & (1<<(i&7)))!=0; + } + if( p->iDivisor>0 ){ + u32 bin = (i-1)/p->iDivisor; + i = (i-1)%p->iDivisor + 1; + return sqlite3BitvecTest(p->u.apSub[bin], i); + }else{ + u32 h = BITVEC_HASH(i); + while( p->u.aHash[h] ){ + if( p->u.aHash[h]==i ) return 1; + h++; + if( h>=BITVEC_NINT ) h = 0; + } + return 0; + } +} + +/* +** Set the i-th bit. Return 0 on success and an error code if +** anything goes wrong. +*/ +SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){ + u32 h; + assert( p!=0 ); + assert( i>0 ); + assert( i<=p->iSize ); + if( p->iSize<=BITVEC_NBIT ){ + i--; + p->u.aBitmap[i/8] |= 1 << (i&7); + return SQLITE_OK; + } + if( p->iDivisor ){ + u32 bin = (i-1)/p->iDivisor; + i = (i-1)%p->iDivisor + 1; + if( p->u.apSub[bin]==0 ){ + sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, 1); + p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor ); + sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, 0); + if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM; + } + return sqlite3BitvecSet(p->u.apSub[bin], i); + } + h = BITVEC_HASH(i); + while( p->u.aHash[h] ){ + if( p->u.aHash[h]==i ) return SQLITE_OK; + h++; + if( h==BITVEC_NINT ) h = 0; + } + p->nSet++; + if( p->nSet>=BITVEC_MXHASH ){ + int j, rc; + u32 aiValues[BITVEC_NINT]; + memcpy(aiValues, p->u.aHash, sizeof(aiValues)); + memset(p->u.apSub, 0, sizeof(p->u.apSub[0])*BITVEC_NPTR); + p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; + rc = sqlite3BitvecSet(p, i); + for(j=0; ju.aHash[h] = i; + return SQLITE_OK; +} + +/* +** Clear the i-th bit. Return 0 on success and an error code if +** anything goes wrong. +*/ +SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i){ + assert( p!=0 ); + assert( i>0 ); + if( p->iSize<=BITVEC_NBIT ){ + i--; + p->u.aBitmap[i/8] &= ~(1 << (i&7)); + }else if( p->iDivisor ){ + u32 bin = (i-1)/p->iDivisor; + i = (i-1)%p->iDivisor + 1; + if( p->u.apSub[bin] ){ + sqlite3BitvecClear(p->u.apSub[bin], i); + } + }else{ + int j; + u32 aiValues[BITVEC_NINT]; + memcpy(aiValues, p->u.aHash, sizeof(aiValues)); + memset(p->u.aHash, 0, sizeof(p->u.aHash[0])*BITVEC_NINT); + p->nSet = 0; + for(j=0; jiDivisor ){ + int i; + for(i=0; iu.apSub[i]); + } + } + sqlite3_free(p); +} + +#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>3] |= (1<<(I&7)) +#define CLEARBIT(V,I) V[I>>3] &= ~(1<<(I&7)) +#define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 + +/* +** This routine runs an extensive test of the Bitvec code. +** +** The input is an array of integers that acts as a program +** to test the Bitvec. The integers are opcodes followed +** by 0, 1, or 3 operands, depending on the opcode. Another +** opcode follows immediately after the last operand. +** +** There are 6 opcodes numbered from 0 through 5. 0 is the +** "halt" opcode and causes the test to end. +** +** 0 Halt and return the number of errors +** 1 N S X Set N bits beginning with S and incrementing by X +** 2 N S X Clear N bits beginning with S and incrementing by X +** 3 N Set N randomly chosen bits +** 4 N Clear N randomly chosen bits +** 5 N S X Set N bits from S increment X in array only, not in bitvec +** +** The opcodes 1 through 4 perform set and clear operations are performed +** on both a Bitvec object and on a linear array of bits obtained from malloc. +** Opcode 5 works on the linear array only, not on the Bitvec. +** Opcode 5 is used to deliberately induce a fault in order to +** confirm that error detection works. +** +** At the conclusion of the test the linear array is compared +** against the Bitvec object. If there are any differences, +** an error is returned. If they are the same, zero is returned. +** +** If a memory allocation error occurs, return -1. +*/ +SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ + Bitvec *pBitvec = 0; + unsigned char *pV = 0; + int rc = -1; + int i, nx, pc, op; + + /* Allocate the Bitvec to be tested and a linear array of + ** bits to act as the reference */ + pBitvec = sqlite3BitvecCreate( sz ); + pV = sqlite3_malloc( (sz+7)/8 + 1 ); + if( pBitvec==0 || pV==0 ) goto bitvec_end; + memset(pV, 0, (sz+7)/8 + 1); + + /* Run the program */ + pc = 0; + while( (op = aOp[pc])!=0 ){ + switch( op ){ + case 1: + case 2: + case 5: { + nx = 4; + i = aOp[pc+2] - 1; + aOp[pc+2] += aOp[pc+3]; + break; + } + case 3: + case 4: + default: { + nx = 2; + sqlite3_randomness(sizeof(i), &i); + break; + } + } + if( (--aOp[pc+1]) > 0 ) nx = 0; + pc += nx; + i = (i & 0x7fffffff)%sz; + if( (op & 1)!=0 ){ + SETBIT(pV, (i+1)); + if( op!=5 ){ + if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; + } + }else{ + CLEARBIT(pV, (i+1)); + sqlite3BitvecClear(pBitvec, i+1); + } + } + + /* Test to make sure the linear array exactly matches the + ** Bitvec object. Start with the assumption that they do + ** match (rc==0). Change rc to non-zero if a discrepancy + ** is found. + */ + rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) + + sqlite3BitvecTest(pBitvec, 0); + for(i=1; i<=sz; i++){ + if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ + rc = i; + break; + } + } + + /* Free allocated structure */ +bitvec_end: + sqlite3_free(pV); + sqlite3BitvecDestroy(pBitvec); + return rc; +} +#endif /* SQLITE_OMIT_BUILTIN_TEST */ + +/************** End of bitvec.c **********************************************/ /************** Begin file pager.c *******************************************/ /* ** 2001 September 15 @@ -21415,7 +23444,7 @@ SQLITE_PRIVATE sqlite3_vfs *sqlite3OsDefaultVfs(void){ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.404 2008/01/22 21:30:53 drh Exp $ +** @(#) $Id: pager.c,v 1.426 2008/04/14 23:13:46 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO @@ -21607,9 +23636,9 @@ struct PagerLruLink { ** has been synced to disk. For pages that are in the original ** database file, the following expression should always be true: ** -** inJournal = (pPager->aInJournal[(pgno-1)/8] & (1<<((pgno-1)%8))!=0 +** inJournal = sqlite3BitvecTest(pPager->pInJournal, pgno) ** -** The pPager->aInJournal[] array is only valid for the original +** The pPager->pInJournal object is only valid for the original ** pages of the database, not new pages that are added to the end ** of the database, so obviously the above expression cannot be ** valid for new pages. For new pages inJournal is always 0. @@ -21759,8 +23788,8 @@ struct Pager { int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */ int mxPage; /* Maximum number of pages to hold in cache */ Pgno mxPgno; /* Maximum allowed size of the database */ - u8 *aInJournal; /* One bit for each page in the database file */ - u8 *aInStmt; /* One bit for each page in the database */ + Bitvec *pInJournal; /* One bit for each page in the database file */ + Bitvec *pInStmt; /* One bit for each page in the database */ char *zFilename; /* Name of the database file */ char *zJournal; /* Name of the journal file */ char *zDirectory; /* Directory hold database and journal files */ @@ -21926,25 +23955,6 @@ static const unsigned char aJournalMagic[] = { # define pagerLeave(X) #endif -/* -** Enable reference count tracking (for debugging) here: -*/ -#ifdef SQLITE_DEBUG - int pager3_refinfo_enable = 0; - static void pager_refinfo(PgHdr *p){ - static int cnt = 0; - if( !pager3_refinfo_enable ) return; - sqlite3DebugPrintf( - "REFCNT: %4d addr=%p nRef=%-3d total=%d\n", - p->pgno, PGHDR_TO_DATA(p), p->nRef, p->pPager->nRef - ); - cnt++; /* Something to set a breakpoint on */ - } -# define REFINFO(X) pager_refinfo(X) -#else -# define REFINFO(X) -#endif - /* ** Add page pPg to the end of the linked list managed by structure ** pList (pPg becomes the last entry in the list - the most recently @@ -22079,9 +24089,7 @@ static int pageInStatement(PgHdr *pPg){ if( MEMDB ){ return PGHDR_TO_HIST(pPg, pPager)->inStmt; }else{ - Pgno pgno = pPg->pgno; - u8 *a = pPager->aInStmt; - return (a && (int)pgno<=pPager->stmtSize && (a[pgno/8] & (1<<(pgno&7)))); + return sqlite3BitvecTest(pPager->pInStmt, pPg->pgno); } } @@ -22092,6 +24100,12 @@ static int pageInStatement(PgHdr *pPg){ static void pager_resize_hash_table(Pager *pPager, int N){ PgHdr **aHash, *pPg; assert( N>0 && (N&(N-1))==0 ); +#ifdef SQLITE_MALLOC_SOFT_LIMIT + if( N*sizeof(aHash[0])>SQLITE_MALLOC_SOFT_LIMIT ){ + N = SQLITE_MALLOC_SOFT_LIMIT/sizeof(aHash[0]); + } + if( N==pPager->nHash ) return; +#endif pagerLeave(pPager); sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, pPager->aHash!=0); aHash = sqlite3MallocZero( sizeof(aHash[0])*N ); @@ -22380,11 +24394,12 @@ static void seekJournalHdr(Pager *pPager){ ** - 4 bytes: Random number used for page hash. ** - 4 bytes: Initial database page count. ** - 4 bytes: Sector size used by the process that wrote this journal. +** - 4 bytes: Database page size. ** -** Followed by (JOURNAL_HDR_SZ - 24) bytes of unused space. +** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space. */ static int writeJournalHdr(Pager *pPager){ - char zHeader[sizeof(aJournalMagic)+16]; + char zHeader[sizeof(aJournalMagic)+20]; int rc; if( pPager->stmtHdrOff==0 ){ @@ -22426,12 +24441,16 @@ static int writeJournalHdr(Pager *pPager){ } /* The random check-hash initialiser */ - sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); + sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); /* The initial database size */ put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbSize); /* The assumed sector size for this process */ put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize); + if( pPager->journalHdr==0 ){ + /* The page size */ + put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize); + } IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, sizeof(zHeader))) rc = sqlite3OsWrite(pPager->jfd, zHeader, sizeof(zHeader),pPager->journalOff); pPager->journalOff += JOURNAL_HDR_SZ(pPager); @@ -22471,6 +24490,7 @@ static int readJournalHdr( int rc; unsigned char aMagic[8]; /* A buffer to hold the magic header */ i64 jrnlOff; + int iPageSize; seekJournalHdr(pPager); if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){ @@ -22495,6 +24515,17 @@ static int readJournalHdr( rc = read32bits(pPager->jfd, jrnlOff+8, pDbSize); if( rc ) return rc; + rc = read32bits(pPager->jfd, jrnlOff+16, (u32 *)&iPageSize); + if( rc==SQLITE_OK + && iPageSize>=512 + && iPageSize<=SQLITE_MAX_PAGE_SIZE + && ((iPageSize-1)&iPageSize)==0 + ){ + u16 pagesize = iPageSize; + rc = sqlite3PagerSetPagesize(pPager, &pagesize); + } + if( rc ) return rc; + /* 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 @@ -22622,6 +24653,7 @@ static void pager_reset(Pager *pPager){ PAGER_INCR(sqlite3_pager_pgfree_count); pNext = pPg->pNextAll; lruListRemove(pPg); + sqlite3_free(pPg->pData); sqlite3_free(pPg); } assert(pPager->lru.pFirst==0); @@ -22649,9 +24681,8 @@ static void pager_reset(Pager *pPager){ static void pager_unlock(Pager *pPager){ if( !pPager->exclusiveMode ){ if( !MEMDB ){ - if( pPager->fd->pMethods ){ - osUnlock(pPager->fd, NO_LOCK); - } + int rc = osUnlock(pPager->fd, NO_LOCK); + if( rc ) pPager->errCode = rc; pPager->dbSize = -1; IOTRACE(("UNLOCK %p\n", pPager)) @@ -22660,18 +24691,18 @@ static void pager_unlock(Pager *pPager){ ** cache can be discarded and the error code safely cleared. */ if( pPager->errCode ){ - pPager->errCode = SQLITE_OK; + if( rc==SQLITE_OK ) pPager->errCode = SQLITE_OK; pager_reset(pPager); if( pPager->stmtOpen ){ sqlite3OsClose(pPager->stfd); - sqlite3_free(pPager->aInStmt); - pPager->aInStmt = 0; + sqlite3BitvecDestroy(pPager->pInStmt); + pPager->pInStmt = 0; } if( pPager->journalOpen ){ sqlite3OsClose(pPager->jfd); pPager->journalOpen = 0; - sqlite3_free(pPager->aInJournal); - pPager->aInJournal = 0; + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; } pPager->stmtOpen = 0; pPager->stmtInUse = 0; @@ -22746,8 +24777,8 @@ static int pager_end_transaction(Pager *pPager){ rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); } } - sqlite3_free( pPager->aInJournal ); - pPager->aInJournal = 0; + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ pPg->inJournal = 0; pPg->dirty = 0; @@ -22761,7 +24792,7 @@ static int pager_end_transaction(Pager *pPager){ pPager->dirtyCache = 0; pPager->nRec = 0; }else{ - assert( pPager->aInJournal==0 ); + assert( pPager->pInJournal==0 ); assert( pPager->dirtyCache==0 || pPager->useJournal==0 ); } @@ -22894,11 +24925,16 @@ static int pager_playback_one_page( ** locked. (2) we know that the original page content is fully synced ** in the main journal either because the page is not in cache or else ** the page is marked as needSync==0. + ** + ** 2008-04-14: When attempting to vacuum a corrupt database file, it + ** 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); PAGERTRACE4("PLAYBACK %d page %d hash(%08x)\n", PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, aData)); - if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){ + if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) + && pPager->fd->pMethods ){ i64 offset = (pgno-1)*(i64)pPager->pageSize; rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize, offset); if( pPg ){ @@ -22994,7 +25030,12 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ zJournal = zMasterJournal; while( (zJournal-zMasterJournal)fd->pMethods||pPager->tempFile); @@ -23082,8 +25123,8 @@ static void setSectorSize(Pager *pPager){ */ pPager->sectorSize = sqlite3OsSectorSize(pPager->fd); } - if( pPager->sectorSizepageSize ){ - pPager->sectorSize = pPager->pageSize; + if( pPager->sectorSize<512 ){ + pPager->sectorSize = 512; } } @@ -23101,20 +25142,23 @@ static void setSectorSize(Pager *pPager){ ** sanity checksum. ** (4) 4 byte integer which is the number of pages to truncate the ** database to during a rollback. -** (5) 4 byte integer which is the number of bytes in the master journal +** (5) 4 byte big-endian integer which is the sector size. The header +** is this many bytes in size. +** (6) 4 byte big-endian integer which is the page case. +** (7) 4 byte integer which is the number of bytes in the master journal ** name. The value may be zero (indicate that there is no master ** journal.) -** (6) N bytes of the master journal name. The name will be nul-terminated +** (8) N bytes of the master journal name. The name will be nul-terminated ** and might be shorter than the value read from (5). If the first byte ** of the name is \000 then there is no master journal. The master ** journal name is stored in UTF-8. -** (7) Zero or more pages instances, each as follows: +** (9) Zero or more pages instances, each as follows: ** + 4 byte page number. ** + pPager->pageSize bytes of data. ** + 4 byte checksum ** -** When we speak of the journal header, we mean the first 6 items above. -** Each entry in the journal is an instance of the 7th item. +** When we speak of the journal header, we mean the first 8 items above. +** Each entry in the journal is an instance of the 9th item. ** ** Call the value from the second bullet "nRec". nRec is the number of ** valid page entries in the journal. In most cases, you can compute the @@ -23147,6 +25191,7 @@ static int pager_playback(Pager *pPager, int isHot){ int i; /* Loop counter */ Pgno mxPg = 0; /* Size of the original file in pages */ int rc; /* Result code of a subroutine */ + int res = 0; /* Value returned by sqlite3OsAccess() */ char *zMaster = 0; /* Name of master journal file if any */ /* Figure out how many records are in the journal. Abort early if @@ -23165,16 +25210,18 @@ static int pager_playback(Pager *pPager, int isHot){ */ zMaster = pPager->pTmpSpace; rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); - assert( rc!=SQLITE_DONE ); - if( rc!=SQLITE_OK - || (zMaster[0] && !sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS)) + if( rc!=SQLITE_OK || (zMaster[0] + && (res=sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS))==0 ) ){ zMaster = 0; - if( rc==SQLITE_DONE ) rc = SQLITE_OK; + goto end_playback; + } + zMaster = 0; + if( res<0 ){ + rc = SQLITE_IOERR_NOMEM; goto end_playback; } pPager->journalOff = 0; - zMaster = 0; /* This loop terminates either when the readJournalHdr() call returns ** SQLITE_DONE or an IO error occurs. */ @@ -23492,13 +25539,15 @@ SQLITE_PRIVATE int sqlite3PagerOpen( int nDefaultPage = SQLITE_DEFAULT_PAGE_SIZE; char *zPathname; int nPathname; + char *zStmtJrnl; + int nStmtJrnl; /* The default return is a NULL pointer */ *ppPager = 0; /* Compute the full pathname */ nPathname = pVfs->mxPathname+1; - zPathname = sqlite3_malloc(nPathname); + zPathname = sqlite3_malloc(nPathname*2); if( zPathname==0 ){ return SQLITE_NOMEM; } @@ -23521,12 +25570,26 @@ SQLITE_PRIVATE int sqlite3PagerOpen( } nPathname = strlen(zPathname); + /* Put the statement journal in temporary disk space since this is + ** sometimes RAM disk or other optimized storage. Unlikely the main + ** main journal file, the statement journal does not need to be + ** colocated with the database nor does it need to be persistent. + */ + zStmtJrnl = &zPathname[nPathname+1]; + rc = sqlite3OsGetTempname(pVfs, pVfs->mxPathname+1, zStmtJrnl); + if( rc!=SQLITE_OK ){ + sqlite3_free(zPathname); + return rc; + } + nStmtJrnl = strlen(zStmtJrnl); + /* Allocate memory for the pager structure */ pPager = sqlite3MallocZero( sizeof(*pPager) + /* Pager structure */ journalFileSize + /* The journal file structure */ - pVfs->szOsFile * 2 + /* The db and stmt journal files */ - 4*nPathname + 40 /* zFilename, zDirectory, zJournal, zStmtJrnl */ + pVfs->szOsFile * 3 + /* The main db and two journal files */ + 3*nPathname + 40 + /* zFilename, zDirectory, zJournal */ + nStmtJrnl /* zStmtJrnl */ ); if( !pPager ){ sqlite3_free(zPathname); @@ -23543,6 +25606,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( pPager->zStmtJrnl = &pPager->zJournal[nPathname+10]; pPager->pVfs = pVfs; memcpy(pPager->zFilename, zPathname, nPathname+1); + memcpy(pPager->zStmtJrnl, zStmtJrnl, nStmtJrnl+1); sqlite3_free(zPathname); /* Open the pager file. @@ -23618,11 +25682,9 @@ SQLITE_PRIVATE int sqlite3PagerOpen( for(i=strlen(pPager->zDirectory); i>0 && pPager->zDirectory[i-1]!='/'; i--){} if( i>0 ) pPager->zDirectory[i-1] = 0; - /* Fill in Pager.zJournal[] and Pager.zStmtJrnl[] */ + /* Fill in Pager.zJournal[] */ memcpy(pPager->zJournal, pPager->zFilename, nPathname); memcpy(&pPager->zJournal[nPathname], "-journal", 9); - memcpy(pPager->zStmtJrnl, pPager->zFilename, nPathname); - memcpy(&pPager->zStmtJrnl[nPathname], "-stmtjrnl", 10); /* pPager->journalOpen = 0; */ pPager->useJournal = useJournal && !memDb; @@ -23829,7 +25891,7 @@ SQLITE_PRIVATE int sqlite3PagerPagecount(Pager *pPager){ int rc; assert( pPager!=0 ); if( pPager->errCode ){ - return 0; + return -1; } if( pPager->dbSize>=0 ){ n = pPager->dbSize; @@ -23840,7 +25902,7 @@ SQLITE_PRIVATE int sqlite3PagerPagecount(Pager *pPager){ pPager->nRef++; pager_error(pPager, rc); pPager->nRef--; - return 0; + return -1; } if( n>0 && npageSize ){ n = 1; @@ -23952,6 +26014,7 @@ static void pager_truncate_cache(Pager *pPager){ PAGER_INCR(sqlite3_pager_pgfree_count); unlinkPage(pPg); makeClean(pPg); + sqlite3_free(pPg->pData); sqlite3_free(pPg); pPager->nPage--; } @@ -23980,6 +26043,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ if( pPager->state>=locktype ){ rc = SQLITE_OK; }else{ + if( pPager->pBusyHandler ) pPager->pBusyHandler->nBusy = 0; do { rc = sqlite3OsLock(pPager->fd, locktype); }while( rc==SQLITE_BUSY && sqlite3InvokeBusyHandler(pPager->pBusyHandler) ); @@ -24072,7 +26136,7 @@ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){ if( pPager->journalOpen ){ sqlite3OsClose(pPager->jfd); } - sqlite3_free(pPager->aInJournal); + sqlite3BitvecDestroy(pPager->pInJournal); if( pPager->stmtOpen ){ sqlite3OsClose(pPager->stfd); } @@ -24114,7 +26178,6 @@ static void _page_ref(PgHdr *pPg){ pPg->pPager->nRef++; } pPg->nRef++; - REFINFO(pPg); } #ifdef SQLITE_DEBUG static void page_ref(PgHdr *pPg){ @@ -24122,7 +26185,6 @@ static void _page_ref(PgHdr *pPg){ _page_ref(pPg); }else{ pPg->nRef++; - REFINFO(pPg); } } #else @@ -24413,23 +26475,40 @@ static int pager_write_pagelist(PgHdr *pList){ ** collected even if they are still in use. */ static PgHdr *pager_get_all_dirty_pages(Pager *pPager){ + +#ifndef NDEBUG + /* Verify the sanity of the dirty list when we are running + ** in debugging mode. This is expensive, so do not + ** do this on a normal build. */ + int n1 = 0; + int n2 = 0; + PgHdr *p; + for(p=pPager->pAll; p; p=p->pNextAll){ if( p->dirty ) n1++; } + for(p=pPager->pDirty; p; p=p->pDirty){ n2++; } + assert( n1==n2 ); +#endif + return pPager->pDirty; } /* -** Return TRUE if there is a hot journal on the given pager. +** Return 1 if there is a hot journal on the given pager. ** A hot journal is one that needs to be played back. ** ** 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. */ static int hasHotJournal(Pager *pPager){ sqlite3_vfs *pVfs = pPager->pVfs; + int rc; if( !pPager->useJournal ) return 0; if( !pPager->fd->pMethods ) return 0; - if( !sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){ - return 0; + rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS); + if( rc<=0 ){ + return rc; } if( sqlite3OsCheckReservedLock(pPager->fd) ){ return 0; @@ -24620,6 +26699,7 @@ SQLITE_PRIVATE int sqlite3PagerReleaseMemory(int nReq){ ); IOTRACE(("PGFREE %p %d *\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); + sqlite3_free(pPg->pData); sqlite3_free(pPg); pPager->nPage--; }else{ @@ -24728,7 +26808,11 @@ static int pagerSharedLock(Pager *pPager){ /* If a journal file exists, and there is no RESERVED lock on the ** database file, then it either needs to be played back or deleted. */ - if( hasHotJournal(pPager) || isHot ){ + rc = hasHotJournal(pPager); + if( rc<0 ){ + return SQLITE_IOERR_NOMEM; + } + if( rc==1 || isHot ){ /* 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 @@ -24764,8 +26848,8 @@ static int pagerSharedLock(Pager *pPager){ ** a read/write file handle. */ if( !isHot ){ - rc = SQLITE_BUSY; - if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){ + int res = sqlite3OsAccess(pVfs,pPager->zJournal,SQLITE_ACCESS_EXISTS); + if( res==1 ){ int fout = 0; int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; assert( !pPager->tempFile ); @@ -24775,11 +26859,20 @@ static int pagerSharedLock(Pager *pPager){ rc = SQLITE_BUSY; sqlite3OsClose(pPager->jfd); } + }else{ + rc = (res==0?SQLITE_BUSY:SQLITE_IOERR_NOMEM); } } if( rc!=SQLITE_OK ){ pager_unlock(pPager); - return ((rc==SQLITE_NOMEM||rc==SQLITE_IOERR_NOMEM)?rc:SQLITE_BUSY); + switch( rc ){ + case SQLITE_NOMEM: + case SQLITE_IOERR_UNLOCK: + case SQLITE_IOERR_NOMEM: + return rc; + default: + return SQLITE_BUSY; + } } pPager->journalOpen = 1; pPager->journalStarted = 0; @@ -24891,6 +26984,7 @@ static int pagerAllocatePage(Pager *pPager, PgHdr **ppPg){ || MEMDB || (pPager->lru.pFirstSynced==0 && pPager->doNotSync) ){ + void *pData; if( pPager->nPage>=pPager->nHash ){ pager_resize_hash_table(pPager, pPager->nHash<256 ? 256 : pPager->nHash*2); @@ -24902,14 +26996,21 @@ static int pagerAllocatePage(Pager *pPager, PgHdr **ppPg){ pagerLeave(pPager); nByteHdr = sizeof(*pPg) + sizeof(u32) + pPager->nExtra + MEMDB*sizeof(PgHistory); - pPg = sqlite3_malloc( nByteHdr + pPager->pageSize ); + pPg = sqlite3_malloc( nByteHdr ); + if( pPg ){ + pData = sqlite3_malloc( pPager->pageSize ); + if( pData==0 ){ + sqlite3_free(pPg); + pPg = 0; + } + } pagerEnter(pPager); if( pPg==0 ){ rc = SQLITE_NOMEM; goto pager_allocate_out; } memset(pPg, 0, nByteHdr); - pPg->pData = (void*)(nByteHdr + (char*)pPg); + pPg->pData = pData; pPg->pPager = pPager; pPg->pNextAll = pPager->pAll; pPager->pAll = pPg; @@ -25029,21 +27130,11 @@ static int pagerAcquire( pPg->pgno = pgno; assert( !MEMDB || pgno>pPager->stmtSize ); - if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){ -#if 0 - sqlite3CheckMemory(pPager->aInJournal, pgno/8); -#endif - assert( pPager->journalOpen ); - pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0; - pPg->needSync = 0; - }else{ - pPg->inJournal = 0; - pPg->needSync = 0; - } + pPg->inJournal = sqlite3BitvecTest(pPager->pInJournal, pgno); + pPg->needSync = 0; makeClean(pPg); pPg->nRef = 1; - REFINFO(pPg); pPager->nRef++; if( pPager->nExtra>0 ){ @@ -25164,7 +27255,6 @@ SQLITE_PRIVATE int sqlite3PagerUnref(DbPage *pPg){ assert( pPg->nRef>0 ); pagerEnter(pPg->pPager); pPg->nRef--; - REFINFO(pPg); CHECK_PAGE(pPg); @@ -25207,12 +27297,12 @@ static int pager_open_journal(Pager *pPager){ assert( pPager->state>=PAGER_RESERVED ); assert( pPager->journalOpen==0 ); assert( pPager->useJournal ); - assert( pPager->aInJournal==0 ); + assert( pPager->pInJournal==0 ); sqlite3PagerPagecount(pPager); pagerLeave(pPager); - pPager->aInJournal = sqlite3MallocZero( pPager->dbSize/8 + 1 ); + pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize); pagerEnter(pPager); - if( pPager->aInJournal==0 ){ + if( pPager->pInJournal==0 ){ rc = SQLITE_NOMEM; goto failed_to_open_journal; } @@ -25264,8 +27354,8 @@ static int pager_open_journal(Pager *pPager){ return rc; failed_to_open_journal: - sqlite3_free(pPager->aInJournal); - pPager->aInJournal = 0; + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; return rc; } @@ -25303,7 +27393,7 @@ SQLITE_PRIVATE int sqlite3PagerBegin(DbPage *pPg, int exFlag){ assert( pPg->nRef>0 ); assert( pPager->state!=PAGER_UNLOCK ); if( pPager->state==PAGER_SHARED ){ - assert( pPager->aInJournal==0 ); + assert( pPager->pInJournal==0 ); if( MEMDB ){ pPager->state = PAGER_EXCLUSIVE; pPager->origDbSize = pPager->dbSize; @@ -25333,12 +27423,12 @@ SQLITE_PRIVATE int sqlite3PagerBegin(DbPage *pPg, int exFlag){ */ assert( pPager->nRec==0 ); assert( pPager->origDbSize==0 ); - assert( pPager->aInJournal==0 ); + assert( pPager->pInJournal==0 ); sqlite3PagerPagecount(pPager); pagerLeave(pPager); - pPager->aInJournal = sqlite3MallocZero( pPager->dbSize/8 + 1 ); + pPager->pInJournal = sqlite3BitvecCreate( pPager->dbSize ); pagerEnter(pPager); - if( !pPager->aInJournal ){ + if( !pPager->pInJournal ){ rc = SQLITE_NOMEM; }else{ pPager->origDbSize = pPager->dbSize; @@ -25514,11 +27604,11 @@ static int pager_write(PgHdr *pPg){ } pPager->nRec++; - assert( pPager->aInJournal!=0 ); - pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); + assert( pPager->pInJournal!=0 ); + sqlite3BitvecSet(pPager->pInJournal, pPg->pgno); pPg->needSync = !pPager->noSync; if( pPager->stmtInUse ){ - pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); + sqlite3BitvecSet(pPager->pInStmt, pPg->pgno); } } }else{ @@ -25563,8 +27653,8 @@ static int pager_write(PgHdr *pPg){ return rc; } pPager->stmtNRec++; - assert( pPager->aInStmt!=0 ); - pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); + assert( pPager->pInStmt!=0 ); + sqlite3BitvecSet(pPager->pInStmt, pPg->pgno); } } } @@ -25633,9 +27723,7 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){ for(ii=0; iiaInJournal || pg==pPg->pgno || - pg>pPager->origDbSize || !(pPager->aInJournal[pg/8]&(1<<(pg&7))) - ) { + if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ if( pg!=PAGER_MJ_PGNO(pPager) ){ rc = sqlite3PagerGet(pPager, pg, &pPage); if( rc==SQLITE_OK ){ @@ -25646,7 +27734,7 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){ sqlite3PagerUnref(pPage); } } - }else if( (pPage = pager_lookup(pPager, pg)) ){ + }else if( (pPage = pager_lookup(pPager, pg))!=0 ){ if( pPage->needSync ){ needSync = 1; } @@ -25774,19 +27862,6 @@ SQLITE_PRIVATE void sqlite3PagerDontWrite(DbPage *pDbPage){ ** 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. -** -** This routine is only called from a single place in the sqlite btree -** code (when a leaf is removed from the free-list). This allows the -** following assumptions to be made about pPg: -** -** 1. PagerDontWrite() has been called on the page, OR -** PagerWrite() has not yet been called on the page. -** -** 2. The page existed when the transaction was started. -** -** Details: DontRollback() (this routine) is only called when a leaf is -** removed from the free list. DontWrite() is called whenever a page -** becomes a free-list leaf. */ SQLITE_PRIVATE void sqlite3PagerDontRollback(DbPage *pPg){ Pager *pPager = pPg->pPager; @@ -25804,18 +27879,27 @@ SQLITE_PRIVATE void sqlite3PagerDontRollback(DbPage *pPg){ } assert( !MEMDB ); /* For a memdb, pPager->journalOpen is always 0 */ - /* Check that PagerWrite() has not yet been called on this page, and - ** that the page existed when the transaction started. +#ifdef SQLITE_SECURE_DELETE + if( pPg->inJournal || (int)pPg->pgno > pPager->origDbSize ){ + 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. */ assert( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ); - assert( pPager->aInJournal!=0 ); - pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); + assert( pPager->pInJournal!=0 ); + sqlite3BitvecSet(pPager->pInJournal, pPg->pgno); pPg->inJournal = 1; pPg->needRead = 0; if( pPager->stmtInUse ){ - assert( pPager->stmtSize <= pPager->origDbSize ); - pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); + assert( pPager->stmtSize >= pPager->origDbSize ); + sqlite3BitvecSet(pPager->pInStmt, pPg->pgno); } PAGERTRACE3("DONT_ROLLBACK page %d of %d\n", pPg->pgno, PAGERID(pPager)); IOTRACE(("GARBAGE %p %d\n", pPager, pPg->pgno)) @@ -25862,6 +27946,17 @@ static int pager_incr_changecounter(Pager *pPager, int isDirect){ return rc; } +/* +** Sync the pager file to disk. +*/ +SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager){ + int rc; + pagerEnter(pPager); + rc = sqlite3OsSync(pPager->fd, pPager->sync_flags); + pagerLeave(pPager); + return rc; +} + /* ** Sync the database file for the pager pPager. zMaster points to the name ** of a master journal file that should be written into the individual @@ -25878,8 +27973,18 @@ static int pager_incr_changecounter(Pager *pPager, int isDirect){ ** ** If parameter nTrunc is non-zero, then the pager file is truncated to ** nTrunc pages (this is used by auto-vacuum databases). +** +** If the final parameter - noSync - is true, then the database file itself +** is not synced. The caller must call sqlite3PagerSync() directly to +** sync the database file before calling CommitPhaseTwo() to delete the +** journal file in this case. */ -SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager *pPager, const char *zMaster, Pgno nTrunc){ +SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( + Pager *pPager, + const char *zMaster, + Pgno nTrunc, + int noSync +){ int rc = SQLITE_OK; PAGERTRACE4("DATABASE SYNC: File=%s zMaster=%s nTrunc=%d\n", @@ -25951,7 +28056,7 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager *pPager, const char *zMaster Pgno i; int iSkip = PAGER_MJ_PGNO(pPager); for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){ - if( !(pPager->aInJournal[i/8] & (1<<(i&7))) && i!=iSkip ){ + if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){ rc = sqlite3PagerGet(pPager, i, &pPg); if( rc!=SQLITE_OK ) goto sync_exit; rc = sqlite3PagerWrite(pPg); @@ -25978,14 +28083,20 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager *pPager, const char *zMaster pPg = pager_get_all_dirty_pages(pPager); rc = pager_write_pagelist(pPg); if( rc!=SQLITE_OK ){ - while( pPg && !pPg->dirty ){ pPg = pPg->pDirty; } - pPager->pDirty = pPg; + 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; } pPager->pDirty = 0; /* Sync the database file. */ - if( !pPager->noSync ){ + if( !pPager->noSync && !noSync ){ rc = sqlite3OsSync(pPager->fd, pPager->sync_flags); } IOTRACE(("DBSYNC %p\n", pPager)) @@ -26209,10 +28320,10 @@ static int pagerStmtBegin(Pager *pPager){ } assert( pPager->journalOpen ); pagerLeave(pPager); - assert( pPager->aInStmt==0 ); - pPager->aInStmt = sqlite3MallocZero( pPager->dbSize/8 + 1 ); + assert( pPager->pInStmt==0 ); + pPager->pInStmt = sqlite3BitvecCreate(pPager->dbSize); pagerEnter(pPager); - if( pPager->aInStmt==0 ){ + if( pPager->pInStmt==0 ){ /* sqlite3OsLock(pPager->fd, SHARED_LOCK); */ return SQLITE_NOMEM; } @@ -26238,9 +28349,9 @@ static int pagerStmtBegin(Pager *pPager){ return SQLITE_OK; stmt_begin_failed: - if( pPager->aInStmt ){ - sqlite3_free(pPager->aInStmt); - pPager->aInStmt = 0; + if( pPager->pInStmt ){ + sqlite3BitvecDestroy(pPager->pInStmt); + pPager->pInStmt = 0; } return rc; } @@ -26262,8 +28373,8 @@ SQLITE_PRIVATE int sqlite3PagerStmtCommit(Pager *pPager){ PAGERTRACE2("STMT-COMMIT %d\n", PAGERID(pPager)); if( !MEMDB ){ /* sqlite3OsTruncate(pPager->stfd, 0); */ - sqlite3_free( pPager->aInStmt ); - pPager->aInStmt = 0; + sqlite3BitvecDestroy(pPager->pInStmt); + pPager->pInStmt = 0; }else{ for(pPg=pPager->pStmt; pPg; pPg=pNext){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); @@ -26433,12 +28544,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){ }else{ pPg->needSync = 0; } - if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){ - pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0; - }else{ - pPg->inJournal = 0; - assert( pPg->needSync==0 || (int)pgno>pPager->origDbSize ); - } + pPg->inJournal = sqlite3BitvecTest(pPager->pInJournal, pgno); /* Change the page number for pPg and insert it into the new hash-chain. */ assert( pgno!=0 ); @@ -26459,11 +28565,11 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){ /* If needSyncPgno is non-zero, then the journal file needs to be ** sync()ed before any data is written to database file page needSyncPgno. ** Currently, no such page exists in the page-cache and the - ** Pager.aInJournal bit has been set. This needs to be remedied by loading + ** Pager.pInJournal bit has been set. This needs to be remedied by loading ** the page into the pager-cache and setting the PgHdr.needSync flag. ** ** If the attempt to load the page into the page-cache fails, (due - ** to a malloc() or IO failure), clear the bit in the aInJournal[] + ** to a malloc() or IO failure), clear the bit in the pInJournal[] ** array. Otherwise, if the page is loaded and written again in ** this transaction, it may be written to the database file before ** it is synced into the journal file. This way, it may end up in @@ -26477,8 +28583,8 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){ assert( pPager->needSync ); rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr); if( rc!=SQLITE_OK ){ - if( pPager->aInJournal && (int)needSyncPgno<=pPager->origDbSize ){ - pPager->aInJournal[needSyncPgno/8] &= ~(1<<(needSyncPgno&7)); + if( pPager->pInJournal && (int)needSyncPgno<=pPager->origDbSize ){ + sqlite3BitvecClear(pPager->pInJournal, needSyncPgno); } pagerLeave(pPager); return rc; @@ -26583,7 +28689,7 @@ SQLITE_PRIVATE void sqlite3PagerRefdump(Pager *pPager){ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btreeInt.h,v 1.15 2007/12/21 04:47:26 danielk1977 Exp $ +** $Id: btreeInt.h,v 1.20 2008/03/29 16:01:04 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -26790,10 +28896,11 @@ SQLITE_PRIVATE void sqlite3PagerRefdump(Pager *pPager){ #define MX_CELL_SIZE(pBt) (pBt->pageSize-8) /* The maximum number of cells on a single page of the database. This -** assumes a minimum cell size of 3 bytes. Such small cells will be -** exceedingly rare, but they are possible. +** assumes a minimum cell size of 6 bytes (4 bytes for the cell itself +** plus 2 bytes for the index to the cell in the page header). Such +** small cells will be rare, but they are possible. */ -#define MX_CELL(pBt) ((pBt->pageSize-8)/3) +#define MX_CELL(pBt) ((pBt->pageSize-8)/6) /* Forward declarations */ typedef struct MemPage MemPage; @@ -26966,6 +29073,7 @@ struct BtShared { BtLock *pLock; /* List of locks held on this shared-btree struct */ Btree *pExclusive; /* Btree with an EXCLUSIVE lock on the whole db */ #endif + u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */ }; /* @@ -27003,13 +29111,14 @@ struct BtCursor { Btree *pBtree; /* The Btree to which this cursor belongs */ BtShared *pBt; /* The BtShared this cursor points to */ BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */ - int (*xCompare)(void*,int,const void*,int,const void*); /* Key comp func */ - void *pArg; /* First arg to xCompare() */ + struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */ Pgno pgnoRoot; /* The root page of this tree */ MemPage *pPage; /* Page that contains the entry */ int idx; /* Index of the entry in pPage->aCell[] */ 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 */ u8 eState; /* One of the CURSOR_XXX constants (see below) */ void *pKey; /* Saved key that was cursor's last known position */ i64 nKey; /* Size of pKey, or last integer key */ @@ -27052,11 +29161,11 @@ struct BtCursor { /* ** The TRACE macro will print high-level status information about the -** btree operation when the global variable sqlite3_btree_trace is +** btree operation when the global variable sqlite3BtreeTrace is ** enabled. */ #if SQLITE_TEST -# define TRACE(X) if( sqlite3_btree_trace ){ printf X; fflush(stdout); } +# define TRACE(X) if( sqlite3BtreeTrace ){ printf X; fflush(stdout); } #else # define TRACE(X) #endif @@ -27531,7 +29640,7 @@ SQLITE_PRIVATE void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pArray){ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.438 2008/01/31 14:54:44 drh Exp $ +** $Id: btree.c,v 1.451 2008/04/03 21:46:57 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -27549,7 +29658,7 @@ static const char zMagicHeader[] = SQLITE_FILE_HEADER; ** macro. */ #if SQLITE_TEST -int sqlite3_btree_trace=0; /* True to enable tracing */ +int sqlite3BtreeTrace=0; /* True to enable tracing */ #endif @@ -27900,7 +30009,7 @@ SQLITE_PRIVATE int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur){ } #endif pCur->eState = CURSOR_INVALID; - rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip); + rc = sqlite3BtreeMoveto(pCur, pCur->pKey, 0, pCur->nKey, 0, &pCur->skip); if( rc==SQLITE_OK ){ sqlite3_free(pCur->pKey); pCur->pKey = 0; @@ -28143,13 +30252,13 @@ SQLITE_PRIVATE void sqlite3BtreeParseCell( ** the space used by the cell pointer. */ #ifndef NDEBUG -static int cellSize(MemPage *pPage, int iCell){ +static u16 cellSize(MemPage *pPage, int iCell){ CellInfo info; sqlite3BtreeParseCell(pPage, iCell, &info); return info.nSize; } #endif -static int cellSizePtr(MemPage *pPage, u8 *pCell){ +static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ CellInfo info; sqlite3BtreeParseCellPtr(pPage, pCell, &info); return info.nSize; @@ -28961,6 +31070,7 @@ SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){ pBt->xFreeSchema(pBt->pSchema); } sqlite3_free(pBt->pSchema); + sqlite3_free(pBt->pTmpSpace); sqlite3_free(pBt); } @@ -29065,6 +31175,8 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve) assert( (pageSize & 7)==0 ); assert( !pBt->pPage1 && !pBt->pCursor ); pBt->pageSize = pageSize; + sqlite3_free(pBt->pTmpSpace); + pBt->pTmpSpace = 0; rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); } pBt->usableSize = pBt->pageSize - nReserve; @@ -29156,20 +31268,21 @@ SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){ ** is returned if we run out of memory. */ static int lockBtree(BtShared *pBt){ - int rc, pageSize; + int rc; MemPage *pPage1; assert( sqlite3_mutex_held(pBt->mutex) ); if( pBt->pPage1 ) return SQLITE_OK; rc = sqlite3BtreeGetPage(pBt, 1, &pPage1, 0); if( rc!=SQLITE_OK ) return rc; - /* Do some checking to help insure the file we opened really is ** a valid database file. */ rc = SQLITE_NOTADB; if( sqlite3PagerPagecount(pBt->pPager)>0 ){ + int pageSize; + int usableSize; u8 *page1 = pPage1->aData; if( memcmp(page1, zMagicHeader, 16)!=0 ){ goto page1_init_failed; @@ -29187,11 +31300,27 @@ static int lockBtree(BtShared *pBt){ goto page1_init_failed; } assert( (pageSize & 7)==0 ); - pBt->pageSize = pageSize; - pBt->usableSize = pageSize - page1[20]; - if( pBt->usableSize<500 ){ + usableSize = pageSize - page1[20]; + if( pageSize!=pBt->pageSize ){ + /* After reading the first page of the database assuming a page size + ** of BtShared.pageSize, we have discovered that the page-size is + ** actually pageSize. Unlock the database, leave pBt->pPage1 at + ** zero and return SQLITE_OK. The caller will call this function + ** again with the correct page-size. + */ + releasePage(pPage1); + pBt->usableSize = usableSize; + pBt->pageSize = pageSize; + sqlite3_free(pBt->pTmpSpace); + pBt->pTmpSpace = 0; + sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); + return SQLITE_OK; + } + if( usableSize<500 ){ goto page1_init_failed; } + pBt->pageSize = pageSize; + pBt->usableSize = usableSize; pBt->maxEmbedFrac = page1[21]; pBt->minEmbedFrac = page1[22]; pBt->minLeafFrac = page1[23]; @@ -29400,7 +31529,7 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ #endif do { - if( pBt->pPage1==0 ){ + while( rc==SQLITE_OK && pBt->pPage1==0 ){ rc = lockBtree(pBt); } @@ -29880,7 +32009,7 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){ } } #endif - rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, nTrunc); + rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, nTrunc, 0); sqlite3BtreeLeave(p); } return rc; @@ -30155,23 +32284,6 @@ SQLITE_PRIVATE int sqlite3BtreeRollbackStmt(Btree *p){ return rc; } -/* -** Default key comparison function to be used if no comparison function -** is specified on the sqlite3BtreeCursor() call. -*/ -static int dfltCompare( - void *NotUsed, /* User data is not used */ - int n1, const void *p1, /* First key to compare */ - int n2, const void *p2 /* Second key to compare */ -){ - int c; - c = memcmp(p1, p2, n1pBt; assert( sqlite3BtreeHoldsMutex(p) ); - *ppCur = 0; if( wrFlag ){ if( pBt->readOnly ){ return SQLITE_READONLY; @@ -30237,11 +32340,6 @@ static int btreeCursor( return SQLITE_READONLY; } } - pCur = sqlite3MallocZero( sizeof(*pCur) ); - if( pCur==0 ){ - rc = SQLITE_NOMEM; - goto create_cursor_exception; - } pCur->pgnoRoot = (Pgno)iTable; if( iTable==1 && sqlite3PagerPagecount(pBt->pPager)==0 ){ rc = SQLITE_EMPTY; @@ -30256,8 +32354,7 @@ static int btreeCursor( ** variables, link the cursor into the BtShared list and set *ppCur (the ** output argument to this function). */ - pCur->xCompare = xCmp ? xCmp : dfltCompare; - pCur->pArg = pArg; + pCur->pKeyInfo = pKeyInfo; pCur->pBtree = p; pCur->pBt = pBt; pCur->wrFlag = wrFlag; @@ -30267,14 +32364,12 @@ static int btreeCursor( } pBt->pCursor = pCur; pCur->eState = CURSOR_INVALID; - *ppCur = pCur; return SQLITE_OK; create_cursor_exception: if( pCur ){ releasePage(pCur->pPage); - sqlite3_free(pCur); } unlockBtreeIfUnused(pBt); return rc; @@ -30283,17 +32378,20 @@ SQLITE_PRIVATE int sqlite3BtreeCursor( Btree *p, /* The btree */ int iTable, /* Root page of table to open */ int wrFlag, /* 1 to write. 0 read-only */ - int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */ - void *pArg, /* First arg to xCompare() */ - BtCursor **ppCur /* Write new cursor here */ + struct KeyInfo *pKeyInfo, /* First arg to xCompare() */ + BtCursor *pCur /* Write new cursor here */ ){ int rc; sqlite3BtreeEnter(p); p->pBt->db = p->db; - rc = btreeCursor(p, iTable, wrFlag, xCmp, pArg, ppCur); + rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur); sqlite3BtreeLeave(p); return rc; } +SQLITE_PRIVATE int sqlite3BtreeCursorSize(){ + return sizeof(BtCursor); +} + /* @@ -30301,25 +32399,26 @@ SQLITE_PRIVATE int sqlite3BtreeCursor( ** when the last cursor is closed. */ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){ - BtShared *pBt = pCur->pBt; Btree *pBtree = pCur->pBtree; - - sqlite3BtreeEnter(pBtree); - pBt->db = pBtree->db; - clearCursorPosition(pCur); - if( pCur->pPrev ){ - pCur->pPrev->pNext = pCur->pNext; - }else{ - pBt->pCursor = pCur->pNext; + if( pBtree ){ + BtShared *pBt = pCur->pBt; + sqlite3BtreeEnter(pBtree); + pBt->db = pBtree->db; + clearCursorPosition(pCur); + if( pCur->pPrev ){ + pCur->pPrev->pNext = pCur->pNext; + }else{ + pBt->pCursor = pCur->pNext; + } + if( pCur->pNext ){ + pCur->pNext->pPrev = pCur->pPrev; + } + releasePage(pCur->pPage); + unlockBtreeIfUnused(pBt); + invalidateOverflowCache(pCur); + /* sqlite3_free(pCur); */ + sqlite3BtreeLeave(pBtree); } - if( pCur->pNext ){ - pCur->pNext->pPrev = pCur->pPrev; - } - releasePage(pCur->pPage); - unlockBtreeIfUnused(pBt); - invalidateOverflowCache(pCur); - sqlite3_free(pCur); - sqlite3BtreeLeave(pBtree); return SQLITE_OK; } @@ -30378,6 +32477,7 @@ SQLITE_PRIVATE void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){ static void getCellInfo(BtCursor *pCur){ if( pCur->info.nSize==0 ){ sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &pCur->info); + pCur->validNKey = 1; }else{ assertCellInfo(pCur); } @@ -30387,6 +32487,7 @@ SQLITE_PRIVATE void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){ #define getCellInfo(pCur) \ if( pCur->info.nSize==0 ){ \ sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &pCur->info); \ + pCur->validNKey = 1; \ }else{ \ assertCellInfo(pCur); \ } @@ -30880,6 +32981,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ pCur->pPage = pNewPage; pCur->idx = 0; pCur->info.nSize = 0; + pCur->validNKey = 0; if( pNewPage->nCell<1 ){ return SQLITE_CORRUPT_BKPT; } @@ -30931,6 +33033,7 @@ SQLITE_PRIVATE void sqlite3BtreeMoveToParent(BtCursor *pCur){ releasePage(pPage); pCur->pPage = pParent; pCur->info.nSize = 0; + pCur->validNKey = 0; assert( pParent->idxShift==0 ); pCur->idx = idxParent; } @@ -30969,6 +33072,8 @@ static int moveToRoot(BtCursor *pCur){ } pCur->idx = 0; pCur->info.nSize = 0; + pCur->atLast = 0; + pCur->validNKey = 0; if( pRoot->nCell==0 && !pRoot->leaf ){ Pgno subpage; assert( pRoot->pgno==1 ); @@ -31028,6 +33133,7 @@ static int moveToRightmost(BtCursor *pCur){ if( rc==SQLITE_OK ){ pCur->idx = pPage->nCell - 1; pCur->info.nSize = 0; + pCur->validNKey = 0; } return SQLITE_OK; } @@ -31074,18 +33180,20 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ assert( pCur->eState==CURSOR_VALID ); *pRes = 0; rc = moveToRightmost(pCur); + getCellInfo(pCur); + pCur->atLast = rc==SQLITE_OK; } } return rc; } -/* Move the cursor so that it points to an entry near pKey/nKey. -** Return a success code. +/* Move the cursor so that it points to an entry near the key +** specified by pKey/nKey/pUnKey. Return a success code. ** -** For INTKEY tables, only the nKey parameter is used. pKey is -** ignored. For other tables, nKey is the number of bytes of data -** in pKey. The comparison function specified when the cursor was -** created is used to compare keys. +** For INTKEY tables, only the nKey parameter is used. pKey +** and pUnKey must be NULL. For index tables, either pUnKey +** must point to a key that has already been unpacked, or else +** pKey/nKey describes a blob containing the key. ** ** If an exact match is not found, then the cursor is always ** left pointing at a leaf page which would hold the entry if it @@ -31110,14 +33218,31 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ SQLITE_PRIVATE int sqlite3BtreeMoveto( BtCursor *pCur, /* The cursor to be moved */ const void *pKey, /* The key content for indices. Not used by tables */ + UnpackedRecord *pUnKey,/* Unpacked version of pKey */ i64 nKey, /* Size of pKey. Or the key for tables */ int biasRight, /* If true, bias the search to the high end */ int *pRes /* Search result flag */ ){ int rc; + char aSpace[200]; assert( cursorHoldsMutex(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + + /* If the cursor is already positioned at the point we are trying + ** to move to, then just return without doing any work */ + if( pCur->eState==CURSOR_VALID && pCur->validNKey && pCur->pPage->intKey ){ + if( pCur->info.nKey==nKey ){ + *pRes = 0; + return SQLITE_OK; + } + if( pCur->atLast && pCur->info.nKeypPage->nCell==0 ); return SQLITE_OK; } + if( pCur->pPage->intKey ){ + /* We are given an SQL table to search. The key is the integer + ** rowid contained in nKey. pKey and pUnKey should both be NULL */ + assert( pUnKey==0 ); + assert( pKey==0 ); + }else if( pUnKey==0 ){ + /* We are to search an SQL index using a key encoded as a blob. + ** The blob is found at pKey and is nKey bytes in length. Unpack + ** this key so that we can use it. */ + assert( pKey!=0 ); + pUnKey = sqlite3VdbeRecordUnpack(pCur->pKeyInfo, nKey, pKey, + aSpace, sizeof(aSpace)); + if( pUnKey==0 ) return SQLITE_NOMEM; + }else{ + /* We are to search an SQL index using a key that is already unpacked + ** and handed to us in pUnKey. */ + assert( pKey==0 ); + } for(;;){ int lwr, upr; Pgno chldPg; @@ -31136,8 +33279,9 @@ SQLITE_PRIVATE int sqlite3BtreeMoveto( int c = -1; /* pRes return if table is empty must be -1 */ lwr = 0; upr = pPage->nCell-1; - if( !pPage->intKey && pKey==0 ){ - return SQLITE_CORRUPT_BKPT; + if( !pPage->intKey && pUnKey==0 ){ + rc = SQLITE_CORRUPT_BKPT; + goto moveto_finish; } if( biasRight ){ pCur->idx = upr; @@ -31148,6 +33292,7 @@ SQLITE_PRIVATE int sqlite3BtreeMoveto( void *pCellKey; i64 nCellKey; pCur->info.nSize = 0; + pCur->validNKey = 1; if( pPage->intKey ){ u8 *pCell; pCell = findCell(pPage, pCur->idx) + pPage->childPtrSize; @@ -31155,39 +33300,43 @@ SQLITE_PRIVATE int sqlite3BtreeMoveto( u32 dummy; pCell += getVarint32(pCell, &dummy); } - getVarint(pCell, (u64 *)&nCellKey); - if( nCellKeynKey ){ - c = +1; - }else{ + getVarint(pCell, (u64*)&nCellKey); + if( nCellKey==nKey ){ c = 0; + }else if( nCellKeynKey ); + c = +1; } }else{ int available; pCellKey = (void *)fetchPayload(pCur, &available, 0); nCellKey = pCur->info.nKey; if( available>=nCellKey ){ - c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey); + c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pUnKey); }else{ pCellKey = sqlite3_malloc( nCellKey ); - if( pCellKey==0 ) return SQLITE_NOMEM; - rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey); - c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey); - sqlite3_free(pCellKey); - if( rc ){ - return rc; + if( pCellKey==0 ){ + rc = SQLITE_NOMEM; + goto moveto_finish; } + rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey); + c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pUnKey); + sqlite3_free(pCellKey); + if( rc ) goto moveto_finish; } } if( c==0 ){ + pCur->info.nKey = nCellKey; if( pPage->leafData && !pPage->leaf ){ lwr = pCur->idx; upr = lwr - 1; break; }else{ if( pRes ) *pRes = 0; - return SQLITE_OK; + rc = SQLITE_OK; + goto moveto_finish; } } if( c<0 ){ @@ -31196,6 +33345,7 @@ SQLITE_PRIVATE int sqlite3BtreeMoveto( upr = pCur->idx-1; } if( lwr>upr ){ + pCur->info.nKey = nCellKey; break; } pCur->idx = (lwr+upr)/2; @@ -31212,16 +33362,22 @@ SQLITE_PRIVATE int sqlite3BtreeMoveto( if( chldPg==0 ){ assert( pCur->idx>=0 && pCur->idxpPage->nCell ); if( pRes ) *pRes = c; - return SQLITE_OK; + rc = SQLITE_OK; + goto moveto_finish; } pCur->idx = lwr; pCur->info.nSize = 0; + pCur->validNKey = 0; rc = moveToChild(pCur, chldPg); - if( rc ){ - return rc; - } + if( rc ) goto moveto_finish; } - /* NOT REACHED */ +moveto_finish: + if( pKey ){ + /* If we created our own unpacked key at the top of this + ** procedure, then destroy that key before returning. */ + sqlite3VdbeDeleteUnpackedRecord(pUnKey); + } + return rc; } @@ -31254,7 +33410,7 @@ SQLITE_PRIVATE sqlite3 *sqlite3BtreeCursorDb(const BtCursor *pCur){ ** was already pointing to the last entry in the database before ** this routine was called, then set *pRes=1. */ -static int btreeNext(BtCursor *pCur, int *pRes){ +SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ int rc; MemPage *pPage; @@ -31281,6 +33437,7 @@ static int btreeNext(BtCursor *pCur, int *pRes){ pCur->idx++; pCur->info.nSize = 0; + pCur->validNKey = 0; if( pCur->idx>=pPage->nCell ){ if( !pPage->leaf ){ rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); @@ -31313,12 +33470,6 @@ static int btreeNext(BtCursor *pCur, int *pRes){ rc = moveToLeftmost(pCur); return rc; } -SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ - int rc; - assert( cursorHoldsMutex(pCur) ); - rc = btreeNext(pCur, pRes); - return rc; -} /* @@ -31327,7 +33478,7 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ ** was already pointing to the first entry in the database before ** this routine was called, then set *pRes=1. */ -static int btreePrevious(BtCursor *pCur, int *pRes){ +SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ int rc; Pgno pgno; MemPage *pPage; @@ -31337,6 +33488,7 @@ static int btreePrevious(BtCursor *pCur, int *pRes){ if( rc!=SQLITE_OK ){ return rc; } + pCur->atLast = 0; if( CURSOR_INVALID==pCur->eState ){ *pRes = 1; return SQLITE_OK; @@ -31370,6 +33522,7 @@ static int btreePrevious(BtCursor *pCur, int *pRes){ } pCur->idx--; pCur->info.nSize = 0; + pCur->validNKey = 0; if( pPage->leafData && !pPage->leaf ){ rc = sqlite3BtreePrevious(pCur, pRes); }else{ @@ -31379,12 +33532,6 @@ static int btreePrevious(BtCursor *pCur, int *pRes){ *pRes = 0; return rc; } -SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ - int rc; - assert( cursorHoldsMutex(pCur) ); - rc = btreePrevious(pCur, pRes); - return rc; -} /* ** Allocate a new page from the database file. @@ -31961,16 +34108,12 @@ static int reparentChildPages(MemPage *pPage){ for(i=0; inCell; i++){ u8 *pCell = findCell(pPage, i); - if( !pPage->leaf ){ - rc = reparentPage(pBt, get4byte(pCell), pPage, i); - if( rc!=SQLITE_OK ) return rc; - } - } - if( !pPage->leaf ){ - rc = reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]), - pPage, i); - pPage->idxShift = 0; + rc = reparentPage(pBt, get4byte(pCell), pPage, i); + if( rc!=SQLITE_OK ) return rc; } + rc = reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]), + pPage, i); + pPage->idxShift = 0; return rc; } @@ -32114,7 +34257,7 @@ static void assemblePage( MemPage *pPage, /* The page to be assemblied */ int nCell, /* The number of cells to add to this page */ u8 **apCell, /* Pointers to cell bodies */ - int *aSize /* Sizes of the cells */ + u16 *aSize /* Sizes of the cells */ ){ int i; /* Loop counter */ int totalSize; /* Total size of all cells */ @@ -32192,7 +34335,7 @@ static int balance_quick(MemPage *pPage, MemPage *pParent){ MemPage *pNew; Pgno pgnoNew; u8 *pCell; - int szCell; + u16 szCell; CellInfo info; BtShared *pBt = pPage->pBt; int parentIdx = pParent->nCell; /* pParent new divider cell index */ @@ -32318,7 +34461,7 @@ static int balance_nonroot(MemPage *pPage){ int cntNew[NB+2]; /* Index in aCell[] of cell after i-th page */ int szNew[NB+2]; /* Combined size of cells place on i-th page */ u8 **apCell = 0; /* All cells begin balanced */ - int *szCell; /* Local size of all cells in apCell[] */ + u16 *szCell; /* Local size of all cells in apCell[] */ u8 *aCopy[NB]; /* Space for holding data of apCopy[] */ u8 *aSpace; /* Space to hold copies of dividers cells */ #ifndef SQLITE_OMIT_AUTOVACUUM @@ -32431,25 +34574,25 @@ static int balance_nonroot(MemPage *pPage){ nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow; } - /* Make nMaxCells a multiple of 2 in order to preserve 8-byte + /* Make nMaxCells a multiple of 4 in order to preserve 8-byte ** alignment */ - nMaxCells = (nMaxCells + 1)&~1; + nMaxCells = (nMaxCells + 3)&~3; /* ** Allocate space for memory structures */ apCell = sqlite3_malloc( - nMaxCells*sizeof(u8*) /* apCell */ - + nMaxCells*sizeof(int) /* szCell */ - + ROUND8(sizeof(MemPage))*NB /* aCopy */ - + pBt->pageSize*(5+NB) /* aSpace */ - + (ISAUTOVACUUM ? nMaxCells : 0) /* aFrom */ + nMaxCells*sizeof(u8*) /* apCell */ + + nMaxCells*sizeof(u16) /* szCell */ + + (ROUND8(sizeof(MemPage))+pBt->pageSize)*NB /* aCopy */ + + pBt->pageSize*5 /* aSpace */ + + (ISAUTOVACUUM ? nMaxCells : 0) /* aFrom */ ); if( apCell==0 ){ rc = SQLITE_NOMEM; goto balance_cleanup; } - szCell = (int*)&apCell[nMaxCells]; + szCell = (u16*)&apCell[nMaxCells]; aCopy[0] = (u8*)&szCell[nMaxCells]; assert( ((aCopy[0] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */ for(i=1; ipParent==0 ); assert( pPage->nCell==0 ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); pBt = pPage->pBt; mxCellPerPage = MX_CELL(pBt); - apCell = sqlite3_malloc( mxCellPerPage*(sizeof(u8*)+sizeof(int)) ); + apCell = sqlite3_malloc( mxCellPerPage*(sizeof(u8*)+sizeof(u16)) ); if( apCell==0 ) return SQLITE_NOMEM; - szCell = (int*)&apCell[mxCellPerPage]; + szCell = (u16*)&apCell[mxCellPerPage]; if( pPage->leaf ){ /* The table is completely empty */ TRACE(("BALANCE: empty table %d\n", pPage->pgno)); @@ -33086,6 +35229,16 @@ static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){ return SQLITE_OK; } +/* +** Make sure pBt->pTmpSpace points to an allocation of +** MX_CELL_SIZE(pBt) bytes. +*/ +static void allocateTempSpace(BtShared *pBt){ + if( !pBt->pTmpSpace ){ + pBt->pTmpSpace = sqlite3_malloc(MX_CELL_SIZE(pBt)); + } +} + /* ** Insert a new record into the BTree. The key is given by (pKey,nKey) ** and the data is given by (pData,nData). The cursor is used only to @@ -33132,7 +35285,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( clearCursorPosition(pCur); if( SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) || - SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc)) + SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, 0, nKey, appendBias, &loc)) ){ return rc; } @@ -33144,14 +35297,15 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( pCur->pgnoRoot, nKey, nData, pPage->pgno, loc==0 ? "overwrite" : "new entry")); assert( pPage->isInit ); - newCell = sqlite3_malloc( MX_CELL_SIZE(pBt) ); + allocateTempSpace(pBt); + newCell = pBt->pTmpSpace; if( newCell==0 ) return SQLITE_NOMEM; rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew); if( rc ) goto end_insert; assert( szNew==cellSizePtr(pPage, newCell) ); assert( szNew<=MX_CELL_SIZE(pBt) ); if( loc==0 && CURSOR_VALID==pCur->eState ){ - int szOld; + u16 szOld; assert( pCur->idx>=0 && pCur->idxnCell ); rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ){ @@ -33169,6 +35323,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( assert( pPage->leaf ); pCur->idx++; pCur->info.nSize = 0; + pCur->validNKey = 0; }else{ assert( pPage->leaf ); } @@ -33181,7 +35336,6 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( moveToRoot(pCur); } end_insert: - sqlite3_free(newCell); return rc; } @@ -33263,14 +35417,15 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){ rc = sqlite3PagerWrite(leafCur.pPage->pDbPage); } if( rc==SQLITE_OK ){ - int szNext; + u16 szNext; TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n", pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno)); dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell)); pNext = findCell(leafCur.pPage, leafCur.idx); szNext = cellSizePtr(leafCur.pPage, pNext); assert( MX_CELL_SIZE(pBt)>=szNext+4 ); - tempCell = sqlite3_malloc( MX_CELL_SIZE(pBt) ); + allocateTempSpace(pBt); + tempCell = pBt->pTmpSpace; if( tempCell==0 ){ rc = SQLITE_NOMEM; } @@ -33286,7 +35441,6 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){ rc = balance(leafCur.pPage, 0); } } - sqlite3_free(tempCell); sqlite3BtreeReleaseTempCursor(&leafCur); }else{ TRACE(("DELETE: table=%d delete from leaf %d\n", @@ -34048,7 +36202,7 @@ static int checkTreePage( cellStart = hdr + 12 - 4*pPage->leaf; for(i=0; i=usableSize || pc<0 ){ checkAppendMsg(pCheck, 0, @@ -34250,62 +36404,209 @@ SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *p){ ** Copy the complete content of pBtFrom into pBtTo. A transaction ** must be active for both files. ** -** The size of file pBtFrom may be reduced by this operation. -** If anything goes wrong, the transaction on pBtFrom is rolled back. +** 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, nPage, nToPage, iSkip; + 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; if( pTo->inTrans!=TRANS_WRITE || pFrom->inTrans!=TRANS_WRITE ){ return SQLITE_ERROR; } - if( pBtTo->pCursor ) return SQLITE_BUSY; - nToPage = sqlite3PagerPagecount(pBtTo->pPager); - nPage = sqlite3PagerPagecount(pBtFrom->pPager); - iSkip = PENDING_BYTE_PAGE(pBtTo); - for(i=1; rc==SQLITE_OK && i<=nPage; i++){ - DbPage *pDbPage; - if( i==iSkip ) continue; - rc = sqlite3PagerGet(pBtFrom->pPager, i, &pDbPage); - if( rc ) break; - rc = sqlite3PagerOverwrite(pBtTo->pPager, i, sqlite3PagerGetData(pDbPage)); - sqlite3PagerUnref(pDbPage); + if( pBtTo->pCursor ){ + return SQLITE_BUSY; } - /* If the file is shrinking, journal the pages that are being truncated - ** so that they can be rolled back if the commit fails. + nToPage = sqlite3PagerPagecount(pBtTo->pPager); + nFromPage = sqlite3PagerPagecount(pBtFrom->pPager); + 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. */ - for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){ - DbPage *pDbPage; - if( i==iSkip ) continue; - rc = sqlite3PagerGet(pBtTo->pPager, i, &pDbPage); - if( rc ) break; - rc = sqlite3PagerWrite(pDbPage); - sqlite3PagerDontWrite(pDbPage); - /* 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 loop: to put pages on the rollback journal. */ - sqlite3PagerUnref(pDbPage); + nNewPage = ((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; + rc = sqlite3PagerGet(pBtTo->pPager, i, &pDbPage); + if( rc ){ + break; + } + rc = sqlite3PagerWrite(pDbPage); + if( rc ){ + break; + } + if( 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. + */ + 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 && iOffpPager, 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 ) sqlite3PagerUnref(pToPage); + } } - if( !rc && nPagepPager, nPage); + + /* 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 ){ + if( nFromPageSize!=nToPageSize ){ + 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, 0, 1); + if( iSizeiPending){ + i64 iOff; + for( + iOff=iPending; + rc==SQLITE_OK && iOff<(iPending+nToPageSize); + iOff += nFromPageSize + ){ + DbPage *pFromPage = 0; + Pgno iFrom = (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); + } + }else{ + rc = sqlite3PagerTruncate(pBtTo->pPager, nNewPage); + } + if( rc==SQLITE_OK ){ + pBtTo->pageSizeFixed = 0; + } } if( rc ){ sqlite3BtreeRollback(pTo); } + return rc; } SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ @@ -34393,13 +36694,17 @@ SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ */ SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ int rc = SQLITE_OK; - u8 lockType = (isWriteLock?WRITE_LOCK:READ_LOCK); - sqlite3BtreeEnter(p); - rc = queryTableLock(p, iTab, lockType); - if( rc==SQLITE_OK ){ - rc = lockTable(p, iTab, lockType); + if( p->sharable ){ + 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); + } + sqlite3BtreeLeave(p); } - sqlite3BtreeLeave(p); return rc; } #endif @@ -34480,14 +36785,26 @@ SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *pCur){ ** UPDATE and DELETE statements. */ +/* +** Constants FIFOSIZE_FIRST and FIFOSIZE_MAX are the initial +** number of entries in a fifo page and the maximum number of +** entries in a fifo page. +*/ +#define FIFOSIZE_FIRST (((128-sizeof(FifoPage))/8)+1) +#ifdef SQLITE_MALLOC_SOFT_LIMIT +# define FIFOSIZE_MAX (((SQLITE_MALLOC_SOFT_LIMIT-sizeof(FifoPage))/8)+1) +#else +# define FIFOSIZE_MAX (((262144-sizeof(FifoPage))/8)+1) +#endif + /* ** Allocate a new FifoPage and return a pointer to it. Return NULL if ** we run out of memory. Leave space on the page for nEntry entries. */ static FifoPage *allocateFifoPage(int nEntry){ FifoPage *pPage; - if( nEntry>32767 ){ - nEntry = 32767; + if( nEntry>FIFOSIZE_MAX ){ + nEntry = FIFOSIZE_MAX; } pPage = sqlite3_malloc( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) ); if( pPage ){ @@ -34515,7 +36832,7 @@ SQLITE_PRIVATE int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){ FifoPage *pPage; pPage = pFifo->pLast; if( pPage==0 ){ - pPage = pFifo->pLast = pFifo->pFirst = allocateFifoPage(20); + pPage = pFifo->pLast = pFifo->pFirst = allocateFifoPage(FIFOSIZE_FIRST); if( pPage==0 ){ return SQLITE_NOMEM; } @@ -34638,33 +36955,73 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ #endif } +/* +** Make sure pMem->z points to a writable allocation of at least +** n bytes. +** +** If the memory cell currently contains string or blob data +** and the third argument passed to this function is true, the +** current content of the cell is preserved. Otherwise, it may +** be discarded. +** +** This function sets the MEM_Dyn flag and clears any xDel callback. +** It also clears MEM_Ephem and MEM_Static. If the preserve flag is +** not set, Mem.n is zeroed. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){ + assert( 1 >= + ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) + + (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) + + ((pMem->flags&MEM_Ephem) ? 1 : 0) + + ((pMem->flags&MEM_Static) ? 1 : 0) + ); + + if( !pMem->zMalloc || sqlite3MallocSize(pMem->zMalloc)32?n:32); + if( preserve && pMem->z==pMem->zMalloc ){ + pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); + if( !pMem->z ){ + pMem->flags = MEM_Null; + } + preserve = 0; + }else{ + sqlite3_free(pMem->zMalloc); + pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); + } + } + + if( preserve && pMem->z && pMem->zMalloc && pMem->z!=pMem->zMalloc ){ + memcpy(pMem->zMalloc, pMem->z, pMem->n); + } + if( pMem->flags&MEM_Dyn && pMem->xDel ){ + pMem->xDel((void *)(pMem->z)); + } + + pMem->z = pMem->zMalloc; + pMem->flags &= ~(MEM_Ephem|MEM_Static); + pMem->xDel = 0; + return (pMem->z ? SQLITE_OK : SQLITE_NOMEM); +} + /* ** Make the given Mem object MEM_Dyn. ** ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. */ SQLITE_PRIVATE int sqlite3VdbeMemDynamicify(Mem *pMem){ - int n; - u8 *z; + int f; assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); expandBlob(pMem); - if( (pMem->flags & (MEM_Ephem|MEM_Static|MEM_Short))==0 ){ - return SQLITE_OK; + f = pMem->flags; + if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){ + if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){ + return SQLITE_NOMEM; + } + pMem->z[pMem->n] = 0; + pMem->z[pMem->n+1] = 0; + pMem->flags |= MEM_Term; } - assert( (pMem->flags & MEM_Dyn)==0 ); - n = pMem->n; - assert( pMem->flags & (MEM_Str|MEM_Blob) ); - z = sqlite3DbMallocRaw(pMem->db, n+2 ); - if( z==0 ){ - return SQLITE_NOMEM; - } - pMem->flags |= MEM_Dyn|MEM_Term; - pMem->xDel = 0; - memcpy(z, pMem->z, n ); - z[n] = 0; - z[n+1] = 0; - pMem->z = (char*)z; - pMem->flags &= ~(MEM_Ephem|MEM_Static|MEM_Short); + return SQLITE_OK; } @@ -34675,24 +37032,22 @@ SQLITE_PRIVATE int sqlite3VdbeMemDynamicify(Mem *pMem){ #ifndef SQLITE_OMIT_INCRBLOB SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){ if( pMem->flags & MEM_Zero ){ - char *pNew; int nByte; - assert( (pMem->flags & MEM_Blob)!=0 ); - nByte = pMem->n + pMem->u.i; - if( nByte<=0 ) nByte = 1; + assert( pMem->flags&MEM_Blob ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - pNew = sqlite3DbMallocRaw(pMem->db, nByte); - if( pNew==0 ){ + + /* Set nByte to the number of bytes required to store the expanded blob. */ + nByte = pMem->n + pMem->u.i; + if( nByte<=0 ){ + nByte = 1; + } + if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){ return SQLITE_NOMEM; } - memcpy(pNew, pMem->z, pMem->n); - memset(&pNew[pMem->n], 0, pMem->u.i); - sqlite3VdbeMemRelease(pMem); - pMem->z = pNew; + + memset(&pMem->z[pMem->n], 0, pMem->u.i); pMem->n += pMem->u.i; - pMem->u.i = 0; - pMem->flags &= ~(MEM_Zero|MEM_Static|MEM_Ephem|MEM_Short|MEM_Term); - pMem->flags |= MEM_Dyn; + pMem->flags &= ~(MEM_Zero|MEM_Term); } return SQLITE_OK; } @@ -34706,33 +37061,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){ ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. */ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ - int n; - u8 *z; - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - expandBlob(pMem); - if( (pMem->flags & (MEM_Ephem|MEM_Static))==0 ){ - return SQLITE_OK; - } - assert( (pMem->flags & MEM_Dyn)==0 ); - assert( pMem->flags & (MEM_Str|MEM_Blob) ); - if( (n = pMem->n)+2zShort) ){ - z = (u8*)pMem->zShort; - pMem->flags |= MEM_Short|MEM_Term; - }else{ - z = sqlite3DbMallocRaw(pMem->db, n+2 ); - if( z==0 ){ - return SQLITE_NOMEM; - } - pMem->flags |= MEM_Dyn|MEM_Term; - pMem->xDel = 0; - } - memcpy(z, pMem->z, n ); - z[n] = 0; - z[n+1] = 0; - pMem->z = (char*)z; - pMem->flags &= ~(MEM_Ephem|MEM_Static); - assert(0==(1&(int)pMem->z)); - return SQLITE_OK; + return sqlite3VdbeMemDynamicify(pMem); } /* @@ -34743,27 +37072,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){ if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){ return SQLITE_OK; /* Nothing to do */ } - if( pMem->flags & (MEM_Static|MEM_Ephem) ){ - return sqlite3VdbeMemMakeWriteable(pMem); - }else{ - char *z; - sqlite3VdbeMemExpandBlob(pMem); - z = sqlite3DbMallocRaw(pMem->db, pMem->n+2); - if( !z ){ - return SQLITE_NOMEM; - } - memcpy(z, pMem->z, pMem->n); - z[pMem->n] = 0; - z[pMem->n+1] = 0; - if( pMem->xDel ){ - pMem->xDel(pMem->z); - }else{ - sqlite3_free(pMem->z); - } - pMem->xDel = 0; - pMem->z = z; - pMem->flags |= MEM_Term; + if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){ + return SQLITE_NOMEM; } + pMem->z[pMem->n] = 0; + pMem->z[pMem->n+1] = 0; + pMem->flags |= MEM_Term; return SQLITE_OK; } @@ -34783,29 +37097,32 @@ SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, int enc){ int rc = SQLITE_OK; int fg = pMem->flags; - char *z = pMem->zShort; + const int nByte = 32; assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( !(fg&MEM_Zero) ); assert( !(fg&(MEM_Str|MEM_Blob)) ); assert( fg&(MEM_Int|MEM_Real) ); - /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8 + if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){ + return SQLITE_NOMEM; + } + + /* For a Real or Integer, use sqlite3_mprintf() to produce the UTF-8 ** string representation of the value. Then, if the required encoding ** is UTF-16le or UTF-16be do a translation. ** ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16. */ if( fg & MEM_Int ){ - sqlite3_snprintf(NBFS, z, "%lld", pMem->u.i); + sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i); }else{ assert( fg & MEM_Real ); - sqlite3_snprintf(NBFS, z, "%!.15g", pMem->r); + sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->r); } - pMem->n = strlen(z); - pMem->z = z; + pMem->n = strlen(pMem->z); pMem->enc = SQLITE_UTF8; - pMem->flags |= MEM_Str | MEM_Short | MEM_Term; + pMem->flags |= MEM_Str|MEM_Term; sqlite3VdbeChangeEncoding(pMem, enc); return rc; } @@ -34825,46 +37142,48 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); ctx.s.flags = MEM_Null; - ctx.s.z = pMem->zShort; ctx.s.db = pMem->db; + ctx.s.zMalloc = 0; ctx.pMem = pMem; ctx.pFunc = pFunc; ctx.isError = 0; pFunc->xFinalize(&ctx); - if( pMem->z && pMem->z!=pMem->zShort ){ - sqlite3_free( pMem->z ); - } + assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel ); + sqlite3_free(pMem->zMalloc); *pMem = ctx.s; - if( pMem->flags & MEM_Short ){ - pMem->z = pMem->zShort; - } rc = (ctx.isError?SQLITE_ERROR:SQLITE_OK); } return rc; } +/* +** If the memory cell contains a string value that must be freed by +** invoking an external callback, free it now. Calling this function +** does not free any Mem.zMalloc buffer. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){ + assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) ); + if( p->flags&MEM_Agg ){ + sqlite3VdbeMemFinalize(p, p->u.pDef); + assert( (p->flags & MEM_Agg)==0 ); + sqlite3VdbeMemRelease(p); + }else if( p->flags&MEM_Dyn && p->xDel ){ + p->xDel((void *)p->z); + p->xDel = 0; + } +} + /* ** Release any memory held by the Mem. This may leave the Mem in an ** inconsistent state, for example with (Mem.z==0) and ** (Mem.type==SQLITE_TEXT). */ SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){ - assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) ); - if( p->flags & (MEM_Dyn|MEM_Agg) ){ - if( p->xDel ){ - if( p->flags & MEM_Agg ){ - sqlite3VdbeMemFinalize(p, p->u.pDef); - assert( (p->flags & MEM_Agg)==0 ); - sqlite3VdbeMemRelease(p); - }else{ - p->xDel((void *)p->z); - } - }else{ - sqlite3_free(p->z); - } - p->z = 0; - p->xDel = 0; - } + sqlite3VdbeMemReleaseExternal(p); + sqlite3_free(p->zMalloc); + p->z = 0; + p->zMalloc = 0; + p->xDel = 0; } /* @@ -34973,14 +37292,17 @@ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ } } +static void setTypeFlag(Mem *pMem, int f){ + MemSetTypeFlag(pMem, f); +} + /* ** Convert pMem to type integer. Invalidate any prior representations. */ SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); pMem->u.i = sqlite3VdbeIntValue(pMem); - sqlite3VdbeMemRelease(pMem); - pMem->flags = MEM_Int; + setTypeFlag(pMem, MEM_Int); return SQLITE_OK; } @@ -34991,8 +37313,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){ SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); pMem->r = sqlite3VdbeRealValue(pMem); - sqlite3VdbeMemRelease(pMem); - pMem->flags = MEM_Real; + setTypeFlag(pMem, MEM_Real); return SQLITE_OK; } @@ -35013,8 +37334,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ sqlite3VdbeMemIntegerify(pMem); }else{ pMem->r = r1; - pMem->flags = MEM_Real; - sqlite3VdbeMemRelease(pMem); + setTypeFlag(pMem, MEM_Real); } return SQLITE_OK; } @@ -35023,10 +37343,8 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ ** Delete any previous value and set the value stored in *pMem to NULL. */ SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){ - sqlite3VdbeMemRelease(pMem); - pMem->flags = MEM_Null; + setTypeFlag(pMem, MEM_Null); pMem->type = SQLITE_NULL; - pMem->n = 0; } /* @@ -35035,12 +37353,12 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){ */ SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ sqlite3VdbeMemRelease(pMem); - pMem->flags = MEM_Blob|MEM_Zero|MEM_Short; + setTypeFlag(pMem, MEM_Blob); + pMem->flags = MEM_Blob|MEM_Zero; pMem->type = SQLITE_BLOB; pMem->n = 0; if( n<0 ) n = 0; pMem->u.i = n; - pMem->z = pMem->zShort; pMem->enc = SQLITE_UTF8; } @@ -35075,16 +37393,22 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ ** too large - whose size exceeds SQLITE_MAX_LENGTH. */ SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){ + assert( p->db!=0 ); if( p->flags & (MEM_Str|MEM_Blob) ){ int n = p->n; if( p->flags & MEM_Zero ){ n += p->u.i; } - return n>SQLITE_MAX_LENGTH; + return n>p->db->aLimit[SQLITE_LIMIT_LENGTH]; } return 0; } +/* +** Size of struct Mem not including the Mem.zMalloc member. +*/ +#define MEMCELLSIZE (size_t)(&(((Mem *)0)->zMalloc)) + /* ** Make an shallow copy of pFrom into pTo. Prior contents of ** pTo are freed. The pFrom->z field is not duplicated. If @@ -35092,11 +37416,11 @@ SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){ ** and flags gets srcType (either MEM_Ephem or MEM_Static). */ SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ - sqlite3VdbeMemRelease(pTo); - memcpy(pTo, pFrom, sizeof(*pFrom)-sizeof(pFrom->zShort)); + sqlite3VdbeMemReleaseExternal(pTo); + memcpy(pTo, pFrom, MEMCELLSIZE); pTo->xDel = 0; - if( pTo->flags & (MEM_Str|MEM_Blob) ){ - pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short|MEM_Ephem); + if( (pFrom->flags&MEM_Dyn)!=0 || pFrom->z==pFrom->zMalloc ){ + pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem); assert( srcType==MEM_Ephem || srcType==MEM_Static ); pTo->flags |= srcType; } @@ -35107,13 +37431,19 @@ SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int sr ** freed before the copy is made. */ SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ - int rc; - sqlite3VdbeMemShallowCopy(pTo, pFrom, MEM_Ephem); - if( pTo->flags & MEM_Ephem ){ - rc = sqlite3VdbeMemMakeWriteable(pTo); - }else{ - rc = SQLITE_OK; + int rc = SQLITE_OK; + + sqlite3VdbeMemReleaseExternal(pTo); + memcpy(pTo, pFrom, MEMCELLSIZE); + pTo->flags &= ~MEM_Dyn; + + if( pTo->flags&(MEM_Str|MEM_Blob) ){ + if( 0==(pFrom->flags&MEM_Static) ){ + pTo->flags |= MEM_Ephem; + rc = sqlite3VdbeMemMakeWriteable(pTo); + } } + return rc; } @@ -35127,19 +37457,22 @@ SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) ); assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) ); assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db ); - if( pTo->flags & MEM_Dyn ){ - sqlite3VdbeMemRelease(pTo); - } + + sqlite3VdbeMemRelease(pTo); memcpy(pTo, pFrom, sizeof(Mem)); - if( pFrom->flags & MEM_Short ){ - pTo->z = pTo->zShort; - } pFrom->flags = MEM_Null; pFrom->xDel = 0; + pFrom->zMalloc = 0; } /* ** Change the value of a Mem to be a string or a BLOB. +** +** The memory management strategy depends on the value of the xDel +** parameter. If the value passed is SQLITE_TRANSIENT, then the +** string is copied into a (possibly existing) buffer managed by the +** Mem structure. Otherwise, any existing buffer is freed and the +** pointer copied. */ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( Mem *pMem, /* Memory cell to set to string value */ @@ -35148,59 +37481,59 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( u8 enc, /* Encoding of z. 0 for BLOBs */ void (*xDel)(void*) /* Destructor function */ ){ + int nByte = n; /* New value for pMem->n */ + int flags = 0; /* New value for pMem->flags */ + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - sqlite3VdbeMemRelease(pMem); + + /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ if( !z ){ - pMem->flags = MEM_Null; - pMem->type = SQLITE_NULL; + sqlite3VdbeMemSetNull(pMem); return SQLITE_OK; } - pMem->z = (char *)z; - if( xDel==SQLITE_STATIC ){ - pMem->flags = MEM_Static; - }else if( xDel==SQLITE_TRANSIENT ){ - pMem->flags = MEM_Ephem; - }else{ - pMem->flags = MEM_Dyn; - pMem->xDel = xDel; + + flags = (enc==0?MEM_Blob:MEM_Str); + if( nByte<0 ){ + assert( enc!=0 ); + if( enc==SQLITE_UTF8 ){ + for(nByte=0; z[nByte]; nByte++){} + }else{ + for(nByte=0; z[nByte] | z[nByte+1]; nByte+=2){} + } + flags |= MEM_Term; } - pMem->enc = enc; - pMem->type = enc==0 ? SQLITE_BLOB : SQLITE_TEXT; - pMem->n = n; + /* The following block sets the new values of Mem.z and Mem.xDel. It + ** also sets a flag in local variable "flags" to indicate the memory + ** management (one of MEM_Dyn or MEM_Static). + */ + if( xDel==SQLITE_TRANSIENT ){ + int nAlloc = nByte; + if( flags&MEM_Term ){ + nAlloc += (enc==SQLITE_UTF8?1:2); + } + if( sqlite3VdbeMemGrow(pMem, nAlloc, 0) ){ + return SQLITE_NOMEM; + } + memcpy(pMem->z, z, nAlloc); + }else{ + sqlite3VdbeMemRelease(pMem); + pMem->z = (char *)z; + pMem->xDel = xDel; + flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn); + } - assert( enc==0 || enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE - || enc==SQLITE_UTF16BE ); - switch( enc ){ - case 0: - pMem->flags |= MEM_Blob; - pMem->enc = SQLITE_UTF8; - break; - - case SQLITE_UTF8: - pMem->flags |= MEM_Str; - if( n<0 ){ - pMem->n = strlen(z); - pMem->flags |= MEM_Term; - } - break; + pMem->n = nByte; + pMem->flags = flags; + pMem->enc = (enc==0 ? SQLITE_UTF8 : enc); + pMem->type = (enc==0 ? SQLITE_BLOB : SQLITE_TEXT); #ifndef SQLITE_OMIT_UTF16 - case SQLITE_UTF16LE: - case SQLITE_UTF16BE: - pMem->flags |= MEM_Str; - if( pMem->n<0 ){ - pMem->n = sqlite3Utf16ByteLen(pMem->z,-1); - pMem->flags |= MEM_Term; - } - if( sqlite3VdbeMemHandleBom(pMem) ){ - return SQLITE_NOMEM; - } -#endif /* SQLITE_OMIT_UTF16 */ - } - if( pMem->flags&MEM_Ephem ){ - return sqlite3VdbeMemMakeWriteable(pMem); + if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ + return SQLITE_NOMEM; } +#endif + return SQLITE_OK; } @@ -35348,6 +37681,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( char *zData; /* Data from the btree layer */ int available = 0; /* Number of bytes available on the local btree page */ sqlite3 *db; /* Database connection */ + int rc = SQLITE_OK; db = sqlite3BtreeCursorDb(pCur); assert( sqlite3_mutex_held(db->mutex) ); @@ -35358,49 +37692,28 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( } assert( zData!=0 ); - pMem->db = db; - pMem->n = amt; - if( offset+amt<=available ){ + if( offset+amt<=available && ((pMem->flags&MEM_Dyn)==0 || pMem->xDel) ){ + sqlite3VdbeMemRelease(pMem); pMem->z = &zData[offset]; pMem->flags = MEM_Blob|MEM_Ephem; - }else{ - int rc; - if( amt>NBFS-2 ){ - zData = (char *)sqlite3DbMallocRaw(db, amt+2); - if( !zData ){ - return SQLITE_NOMEM; - } - pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term; - pMem->xDel = 0; - }else{ - zData = &(pMem->zShort[0]); - pMem->flags = MEM_Blob|MEM_Short|MEM_Term; - } - pMem->z = zData; + }else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){ + pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term; pMem->enc = 0; pMem->type = SQLITE_BLOB; - if( key ){ - rc = sqlite3BtreeKey(pCur, offset, amt, zData); + rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z); }else{ - rc = sqlite3BtreeData(pCur, offset, amt, zData); + rc = sqlite3BtreeData(pCur, offset, amt, pMem->z); } - zData[amt] = 0; - zData[amt+1] = 0; + pMem->z[amt] = 0; + pMem->z[amt+1] = 0; if( rc!=SQLITE_OK ){ - if( amt>NBFS-2 ){ - assert( zData!=pMem->zShort ); - assert( pMem->flags & MEM_Dyn ); - sqlite3_free(zData); - } else { - assert( zData==pMem->zShort ); - assert( pMem->flags & MEM_Short ); - } - return rc; + sqlite3VdbeMemRelease(pMem); } } + pMem->n = amt; - return SQLITE_OK; + return rc; } #if 0 @@ -35476,7 +37789,7 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ expandBlob(pVal); if( pVal->flags&MEM_Str ){ sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); - if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){ + if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(sqlite3_intptr_t)pVal->z) ){ assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ return 0; @@ -35486,7 +37799,7 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ }else{ assert( (pVal->flags&MEM_Blob)==0 ); sqlite3VdbeMemStringify(pVal, enc); - assert( 0==(1&(int)pVal->z) ); + assert( 0==(1&(sqlite3_intptr_t)pVal->z) ); } assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0 || pVal->db->mallocFailed ); @@ -35598,7 +37911,7 @@ SQLITE_PRIVATE void sqlite3ValueSetStr( */ SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){ if( !v ) return; - sqlite3ValueSetStr(v, 0, 0, SQLITE_UTF8, SQLITE_STATIC); + sqlite3VdbeMemRelease((Mem *)v); sqlite3_free(v); } @@ -35641,11 +37954,11 @@ SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){ /* ** When debugging the code generator in a symbolic debugger, one can -** set the sqlite3_vdbe_addop_trace to 1 and all opcodes will be printed +** set the sqlite3VdbeAddopTrace to 1 and all opcodes will be printed ** as they are added to the instruction stream. */ #ifdef SQLITE_DEBUG -SQLITE_API int sqlite3_vdbe_addop_trace = 0; +SQLITE_PRIVATE int sqlite3VdbeAddopTrace = 0; #endif @@ -35727,14 +38040,10 @@ SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe *p, FILE *trace){ */ static void resizeOpArray(Vdbe *p, int N){ VdbeOp *pNew; - int oldSize = p->nOpAlloc; pNew = sqlite3DbRealloc(p->db, p->aOp, N*sizeof(Op)); if( pNew ){ p->nOpAlloc = N; p->aOp = pNew; - if( N>oldSize ){ - memset(&p->aOp[oldSize], 0, (N-oldSize)*sizeof(Op)); - } } } @@ -35761,7 +38070,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ i = p->nOp; assert( p->magic==VDBE_MAGIC_INIT ); if( p->nOpAlloc<=i ){ - resizeOpArray(p, p->nOpAlloc*2 + 100); + resizeOpArray(p, p->nOpAlloc ? p->nOpAlloc*2 : 1024/sizeof(Op)); if( p->db->mallocFailed ){ return 0; } @@ -35769,6 +38078,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ p->nOp++; pOp = &p->aOp[i]; pOp->opcode = op; + pOp->p5 = 0; pOp->p1 = p1; pOp->p2 = p2; pOp->p3 = p3; @@ -35776,7 +38086,12 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ pOp->p4type = P4_NOTUSED; p->expired = 0; #ifdef SQLITE_DEBUG - if( sqlite3_vdbe_addop_trace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]); + pOp->zComment = 0; + if( sqlite3VdbeAddopTrace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]); +#endif +#ifdef VDBE_PROFILE + pOp->cycles = 0; + pOp->cnt = 0; #endif return i; } @@ -35954,7 +38269,8 @@ SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp) int addr; assert( p->magic==VDBE_MAGIC_INIT ); if( p->nOp + nOp > p->nOpAlloc ){ - resizeOpArray(p, p->nOp*2 + nOp); + resizeOpArray(p, p->nOpAlloc ? p->nOpAlloc*2 : 1024/sizeof(Op)); + assert( p->nOp+nOp<=p->nOpAlloc || p->db->mallocFailed ); } if( p->db->mallocFailed ){ return 0; @@ -35978,7 +38294,8 @@ SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp) pOut->p4.p = 0; pOut->p5 = 0; #ifdef SQLITE_DEBUG - if( sqlite3_vdbe_addop_trace ){ + pOut->zComment = 0; + if( sqlite3VdbeAddopTrace ){ sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]); } #endif @@ -36147,7 +38464,9 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int freeP4(pOp->p4type, pOp->p4.p); pOp->p4.p = 0; if( n==P4_INT32 ){ - pOp->p4.i = (int)zP4; + /* Note: this cast is safe, because the origin data point was an int + ** that was cast to a (const char *). */ + pOp->p4.i = (int)(sqlite3_intptr_t)zP4; pOp->p4type = n; }else if( zP4==0 ){ pOp->p4.p = 0; @@ -36353,15 +38672,41 @@ SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){ /* ** Release an array of N Mem elements */ -static void releaseMemArray(Mem *p, int N){ - if( p ){ +static void releaseMemArray(Mem *p, int N, int freebuffers){ + if( p && N ){ + sqlite3 *db = p->db; + int malloc_failed = db->mallocFailed; while( N-->0 ){ assert( N<2 || p[0].db==p[1].db ); - sqlite3VdbeMemSetNull(p++); + if( freebuffers ){ + sqlite3VdbeMemRelease(p); + }else{ + sqlite3VdbeMemReleaseExternal(p); + } + p->flags = MEM_Null; + p++; } + db->mallocFailed = malloc_failed; } } +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT +SQLITE_PRIVATE int sqlite3VdbeReleaseBuffers(Vdbe *p){ + int ii; + int nFree = 0; + assert( sqlite3_mutex_held(p->db->mutex) ); + for(ii=1; ii<=p->nMem; ii++){ + Mem *pMem = &p->aMem[ii]; + if( pMem->z && pMem->flags&MEM_Dyn ){ + assert( !pMem->xDel ); + nFree += sqlite3MallocSize(pMem->z); + sqlite3VdbeMemRelease(pMem); + } + } + return nFree; +} +#endif + #ifndef SQLITE_OMIT_EXPLAIN /* ** Give a listing of the program in the virtual machine. @@ -36392,7 +38737,7 @@ SQLITE_PRIVATE int sqlite3VdbeList( ** the result, result columns may become dynamic if the user calls ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. */ - releaseMemArray(pMem, p->nMem); + releaseMemArray(pMem, p->nMem, 1); do{ i = p->pc++; @@ -36405,6 +38750,7 @@ SQLITE_PRIVATE int sqlite3VdbeList( rc = SQLITE_ERROR; sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(p->rc), (char*)0); }else{ + char *z; Op *pOp = &p->aOp[i]; if( p->explain==1 ){ pMem->flags = MEM_Int; @@ -36438,31 +38784,46 @@ SQLITE_PRIVATE int sqlite3VdbeList( pMem++; } - pMem->flags = MEM_Ephem|MEM_Str|MEM_Term; /* P4 */ - pMem->z = displayP4(pOp, pMem->zShort, sizeof(pMem->zShort)); - assert( pMem->z!=0 ); - pMem->n = strlen(pMem->z); + if( sqlite3VdbeMemGrow(pMem, 32, 0) ){ /* P4 */ + p->db->mallocFailed = 1; + return SQLITE_NOMEM; + } + pMem->flags = MEM_Dyn|MEM_Str|MEM_Term; + z = displayP4(pOp, pMem->z, 32); + if( z!=pMem->z ){ + sqlite3VdbeMemSetStr(pMem, z, -1, SQLITE_UTF8, 0); + }else{ + assert( pMem->z!=0 ); + pMem->n = strlen(pMem->z); + pMem->enc = SQLITE_UTF8; + } pMem->type = SQLITE_TEXT; - pMem->enc = SQLITE_UTF8; pMem++; if( p->explain==1 ){ - pMem->flags = MEM_Str|MEM_Term|MEM_Short; - pMem->n = sprintf(pMem->zShort, "%.2x", pOp->p5); /* P5 */ - pMem->z = pMem->zShort; + if( sqlite3VdbeMemGrow(pMem, 4, 0) ){ + p->db->mallocFailed = 1; + return SQLITE_NOMEM; + } + pMem->flags = MEM_Dyn|MEM_Str|MEM_Term; + pMem->n = 2; + sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */ pMem->type = SQLITE_TEXT; pMem->enc = SQLITE_UTF8; pMem++; - pMem->flags = MEM_Null; /* Comment */ #ifdef SQLITE_DEBUG if( pOp->zComment ){ pMem->flags = MEM_Str|MEM_Term; pMem->z = pOp->zComment; pMem->n = strlen(pMem->z); pMem->enc = SQLITE_UTF8; - } + }else #endif + { + pMem->flags = MEM_Null; /* Comment */ + pMem->type = SQLITE_NULL; + } } p->nResColumn = 8 - 5*(p->explain-1); @@ -36497,7 +38858,7 @@ SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe *p){ SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){ int nOp = p->nOp; VdbeOp *pOp; - if( sqlite3_io_trace==0 ) return; + if( sqlite3IoTrace==0 ) return; if( nOp<1 ) return; pOp = &p->aOp[0]; if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){ @@ -36515,7 +38876,7 @@ SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){ } } z[j] = 0; - sqlite3_io_trace("SQL %s\n", z); + sqlite3IoTrace("SQL %s\n", z); } } #endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */ @@ -36554,13 +38915,24 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( */ p->magic = VDBE_MAGIC_RUN; + /* For each cursor required, also allocate a memory cell. Memory + ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by + ** the vdbe program. Instead they are used to allocate space for + ** Cursor/BtCursor structures. The blob of memory associated with + ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) + ** stores the blob of memory associated with cursor 1, etc. + ** + ** See also: allocateCursor(). + */ + nMem += nCursor; + /* ** Allocation space for registers. */ if( p->aMem==0 ){ int nArg; /* Maximum number of args passed to a user function. */ resolveP2Values(p, &nArg); - resizeOpArray(p, p->nOp); + /*resizeOpArray(p, p->nOp);*/ assert( nVar>=0 ); if( isExplain && nMem<10 ){ p->nMem = nMem = 10; @@ -36595,7 +38967,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( #ifdef SQLITE_DEBUG for(n=1; nnMem; n++){ assert( p->aMem[n].db==db ); - assert( p->aMem[n].flags==MEM_Null ); } #endif @@ -36622,8 +38993,8 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( } /* -** Close a VDBE cursor and release all the resources that cursor happens -** to hold. +** Close a VDBE cursor and release all the resources that cursor +** happens to hold. */ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, Cursor *pCx){ if( pCx==0 ){ @@ -36646,9 +39017,12 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, Cursor *pCx){ p->inVtabMethod = 0; } #endif - sqlite3_free(pCx->pData); - sqlite3_free(pCx->aType); - sqlite3_free(pCx); + if( !pCx->ephemPseudoTable ){ + sqlite3_free(pCx->pData); + } + /* memset(pCx, 0, sizeof(Cursor)); */ + /* sqlite3_free(pCx->aType); */ + /* sqlite3_free(pCx); */ } /* @@ -36674,10 +39048,13 @@ static void closeAllCursorsExceptActiveVtabs(Vdbe *p){ ** sorters that were left open. It also deletes the values of ** variables in the aVar[] array. */ -static void Cleanup(Vdbe *p){ +static void Cleanup(Vdbe *p, int freebuffers){ int i; closeAllCursorsExceptActiveVtabs(p); - releaseMemArray(&p->aMem[1], p->nMem); + for(i=1; i<=p->nMem; i++){ + MemSetTypeFlag(&p->aMem[i], MEM_Null); + } + releaseMemArray(&p->aMem[1], p->nMem, freebuffers); sqlite3VdbeFifoClear(&p->sFifo); if( p->contextStack ){ for(i=0; icontextStackTop; i++){ @@ -36703,7 +39080,7 @@ SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ Mem *pColName; int n; - releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); + releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1); sqlite3_free(p->aColName); n = nResColumn*COLNAME_N; p->nResColumn = nResColumn; @@ -36741,8 +39118,8 @@ SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe *p, int idx, int var, const char * rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT); } if( rc==SQLITE_OK && N==P4_DYNAMIC ){ - pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn; - pColName->xDel = 0; + pColName->flags &= (~MEM_Static); + pColName->zMalloc = pColName->z; } return rc; } @@ -36844,18 +39221,22 @@ static int vdbeCommit(sqlite3 *db){ do { u32 random; sqlite3_free(zMaster); - sqlite3Randomness(sizeof(random), &random); + sqlite3_randomness(sizeof(random), &random); zMaster = sqlite3MPrintf(db, "%s-mj%08X", zMainFile, random&0x7fffffff); if( !zMaster ){ return SQLITE_NOMEM; } - }while( sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS) ); - - /* Open the master journal. */ - rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, - SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| - SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0 - ); + rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS); + }while( rc==1 ); + if( rc!=0 ){ + rc = SQLITE_IOERR_NOMEM; + }else{ + /* Open the master journal. */ + rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| + SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0 + ); + } if( rc!=SQLITE_OK ){ sqlite3_free(zMaster); return rc; @@ -37228,7 +39609,7 @@ SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe *p){ ** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to ** VDBE_MAGIC_INIT. */ -SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ +SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p, int freebuffers){ sqlite3 *db; db = p->db; @@ -37267,7 +39648,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ /* Reclaim all memory used by the VDBE */ - Cleanup(p); + Cleanup(p, freebuffers); /* Save profiling information from this VDBE run. */ @@ -37305,11 +39686,12 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ - rc = sqlite3VdbeReset(p); + rc = sqlite3VdbeReset(p, 1); assert( (rc & p->db->errMask)==rc ); }else if( p->magic!=VDBE_MAGIC_INIT ){ return SQLITE_MISUSE; } + releaseMemArray(&p->aMem[1], p->nMem, 1); sqlite3VdbeDelete(p); return rc; } @@ -37339,7 +39721,7 @@ SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ int i; if( p==0 ) return; - Cleanup(p); + Cleanup(p, 1); if( p->pPrev ){ p->pPrev->pNext = p->pNext; }else{ @@ -37359,12 +39741,12 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ } sqlite3_free(p->aOp); } - releaseMemArray(p->aVar, p->nVar); + releaseMemArray(p->aVar, p->nVar, 1); sqlite3_free(p->aLabel); if( p->aMem ){ sqlite3_free(&p->aMem[1]); } - releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); + releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1); sqlite3_free(p->aColName); sqlite3_free(p->zSql); p->magic = VDBE_MAGIC_DEAD; @@ -37383,7 +39765,7 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(Cursor *p){ extern int sqlite3_search_count; #endif assert( p->isTable ); - rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, 0, &res); + rc = sqlite3BtreeMoveto(p->pCursor, 0, 0, p->movetoTarget, 0, &res); if( rc ) return rc; *p->pIncrKey = 0; p->lastRowid = keyToInt(p->movetoTarget); @@ -37724,67 +40106,149 @@ SQLITE_PRIVATE int sqlite3VdbeSerialGet( #define GetVarint(A,B) ((B = *(A))<=0x7f ? 1 : sqlite3GetVarint32(A, &B)) /* -** This function compares the two table rows or index records specified by -** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero +** Given the nKey-byte encoding of a record in pKey[], parse the +** record into a UnpackedRecord structure. Return a pointer to +** that structure. +** +** The calling function might provide szSpace bytes of memory +** space at pSpace. This space can be used to hold the returned +** VDbeParsedRecord structure if it is large enough. If it is +** not big enough, space is obtained from sqlite3_malloc(). +** +** The returned structure should be closed by a call to +** sqlite3VdbeDeleteUnpackedRecord(). +*/ +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack( + KeyInfo *pKeyInfo, /* Information about the record format */ + int nKey, /* Size of the binary record */ + const void *pKey, /* The binary record */ + void *pSpace, /* Space available to hold resulting object */ + int szSpace /* Size of pSpace[] in bytes */ +){ + const unsigned char *aKey = (const unsigned char *)pKey; + UnpackedRecord *p; + int nByte; + int i, idx, d; + u32 szHdr; + Mem *pMem; + + assert( sizeof(Mem)>sizeof(*p) ); + nByte = sizeof(Mem)*(pKeyInfo->nField+2); + if( nByte>szSpace ){ + p = sqlite3DbMallocRaw(pKeyInfo->db, nByte); + if( p==0 ) return 0; + p->needFree = 1; + }else{ + p = pSpace; + p->needFree = 0; + } + p->pKeyInfo = pKeyInfo; + p->nField = pKeyInfo->nField + 1; + p->needDestroy = 1; + p->aMem = pMem = &((Mem*)p)[1]; + idx = GetVarint(aKey, szHdr); + d = szHdr; + i = 0; + while( idxnField ){ + u32 serial_type; + + idx += GetVarint( aKey+idx, serial_type); + if( d>=nKey && sqlite3VdbeSerialTypeLen(serial_type)>0 ) break; + pMem->enc = pKeyInfo->enc; + pMem->db = pKeyInfo->db; + pMem->flags = 0; + pMem->zMalloc = 0; + d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); + pMem++; + i++; + } + p->nField = i; + return (void*)p; +} + +/* +** This routine destroys a UnpackedRecord object +*/ +SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ + if( p ){ + if( p->needDestroy ){ + int i; + Mem *pMem; + for(i=0, pMem=p->aMem; inField; i++, pMem++){ + if( pMem->zMalloc ){ + sqlite3VdbeMemRelease(pMem); + } + } + } + if( p->needFree ){ + sqlite3_free(p); + } + } +} + +/* +** This function compares the two table rows or index records +** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero ** or positive integer if {nKey1, pKey1} is less than, equal to or -** greater than {nKey2, pKey2}. Both Key1 and Key2 must be byte strings -** composed by the OP_MakeRecord opcode of the VDBE. +** greater than pPKey2. The {nKey1, pKey1} key must be a blob +** created by th OP_MakeRecord opcode of the VDBE. The pPKey2 +** key must be a parsed key such as obtained from +** sqlite3VdbeParseRecord. ** ** Key1 and Key2 do not have to contain the same number of fields. ** But if the lengths differ, Key2 must be the shorter of the two. +** +** Historical note: In earlier versions of this routine both Key1 +** and Key2 were blobs obtained from OP_MakeRecord. But we found +** that in typical use the same Key2 would be submitted multiple times +** in a row. So an optimization was added to parse the Key2 key +** separately and submit the parsed version. In this way, we avoid +** parsing the same Key2 multiple times in a row. */ SQLITE_PRIVATE int sqlite3VdbeRecordCompare( - void *userData, int nKey1, const void *pKey1, - int nKey2, const void *pKey2 + UnpackedRecord *pPKey2 ){ - KeyInfo *pKeyInfo = (KeyInfo*)userData; - u32 d1, d2; /* Offset into aKey[] of next data element */ - u32 idx1, idx2; /* Offset into aKey[] of next header element */ - u32 szHdr1, szHdr2; /* Number of bytes in header */ + u32 d1; /* Offset into aKey[] of next data element */ + u32 idx1; /* Offset into aKey[] of next header element */ + u32 szHdr1; /* Number of bytes in header */ int i = 0; int nField; int rc = 0; const unsigned char *aKey1 = (const unsigned char *)pKey1; - const unsigned char *aKey2 = (const unsigned char *)pKey2; - + KeyInfo *pKeyInfo; Mem mem1; - Mem mem2; + + pKeyInfo = pPKey2->pKeyInfo; mem1.enc = pKeyInfo->enc; mem1.db = pKeyInfo->db; - mem2.enc = pKeyInfo->enc; - mem2.db = pKeyInfo->db; + mem1.flags = 0; + mem1.zMalloc = 0; idx1 = GetVarint(aKey1, szHdr1); d1 = szHdr1; - idx2 = GetVarint(aKey2, szHdr2); - d2 = szHdr2; nField = pKeyInfo->nField; - while( idx1nField ){ u32 serial_type1; - u32 serial_type2; /* Read the serial types for the next element in each key. */ idx1 += GetVarint( aKey1+idx1, serial_type1 ); if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break; - idx2 += GetVarint( aKey2+idx2, serial_type2 ); - if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break; /* Extract the values to be compared. */ d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); - d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2); /* Do the comparison */ - rc = sqlite3MemCompare(&mem1, &mem2, iaColl[i] : 0); - if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1); - if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2); + rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], + iaColl[i] : 0); if( rc!=0 ){ break; } i++; } + if( mem1.zMalloc ) sqlite3VdbeMemRelease(&mem1); /* One of the keys ran out of fields, but all the fields up to that point ** were equal. If the incrKey flag is true, then the second key is @@ -37796,8 +40260,6 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare( }else if( !pKeyInfo->prefixIsEqual ){ if( d1aSortOrder && inField @@ -37841,6 +40303,9 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ if( nCellKey<=0 ){ return SQLITE_CORRUPT_BKPT; } + m.flags = 0; + m.db = 0; + m.zMalloc = 0; rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m); if( rc ){ return rc; @@ -37874,18 +40339,29 @@ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare( BtCursor *pCur = pC->pCursor; int lenRowid; Mem m; + UnpackedRecord *pRec; + char zSpace[200]; sqlite3BtreeKeySize(pCur, &nCellKey); if( nCellKey<=0 ){ *res = 0; return SQLITE_OK; } + m.db = 0; + m.flags = 0; + m.zMalloc = 0; rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m); if( rc ){ return rc; } lenRowid = sqlite3VdbeIdxRowidLen((u8*)m.z); - *res = sqlite3VdbeRecordCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey); + pRec = sqlite3VdbeRecordUnpack(pC->pKeyInfo, nKey, pKey, + zSpace, sizeof(zSpace)); + if( pRec==0 ){ + return SQLITE_NOMEM; + } + *res = sqlite3VdbeRecordCompare(m.n-lenRowid, m.z, pRec); + sqlite3VdbeDeleteUnpackedRecord(pRec); sqlite3VdbeMemRelease(&m); return SQLITE_OK; } @@ -37950,6 +40426,160 @@ SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){ ** VDBE. */ +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT +/* +** The following structure contains pointers to the end points of a +** doubly-linked list of all compiled SQL statements that may be holding +** buffers eligible for release when the sqlite3_release_memory() interface is +** invoked. Access to this list is protected by the SQLITE_MUTEX_STATIC_LRU2 +** mutex. +** +** Statements are added to the end of this list when sqlite3_reset() is +** called. They are removed either when sqlite3_step() or sqlite3_finalize() +** is called. When statements are added to this list, the associated +** register array (p->aMem[1..p->nMem]) may contain dynamic buffers that +** can be freed using sqlite3VdbeReleaseMemory(). +** +** When statements are added or removed from this list, the mutex +** associated with the Vdbe being added or removed (Vdbe.db->mutex) is +** already held. The LRU2 mutex is then obtained, blocking if necessary, +** the linked-list pointers manipulated and the LRU2 mutex relinquished. +*/ +struct StatementLruList { + Vdbe *pFirst; + Vdbe *pLast; +}; +static struct StatementLruList sqlite3LruStatements; + +/* +** Check that the list looks to be internally consistent. This is used +** as part of an assert() statement as follows: +** +** assert( stmtLruCheck() ); +*/ +static int stmtLruCheck(){ + Vdbe *p; + for(p=sqlite3LruStatements.pFirst; p; p=p->pLruNext){ + assert(p->pLruNext || p==sqlite3LruStatements.pLast); + assert(!p->pLruNext || p->pLruNext->pLruPrev==p); + assert(p->pLruPrev || p==sqlite3LruStatements.pFirst); + assert(!p->pLruPrev || p->pLruPrev->pLruNext==p); + } + return 1; +} + +/* +** Add vdbe p to the end of the statement lru list. It is assumed that +** p is not already part of the list when this is called. The lru list +** is protected by the SQLITE_MUTEX_STATIC_LRU mutex. +*/ +static void stmtLruAdd(Vdbe *p){ + sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); + + if( p->pLruPrev || p->pLruNext || sqlite3LruStatements.pFirst==p ){ + sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); + return; + } + + assert( stmtLruCheck() ); + + if( !sqlite3LruStatements.pFirst ){ + assert( !sqlite3LruStatements.pLast ); + sqlite3LruStatements.pFirst = p; + sqlite3LruStatements.pLast = p; + }else{ + assert( !sqlite3LruStatements.pLast->pLruNext ); + p->pLruPrev = sqlite3LruStatements.pLast; + sqlite3LruStatements.pLast->pLruNext = p; + sqlite3LruStatements.pLast = p; + } + + assert( stmtLruCheck() ); + + sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); +} + +/* +** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is already held, remove +** statement p from the least-recently-used statement list. If the +** statement is not currently part of the list, this call is a no-op. +*/ +static void stmtLruRemoveNomutex(Vdbe *p){ + if( p->pLruPrev || p->pLruNext || p==sqlite3LruStatements.pFirst ){ + assert( stmtLruCheck() ); + if( p->pLruNext ){ + p->pLruNext->pLruPrev = p->pLruPrev; + }else{ + sqlite3LruStatements.pLast = p->pLruPrev; + } + if( p->pLruPrev ){ + p->pLruPrev->pLruNext = p->pLruNext; + }else{ + sqlite3LruStatements.pFirst = p->pLruNext; + } + p->pLruNext = 0; + p->pLruPrev = 0; + assert( stmtLruCheck() ); + } +} + +/* +** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is not held, remove +** statement p from the least-recently-used statement list. If the +** statement is not currently part of the list, this call is a no-op. +*/ +static void stmtLruRemove(Vdbe *p){ + sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); + stmtLruRemoveNomutex(p); + sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); +} + +/* +** Try to release n bytes of memory by freeing buffers associated +** with the memory registers of currently unused vdbes. +*/ +SQLITE_PRIVATE int sqlite3VdbeReleaseMemory(int n){ + Vdbe *p; + Vdbe *pNext; + int nFree = 0; + + sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); + for(p=sqlite3LruStatements.pFirst; p && nFreepLruNext; + + /* For each statement handle in the lru list, attempt to obtain the + ** associated database mutex. If it cannot be obtained, continue + ** to the next statement handle. It is not possible to block on + ** the database mutex - that could cause deadlock. + */ + if( SQLITE_OK==sqlite3_mutex_try(p->db->mutex) ){ + nFree += sqlite3VdbeReleaseBuffers(p); + stmtLruRemoveNomutex(p); + sqlite3_mutex_leave(p->db->mutex); + } + } + sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); + + return nFree; +} + +/* +** Call sqlite3Reprepare() on the statement. Remove it from the +** lru list before doing so, as Reprepare() will free all the +** memory register buffers anyway. +*/ +int vdbeReprepare(Vdbe *p){ + stmtLruRemove(p); + return sqlite3Reprepare(p); +} + +#else /* !SQLITE_ENABLE_MEMORY_MANAGEMENT */ + #define stmtLruRemove(x) + #define stmtLruAdd(x) + #define vdbeReprepare(x) sqlite3Reprepare(x) +#endif + + /* ** Return TRUE (non-zero) of the statement supplied as an argument needs ** to be recompiled. A statement needs to be recompiled whenever the @@ -37982,6 +40612,7 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){ sqlite3_mutex *mutex = v->db->mutex; #endif sqlite3_mutex_enter(mutex); + stmtLruRemove(v); rc = sqlite3VdbeFinalize(v); sqlite3_mutex_leave(mutex); } @@ -38003,7 +40634,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){ }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3_mutex_enter(v->db->mutex); - rc = sqlite3VdbeReset(v); + rc = sqlite3VdbeReset(v, 1); + stmtLruAdd(v); sqlite3VdbeMakeReady(v, -1, 0, 0, 0); assert( (rc & (v->db->errMask))==rc ); sqlite3_mutex_leave(v->db->mutex); @@ -38097,13 +40729,13 @@ SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ } SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - pCtx->isError = 1; + pCtx->isError = SQLITE_ERROR; sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); } #ifndef SQLITE_OMIT_UTF16 SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - pCtx->isError = 1; + pCtx->isError = SQLITE_ERROR; sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); } #endif @@ -38165,18 +40797,23 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); sqlite3VdbeMemSetZeroBlob(&pCtx->s, n); } +SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ + pCtx->isError = errCode; +} /* Force an SQLITE_TOOBIG error. */ SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - sqlite3VdbeMemSetZeroBlob(&pCtx->s, SQLITE_MAX_LENGTH+1); + pCtx->isError = SQLITE_TOOBIG; + sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1, + SQLITE_UTF8, SQLITE_STATIC); } /* An SQLITE_NOMEM error. */ SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); sqlite3VdbeMemSetNull(&pCtx->s); - pCtx->isError = 1; + pCtx->isError = SQLITE_NOMEM; pCtx->s.db->mallocFailed = 1; } @@ -38235,6 +40872,7 @@ static int sqlite3Step(Vdbe *p){ db->activeVdbeCnt++; p->pc = 0; + stmtLruRemove(p); } #ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ @@ -38306,7 +40944,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ sqlite3_mutex_enter(db->mutex); while( (rc = sqlite3Step(v))==SQLITE_SCHEMA && cnt++ < 5 - && sqlite3Reprepare(v) ){ + && vdbeReprepare(v) ){ sqlite3_reset(pStmt); v->expired = 0; } @@ -38344,6 +40982,15 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ return p->pFunc->pUserData; } +/* +** Extract the user data from a sqlite3_context structure and return a +** pointer to it. +*/ +SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ + assert( p && p->pFunc ); + return p->s.db; +} + /* ** The following is the implementation of an SQL function that always ** fails with an error message stating that the function is used in the @@ -38377,13 +41024,16 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ pMem = p->pMem; if( (pMem->flags & MEM_Agg)==0 ){ if( nByte==0 ){ - assert( pMem->flags==MEM_Null ); + sqlite3VdbeMemReleaseExternal(pMem); + pMem->flags = MEM_Null; pMem->z = 0; }else{ + sqlite3VdbeMemGrow(pMem, nByte, 0); pMem->flags = MEM_Agg; - pMem->xDel = sqlite3_free; pMem->u.pDef = p->pFunc; - pMem->z = sqlite3DbMallocZero(p->s.db, nByte); + if( pMem->z ){ + memset(pMem->z, 0, nByte); + } } } return (void*)pMem->z; @@ -38498,7 +41148,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ vals = sqlite3_data_count(pStmt); pOut = &pVm->pResultSet[i]; }else{ - static const Mem nullMem = {{0}, 0.0, 0, "", 0, MEM_Null, SQLITE_NULL }; + static const Mem nullMem = {{0}, 0.0, 0, "", 0, MEM_Null, SQLITE_NULL, 0, 0, 0 }; if( pVm->db ){ sqlite3_mutex_enter(pVm->db->mutex); sqlite3Error(pVm->db, SQLITE_RANGE, 0); @@ -38672,6 +41322,16 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){ } #endif +/* +** Constraint: If you have ENABLE_COLUMN_METADATA then you must +** not define OMIT_DECLTYPE. +*/ +#if defined(SQLITE_OMIT_DECLTYPE) && defined(SQLITE_ENABLE_COLUMN_METADATA) +# error "Must not define both SQLITE_OMIT_DECLTYPE \ + and SQLITE_ENABLE_COLUMN_METADATA" +#endif + +#ifndef SQLITE_OMIT_DECLTYPE /* ** Return the column declaration type (if applicable) of the 'i'th column ** of the result set of SQL statement pStmt. @@ -38686,6 +41346,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){ pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE); } #endif /* SQLITE_OMIT_UTF16 */ +#endif /* SQLITE_OMIT_DECLTYPE */ #ifdef SQLITE_ENABLE_COLUMN_METADATA /* @@ -38875,6 +41536,7 @@ SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_valu if( rc==SQLITE_OK ){ rc = sqlite3VdbeMemCopy(&p->aVar[i-1], pValue); } + rc = sqlite3ApiExit(p->db, rc); sqlite3_mutex_leave(p->db->mutex); return rc; } @@ -39043,7 +41705,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){ ** 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.706 2008/01/31 15:53:45 drh Exp $ +** $Id: vdbe.c,v 1.730 2008/04/15 12:14:22 drh Exp $ */ /* @@ -39100,7 +41762,7 @@ static void updateMaxBlobsize(Mem *p){ ** Test a register to see if it exceeds the current maximum blob size. ** If it does, record the new maximum blob size. */ -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) && !defined(SQLITE_OMIT_BUILTIN_TEST) # define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P) #else # define UPDATE_MAX_BLOBSIZE(P) @@ -39205,15 +41867,65 @@ SQLITE_PRIVATE int sqlite3VdbeOpcodeHasProperty(int opcode, int mask){ ** Allocate cursor number iCur. Return a pointer to it. Return NULL ** if we run out of memory. */ -static Cursor *allocateCursor(Vdbe *p, int iCur, int iDb){ - Cursor *pCx; +static Cursor *allocateCursor( + Vdbe *p, + int iCur, + Op *pOp, + int iDb, + int isBtreeCursor +){ + /* Find the memory cell that will be used to store the blob of memory + ** required for this Cursor structure. It is convenient to use a + ** vdbe memory cell to manage the memory allocation required for a + ** Cursor structure for the following reasons: + ** + ** * Sometimes cursor numbers are used for a couple of different + ** purposes in a vdbe program. The different uses might require + ** different sized allocations. Memory cells provide growable + ** allocations. + ** + ** * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can + ** be freed lazily via the sqlite3_release_memory() API. This + ** minimizes the number of malloc calls made by the system. + ** + ** Memory cells for cursors are allocated at the top of the address + ** space. Memory cell (p->nMem) corresponds to cursor 0. Space for + ** cursor 1 is managed by memory cell (p->nMem-1), etc. + */ + Mem *pMem = &p->aMem[p->nMem-iCur]; + + int nByte; + Cursor *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 + ** Cursor.aType[] array. + */ + int nField = 0; + if( pOp->opcode==OP_SetNumColumns || pOp->opcode==OP_OpenEphemeral ){ + nField = pOp->p2; + } + nByte = + sizeof(Cursor) + + (isBtreeCursor?sqlite3BtreeCursorSize():0) + + 2*nField*sizeof(u32); + assert( iCurnCursor ); if( p->apCsr[iCur] ){ sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); + p->apCsr[iCur] = 0; } - p->apCsr[iCur] = pCx = sqlite3MallocZero( sizeof(Cursor) ); - if( pCx ){ + if( SQLITE_OK==sqlite3VdbeMemGrow(pMem, nByte, 0) ){ + p->apCsr[iCur] = pCx = (Cursor *)pMem->z; + memset(pMem->z, 0, nByte); pCx->iDb = iDb; + pCx->nField = nField; + if( nField ){ + pCx->aType = (u32 *)&pMem->z[sizeof(Cursor)]; + } + if( isBtreeCursor ){ + pCx->pCursor = (BtCursor *)&pMem->z[sizeof(Cursor)+2*nField*sizeof(u32)]; + } } return pCx; } @@ -39233,9 +41945,8 @@ static void applyNumericAffinity(Mem *pRec){ i64 value; sqlite3VdbeChangeEncoding(pRec, SQLITE_UTF8); if( !realnum && sqlite3Atoi64(pRec->z, &value) ){ - sqlite3VdbeMemRelease(pRec); pRec->u.i = value; - pRec->flags = MEM_Int; + MemSetTypeFlag(pRec, MEM_Int); }else{ sqlite3VdbeMemRealify(pRec); } @@ -39437,11 +42148,10 @@ static void registerTrace(FILE *out, int iReg, Mem *p){ ** profiling. */ __inline__ unsigned long long int hwtime(void){ - unsigned long long int x; - __asm__("rdtsc\n\t" - "mov %%edx, %%ecx\n\t" - :"=A" (x)); - return x; + unsigned int lo, hi; + /* We cannot use "=A", since this would use %rax on x86_64 */ + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (unsigned long long int)hi << 32 | lo; } #endif @@ -39525,8 +42235,9 @@ SQLITE_PRIVATE int sqlite3VdbeExec( CHECK_FOR_INTERRUPT; sqlite3VdbeIOTraceSql(p); #ifdef SQLITE_DEBUG + sqlite3FaultBenign(-1, 1); if( p->pc==0 && ((p->db->flags & SQLITE_VdbeListing)!=0 - || sqlite3OsAccess(db->pVfs, "vdbe_explain", SQLITE_ACCESS_EXISTS)) + || sqlite3OsAccess(db->pVfs, "vdbe_explain", SQLITE_ACCESS_EXISTS)==1 ) ){ int i; printf("VDBE Program Listing:\n"); @@ -39535,9 +42246,10 @@ SQLITE_PRIVATE int sqlite3VdbeExec( sqlite3VdbePrintOp(stdout, i, &p->aOp[i]); } } - if( sqlite3OsAccess(db->pVfs, "vdbe_trace", SQLITE_ACCESS_EXISTS) ){ + if( sqlite3OsAccess(db->pVfs, "vdbe_trace", SQLITE_ACCESS_EXISTS)==1 ){ p->trace = stdout; } + sqlite3FaultBenign(-1, 0); #endif for(pc=p->pc; rc==SQLITE_OK; pc++){ assert( pc>=0 && pcnOp ); @@ -39558,9 +42270,12 @@ SQLITE_PRIVATE int sqlite3VdbeExec( } sqlite3VdbePrintOp(p->trace, pc, pOp); } - if( p->trace==0 && pc==0 - && sqlite3OsAccess(db->pVfs, "vdbe_sqltrace", SQLITE_ACCESS_EXISTS) ){ - sqlite3VdbePrintSql(p); + if( p->trace==0 && pc==0 ){ + sqlite3FaultBenign(-1, 1); + if( sqlite3OsAccess(db->pVfs, "vdbe_sqltrace", SQLITE_ACCESS_EXISTS)==1 ){ + sqlite3VdbePrintSql(p); + } + sqlite3FaultBenign(-1, 0); } #endif @@ -39610,7 +42325,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec( assert( pOp->p2>0 ); assert( pOp->p2<=p->nMem ); pOut = &p->aMem[pOp->p2]; - sqlite3VdbeMemRelease(pOut); + sqlite3VdbeMemReleaseExternal(pOut); pOut->flags = MEM_Null; }else @@ -39822,22 +42537,23 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */ sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pOut) ) goto no_mem; - pOut->flags &= ~(MEM_Dyn); + pOut->zMalloc = 0; pOut->flags |= MEM_Static; + pOut->flags &= ~MEM_Dyn; if( pOp->p4type==P4_DYNAMIC ){ sqlite3_free(pOp->p4.z); } pOp->p4type = P4_DYNAMIC; pOp->p4.z = pOut->z; pOp->p1 = pOut->n; - if( pOp->p1>SQLITE_MAX_LENGTH ){ + if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } UPDATE_MAX_BLOBSIZE(pOut); break; } #endif - if( pOp->p1>SQLITE_MAX_LENGTH ){ + if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } /* Fall through to the next case, OP_String */ @@ -39914,6 +42630,24 @@ case OP_Variable: { /* out2-prerelease */ ** is left holding a NULL. It is an error for P1 and P2 to be the ** same register. */ +case OP_Move: { + char *zMalloc; + assert( pOp->p1>0 ); + assert( pOp->p1<=p->nMem ); + pIn1 = &p->aMem[pOp->p1]; + REGISTER_TRACE(pOp->p1, pIn1); + assert( pOp->p2>0 ); + assert( pOp->p2<=p->nMem ); + pOut = &p->aMem[pOp->p2]; + assert( pOut!=pIn1 ); + zMalloc = pOut->zMalloc; + pOut->zMalloc = 0; + sqlite3VdbeMemMove(pOut, pIn1); + pIn1->zMalloc = zMalloc; + REGISTER_TRACE(pOp->p2, pOut); + break; +} + /* Opcode: Copy P1 P2 * * * ** ** Make a copy of register P1 into register P2. @@ -39921,6 +42655,21 @@ case OP_Variable: { /* out2-prerelease */ ** This instruction makes a deep copy of the value. A duplicate ** is made of any string or blob constant. See also OP_SCopy. */ +case OP_Copy: { + assert( pOp->p1>0 ); + assert( pOp->p1<=p->nMem ); + pIn1 = &p->aMem[pOp->p1]; + REGISTER_TRACE(pOp->p1, pIn1); + assert( pOp->p2>0 ); + assert( pOp->p2<=p->nMem ); + pOut = &p->aMem[pOp->p2]; + assert( pOut!=pIn1 ); + sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); + Deephemeralize(pOut); + REGISTER_TRACE(pOp->p2, pOut); + break; +} + /* Opcode: SCopy P1 P2 * * * ** ** Make a shallow copy of register P1 into register P2. @@ -39933,8 +42682,6 @@ case OP_Variable: { /* out2-prerelease */ ** during the lifetime of the copy. Use OP_Copy to make a complete ** copy. */ -case OP_Move: -case OP_Copy: case OP_SCopy: { assert( pOp->p1>0 ); assert( pOp->p1<=p->nMem ); @@ -39944,14 +42691,7 @@ case OP_SCopy: { assert( pOp->p2<=p->nMem ); pOut = &p->aMem[pOp->p2]; assert( pOut!=pIn1 ); - if( pOp->opcode==OP_Move ){ - sqlite3VdbeMemMove(pOut, pIn1); - }else{ - sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); - if( pOp->opcode==OP_Copy ){ - Deephemeralize(pOut); - } - } + sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); REGISTER_TRACE(pOp->p2, pOut); break; } @@ -39983,6 +42723,7 @@ case OP_ResultRow: { sqlite3VdbeMemNulTerminate(&pMem[i]); storeTypeInfo(&pMem[i], encoding); } + if( db->mallocFailed ) goto no_mem; /* Return SQLITE_ROW */ @@ -39997,14 +42738,19 @@ case OP_ResultRow: { ** Add the text in register P1 onto the end of the text in ** register P2 and store the result in register P3. ** If either the P1 or P2 text are NULL then store NULL in P3. +** +** P3 = P2 || P1 +** +** It is illegal for P1 and P3 to be the same register. Sometimes, +** if P3 is the same register as P2, the implementation is able +** to avoid a memcpy(). */ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ - char *zNew; i64 nByte; + assert( pIn1!=pOut ); if( (pIn1->flags | pIn2->flags) & MEM_Null ){ - Release(pOut); - pOut->flags = MEM_Null; + sqlite3VdbeMemSetNull(pOut); break; } ExpandBlob(pIn1); @@ -40012,23 +42758,22 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ ExpandBlob(pIn2); Stringify(pIn2, encoding); nByte = pIn1->n + pIn2->n; - if( nByte>SQLITE_MAX_LENGTH ){ + if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } - zNew = sqlite3DbMallocRaw(db, nByte+2); - if( zNew==0 ){ + MemSetTypeFlag(pOut, MEM_Str); + if( sqlite3VdbeMemGrow(pOut, nByte+2, pOut==pIn2) ){ goto no_mem; } - memcpy(zNew, pIn2->z, pIn2->n); - memcpy(&zNew[pIn2->n], pIn1->z, pIn1->n); - zNew[nByte] = 0; - zNew[nByte+1] = 0; - Release(pOut); + if( pOut!=pIn2 ){ + memcpy(pOut->z, pIn2->z, pIn2->n); + } + memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n); + pOut->z[nByte] = 0; + pOut->z[nByte+1] = 0; + pOut->flags |= MEM_Term; pOut->n = nByte; - pOut->flags = MEM_Str|MEM_Dyn|MEM_Term; - pOut->xDel = 0; pOut->enc = encoding; - pOut->z = zNew; UPDATE_MAX_BLOBSIZE(pOut); break; } @@ -40102,9 +42847,8 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ break; } } - Release(pOut); pOut->u.i = b; - pOut->flags = MEM_Int; + MemSetTypeFlag(pOut, MEM_Int); }else{ double a, b; a = sqlite3VdbeRealValue(pIn1); @@ -40130,9 +42874,8 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ if( sqlite3_isnan(b) ){ goto arithmetic_result_is_null; } - Release(pOut); pOut->r = b; - pOut->flags = MEM_Real; + MemSetTypeFlag(pOut, MEM_Real); if( (flags & MEM_Real)==0 ){ sqlite3VdbeIntegerAffinity(pOut); } @@ -40165,6 +42908,7 @@ case OP_CollSeq: { ** Invoke a user function (P4 is a pointer to a Function structure that ** defines the function) with P5 arguments taken from register P2 and ** successors. The result of the function is stored in register P3. +** Register P3 must not be one of the function inputs. ** ** P1 is a 32-bit bitmask indicating whether or not each argument to the ** function was determined to be constant at compile time. If the first @@ -40186,6 +42930,7 @@ case OP_Function: { assert( apVal || n==0 ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem) ); + assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); pArg = &p->aMem[pOp->p2]; for(i=0; ipFunc; } + assert( pOp->p3>0 && pOp->p3<=p->nMem ); + pOut = &p->aMem[pOp->p3]; ctx.s.flags = MEM_Null; - ctx.s.z = 0; - ctx.s.xDel = 0; ctx.s.db = db; + ctx.s.xDel = 0; + ctx.s.zMalloc = 0; + + /* The output cell may already have a buffer allocated. Move + ** the pointer to ctx.s so in case the user-function can use + ** the already allocated buffer instead of allocating a new one. + */ + sqlite3VdbeMemMove(&ctx.s, pOut); + MemSetTypeFlag(&ctx.s, MEM_Null); + ctx.isError = 0; if( ctx.pFunc->needCollSeq ){ assert( pOp>p->aOp ); @@ -40215,7 +42970,10 @@ case OP_Function: { } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; (*ctx.pFunc->xFunc)(&ctx, n, apVal); - if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; + if( sqlite3SafetyOn(db) ){ + sqlite3VdbeMemRelease(&ctx.s); + goto abort_due_to_misuse; + } if( db->mallocFailed ){ /* Even though a malloc() has failed, the implementation of the ** user function may have called an sqlite3_result_XXX() function @@ -40242,13 +43000,11 @@ case OP_Function: { /* If the function returned an error, throw an exception */ if( ctx.isError ){ sqlite3SetString(&p->zErrMsg, sqlite3_value_text(&ctx.s), (char*)0); - rc = SQLITE_ERROR; + rc = ctx.isError; } /* Copy the result of the function into register P3 */ sqlite3VdbeChangeEncoding(&ctx.s, encoding); - assert( pOp->p3>0 && pOp->p3<=p->nMem ); - pOut = &p->aMem[pOp->p3]; sqlite3VdbeMemMove(pOut, &ctx.s); if( sqlite3VdbeMemTooBig(pOut) ){ goto too_big; @@ -40303,9 +43059,8 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ default: assert( pOp->opcode==OP_ShiftRight ); a >>= b; break; } - Release(pOut); pOut->u.i = a; - pOut->flags = MEM_Int; + MemSetTypeFlag(pOut, MEM_Int); break; } @@ -40347,9 +43102,8 @@ case OP_ForceInt: { /* jump, in1 */ if( pIn1->r>(double)v ) v++; if( pOp->p3 && pIn1->r==(double)v ) v++; } - Release(pIn1); pIn1->u.i = v; - pIn1->flags = MEM_Int; + MemSetTypeFlag(pIn1, MEM_Int); break; } @@ -40370,8 +43124,7 @@ case OP_MustBeInt: { /* jump, in1 */ pc = pOp->p2 - 1; } }else{ - Release(pIn1); - pIn1->flags = MEM_Int; + MemSetTypeFlag(pIn1, MEM_Int); } break; } @@ -40408,7 +43161,7 @@ case OP_ToText: { /* same as TK_TO_TEXT, in1 */ pIn1->flags |= (pIn1->flags&MEM_Blob)>>3; applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding); rc = ExpandBlob(pIn1); - assert( pIn1->flags & MEM_Str ); + assert( pIn1->flags & MEM_Str || db->mallocFailed ); pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob); UPDATE_MAX_BLOBSIZE(pIn1); break; @@ -40427,10 +43180,9 @@ case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */ if( pIn1->flags & MEM_Null ) break; if( (pIn1->flags & MEM_Blob)==0 ){ applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding); - assert( pIn1->flags & MEM_Str ); - pIn1->flags |= MEM_Blob; + assert( pIn1->flags & MEM_Str || db->mallocFailed ); } - pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Str); + MemSetTypeFlag(pIn1, MEM_Blob); UPDATE_MAX_BLOBSIZE(pIn1); break; } @@ -40588,8 +43340,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ */ if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &p->aMem[pOp->p2]; - Release(pOut); - pOut->flags = MEM_Null; + MemSetTypeFlag(pOut, MEM_Null); REGISTER_TRACE(pOp->p2, pOut); }else if( pOp->p5 & SQLITE_JUMPIFNULL ){ pc = pOp->p2-1; @@ -40619,8 +43370,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &p->aMem[pOp->p2]; - Release(pOut); - pOut->flags = MEM_Int; + MemSetTypeFlag(pOut, MEM_Int); pOut->u.i = res; REGISTER_TRACE(pOp->p2, pOut); }else if( res ){ @@ -40668,12 +43418,11 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */ static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 }; v1 = or_logic[v1*3+v2]; } - Release(pOut); if( v1==2 ){ - pOut->flags = MEM_Null; + MemSetTypeFlag(pOut, MEM_Null); }else{ pOut->u.i = v1; - pOut->flags = MEM_Int; + MemSetTypeFlag(pOut, MEM_Int); } break; } @@ -40688,7 +43437,7 @@ case OP_Not: { /* same as TK_NOT, in1 */ if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */ sqlite3VdbeMemIntegerify(pIn1); pIn1->u.i = !pIn1->u.i; - assert( pIn1->flags==MEM_Int ); + assert( pIn1->flags&MEM_Int ); break; } @@ -40702,7 +43451,7 @@ case OP_BitNot: { /* same as TK_BITNOT, in1 */ if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */ sqlite3VdbeMemIntegerify(pIn1); pIn1->u.i = ~pIn1->u.i; - assert( pIn1->flags==MEM_Int ); + assert( pIn1->flags&MEM_Int ); break; } @@ -40767,22 +43516,23 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ break; } -/* Opcode: SetNumColumns P1 P2 * * * +/* Opcode: SetNumColumns * P2 * * * ** -** Before the OP_Column opcode can be executed on a cursor, this -** opcode must be called to set the number of fields in the table. +** This opcode sets the number of columns for the cursor opened by the +** following instruction to P2. ** -** This opcode sets the number of columns for cursor P1 to P2. +** An OP_SetNumColumns is only useful if it occurs immediately before +** one of the following opcodes: ** -** If OP_KeyAsData is to be applied to cursor P1, it must be executed -** before this op-code. +** OpenRead +** OpenWrite +** OpenPseudo +** +** 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. */ case OP_SetNumColumns: { - Cursor *pC; - assert( (pOp->p1)nCursor ); - assert( p->apCsr[pOp->p1]!=0 ); - pC = p->apCsr[pOp->p1]; - pC->nField = pOp->p2; break; } @@ -40820,10 +43570,12 @@ case OP_Column: { Mem sMem; /* For storing the record being decoded */ sMem.flags = 0; + sMem.db = 0; + sMem.zMalloc = 0; assert( p1nCursor ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); pDest = &p->aMem[pOp->p3]; - sqlite3VdbeMemSetNull(pDest); + MemSetTypeFlag(pDest, MEM_Null); /* This block sets the variable payloadSize to be the total number of ** bytes in the record. @@ -40874,10 +43626,10 @@ case OP_Column: { /* If payloadSize is 0, then just store a NULL */ if( payloadSize==0 ){ - assert( pDest->flags==MEM_Null ); + assert( pDest->flags&MEM_Null ); goto op_column_out; } - if( payloadSize>SQLITE_MAX_LENGTH ){ + if( payloadSize>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } @@ -40886,8 +43638,8 @@ case OP_Column: { /* Read and parse the table header. Store the results of the parse ** into the record header cache fields of the cursor. */ + aType = pC->aType; if( pC->cacheStatus==p->cacheCtr ){ - aType = pC->aType; aOffset = pC->aOffset; }else{ u8 *zIdx; /* Index into header */ @@ -40896,13 +43648,7 @@ case OP_Column: { int szHdrSz; /* Size of the header size field at start of record */ int avail; /* Number of bytes of available data */ - aType = pC->aType; - if( aType==0 ){ - pC->aType = aType = sqlite3DbMallocRaw(db, 2*nField*sizeof(aType) ); - } - if( aType==0 ){ - goto no_mem; - } + assert(aType); pC->aOffset = aOffset = &aType[nField]; pC->payloadSize = payloadSize; pC->cacheStatus = p->cacheCtr; @@ -40940,6 +43686,8 @@ case OP_Column: { ** acquire the complete header text. */ if( !zRec && availisIndex, &sMem); if( rc!=SQLITE_OK ){ goto op_column_out; @@ -40969,7 +43717,7 @@ case OP_Column: { aOffset[i] = 0; } } - Release(&sMem); + sqlite3VdbeMemRelease(&sMem); sMem.flags = MEM_Null; /* If we have read more header data than was contained in the header, @@ -40991,22 +43739,33 @@ case OP_Column: { if( aOffset[p2] ){ assert( rc==SQLITE_OK ); if( zRec ){ - zData = &zRec[aOffset[p2]]; + if( pDest->flags&MEM_Dyn ){ + sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], &sMem); + sMem.db = db; + rc = sqlite3VdbeMemCopy(pDest, &sMem); + assert( !(sMem.flags&MEM_Dyn) ); + if( rc!=SQLITE_OK ){ + goto op_column_out; + } + }else{ + sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest); + } }else{ len = sqlite3VdbeSerialTypeLen(aType[p2]); + sqlite3VdbeMemMove(&sMem, pDest); rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, &sMem); if( rc!=SQLITE_OK ){ goto op_column_out; } zData = sMem.z; + sqlite3VdbeSerialGet((u8*)zData, aType[p2], pDest); } - sqlite3VdbeSerialGet((u8*)zData, aType[p2], pDest); pDest->enc = encoding; }else{ if( pOp->p4type==P4_MEM ){ sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); }else{ - assert( pDest->flags==MEM_Null ); + assert( pDest->flags&MEM_Null ); } } @@ -41015,17 +43774,16 @@ case OP_Column: { ** dynamically allocated space over to the pDest structure. ** This prevents a memory copy. */ - if( (sMem.flags & MEM_Dyn)!=0 ){ - assert( pDest->flags & MEM_Ephem ); - assert( pDest->flags & (MEM_Str|MEM_Blob) ); - assert( pDest->z==sMem.z ); - assert( sMem.flags & MEM_Term ); - pDest->flags &= ~MEM_Ephem; - pDest->flags |= MEM_Dyn|MEM_Term; + if( sMem.zMalloc ){ + assert( sMem.z==sMem.zMalloc ); + assert( !(pDest->flags & MEM_Dyn) ); + assert( !(pDest->flags & (MEM_Blob|MEM_Str)) || pDest->z==sMem.z ); + pDest->flags &= ~(MEM_Ephem|MEM_Static); + pDest->flags |= MEM_Term; + pDest->z = sMem.z; + pDest->zMalloc = sMem.zMalloc; } - /* pDest->z might be pointing to sMem.zShort[]. Fix that so that we - ** can abandon sMem */ rc = sqlite3VdbeMemMakeWriteable(pDest); op_column_out: @@ -41039,9 +43797,8 @@ op_column_out: ** Convert P2 registers beginning with P1 into a single entry ** suitable for use as a data record in a database table or as a key ** in an index. The details of the format are irrelavant as long as -** the OP_Column opcode can decode the record later and as long as the -** sqlite3VdbeRecordCompare function will correctly compare two encoded -** records. Refer to source code comments for the details of the record +** the OP_Column opcode can decode the record later. +** Refer to source code comments for the details of the record ** format. ** ** P4 may be a string that is P1 characters long. The nth character of the @@ -41083,7 +43840,6 @@ case OP_MakeRecord: { char *zAffinity; /* The affinity string for the record */ int file_format; /* File format to use for encoding */ int i; /* Space used in zNewRecord[] */ - char zTemp[NBFS]; /* Space to hold small records */ nField = pOp->p1; zAffinity = pOp->p4.z; @@ -41123,25 +43879,27 @@ case OP_MakeRecord: { nHdr++; } nByte = nHdr+nData-nZero; - if( nByte>SQLITE_MAX_LENGTH ){ + if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } - /* Allocate space for the new record. */ - if( nByte>sizeof(zTemp) ){ - zNewRecord = sqlite3DbMallocRaw(db, nByte); - if( !zNewRecord ){ - goto no_mem; - } - }else{ - zNewRecord = (u8*)zTemp; + /* Make sure the output register has a buffer large enough to store + ** the new record. The output register (pOp->p3) is not allowed to + ** be one of the input registers (because the following call to + ** sqlite3VdbeMemGrow() could clobber the value before it is used). + */ + assert( pOp->p3p1 || pOp->p3>=pOp->p1+pOp->p2 ); + pOut = &p->aMem[pOp->p3]; + if( sqlite3VdbeMemGrow(pOut, nByte, 0) ){ + goto no_mem; } + zNewRecord = (u8 *)pOut->z; /* Write the record */ - i = sqlite3PutVarint(zNewRecord, nHdr); + i = sqlite3PutVarint32(zNewRecord, nHdr); for(pRec=pData0; pRec<=pLast; pRec++){ serial_type = sqlite3VdbeSerialType(pRec, file_format); - i += sqlite3PutVarint(&zNewRecord[i], serial_type); /* serial type */ + i += sqlite3PutVarint32(&zNewRecord[i], serial_type); /* serial type */ } for(pRec=pData0; pRec<=pLast; pRec++){ /* serial data */ i += sqlite3VdbeSerialPut(&zNewRecord[i], nByte-i, pRec, file_format); @@ -41149,20 +43907,9 @@ case OP_MakeRecord: { assert( i==nByte ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); - pOut = &p->aMem[pOp->p3]; - Release(pOut); pOut->n = nByte; - if( nByte<=sizeof(zTemp) ){ - assert( zNewRecord==(unsigned char *)zTemp ); - pOut->z = pOut->zShort; - memcpy(pOut->zShort, zTemp, nByte); - pOut->flags = MEM_Blob | MEM_Short; - }else{ - assert( zNewRecord!=(unsigned char *)zTemp ); - pOut->z = (char*)zNewRecord; - pOut->flags = MEM_Blob | MEM_Dyn; - pOut->xDel = 0; - } + pOut->flags = MEM_Blob | MEM_Dyn; + pOut->xDel = 0; if( nZero ){ pOut->u.i = nZero; pOut->flags |= MEM_Zero; @@ -41340,7 +44087,7 @@ case OP_ReadCookie: { /* out2-prerelease */ */ rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, 1 + iCookie, (u32 *)&iMeta); pOut->u.i = iMeta; - pOut->flags = MEM_Int; + MemSetTypeFlag(pOut, MEM_Int); break; } @@ -41511,14 +44258,10 @@ case OP_OpenWrite: { assert( p2>=2 ); } assert( i>=0 ); - pCur = allocateCursor(p, i, iDb); + pCur = allocateCursor(p, i, &pOp[-1], iDb, 1); if( pCur==0 ) goto no_mem; pCur->nullRow = 1; - /* We always provide a key comparison function. If the table being - ** opened is of type INTKEY, the comparision function will be ignored. */ - rc = sqlite3BtreeCursor(pX, p2, wrFlag, - sqlite3VdbeRecordCompare, pOp->p4.p, - &pCur->pCursor); + rc = sqlite3BtreeCursor(pX, p2, wrFlag, pOp->p4.p, pCur->pCursor); if( pOp->p4type==P4_KEYINFO ){ pCur->pKeyInfo = pOp->p4.pKeyInfo; pCur->pIncrKey = &pCur->pKeyInfo->incrKey; @@ -41561,6 +44304,7 @@ case OP_OpenWrite: { case SQLITE_EMPTY: { pCur->isTable = pOp->p4type!=P4_KEYINFO; pCur->isIndex = !pCur->isTable; + pCur->pCursor = 0; rc = SQLITE_OK; break; } @@ -41600,7 +44344,7 @@ case OP_OpenEphemeral: { SQLITE_OPEN_TRANSIENT_DB; assert( i>=0 ); - pCx = allocateCursor(p, i, -1); + pCx = allocateCursor(p, i, pOp, -1, 1); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; rc = sqlite3BtreeFactory(db, 0, 1, SQLITE_DEFAULT_TEMP_CACHE_SIZE, openFlags, @@ -41620,25 +44364,24 @@ case OP_OpenEphemeral: { rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA); if( rc==SQLITE_OK ){ assert( pgno==MASTER_ROOT+1 ); - rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, sqlite3VdbeRecordCompare, - pOp->p4.z, &pCx->pCursor); + rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, + (KeyInfo*)pOp->p4.z, pCx->pCursor); pCx->pKeyInfo = pOp->p4.pKeyInfo; pCx->pKeyInfo->enc = ENC(p->db); pCx->pIncrKey = &pCx->pKeyInfo->incrKey; } pCx->isTable = 0; }else{ - rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor); + rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor); pCx->isTable = 1; pCx->pIncrKey = &pCx->bogusIncrKey; } } - pCx->nField = pOp->p2; pCx->isIndex = !pCx->isTable; break; } -/* Opcode: OpenPseudo P1 * * * * +/* Opcode: OpenPseudo P1 P2 * * * ** ** 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 @@ -41649,15 +44392,24 @@ case OP_OpenEphemeral: { ** NEW or OLD tables in a trigger. Also used to hold the a single ** row output from the sorter so that the row can be decomposed into ** individual columns using the OP_Column opcode. +** +** When OP_Insert is executed to insert a row in to the pseudo table, +** the pseudo-table cursor may or may not make it's own copy of the +** original row data. If P2 is 0, then the pseudo-table will copy the +** 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). */ case OP_OpenPseudo: { int i = pOp->p1; Cursor *pCx; assert( i>=0 ); - pCx = allocateCursor(p, i, -1); + pCx = allocateCursor(p, i, &pOp[-1], -1, 0); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; pCx->pseudoTable = 1; + pCx->ephemPseudoTable = pOp->p2; pCx->pIncrKey = &pCx->bogusIncrKey; pCx->isTable = 1; pCx->isIndex = 0; @@ -41748,7 +44500,7 @@ case OP_MoveGt: { /* jump, in3 */ pC->deferredMoveto = 1; break; } - rc = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, 0, &res); + rc = sqlite3BtreeMoveto(pC->pCursor, 0, 0, (u64)iKey, 0, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -41757,7 +44509,7 @@ case OP_MoveGt: { /* jump, in3 */ }else{ assert( pIn3->flags & MEM_Blob ); ExpandBlob(pIn3); - rc = sqlite3BtreeMoveto(pC->pCursor, pIn3->z, pIn3->n, 0, &res); + rc = sqlite3BtreeMoveto(pC->pCursor, pIn3->z, 0, pIn3->n, 0, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -41842,7 +44594,7 @@ case OP_Found: { /* jump, in3 */ if( pOp->opcode==OP_Found ){ pC->pKeyInfo->prefixIsEqual = 1; } - rc = sqlite3BtreeMoveto(pC->pCursor, pIn3->z, pIn3->n, 0, &res); + rc = sqlite3BtreeMoveto(pC->pCursor, pIn3->z, 0, pIn3->n, 0, &res); pC->pKeyInfo->prefixIsEqual = 0; if( rc!=SQLITE_OK ){ break; @@ -41893,7 +44645,6 @@ case OP_IsUnique: { /* jump, in3 */ pK = &p->aMem[pOp->p4.i]; sqlite3VdbeMemIntegerify(pIn3); R = pIn3->u.i; - assert( (pIn3->flags & MEM_Dyn)==0 ); assert( i>=0 && inCursor ); pCx = p->apCsr[i]; assert( pCx!=0 ); @@ -41920,7 +44671,7 @@ case OP_IsUnique: { /* jump, in3 */ */ assert( pCx->deferredMoveto==0 ); pCx->cacheStatus = CACHE_STALE; - rc = sqlite3BtreeMoveto(pCrsr, zKey, len, 0, &res); + rc = sqlite3BtreeMoveto(pCrsr, zKey, 0, len, 0, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -41957,7 +44708,7 @@ case OP_IsUnique: { /* jump, in3 */ ** a UNIQUE constraint.) */ pIn3->u.i = v; - assert( pIn3->flags==MEM_Int ); + assert( pIn3->flags&MEM_Int ); } break; } @@ -41988,7 +44739,7 @@ case OP_NotExists: { /* jump, in3 */ assert( pIn3->flags & MEM_Int ); assert( p->apCsr[i]->isTable ); iKey = intToKey(pIn3->u.i); - rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, 0,&res); + rc = sqlite3BtreeMoveto(pCrsr, 0, 0, iKey, 0,&res); pC->lastRowid = pIn3->u.i; pC->rowidIsValid = res==0; pC->nullRow = 0; @@ -42018,7 +44769,7 @@ case OP_Sequence: { /* out2-prerelease */ assert( i>=0 && inCursor ); assert( p->apCsr[i]!=0 ); pOut->u.i = p->apCsr[i]->seqCount++; - pOut->flags = MEM_Int; + MemSetTypeFlag(pOut, MEM_Int); break; } @@ -42153,12 +44904,12 @@ case OP_NewRowid: { /* out2-prerelease */ if( cnt==0 && (v&0xffffff)==v ){ v++; }else{ - sqlite3Randomness(sizeof(v), &v); + sqlite3_randomness(sizeof(v), &v); if( cnt<5 ) v &= 0xffffff; } if( v==0 ) continue; x = intToKey(v); - rx = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)x, 0, &res); + rx = sqlite3BtreeMoveto(pC->pCursor, 0, 0, (u64)x, 0, &res); cnt++; }while( cnt<100 && rx==SQLITE_OK && res==0 ); db->priorNewRowid = v; @@ -42171,7 +44922,7 @@ case OP_NewRowid: { /* out2-prerelease */ pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; } - pOut->flags = MEM_Int; + MemSetTypeFlag(pOut, MEM_Int); pOut->u.i = v; break; } @@ -42231,13 +44982,18 @@ case OP_Insert: { assert( pData->flags & (MEM_Blob|MEM_Str) ); } if( pC->pseudoTable ){ - sqlite3_free(pC->pData); + if( !pC->ephemPseudoTable ){ + sqlite3_free(pC->pData); + } pC->iKey = iKey; pC->nData = pData->n; - if( pData->flags & MEM_Dyn ){ + if( pData->z==pData->zMalloc || pC->ephemPseudoTable ){ pC->pData = pData->z; - pData->flags &= ~MEM_Dyn; - pData->flags |= MEM_Ephem; + if( !pC->ephemPseudoTable ){ + pData->flags &= ~MEM_Dyn; + pData->flags |= MEM_Ephem; + pData->zMalloc = 0; + } }else{ pC->pData = sqlite3_malloc( pC->nData+2 ); if( !pC->pData ) goto no_mem; @@ -42365,13 +45121,15 @@ case OP_ResetCount: { ** If the P1 cursor must be pointing to a valid row (not a NULL row) ** of a real table, not a pseudo-table. */ -case OP_RowKey: /* out2-prerelease */ -case OP_RowData: { /* out2-prerelease */ +case OP_RowKey: +case OP_RowData: { int i = pOp->p1; Cursor *pC; BtCursor *pCrsr; u32 n; + pOut = &p->aMem[pOp->p2]; + /* Note that RowKey and RowData are really exactly the same instruction */ assert( i>=0 && inCursor ); pC = p->apCsr[i]; @@ -42388,27 +45146,21 @@ case OP_RowData: { /* out2-prerelease */ i64 n64; assert( !pC->isTable ); sqlite3BtreeKeySize(pCrsr, &n64); - if( n64>SQLITE_MAX_LENGTH ){ + if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } n = n64; }else{ sqlite3BtreeDataSize(pCrsr, &n); - if( n>SQLITE_MAX_LENGTH ){ + if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } } - pOut->n = n; - if( n<=NBFS ){ - pOut->flags = MEM_Blob | MEM_Short; - pOut->z = pOut->zShort; - }else{ - char *z = sqlite3_malloc( n ); - if( z==0 ) goto no_mem; - pOut->flags = MEM_Blob | MEM_Dyn; - pOut->xDel = 0; - pOut->z = z; + if( sqlite3VdbeMemGrow(pOut, n, 0) ){ + goto no_mem; } + pOut->n = n; + MemSetTypeFlag(pOut, MEM_Blob); if( pC->isIndex ){ rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z); }else{ @@ -42447,7 +45199,7 @@ case OP_Rowid: { /* out2-prerelease */ v = keyToInt(v); } pOut->u.i = v; - pOut->flags = MEM_Int; + MemSetTypeFlag(pOut, MEM_Int); break; } @@ -42575,7 +45327,6 @@ case OP_Prev: /* jump */ case OP_Next: { /* jump */ Cursor *pC; BtCursor *pCrsr; - int res; CHECK_FOR_INTERRUPT; assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -42585,9 +45336,8 @@ case OP_Next: { /* jump */ } pCrsr = pC->pCursor; assert( pCrsr ); - if( pC->nullRow ){ - res = 1; - }else{ + if( pC->nullRow==0 ){ + int res = 1; assert( pC->deferredMoveto==0 ); rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) : sqlite3BtreePrevious(pCrsr, &res); @@ -42637,21 +45387,29 @@ case OP_IdxInsert: { /* in2 */ break; } -/* Opcode: IdxDelete P1 P2 * * * +/* Opcode: IdxDeleteM P1 P2 P3 * * ** -** The content of register P2 is an index key built using the either the -** MakeIdxRec opcode. Removes that entry from the index. +** The content of P3 registers starting at register P2 form +** an unpacked index key. This opcode removes that entry from the +** index opened by cursor P1. */ -case OP_IdxDelete: { /* in2 */ +case OP_IdxDelete: { int i = pOp->p1; Cursor *pC; BtCursor *pCrsr; - assert( pIn2->flags & MEM_Blob ); + assert( pOp->p3>0 ); + assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem ); assert( i>=0 && inCursor ); assert( p->apCsr[i]!=0 ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ int res; - rc = sqlite3BtreeMoveto(pCrsr, pIn2->z, pIn2->n, 0, &res); + UnpackedRecord r; + r.pKeyInfo = pC->pKeyInfo; + r.nField = pOp->p3; + r.needFree = 0; + r.needDestroy = 0; + r.aMem = &p->aMem[pOp->p2]; + rc = sqlite3BtreeMoveto(pCrsr, 0, &r, 0, 0, &res); if( rc==SQLITE_OK && res==0 ){ rc = sqlite3BtreeDelete(pCrsr); } @@ -42686,7 +45444,7 @@ case OP_IdxRowid: { /* out2-prerelease */ if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - pOut->flags = MEM_Int; + MemSetTypeFlag(pOut, MEM_Int); pOut->u.i = rowid; } } @@ -42798,7 +45556,7 @@ case OP_Destroy: { /* out2-prerelease */ assert( iCnt==1 ); assert( (p->btreeMask & (1<aDb[iDb].pBt, pOp->p1, &iMoved); - pOut->flags = MEM_Int; + MemSetTypeFlag(pOut, MEM_Int); pOut->u.i = iMoved; #ifndef SQLITE_OMIT_AUTOVACUUM if( rc==SQLITE_OK && iMoved!=0 ){ @@ -42867,7 +45625,7 @@ case OP_CreateTable: { /* out2-prerelease */ rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags); if( rc==SQLITE_OK ){ pOut->u.i = pgno; - pOut->flags = MEM_Int; + MemSetTypeFlag(pOut, MEM_Int); } break; } @@ -43020,12 +45778,8 @@ case OP_IntegrityCk: { if( nErr==0 ){ assert( z==0 ); }else{ - pIn1->z = z; - pIn1->n = strlen(z); - pIn1->flags = MEM_Str | MEM_Dyn | MEM_Term; - pIn1->xDel = 0; + sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); } - pIn1->enc = SQLITE_UTF8; UPDATE_MAX_BLOBSIZE(pIn1); sqlite3VdbeChangeEncoding(pIn1, encoding); sqlite3_free(aRoot); @@ -43055,8 +45809,7 @@ case OP_FifoRead: { /* jump */ CHECK_FOR_INTERRUPT; assert( pOp->p1>0 && pOp->p1<=p->nMem ); pOut = &p->aMem[pOp->p1]; - Release(pOut); - pOut->flags = MEM_Int; + MemSetTypeFlag(pOut, MEM_Int); if( sqlite3VdbeFifoPop(&p->sFifo, &pOut->u.i)==SQLITE_DONE ){ pc = pOp->p2 - 1; } @@ -43134,7 +45887,7 @@ case OP_MemMax: { /* in1, in2 */ ** not contain an integer. An assertion fault will result if you try. */ case OP_IfPos: { /* jump, in1 */ - assert( pIn1->flags==MEM_Int ); + assert( pIn1->flags&MEM_Int ); if( pIn1->u.i>0 ){ pc = pOp->p2 - 1; } @@ -43149,7 +45902,7 @@ case OP_IfPos: { /* jump, in1 */ ** not contain an integer. An assertion fault will result if you try. */ case OP_IfNeg: { /* jump, in1 */ - assert( pIn1->flags==MEM_Int ); + assert( pIn1->flags&MEM_Int ); if( pIn1->u.i<0 ){ pc = pOp->p2 - 1; } @@ -43164,7 +45917,7 @@ case OP_IfNeg: { /* jump, in1 */ ** not contain an integer. An assertion fault will result if you try. */ case OP_IfZero: { /* jump, in1 */ - assert( pIn1->flags==MEM_Int ); + assert( pIn1->flags&MEM_Int ); if( pIn1->u.i==0 ){ pc = pOp->p2 - 1; } @@ -43202,6 +45955,7 @@ case OP_AggStep: { pMem->n++; ctx.s.flags = MEM_Null; ctx.s.z = 0; + ctx.s.zMalloc = 0; ctx.s.xDel = 0; ctx.s.db = db; ctx.isError = 0; @@ -43215,7 +45969,7 @@ case OP_AggStep: { (ctx.pFunc->xStep)(&ctx, n, apVal); if( ctx.isError ){ sqlite3SetString(&p->zErrMsg, sqlite3_value_text(&ctx.s), (char*)0); - rc = SQLITE_ERROR; + rc = ctx.isError; } sqlite3VdbeMemRelease(&ctx.s); break; @@ -43242,6 +45996,7 @@ case OP_AggFinal: { if( rc==SQLITE_ERROR ){ sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pMem), (char*)0); } + sqlite3VdbeChangeEncoding(pMem, encoding); UPDATE_MAX_BLOBSIZE(pMem); if( sqlite3VdbeMemTooBig(pMem) ){ goto too_big; @@ -43306,16 +46061,14 @@ case OP_Expire: { } #ifndef SQLITE_OMIT_SHARED_CACHE -/* Opcode: TableLock P1 P2 * P4 * +/* Opcode: TableLock P1 P2 P3 P4 * ** ** Obtain a lock on a particular table. This instruction is only used when ** the shared-cache feature is enabled. ** -** If P1 is not negative, then it is the index of the database -** in sqlite3.aDb[] and a read-lock is required. If P1 is negative, a -** write-lock is required. In this case the index of the database is the -** absolute value of P1 minus one (iDb = abs(P1) - 1;) and a write-lock is -** required. +** If P1 is the index of the database in sqlite3.aDb[] of the database +** on which the lock is acquired. A readlock is obtained if P3==0 or +** a write lock if P3==1. ** ** P2 contains the root-page of the table to lock. ** @@ -43324,12 +46077,10 @@ case OP_Expire: { */ case OP_TableLock: { int p1 = pOp->p1; - u8 isWriteLock = (p1<0); - if( isWriteLock ){ - p1 = (-1*p1)-1; - } + u8 isWriteLock = pOp->p3; assert( p1>=0 && p1nDb ); assert( (p->btreeMask & (1<aDb[p1].pBt, pOp->p2, isWriteLock); if( rc==SQLITE_LOCKED ){ const char *z = pOp->p4.z; @@ -43400,7 +46151,7 @@ case OP_VOpen: { pVtabCursor->pVtab = pVtab; /* Initialise vdbe cursor object */ - pCur = allocateCursor(p, pOp->p1, -1); + pCur = allocateCursor(p, pOp->p1, &pOp[-1], -1, 0); if( pCur ){ pCur->pVtabCursor = pVtabCursor; pCur->pModule = pVtabCursor->pVtab->pModule; @@ -43473,6 +46224,7 @@ case OP_VFilter: { /* jump */ pc = pOp->p2 - 1; } } + pCur->nullRow = 0; break; } @@ -43498,7 +46250,7 @@ case OP_VRowid: { /* out2-prerelease */ if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = pModule->xRowid(pCur->pVtabCursor, &iRow); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; - pOut->flags = MEM_Int; + MemSetTypeFlag(pOut, MEM_Int); pOut->u.i = iRow; break; } @@ -43527,8 +46279,15 @@ case OP_VColumn: { pModule = pCur->pVtabCursor->pVtab->pModule; assert( pModule->xColumn ); memset(&sContext, 0, sizeof(sContext)); - sContext.s.flags = MEM_Null; - sContext.s.db = db; + + /* The output cell may already have a buffer allocated. Move + ** the current contents to sContext.s so in case the user-function + ** can use the already allocated buffer instead of allocating a + ** new one. + */ + sqlite3VdbeMemMove(&sContext.s, pDest); + MemSetTypeFlag(&sContext.s, MEM_Null); + if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2); @@ -43669,6 +46428,7 @@ case OP_VUpdate: { assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) ); db->lastRowid = rowid; } + p->nChange++; } break; } @@ -43827,7 +46587,7 @@ abort_due_to_interrupt: ** ** This file contains code used to implement incremental BLOB I/O. ** -** $Id: vdbeblob.c,v 1.20 2008/01/25 15:04:50 drh Exp $ +** $Id: vdbeblob.c,v 1.21 2008/03/25 09:47:35 danielk1977 Exp $ */ @@ -43883,16 +46643,17 @@ SQLITE_API int sqlite3_blob_open( /* One of the following two instructions is replaced by an ** OP_Noop before exection. */ - {OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */ - {OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */ + {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}, /* 5: Push the rowid to the stack */ - {OP_NotExists, 0, 10, 1}, /* 6: Seek the cursor */ - {OP_Column, 0, 0, 1}, /* 7 */ - {OP_ResultRow, 1, 0, 0}, /* 8 */ - {OP_Close, 0, 0, 0}, /* 9 */ - {OP_Halt, 0, 0, 0}, /* 10 */ + {OP_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 */ }; Vdbe *v = 0; @@ -43981,9 +46742,9 @@ SQLITE_API int sqlite3_blob_open( /* Remove either the OP_OpenWrite or OpenRead. Set the P2 ** parameter of the other to pTab->tnum. */ - sqlite3VdbeChangeToNoop(v, (flags ? 2 : 3), 1); - sqlite3VdbeChangeP2(v, (flags ? 3 : 2), pTab->tnum); - sqlite3VdbeChangeP3(v, (flags ? 3 : 2), iDb); + 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 ** think that the table has one more column than it really @@ -43992,7 +46753,7 @@ SQLITE_API int sqlite3_blob_open( ** we can invoke OP_Column to fill in the vdbe cursors type ** and offset cache without causing any IO. */ - sqlite3VdbeChangeP2(v, 4, pTab->nCol+1); + sqlite3VdbeChangeP2(v, flags ? 4 : 2, pTab->nCol+1); if( !db->mallocFailed ){ sqlite3VdbeMakeReady(v, 1, 1, 1, 0); } @@ -44405,7 +47166,7 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.352 2008/01/23 14:51:49 drh Exp $ +** $Id: expr.c,v 1.367 2008/04/15 12:14:22 drh Exp $ */ /* @@ -44592,6 +47353,30 @@ SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq( return pColl; } +/* +** Generate the operands for a comparison operation. Before +** generating the code for each operand, set the EP_AnyAff +** flag on the expression so that it will be able to used a +** cached column value that has previously undergone an +** affinity change. +*/ +static void codeCompareOperands( + Parse *pParse, /* Parsing and code generating context */ + Expr *pLeft, /* The left operand */ + int *pRegLeft, /* Register where left operand is stored */ + int *pFreeLeft, /* Free this register when done */ + Expr *pRight, /* The right operand */ + int *pRegRight, /* Register where right operand is stored */ + int *pFreeRight /* Write temp register for right operand there */ +){ + while( pLeft->op==TK_UPLUS ) pLeft = pLeft->pLeft; + pLeft->flags |= EP_AnyAff; + *pRegLeft = sqlite3ExprCodeTemp(pParse, pLeft, pFreeLeft); + while( pRight->op==TK_UPLUS ) pRight = pRight->pLeft; + pRight->flags |= EP_AnyAff; + *pRegRight = sqlite3ExprCodeTemp(pParse, pRight, pFreeRight); +} + /* ** Generate code for a comparison operator. */ @@ -44613,6 +47398,10 @@ static int codeCompare( addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, (void*)p4, P4_COLLSEQ); sqlite3VdbeChangeP5(pParse->pVdbe, p5); + if( p5 & SQLITE_AFF_MASK ){ + sqlite3ExprCacheAffinityChange(pParse, in1, 1); + sqlite3ExprCacheAffinityChange(pParse, in2, 1); + } return addr; } @@ -44629,7 +47418,8 @@ SQLITE_PRIVATE Expr *sqlite3Expr( const Token *pToken /* Argument token */ ){ Expr *pNew; - pNew = sqlite3DbMallocZero(db, sizeof(Expr)); + static const Expr zeroExpr; + pNew = sqlite3DbMallocRaw(db, sizeof(Expr)); if( pNew==0 ){ /* When malloc fails, delete pLeft and pRight. Expressions passed to ** this function must always be allocated with sqlite3Expr() for this @@ -44639,6 +47429,7 @@ SQLITE_PRIVATE Expr *sqlite3Expr( sqlite3ExprDelete(pRight); return 0; } + *pNew = zeroExpr; pNew->op = op; pNew->pLeft = pLeft; pNew->pRight = pRight; @@ -44791,9 +47582,13 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ ** use it as the variable number */ int i; pExpr->iTable = i = atoi((char*)&pToken->z[1]); - if( i<1 || i>SQLITE_MAX_VARIABLE_NUMBER ){ + testcase( i==0 ); + testcase( i==1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); + if( i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", - SQLITE_MAX_VARIABLE_NUMBER); + db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); } if( i>pParse->nVar ){ pParse->nVar = i; @@ -44831,7 +47626,7 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ } } } - if( !pParse->nErr && pParse->nVar>SQLITE_MAX_VARIABLE_NUMBER ){ + if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "too many SQL variables"); } } @@ -45087,16 +47882,17 @@ no_mem: SQLITE_PRIVATE void sqlite3ExprListCheckLength( Parse *pParse, ExprList *pEList, - int iLimit, const char *zObject ){ - if( pEList && pEList->nExpr>iLimit ){ + int mx = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; + testcase( pEList && pEList->nExpr==mx ); + testcase( pEList && pEList->nExpr==mx+1 ); + if( pEList && pEList->nExpr>mx ){ sqlite3ErrorMsg(pParse, "too many columns in %s", zObject); } } -#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0 /* The following three functions, heightOfExpr(), heightOfExprList() ** and heightOfSelect(), are used to determine the maximum height ** of any expression tree referenced by the structure passed as the @@ -45159,7 +47955,6 @@ SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){ heightOfSelect(p, &nHeight); return nHeight; } -#endif /* ** Delete an entire expression list. @@ -45179,7 +47974,8 @@ SQLITE_PRIVATE void sqlite3ExprListDelete(ExprList *pList){ } /* -** Walk an expression tree. Call xFunc for each node visited. +** Walk an expression tree. Call xFunc for each node visited. xFunc +** is called on the node before xFunc is called on the nodes children. ** ** The return value from xFunc determines whether the tree walk continues. ** 0 means continue walking the tree. 1 means do not walk children @@ -45273,7 +48069,14 @@ static int exprNodeIsConstant(void *pArg, Expr *pExpr){ #ifndef SQLITE_OMIT_SUBQUERY case TK_SELECT: case TK_EXISTS: + testcase( pExpr->op==TK_SELECT ); + testcase( pExpr->op==TK_EXISTS ); #endif + testcase( pExpr->op==TK_ID ); + testcase( pExpr->op==TK_COLUMN ); + testcase( pExpr->op==TK_DOT ); + testcase( pExpr->op==TK_AGG_FUNCTION ); + testcase( pExpr->op==TK_AGG_COLUMN ); *pN = 0; return 2; case TK_IN: @@ -45529,6 +48332,8 @@ static int lookupName( } pExpr->pTab = pTab; if( iCol>=0 ){ + testcase( iCol==31 ); + testcase( iCol==32 ); *piColMask |= ((u32)1<=32?0xffffffff:0); } break; @@ -45638,6 +48443,7 @@ static int lookupName( */ if( pExpr->iColumn>=0 && pMatch!=0 ){ int n = pExpr->iColumn; + testcase( n==sizeof(Bitmask)*8-1 ); if( n>=sizeof(Bitmask)*8 ){ n = sizeof(Bitmask)*8-1; } @@ -45875,21 +48681,24 @@ SQLITE_PRIVATE int sqlite3ExprResolveNames( Expr *pExpr /* The expression to be analyzed. */ ){ int savedHasAgg; + if( pExpr==0 ) return 0; -#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0 - if( (pExpr->nHeight+pNC->pParse->nHeight)>SQLITE_MAX_EXPR_DEPTH ){ - sqlite3ErrorMsg(pNC->pParse, - "Expression tree is too large (maximum depth %d)", - SQLITE_MAX_EXPR_DEPTH - ); - return 1; +#if SQLITE_MAX_EXPR_DEPTH>0 + { + int mxDepth = pNC->pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH]; + if( (pExpr->nHeight+pNC->pParse->nHeight)>mxDepth ){ + sqlite3ErrorMsg(pNC->pParse, + "Expression tree is too large (maximum depth %d)", mxDepth + ); + return 1; + } + pNC->pParse->nHeight += pExpr->nHeight; } - pNC->pParse->nHeight += pExpr->nHeight; #endif savedHasAgg = pNC->hasAgg; pNC->hasAgg = 0; walkExprTree(pExpr, nameResolverStep, pNC); -#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0 +#if SQLITE_MAX_EXPR_DEPTH>0 pNC->pParse->nHeight -= pExpr->nHeight; #endif if( pNC->nErr>0 ){ @@ -45965,10 +48774,10 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique) ** or index instead of generating an epheremal table. */ if( sqlite3_enable_in_opt - && (p=pX->pSelect) && !p->pPrior + && (p=pX->pSelect)!=0 && !p->pPrior && !p->isDistinct && !p->isAgg && !p->pGroupBy && p->pSrc && p->pSrc->nSrc==1 && !p->pSrc->a[0].pSelect - && !p->pSrc->a[0].pTab->pSelect + && p->pSrc->a[0].pTab && !p->pSrc->a[0].pTab->pSelect && p->pEList->nExpr==1 && p->pEList->a[0].pExpr->op==TK_COLUMN && !p->pLimit && !p->pOffset && !p->pWhere ){ @@ -46029,11 +48838,11 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique) 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; - sqlite3VdbeAddOp2(v, OP_SetNumColumns, iTab, pIdx->nColumn); sqlite3VdbeJumpHere(v, iAddr); } @@ -46109,10 +48918,9 @@ SQLITE_PRIVATE void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ** is used. */ pExpr->iTable = pParse->nTab++; - addr = sqlite3VdbeAddOp1(v, OP_OpenEphemeral, pExpr->iTable); + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, 1); memset(&keyInfo, 0, sizeof(keyInfo)); keyInfo.nField = 1; - sqlite3VdbeAddOp2(v, OP_SetNumColumns, pExpr->iTable, 1); if( pExpr->pSelect ){ /* Case 1: expr IN (SELECT ...) @@ -46169,8 +48977,12 @@ SQLITE_PRIVATE void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ } /* Evaluate the expression and insert it into the temp table */ + pParse->disableColCache++; sqlite3ExprCode(pParse, pE2, r1); + assert( pParse->disableColCache>0 ); + pParse->disableColCache--; sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1); + sqlite3ExprCacheAffinityChange(pParse, r1, 1); sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2); } sqlite3ReleaseTempReg(pParse, r1); @@ -46284,17 +49096,42 @@ static void codeInteger(Vdbe *v, const char *z, int n, int negFlag, int iMem){ /* ** Generate code that will extract the iColumn-th column from -** table pTab and store the column value in register iReg. -** There is an open cursor to pTab in -** iTable. If iColumn<0 then code is generated that extracts the rowid. +** table pTab and store the column value in a register. An effort +** is made to store the column value in register iReg, but this is +** not guaranteed. The location of the column value is returned. +** +** There must be an open cursor to pTab in iTable when this routine +** is called. If iColumn<0 then code is generated that extracts the rowid. +** +** This routine might attempt to reuse the value of the column that +** has already been loaded into a register. The value will always +** be used if it has not undergone any affinity changes. But if +** an affinity change has occurred, then the cached value will only be +** used if allowAffChng is true. */ -SQLITE_PRIVATE void sqlite3ExprCodeGetColumn( - Vdbe *v, /* The VM being created */ +SQLITE_PRIVATE int sqlite3ExprCodeGetColumn( + Parse *pParse, /* Parsing and code generating context */ Table *pTab, /* Description of the table we are reading from */ int iColumn, /* Index of the table column */ int iTable, /* The cursor pointing to the table */ - int iReg /* Store results here */ + int iReg, /* Store results here */ + int allowAffChng /* True if prior affinity changes are OK */ ){ + Vdbe *v = pParse->pVdbe; + int i; + struct yColCache *p; + + for(i=0, p=pParse->aColCache; inColCache; i++, p++){ + if( p->iTable==iTable && p->iColumn==iColumn + && (!p->affChange || allowAffChng) ){ +#if 0 + sqlite3VdbeAddOp0(v, OP_Noop); + VdbeComment((v, "OPT: tab%d.col%d -> r%d", iTable, iColumn, p->iReg)); +#endif + return p->iReg; + } + } + assert( v!=0 ); if( iColumn<0 ){ int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid; sqlite3VdbeAddOp2(v, op, iTable, iReg); @@ -46310,6 +49147,130 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumn( } #endif } + if( pParse->disableColCache==0 ){ + i = pParse->iColCache; + p = &pParse->aColCache[i]; + p->iTable = iTable; + p->iColumn = iColumn; + p->iReg = iReg; + p->affChange = 0; + i++; + if( i>=ArraySize(pParse->aColCache) ) i = 0; + if( i>pParse->nColCache ) pParse->nColCache = i; + pParse->iColCache = i; + } + return iReg; +} + +/* +** Clear all column cache entries associated with the vdbe +** cursor with cursor number iTable. +*/ +SQLITE_PRIVATE void sqlite3ExprClearColumnCache(Parse *pParse, int iTable){ + if( iTable<0 ){ + pParse->nColCache = 0; + pParse->iColCache = 0; + }else{ + int i; + for(i=0; inColCache; i++){ + if( pParse->aColCache[i].iTable==iTable ){ + testcase( i==pParse->nColCache-1 ); + pParse->aColCache[i] = pParse->aColCache[--pParse->nColCache]; + pParse->iColCache = pParse->nColCache; + } + } + } +} + +/* +** Record the fact that an affinity change has occurred on iCount +** registers starting with iStart. +*/ +SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){ + int iEnd = iStart + iCount - 1; + int i; + for(i=0; inColCache; i++){ + int r = pParse->aColCache[i].iReg; + if( r>=iStart && r<=iEnd ){ + pParse->aColCache[i].affChange = 1; + } + } +} + +/* +** Generate code to moves content from one register to another. +** Keep the column cache up-to-date. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo){ + int i; + if( iFrom==iTo ) return; + sqlite3VdbeAddOp2(pParse->pVdbe, OP_Move, iFrom, iTo); + for(i=0; inColCache; i++){ + if( pParse->aColCache[i].iReg==iFrom ){ + pParse->aColCache[i].iReg = iTo; + } + } +} + +/* +** Return true if any register in the range iFrom..iTo (inclusive) +** is used as part of the column cache. +*/ +static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){ + int i; + for(i=0; inColCache; i++){ + int r = pParse->aColCache[i].iReg; + if( r>=iFrom && r<=iTo ) return 1; + } + return 0; +} + +/* +** Theres is a value in register iCurrent. We ultimately want +** the value to be in register iTarget. It might be that +** iCurrent and iTarget are the same register. +** +** We are going to modify the value, so we need to make sure it +** is not a cached register. If iCurrent is a cached register, +** then try to move the value over to iTarget. If iTarget is a +** cached register, then clear the corresponding cache line. +** +** Return the register that the value ends up in. +*/ +SQLITE_PRIVATE int sqlite3ExprWritableRegister(Parse *pParse, int iCurrent, int iTarget){ + int i; + assert( pParse->pVdbe!=0 ); + if( !usedAsColumnCache(pParse, iCurrent, iCurrent) ){ + return iCurrent; + } + if( iCurrent!=iTarget ){ + sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, iCurrent, iTarget); + } + for(i=0; inColCache; i++){ + if( pParse->aColCache[i].iReg==iTarget ){ + pParse->aColCache[i] = pParse->aColCache[--pParse->nColCache]; + pParse->iColCache = pParse->nColCache; + } + } + return iTarget; +} + +/* +** If the last instruction coded is an ephemeral copy of any of +** the registers in the nReg registers beginning with iReg, then +** convert the last instruction from OP_SCopy to OP_Copy. +*/ +SQLITE_PRIVATE void sqlite3ExprHardCopy(Parse *pParse, int iReg, int nReg){ + int addr; + VdbeOp *pOp; + Vdbe *v; + + v = pParse->pVdbe; + addr = sqlite3VdbeCurrentAddr(v); + pOp = sqlite3VdbeGetOp(v, addr-1); + if( pOp->opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1opcode = OP_Copy; + } } /* @@ -46323,13 +49284,13 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumn( ** must check the return code and move the results to the desired ** register. */ -static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ +SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ Vdbe *v = pParse->pVdbe; /* The VM under construction */ int op; /* The opcode being coded */ int inReg = target; /* Results stored in register inReg */ int regFree1 = 0; /* If non-zero free this temporary register */ int regFree2 = 0; /* If non-zero free this temporary register */ - int r1, r2, r3; /* Various register numbers */ + int r1, r2, r3, r4; /* Various register numbers */ assert( v!=0 || pParse->db->mallocFailed ); assert( target>0 && target<=pParse->nMem ); @@ -46361,8 +49322,10 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ assert( pParse->ckBase>0 ); inReg = pExpr->iColumn + pParse->ckBase; }else{ - sqlite3ExprCodeGetColumn(v, pExpr->pTab, - pExpr->iColumn, pExpr->iTable, target); + testcase( (pExpr->flags & EP_AnyAff)!=0 ); + inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, + pExpr->iColumn, pExpr->iTable, target, + pExpr->flags & EP_AnyAff); } break; } @@ -46423,7 +49386,14 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC ); assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER ); assert( to_op==OP_ToReal || aff!=SQLITE_AFF_REAL ); + testcase( to_op==OP_ToText ); + testcase( to_op==OP_ToBlob ); + testcase( to_op==OP_ToNumeric ); + testcase( to_op==OP_ToInt ); + testcase( to_op==OP_ToReal ); sqlite3VdbeAddOp1(v, to_op, inReg); + testcase( usedAsColumnCache(pParse, inReg, inReg) ); + sqlite3ExprCacheAffinityChange(pParse, inReg, 1); break; } #endif /* SQLITE_OMIT_CAST */ @@ -46439,10 +49409,18 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ assert( TK_GE==OP_Ge ); assert( TK_EQ==OP_Eq ); assert( TK_NE==OP_Ne ); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + testcase( op==TK_LT ); + testcase( op==TK_LE ); + testcase( op==TK_GT ); + testcase( op==TK_GE ); + testcase( op==TK_EQ ); + testcase( op==TK_NE ); + codeCompareOperands(pParse, pExpr->pLeft, &r1, ®Free1, + pExpr->pRight, &r2, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, r1, r2, inReg, SQLITE_STOREP2); + testcase( regFree1==0 ); + testcase( regFree2==0 ); break; } case TK_AND: @@ -46468,9 +49446,22 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ assert( TK_LSHIFT==OP_ShiftLeft ); assert( TK_RSHIFT==OP_ShiftRight ); assert( TK_CONCAT==OP_Concat ); + testcase( op==TK_AND ); + testcase( op==TK_OR ); + testcase( op==TK_PLUS ); + testcase( op==TK_MINUS ); + testcase( op==TK_REM ); + testcase( op==TK_BITAND ); + testcase( op==TK_BITOR ); + testcase( op==TK_SLASH ); + testcase( op==TK_LSHIFT ); + testcase( op==TK_RSHIFT ); + testcase( op==TK_CONCAT ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); sqlite3VdbeAddOp3(v, op, r2, r1, target); + testcase( regFree1==0 ); + testcase( regFree2==0 ); break; } case TK_UMINUS: { @@ -46486,8 +49477,9 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ }else{ regFree1 = r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp2(v, OP_Integer, 0, r1); - r2 = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2); sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target); + testcase( regFree2==0 ); } inReg = target; break; @@ -46496,7 +49488,12 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ case TK_NOT: { assert( TK_BITNOT==OP_BitNot ); assert( TK_NOT==OP_Not ); + testcase( op==TK_BITNOT ); + testcase( op==TK_NOT ); inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + testcase( inReg==target ); + testcase( usedAsColumnCache(pParse, inReg, inReg) ); + inReg = sqlite3ExprWritableRegister(pParse, inReg, target); sqlite3VdbeAddOp1(v, op, inReg); break; } @@ -46505,8 +49502,11 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ int addr; assert( TK_ISNULL==OP_IsNull ); assert( TK_NOTNULL==OP_NotNull ); + testcase( op==TK_ISNULL ); + testcase( op==TK_NOTNULL ); sqlite3VdbeAddOp2(v, OP_Integer, 1, target); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + testcase( regFree1==0 ); addr = sqlite3VdbeAddOp1(v, op, r1); sqlite3VdbeAddOp2(v, OP_AddImm, target, -1); sqlite3VdbeJumpHere(v, addr); @@ -46535,6 +49535,8 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ u8 enc = ENC(db); CollSeq *pColl = 0; + testcase( op==TK_CONST_FUNC ); + testcase( op==TK_FUNCTION ); zId = (char*)pExpr->token.z; nId = pExpr->token.n; pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); @@ -46542,7 +49544,7 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ if( pList ){ nExpr = pList->nExpr; r1 = sqlite3GetTempRange(pParse, nExpr); - sqlite3ExprCodeExprList(pParse, pList, r1); + sqlite3ExprCodeExprList(pParse, pList, r1, 1); }else{ nExpr = r1 = 0; } @@ -46583,11 +49585,14 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ if( nExpr ){ sqlite3ReleaseTempRange(pParse, r1, nExpr); } + sqlite3ExprCacheAffinityChange(pParse, r1, nExpr); break; } #ifndef SQLITE_OMIT_SUBQUERY case TK_EXISTS: case TK_SELECT: { + testcase( op==TK_EXISTS ); + testcase( op==TK_SELECT ); if( pExpr->iColumn==0 ){ sqlite3CodeSubselect(pParse, pExpr); } @@ -46613,12 +49618,13 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ ** pExpr->iTable contains the values that make up the (...) set. */ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + testcase( regFree1==0 ); j1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); sqlite3VdbeAddOp2(v, OP_Null, 0, target); j2 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, j1); if( eType==IN_INDEX_ROWID ){ - j3 = sqlite3VdbeAddOp3(v, OP_MustBeInt, r1, 0, 1); + j3 = sqlite3VdbeAddOp1(v, OP_MustBeInt, r1); j4 = sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, 0, r1); j5 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, j3); @@ -46626,6 +49632,7 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ }else{ r2 = regFree2 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1); + sqlite3ExprCacheAffinityChange(pParse, r1, 1); j5 = sqlite3VdbeAddOp3(v, OP_Found, pExpr->iTable, 0, r2); } sqlite3VdbeAddOp2(v, OP_AddImm, target, -1); @@ -46650,18 +49657,23 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ struct ExprList_item *pLItem = pExpr->pList->a; Expr *pRight = pLItem->pExpr; - r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2); + codeCompareOperands(pParse, pLeft, &r1, ®Free1, + pRight, &r2, ®Free2); + testcase( regFree1==0 ); + testcase( regFree2==0 ); r3 = sqlite3GetTempReg(pParse); + r4 = sqlite3GetTempReg(pParse); codeCompare(pParse, pLeft, pRight, OP_Ge, r1, r2, r3, SQLITE_STOREP2); pLItem++; pRight = pLItem->pExpr; sqlite3ReleaseTempReg(pParse, regFree2); r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2); - codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r2, SQLITE_STOREP2); - sqlite3VdbeAddOp3(v, OP_And, r3, r2, target); + testcase( regFree2==0 ); + codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2); + sqlite3VdbeAddOp3(v, OP_And, r3, r4, target); sqlite3ReleaseTempReg(pParse, r3); + sqlite3ReleaseTempReg(pParse, r4); break; } case TK_UPLUS: { @@ -46711,12 +49723,16 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ endLabel = sqlite3VdbeMakeLabel(v); if( (pX = pExpr->pLeft)!=0 ){ cacheX = *pX; + testcase( pX->op==TK_COLUMN || pX->op==TK_REGISTER ); cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, ®Free1); + testcase( regFree1==0 ); cacheX.op = TK_REGISTER; + cacheX.iColumn = 0; opCompare.op = TK_EQ; opCompare.pLeft = &cacheX; pTest = &opCompare; } + pParse->disableColCache++; for(i=0; iop==TK_COLUMN || pTest->op==TK_REGISTER ); sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); + testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); + testcase( aListelem[i+1].pExpr->op==TK_REGISTER ); sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel); sqlite3VdbeResolveLabel(v, nextCase); @@ -46735,6 +49754,8 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3VdbeAddOp2(v, OP_Null, 0, target); } sqlite3VdbeResolveLabel(v, endLabel); + assert( pParse->disableColCache>0 ); + pParse->disableColCache--; break; } #ifndef SQLITE_OMIT_TRIGGER @@ -46772,7 +49793,7 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ ** are stored. ** ** If the register is a temporary register that can be deallocated, -** then write its number into *pReg. If the result register is no +** then write its number into *pReg. If the result register is not ** a temporary, then set *pReg to zero. */ SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ @@ -46826,11 +49847,123 @@ SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int targe iMem = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem); pExpr->iTable = iMem; + pExpr->iColumn = pExpr->op; pExpr->op = TK_REGISTER; } return inReg; } +/* +** Return TRUE if pExpr is an constant expression that is appropriate +** for factoring out of a loop. Appropriate expressions are: +** +** * Any expression that evaluates to two or more opcodes. +** +** * Any OP_Integer, OP_Real, OP_String, OP_Blob, OP_Null, +** or OP_Variable that does not need to be placed in a +** specific register. +** +** There is no point in factoring out single-instruction constant +** expressions that need to be placed in a particular register. +** We could factor them out, but then we would end up adding an +** OP_SCopy instruction to move the value into the correct register +** later. We might as well just use the original instruction and +** avoid the OP_SCopy. +*/ +static int isAppropriateForFactoring(Expr *p){ + if( !sqlite3ExprIsConstantNotJoin(p) ){ + return 0; /* Only constant expressions are appropriate for factoring */ + } + if( (p->flags & EP_FixedDest)==0 ){ + return 1; /* Any constant without a fixed destination is appropriate */ + } + while( p->op==TK_UPLUS ) p = p->pLeft; + switch( p->op ){ +#ifndef SQLITE_OMIT_BLOB_LITERAL + case TK_BLOB: +#endif + case TK_VARIABLE: + case TK_INTEGER: + case TK_FLOAT: + case TK_NULL: + case TK_STRING: { + testcase( p->op==TK_BLOB ); + testcase( p->op==TK_VARIABLE ); + testcase( p->op==TK_INTEGER ); + testcase( p->op==TK_FLOAT ); + testcase( p->op==TK_NULL ); + testcase( p->op==TK_STRING ); + /* Single-instruction constants with a fixed destination are + ** better done in-line. If we factor them, they will just end + ** up generating an OP_SCopy to move the value to the destination + ** register. */ + return 0; + } + case TK_UMINUS: { + if( p->pLeft->op==TK_FLOAT || p->pLeft->op==TK_INTEGER ){ + return 0; + } + break; + } + default: { + break; + } + } + return 1; +} + +/* +** If pExpr is a constant expression that is appropriate for +** factoring out of a loop, then evaluate the expression +** into a register and convert the expression into a TK_REGISTER +** expression. +*/ +static int evalConstExpr(void *pArg, Expr *pExpr){ + Parse *pParse = (Parse*)pArg; + switch( pExpr->op ){ + case TK_REGISTER: { + return 1; + } + case TK_FUNCTION: + case TK_AGG_FUNCTION: + case TK_CONST_FUNC: { + /* The arguments to a function have a fixed destination. + ** Mark them this way to avoid generated unneeded OP_SCopy + ** instructions. + */ + ExprList *pList = pExpr->pList; + if( pList ){ + int i = pList->nExpr; + struct ExprList_item *pItem = pList->a; + for(; i>0; i--, pItem++){ + if( pItem->pExpr ) pItem->pExpr->flags |= EP_FixedDest; + } + } + break; + } + } + if( isAppropriateForFactoring(pExpr) ){ + int r1 = ++pParse->nMem; + int r2; + r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); + if( r1!=r2 ) sqlite3ReleaseTempReg(pParse, r1); + pExpr->iColumn = pExpr->op; + pExpr->op = TK_REGISTER; + pExpr->iTable = r2; + return 1; + } + return 0; +} + +/* +** Preevaluate constant subexpressions within pExpr and store the +** results in registers. Modify pExpr so that the constant subexpresions +** are TK_REGISTER opcodes that refer to the precomputed values. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){ + walkExprTree(pExpr, evalConstExpr, pParse); +} + /* ** Generate code that pushes the value of every element of the given @@ -46841,7 +49974,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int targe SQLITE_PRIVATE int sqlite3ExprCodeExprList( Parse *pParse, /* Parsing context */ ExprList *pList, /* The expression list to be coded */ - int target /* Where to write results */ + int target, /* Where to write results */ + int doHardCopy /* Call sqlite3ExprHardCopy on each element if true */ ){ struct ExprList_item *pItem; int i, n; @@ -46851,9 +49985,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList( } assert( target>0 ); n = pList->nExpr; - for(pItem=pList->a, i=n; i>0; i--, pItem++){ - sqlite3ExprCode(pParse, pItem->pExpr, target); - target++; + for(pItem=pList->a, i=0; ipExpr, target+i); + if( doHardCopy ) sqlite3ExprHardCopy(pParse, target, n); } return n; } @@ -46885,17 +50019,28 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int switch( op ){ case TK_AND: { int d2 = sqlite3VdbeMakeLabel(v); + testcase( jumpIfNull==0 ); + testcase( pParse->disableColCache==0 ); sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL); + pParse->disableColCache++; sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + assert( pParse->disableColCache>0 ); + pParse->disableColCache--; sqlite3VdbeResolveLabel(v, d2); break; } case TK_OR: { + testcase( jumpIfNull==0 ); + testcase( pParse->disableColCache==0 ); sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); + pParse->disableColCache++; sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + assert( pParse->disableColCache>0 ); + pParse->disableColCache--; break; } case TK_NOT: { + testcase( jumpIfNull==0 ); sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); break; } @@ -46911,18 +50056,30 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int assert( TK_GE==OP_Ge ); assert( TK_EQ==OP_Eq ); assert( TK_NE==OP_Ne ); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + testcase( op==TK_LT ); + testcase( op==TK_LE ); + testcase( op==TK_GT ); + testcase( op==TK_GE ); + testcase( op==TK_EQ ); + testcase( op==TK_NE ); + testcase( jumpIfNull==0 ); + codeCompareOperands(pParse, pExpr->pLeft, &r1, ®Free1, + pExpr->pRight, &r2, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, r1, r2, dest, jumpIfNull); + testcase( regFree1==0 ); + testcase( regFree2==0 ); break; } case TK_ISNULL: case TK_NOTNULL: { assert( TK_ISNULL==OP_IsNull ); assert( TK_NOTNULL==OP_NotNull ); + testcase( op==TK_ISNULL ); + testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); sqlite3VdbeAddOp2(v, op, r1, dest); + testcase( regFree1==0 ); break; } case TK_BETWEEN: { @@ -46951,13 +50108,17 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int compRight.pLeft = &exprX; compRight.pRight = pExpr->pList->a[1].pExpr; exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, ®Free1); + testcase( regFree1==0 ); exprX.op = TK_REGISTER; + testcase( jumpIfNull==0 ); sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull); break; } default: { r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0); + testcase( regFree1==0 ); + testcase( jumpIfNull==0 ); break; } } @@ -47017,14 +50178,24 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int switch( pExpr->op ){ case TK_AND: { + testcase( jumpIfNull==0 ); + testcase( pParse->disableColCache==0 ); sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); + pParse->disableColCache++; sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); + assert( pParse->disableColCache>0 ); + pParse->disableColCache--; break; } case TK_OR: { int d2 = sqlite3VdbeMakeLabel(v); + testcase( jumpIfNull==0 ); + testcase( pParse->disableColCache==0 ); sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); + pParse->disableColCache++; sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); + assert( pParse->disableColCache>0 ); + pParse->disableColCache--; sqlite3VdbeResolveLabel(v, d2); break; } @@ -47038,16 +50209,28 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int case TK_GE: case TK_NE: case TK_EQ: { - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + testcase( op==TK_LT ); + testcase( op==TK_LE ); + testcase( op==TK_GT ); + testcase( op==TK_GE ); + testcase( op==TK_EQ ); + testcase( op==TK_NE ); + testcase( jumpIfNull==0 ); + codeCompareOperands(pParse, pExpr->pLeft, &r1, ®Free1, + pExpr->pRight, &r2, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, r1, r2, dest, jumpIfNull); + testcase( regFree1==0 ); + testcase( regFree2==0 ); break; } case TK_ISNULL: case TK_NOTNULL: { + testcase( op==TK_ISNULL ); + testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); sqlite3VdbeAddOp2(v, op, r1, dest); + testcase( regFree1==0 ); break; } case TK_BETWEEN: { @@ -47076,13 +50259,17 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int compRight.pLeft = &exprX; compRight.pRight = pExpr->pList->a[1].pExpr; exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, ®Free1); + testcase( regFree1==0 ); exprX.op = TK_REGISTER; + testcase( jumpIfNull==0 ); sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull); break; } default: { r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0); + testcase( regFree1==0 ); + testcase( jumpIfNull==0 ); break; } } @@ -47338,15 +50525,25 @@ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList) ** Allocate or deallocate temporary use registers during code generation. */ SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){ - if( pParse->nTempReg ){ - return pParse->aTempReg[--pParse->nTempReg]; - }else{ + int i, r; + if( pParse->nTempReg==0 ){ return ++pParse->nMem; } + for(i=0; inTempReg; i++){ + r = pParse->aTempReg[i]; + if( usedAsColumnCache(pParse, r, r) ) continue; + } + if( i>=pParse->nTempReg ){ + return ++pParse->nMem; + } + while( inTempReg-1 ){ + pParse->aTempReg[i] = pParse->aTempReg[i+1]; + } + pParse->nTempReg--; + return r; } SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ if( iReg && pParse->nTempRegaTempReg) ){ - assert( iReg>0 ); pParse->aTempReg[pParse->nTempReg++] = iReg; } } @@ -47355,9 +50552,10 @@ SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ ** Allocate or deallocate a block of nReg consecutive registers */ SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){ - int i; - if( nReg<=pParse->nRangeReg ){ - i = pParse->iRangeReg; + int i, n; + i = pParse->iRangeReg; + n = pParse->nRangeReg; + if( nReg<=n && !usedAsColumnCache(pParse, i, i+n-1) ){ pParse->iRangeReg += nReg; pParse->nRangeReg -= nReg; }else{ @@ -47389,7 +50587,7 @@ SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ ** This file contains C code routines that used to generate VDBE code ** that implements the ALTER TABLE command. ** -** $Id: alter.c,v 1.41 2008/01/25 15:04:48 drh Exp $ +** $Id: alter.c,v 1.43 2008/03/19 21:45:51 drh Exp $ */ /* @@ -47426,7 +50624,7 @@ static void renameTableFunc( int len = 0; char *zRet; - sqlite3 *db = sqlite3_user_data(context); + sqlite3 *db = sqlite3_context_db_handle(context); /* The principle used to locate the table name in the CREATE TABLE ** statement is that the table name is the first token that is immediatedly @@ -47453,7 +50651,7 @@ static void renameTableFunc( assert( len>0 ); } while( token!=TK_LP && token!=TK_USING ); - zRet = sqlite3MPrintf(db, "%.*s%Q%s", tname.z - zSql, zSql, + zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql, zTableName, tname.z+tname.n); sqlite3_result_text(context, zRet, -1, sqlite3_free); } @@ -47482,7 +50680,7 @@ static void renameTriggerFunc( int len = 0; char *zRet; - sqlite3 *db = sqlite3_user_data(context); + sqlite3 *db = sqlite3_context_db_handle(context); /* The principle used to locate the table name in the CREATE TRIGGER ** statement is that the table name is the first token that is immediatedly @@ -47528,7 +50726,7 @@ static void renameTriggerFunc( /* Variable tname now contains the token that is the old table-name ** in the CREATE TRIGGER statement. */ - zRet = sqlite3MPrintf(db, "%.*s%Q%s", tname.z - zSql, zSql, + zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql, zTableName, tname.z+tname.n); sqlite3_result_text(context, zRet, -1, sqlite3_free); } @@ -47553,7 +50751,7 @@ SQLITE_PRIVATE void sqlite3AlterFunctions(sqlite3 *db){ for(i=0; izName); } #endif @@ -47897,7 +51095,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ *zEnd-- = '\0'; } sqlite3NestedParse(pParse, - "UPDATE %Q.%s SET " + "UPDATE \"%w\".%s SET " "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " "WHERE type = 'table' AND name = %Q", zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1, @@ -48019,7 +51217,7 @@ exit_begin_add_column: ************************************************************************* ** This file contains code associated with the ANALYZE command. ** -** @(#) $Id: analyze.c,v 1.41 2008/01/25 15:04:49 drh Exp $ +** @(#) $Id: analyze.c,v 1.42 2008/03/25 09:47:35 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_ANALYZE @@ -48081,9 +51279,9 @@ static void openStatTable( if( !createStat1 ){ sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1"); } + sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, 3); sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur, iRootPage, iDb); sqlite3VdbeChangeP5(v, createStat1); - sqlite3VdbeAddOp2(v, OP_SetNumColumns, iStatCur, 3); } /* @@ -48137,17 +51335,17 @@ static void analyzeOneTable( /* 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)); - nCol = pIdx->nColumn; regFields = iMem+nCol*2; regTemp = regRowid = regCol = regFields+3; regRec = regCol+1; if( regRec>pParse->nMem ){ pParse->nMem = regRec; } - sqlite3VdbeAddOp2(v, OP_SetNumColumns, iIdxCur, nCol+1); /* Memory cells are used as follows: ** @@ -48446,7 +51644,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** -** $Id: attach.c,v 1.70 2008/01/23 03:03:05 drh Exp $ +** $Id: attach.c,v 1.74 2008/03/20 14:03:29 drh Exp $ */ #ifndef SQLITE_OMIT_ATTACH @@ -48503,7 +51701,7 @@ static void attachFunc( ){ int i; int rc = 0; - sqlite3 *db = sqlite3_user_data(context); + sqlite3 *db = sqlite3_context_db_handle(context); const char *zName; const char *zFile; Db *aNew; @@ -48521,10 +51719,10 @@ static void attachFunc( ** * Transaction currently open ** * Specified database name already being used. */ - if( db->nDb>=SQLITE_MAX_ATTACHED+2 ){ + if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){ sqlite3_snprintf( sizeof(zErr), zErr, "too many attached databases - max %d", - SQLITE_MAX_ATTACHED + db->aLimit[SQLITE_LIMIT_ATTACHED] ); goto attach_error; } @@ -48656,6 +51854,7 @@ attach_error: zErr[sizeof(zErr)-1] = 0; sqlite3_result_error(context, zErr, -1); } + if( rc ) sqlite3_result_error_code(context, rc); } /* @@ -48672,7 +51871,7 @@ static void detachFunc( sqlite3_value **argv ){ const char *zName = (const char *)sqlite3_value_text(argv[0]); - sqlite3 *db = sqlite3_user_data(context); + sqlite3 *db = sqlite3_context_db_handle(context); int i; Db *pDb = 0; char zErr[128]; @@ -48761,14 +51960,14 @@ static void codeAttach( } v = sqlite3GetVdbe(pParse); - regArgs = sqlite3GetTempRange(pParse, 3); + regArgs = sqlite3GetTempRange(pParse, 4); sqlite3ExprCode(pParse, pFilename, regArgs); sqlite3ExprCode(pParse, pDbname, regArgs+1); sqlite3ExprCode(pParse, pKey, regArgs+2); assert( v || db->mallocFailed ); if( v ){ - sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-nFunc, regArgs); + sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-nFunc, regArgs+3); sqlite3VdbeChangeP5(v, nFunc); pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0); sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF); @@ -48811,8 +52010,8 @@ SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *p SQLITE_PRIVATE void sqlite3AttachFunctions(sqlite3 *db){ #ifndef SQLITE_OMIT_ATTACH static const int enc = SQLITE_UTF8; - sqlite3CreateFunc(db, "sqlite_attach", 3, enc, db, attachFunc, 0, 0); - sqlite3CreateFunc(db, "sqlite_detach", 1, enc, db, detachFunc, 0, 0); + sqlite3CreateFunc(db, "sqlite_attach", 3, enc, 0, attachFunc, 0, 0); + sqlite3CreateFunc(db, "sqlite_detach", 1, enc, 0, detachFunc, 0, 0); #endif } @@ -49221,7 +52420,7 @@ SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext *pContext){ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.472 2008/01/31 13:35:49 drh Exp $ +** $Id: build.c,v 1.480 2008/04/11 17:11:27 danielk1977 Exp $ */ /* @@ -49308,10 +52507,8 @@ static void codeTableLocks(Parse *pParse){ for(i=0; inTableLock; i++){ TableLock *p = &pParse->aTableLock[i]; int p1 = p->iDb; - if( p->isWriteLock ){ - p1 = -1*(p1+1); - } - sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, 0, p->zName, P4_STATIC); + sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock, + p->zName, P4_STATIC); } } #else @@ -49402,6 +52599,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ 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); pParse->rc = SQLITE_DONE; @@ -49805,8 +53003,8 @@ SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, Token *pName){ 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); - sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */ } /* @@ -50130,11 +53328,14 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName){ int i; char *z; Column *pCol; + sqlite3 *db = pParse->db; if( (p = pParse->pNewTable)==0 ) return; - if( p->nCol+1>SQLITE_MAX_COLUMN ){ +#if SQLITE_MAX_COLUMN + if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); return; } +#endif z = sqlite3NameFromToken(pParse->db, pName); if( z==0 ) return; for(i=0; inCol; i++){ @@ -51267,6 +54468,14 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", pDb->zName, SCHEMA_TABLE(iDb), pTab->zName); + + /* Drop any statistics from the sqlite_stat1 table, if it exists */ + if( sqlite3FindTable(db, "sqlite_stat1", db->aDb[iDb].zName) ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.sqlite_stat1 WHERE tbl=%Q", pDb->zName, pTab->zName + ); + } + if( !isView && !IsVirtual(pTab) ){ destroyTable(pParse, pTab); } @@ -51472,7 +54681,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); regRecord = sqlite3GetTempReg(pParse); - regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord); + regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1); if( pIndex->onError!=OE_None ){ int j1, j2; int regRowid; @@ -51480,7 +54689,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ regRowid = regIdxKey + pIndex->nColumn; j1 = sqlite3VdbeAddOp3(v, OP_IsNull, regIdxKey, 0, pIndex->nColumn); j2 = sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, - 0, regRowid, (char*)regRecord, P4_INT32); + 0, regRowid, (char*)(sqlite3_intptr_t)regRecord, P4_INT32); sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort, 0, "indexed columns are not unique", P4_STATIC); sqlite3VdbeJumpHere(v, j1); @@ -52052,6 +55261,12 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName ); + if( sqlite3FindTable(db, "sqlite_stat1", db->aDb[iDb].zName) ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.sqlite_stat1 WHERE idx=%Q", + db->aDb[iDb].zName, pIndex->zName + ); + } sqlite3ChangeCookie(pParse, iDb); destroyRootPage(pParse, pIndex->tnum, iDb); sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); @@ -53059,7 +56274,7 @@ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ ** 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.160 2008/01/25 15:04:50 drh Exp $ +** $Id: delete.c,v 1.168 2008/04/15 14:36:42 drh Exp $ */ /* @@ -53121,12 +56336,43 @@ SQLITE_PRIVATE void sqlite3OpenTable( v = sqlite3GetVdbe(p); assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName); + sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pTab->nCol); sqlite3VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb); VdbeComment((v, "%s", pTab->zName)); - sqlite3VdbeAddOp2(v, OP_SetNumColumns, iCur, pTab->nCol); } +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) +/* +** Evaluate a view and store its result in an ephemeral table. The +** pWhere argument is an optional WHERE clause that restricts the +** set of rows in the view that are to be added to the ephemeral table. +*/ +SQLITE_PRIVATE void sqlite3MaterializeView( + Parse *pParse, /* Parsing context */ + Select *pView, /* View definition */ + Expr *pWhere, /* Optional WHERE clause to be added */ + int iCur /* Cursor number for ephemerial table */ +){ + SelectDest dest; + Select *pDup; + sqlite3 *db = pParse->db; + + pDup = sqlite3SelectDup(db, pView); + if( pWhere ){ + SrcList *pFrom; + + pWhere = sqlite3ExprDup(db, pWhere); + pFrom = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, 0, pDup, 0, 0); + pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0); + } + sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); + sqlite3Select(pParse, pDup, &dest, 0, 0, 0, 0); + sqlite3SelectDelete(pDup); +} +#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */ + + /* ** Generate code for a DELETE FROM statement. ** @@ -53216,19 +56462,13 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( oldIdx = pParse->nTab++; } - /* Resolve the column names in the WHERE clause. + /* Assign cursor number to the table and all its indices. */ assert( pTabList->nSrc==1 ); iCur = pTabList->a[0].iCursor = pParse->nTab++; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ pParse->nTab++; } - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; - sNC.pSrcList = pTabList; - if( sqlite3ExprResolveNames(&sNC, pWhere) ){ - goto delete_from_cleanup; - } /* Start the view context */ @@ -53267,14 +56507,16 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( ** a ephemeral table. */ if( isView ){ - SelectDest dest; - Select *pView; + sqlite3MaterializeView(pParse, pTab->pSelect, pWhere, iCur); + } - pView = sqlite3SelectDup(db, pTab->pSelect); - sqlite3SelectMask(pParse, pView, old_col_mask); - sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); - sqlite3Select(pParse, pView, &dest, 0, 0, 0, 0); - sqlite3SelectDelete(pView); + /* Resolve the column names in the WHERE clause. + */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + if( sqlite3ExprResolveNames(&sNC, pWhere) ){ + goto delete_from_cleanup; } /* Initialize the counter of the number of rows deleted, if @@ -53339,8 +56581,8 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( /* 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); - sqlite3VdbeAddOp2(v, OP_SetNumColumns, oldIdx, pTab->nCol); } /* Delete every item whose key was written to the list during the @@ -53505,18 +56747,16 @@ SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete( Index *pIdx; int r1; - r1 = sqlite3GetTempReg(pParse); for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue; - sqlite3GenerateIndexKey(pParse, pIdx, iCur, r1); - sqlite3VdbeAddOp2(pParse->pVdbe, OP_IdxDelete, iCur+i, r1); + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0); + sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1); } - sqlite3ReleaseTempReg(pParse, r1); } /* -** Generate code that will assemble an index key and put it on the top -** of the tack. The key with be for index pIdx which is an index on pTab. +** Generate code that will assemble an index key and put it in register +** regOut. The key with be for index pIdx which is an index on pTab. ** iCur is the index of a cursor open on the pTab table and pointing to ** the entry that needs indexing. ** @@ -53529,7 +56769,8 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey( Parse *pParse, /* Parsing context */ Index *pIdx, /* The index for which to generate a key */ int iCur, /* Cursor number for the pIdx->pTable table */ - int regOut /* Write the new index key to this register */ + int regOut, /* Write the new index key to this register */ + int doMakeRec /* Run the OP_MakeRecord instruction if true */ ){ Vdbe *v = pParse->pVdbe; int j; @@ -53549,12 +56790,20 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey( sqlite3ColumnDefault(v, pTab, idx); } } - sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut); - sqlite3IndexAffinityStr(v, pIdx); + if( doMakeRec ){ + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut); + sqlite3IndexAffinityStr(v, pIdx); + sqlite3ExprCacheAffinityChange(pParse, regBase, nCol+1); + } sqlite3ReleaseTempRange(pParse, regBase, nCol+1); return regBase; } +/* Make sure "isView" gets undefined in case this file becomes part of +** the amalgamation - so that subsequent files do not see isView as a +** macro. */ +#undef isView + /************** End of delete.c **********************************************/ /************** Begin file func.c ********************************************/ /* @@ -53575,7 +56824,7 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey( ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.183 2008/01/21 16:22:46 drh Exp $ +** $Id: func.c,v 1.191 2008/03/20 16:30:18 drh Exp $ */ @@ -53742,7 +56991,7 @@ static void substrFunc( if( argc==3 ){ p2 = sqlite3_value_int(argv[2]); }else{ - p2 = SQLITE_MAX_LENGTH; + p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; } if( p1<0 ){ p1 += len; @@ -53797,10 +57046,16 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ ** allocation fails, call sqlite3_result_error_nomem() to notify ** the database handle that malloc() has failed. */ -static void *contextMalloc(sqlite3_context *context, int nByte){ - char *z = sqlite3_malloc(nByte); - if( !z && nByte>0 ){ - sqlite3_result_error_nomem(context); +static void *contextMalloc(sqlite3_context *context, i64 nByte){ + char *z; + if( nByte>sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + z = 0; + }else{ + z = sqlite3_malloc(nByte); + if( !z && nByte>0 ){ + sqlite3_result_error_nomem(context); + } } return z; } @@ -53818,7 +57073,7 @@ static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ /* Verify that the call to _bytes() does not invalidate the _text() pointer */ assert( z2==(char*)sqlite3_value_text(argv[0]) ); if( z2 ){ - z1 = contextMalloc(context, n+1); + z1 = contextMalloc(context, ((i64)n)+1); if( z1 ){ memcpy(z1, z2, n+1); for(i=0; z1[i]; i++){ @@ -53838,7 +57093,7 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ /* Verify that the call to _bytes() does not invalidate the _text() pointer */ assert( z2==(char*)sqlite3_value_text(argv[0]) ); if( z2 ){ - z1 = contextMalloc(context, n+1); + z1 = contextMalloc(context, ((i64)n)+1); if( z1 ){ memcpy(z1, z2, n+1); for(i=0; z1[i]; i++){ @@ -53877,7 +57132,7 @@ static void randomFunc( sqlite3_value **argv ){ sqlite_int64 r; - sqlite3Randomness(sizeof(r), &r); + sqlite3_randomness(sizeof(r), &r); if( (r<<1)==0 ) r = 0; /* Prevent 0x8000.... as the result so that we */ /* can always do abs() of the result */ sqlite3_result_int64(context, r); @@ -53899,13 +57154,9 @@ static void randomBlob( if( n<1 ){ n = 1; } - if( n>SQLITE_MAX_LENGTH ){ - sqlite3_result_error_toobig(context); - return; - } p = contextMalloc(context, n); if( p ){ - sqlite3Randomness(n, p); + sqlite3_randomness(n, p); sqlite3_result_blob(context, (char*)p, n, sqlite3_free); } } @@ -53919,7 +57170,7 @@ static void last_insert_rowid( int arg, sqlite3_value **argv ){ - sqlite3 *db = sqlite3_user_data(context); + sqlite3 *db = sqlite3_context_db_handle(context); sqlite3_result_int64(context, sqlite3_last_insert_rowid(db)); } @@ -53932,7 +57183,7 @@ static void changes( int arg, sqlite3_value **argv ){ - sqlite3 *db = sqlite3_user_data(context); + sqlite3 *db = sqlite3_context_db_handle(context); sqlite3_result_int(context, sqlite3_changes(db)); } @@ -53945,7 +57196,7 @@ static void total_changes( int arg, sqlite3_value **argv ){ - sqlite3 *db = sqlite3_user_data(context); + sqlite3 *db = sqlite3_context_db_handle(context); sqlite3_result_int(context, sqlite3_total_changes(db)); } @@ -54145,6 +57396,7 @@ static void likeFunc( ){ const unsigned char *zA, *zB; int escape = 0; + sqlite3 *db = sqlite3_context_db_handle(context); zB = sqlite3_value_text(argv[0]); zA = sqlite3_value_text(argv[1]); @@ -54152,7 +57404,8 @@ static void likeFunc( /* Limit the length of the LIKE or GLOB pattern to avoid problems ** of deep recursion and N*N behavior in patternCompare(). */ - if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){ + if( sqlite3_value_bytes(argv[0]) > + db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){ sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); return; } @@ -54244,12 +57497,7 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char const *zBlob = sqlite3_value_blob(argv[0]); int nBlob = sqlite3_value_bytes(argv[0]); assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ - - if( 2*nBlob+4>SQLITE_MAX_LENGTH ){ - sqlite3_result_error_toobig(context); - return; - } - zText = (char *)contextMalloc(context, (2*nBlob)+4); + zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4); if( zText ){ int i; for(i=0; iSQLITE_MAX_LENGTH ){ - sqlite3_result_error_toobig(context); - return; - } - z = contextMalloc(context, i+n+3); + z = contextMalloc(context, ((i64)i)+((i64)n)+3); if( z ){ z[0] = '\''; for(i=0, j=1; zArg[i]; i++){ @@ -54309,12 +57553,8 @@ static void hexFunc( assert( argc==1 ); pBlob = sqlite3_value_blob(argv[0]); n = sqlite3_value_bytes(argv[0]); - if( n*2+1>SQLITE_MAX_LENGTH ){ - sqlite3_result_error_toobig(context); - return; - } assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ - z = zHex = contextMalloc(context, n*2 + 1); + z = zHex = contextMalloc(context, ((i64)n)*2 + 1); if( zHex ){ for(i=0; i=SQLITE_MAX_LENGTH ){ + if( nOut>=db->aLimit[SQLITE_LIMIT_LENGTH] ){ sqlite3_result_error_toobig(context); sqlite3_free(zOut); return; @@ -54429,7 +57670,7 @@ static void trimFunc( const unsigned char *zIn; /* Input string */ const unsigned char *zCharSet; /* Set of characters to trim */ int nIn; /* Number of bytes in input */ - int flags; /* 1: trimleft 2: trimright 3: trim */ + sqlite3_intptr_t flags; /* 1: trimleft 2: trimright 3: trim */ int i; /* Loop counter */ unsigned char *aLen; /* Length of each character in zCharSet */ unsigned char **azChar; /* Individual characters in zCharSet */ @@ -54457,7 +57698,7 @@ static void trimFunc( SQLITE_SKIP_UTF8(z); } if( nChar>0 ){ - azChar = contextMalloc(context, nChar*(sizeof(char*)+1)); + azChar = contextMalloc(context, ((i64)nChar)*(sizeof(char*)+1)); if( azChar==0 ){ return; } @@ -54470,7 +57711,7 @@ static void trimFunc( } } if( nChar>0 ){ - flags = (int)sqlite3_user_data(context); + flags = (sqlite3_intptr_t)sqlite3_user_data(context); if( flags & 1 ){ while( nIn>0 ){ int len; @@ -54559,7 +57800,7 @@ static void soundexFunc( static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ const char *zFile = (const char *)sqlite3_value_text(argv[0]); const char *zProc; - sqlite3 *db = sqlite3_user_data(context); + sqlite3 *db = sqlite3_context_db_handle(context); char *zErrMsg = 0; if( argc==2 ){ @@ -54574,165 +57815,6 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ } #endif -#ifdef SQLITE_TEST -/* -** This function generates a string of random characters. Used for -** generating test data. -*/ -static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){ - static const unsigned char zSrc[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789" - ".-!,:*^+=_|?/<> "; - int iMin, iMax, n, r, i; - unsigned char zBuf[1000]; - - /* It used to be possible to call randstr() with any number of arguments, - ** but now it is registered with SQLite as requiring exactly 2. - */ - assert(argc==2); - - iMin = sqlite3_value_int(argv[0]); - if( iMin<0 ) iMin = 0; - if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1; - iMax = sqlite3_value_int(argv[1]); - if( iMax=sizeof(zBuf) ) iMax = sizeof(zBuf)-1; - n = iMin; - if( iMax>iMin ){ - sqlite3Randomness(sizeof(r), &r); - r &= 0x7fffffff; - n += r%(iMax + 1 - iMin); - } - assert( nuseMalloc = 1; + pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; if( pAccum->nChar ){ if( argc==2 ){ zSep = (char*)sqlite3_value_text(argv[1]); @@ -54932,7 +58016,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ static const struct { char *zName; signed char nArg; - u8 argType; /* ff: db 1: 0, 2: 1, 3: 2,... N: N-1. */ + u8 argType; /* 1: 0, 2: 1, 3: 2,... N: N-1. */ u8 eTextRep; /* 1: UTF-16. 0: UTF-8 */ u8 needCollSeq; void (*xFunc)(sqlite3_context*,int,sqlite3_value **); @@ -54960,9 +58044,9 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "nullif", 2, 0, SQLITE_UTF8, 1, nullifFunc }, { "sqlite_version", 0, 0, SQLITE_UTF8, 0, versionFunc}, { "quote", 1, 0, SQLITE_UTF8, 0, quoteFunc }, - { "last_insert_rowid", 0, 0xff, SQLITE_UTF8, 0, last_insert_rowid }, - { "changes", 0, 0xff, SQLITE_UTF8, 0, changes }, - { "total_changes", 0, 0xff, SQLITE_UTF8, 0, total_changes }, + { "last_insert_rowid", 0, 0, SQLITE_UTF8, 0, last_insert_rowid }, + { "changes", 0, 0, SQLITE_UTF8, 0, changes }, + { "total_changes", 0, 0, SQLITE_UTF8, 0, total_changes }, { "replace", 3, 0, SQLITE_UTF8, 0, replaceFunc }, { "ltrim", 1, 1, SQLITE_UTF8, 0, trimFunc }, { "ltrim", 2, 1, SQLITE_UTF8, 0, trimFunc }, @@ -54975,15 +58059,8 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "soundex", 1, 0, SQLITE_UTF8, 0, soundexFunc}, #endif #ifndef SQLITE_OMIT_LOAD_EXTENSION - { "load_extension", 1, 0xff, SQLITE_UTF8, 0, loadExt }, - { "load_extension", 2, 0xff, SQLITE_UTF8, 0, loadExt }, -#endif -#ifdef SQLITE_TEST - { "randstr", 2, 0, SQLITE_UTF8, 0, randStr }, - { "test_destructor", 1, 0xff, SQLITE_UTF8, 0, test_destructor}, - { "test_destructor_count", 0, 0, SQLITE_UTF8, 0, test_destructor_count}, - { "test_auxdata", -1, 0, SQLITE_UTF8, 0, test_auxdata}, - { "test_error", 1, 0, SQLITE_UTF8, 0, test_error}, + { "load_extension", 1, 0, SQLITE_UTF8, 0, loadExt }, + { "load_extension", 2, 0, SQLITE_UTF8, 0, loadExt }, #endif }; static const struct { @@ -55009,11 +58086,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ for(i=0; ipTable; sqlite3 *db = sqlite3VdbeDb(v); - pIdx->zColAff = (char *)sqlite3DbMallocZero(db, pIdx->nColumn+2); + pIdx->zColAff = (char *)sqlite3DbMallocRaw(db, pIdx->nColumn+2); if( !pIdx->zColAff ){ return; } @@ -55214,7 +58287,7 @@ SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ int i; sqlite3 *db = sqlite3VdbeDb(v); - zColAff = (char *)sqlite3DbMallocZero(db, pTab->nCol+1); + zColAff = (char *)sqlite3DbMallocRaw(db, pTab->nCol+1); if( !zColAff ){ return; } @@ -55346,14 +58419,15 @@ static void autoIncEnd( Vdbe *v = pParse->pVdbe; Db *pDb = &pParse->db->aDb[iDb]; int j1; + int iRec = ++pParse->nMem; /* Memory cell used for record */ assert( v ); sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); sqlite3VdbeAddOp2(v, OP_NewRowid, iCur, memId+1); sqlite3VdbeJumpHere(v, j1); - sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, memId-1); - sqlite3VdbeAddOp3(v, OP_Insert, iCur, memId-1, memId+1); + sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec); + sqlite3VdbeAddOp3(v, OP_Insert, iCur, iRec, memId+1); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); sqlite3VdbeAddOp1(v, OP_Close, iCur); } @@ -55664,8 +58738,7 @@ SQLITE_PRIVATE void sqlite3Insert( ** back up and execute the SELECT code above. */ sqlite3VdbeJumpHere(v, iInitCode); - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, 0); - sqlite3VdbeAddOp2(v, OP_SetNumColumns, srcTab, nColumn); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); sqlite3VdbeAddOp2(v, OP_Goto, 0, iSelectLoop); sqlite3VdbeResolveLabel(v, iCleanup); }else{ @@ -55756,8 +58829,8 @@ SQLITE_PRIVATE void sqlite3Insert( /* 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); - sqlite3VdbeAddOp2(v, OP_SetNumColumns, newIdx, pTab->nCol); } /* Initialize the count of rows to be inserted @@ -55774,7 +58847,7 @@ SQLITE_PRIVATE void sqlite3Insert( baseCur = pParse->nTab; nIdx = sqlite3OpenTableAndIndices(pParse, pTab, baseCur, OP_OpenWrite); - aRegIdx = sqlite3DbMallocZero(db, sizeof(int)*(nIdx+1)); + aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1)); if( aRegIdx==0 ){ goto insert_cleanup; } @@ -56299,6 +59372,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i); sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]); sqlite3IndexAffinityStr(v, pIdx); + sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1); sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1); /* Find out what action to take in case there is an indexing conflict */ @@ -56320,7 +59394,8 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( regR = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp2(v, OP_SCopy, regRowid-hasTwoRowids, regR); j3 = sqlite3VdbeAddOp4(v, OP_IsUnique, baseCur+iCur+1, 0, - regR, (char*)aRegIdx[iCur], P4_INT32); + regR, (char*)(sqlite3_intptr_t)aRegIdx[iCur], + P4_INT32); /* Generate code that executes if the new index entry is not unique */ assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail @@ -56412,6 +59487,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( regRec = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec); sqlite3TableAffinityStr(v, pTab); + sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); #ifndef SQLITE_OMIT_TRIGGER if( newIdx>=0 ){ sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRec, regRowid); @@ -56790,6 +59866,11 @@ static int xferOptimization( } #endif /* SQLITE_OMIT_XFER_OPT */ +/* Make sure "isView" gets undefined in case this file becomes part of +** the amalgamation - so that subsequent files do not see isView as a +** macro. */ +#undef isView + /************** End of insert.c **********************************************/ /************** Begin file legacy.c ******************************************/ /* @@ -56808,7 +59889,7 @@ static int xferOptimization( ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: legacy.c,v 1.22 2007/08/29 12:31:26 danielk1977 Exp $ +** $Id: legacy.c,v 1.24 2008/03/21 18:01:14 drh Exp $ */ @@ -56857,12 +59938,7 @@ SQLITE_API int sqlite3_exec( } nCallback = 0; - nCol = sqlite3_column_count(pStmt); - azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char *) + 1); - if( azCols==0 ){ - goto exec_out; - } while( 1 ){ int i; @@ -56872,8 +59948,18 @@ SQLITE_API int sqlite3_exec( if( xCallback && (SQLITE_ROW==rc || (SQLITE_DONE==rc && !nCallback && db->flags&SQLITE_NullCallback)) ){ if( 0==nCallback ){ + if( azCols==0 ){ + azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1); + if( azCols==0 ){ + goto exec_out; + } + } for(i=0; imallocFailed = 1; + goto exec_out; + } } nCallback++; } @@ -56881,6 +59967,10 @@ SQLITE_API int sqlite3_exec( azVals = &azCols[nCol]; for(i=0; imallocFailed = 1; + goto exec_out; + } } } if( xCallback(pArg, nCol, azVals, azCols) ){ @@ -56941,7 +60031,6 @@ exec_out: ** This file contains code used to dynamically load extensions into ** the SQLite library. */ -#ifndef SQLITE_OMIT_LOAD_EXTENSION #ifndef SQLITE_CORE #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */ @@ -56965,7 +60054,7 @@ exec_out: ** as extensions by SQLite should #include this file instead of ** sqlite3.h. ** -** @(#) $Id: sqlite3ext.h,v 1.17 2007/08/31 16:11:36 drh Exp $ +** @(#) $Id: sqlite3ext.h,v 1.21 2008/03/19 21:45:51 drh Exp $ */ #ifndef _SQLITE3EXT_H_ #define _SQLITE3EXT_H_ @@ -56973,13 +60062,13 @@ exec_out: typedef struct sqlite3_api_routines sqlite3_api_routines; /* -** The following structure hold pointers to all of the SQLite API +** The following structure holds pointers to all of the SQLite API ** routines. ** ** WARNING: In order to maintain backwards compatibility, add new ** interfaces to the end of this structure only. If you insert new ** interfaces in the middle of this structure, then older different -** versions of SQLite will not be able to load each others shared +** versions of SQLite will not be able to load each others' shared ** libraries! */ struct sqlite3_api_routines { @@ -57131,6 +60220,12 @@ struct sqlite3_api_routines { sqlite3_vfs *(*vfs_find)(const char*); int (*vfs_register)(sqlite3_vfs*,int); int (*vfs_unregister)(sqlite3_vfs*); + int (*xthreadsafe)(void); + void (*result_zeroblob)(sqlite3_context*,int); + void (*result_error_code)(sqlite3_context*,int); + int (*test_control)(int, ...); + void (*randomness)(int,void*); + sqlite3 *(*context_db_handle)(sqlite3_context*); }; /* @@ -57291,6 +60386,12 @@ struct sqlite3_api_routines { #define sqlite3_vfs_find sqlite3_api->vfs_find #define sqlite3_vfs_register sqlite3_api->vfs_register #define sqlite3_vfs_unregister sqlite3_api->vfs_unregister +#define sqlite3_threadsafe sqlite3_api->xthreadsafe +#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob +#define sqlite3_result_error_code sqlite3_api->result_error_code +#define sqlite3_test_control sqlite3_api->test_control +#define sqlite3_randomness sqlite3_api->randomness +#define sqlite3_context_db_handle sqlite3_api->context_db_handle #endif /* SQLITE_CORE */ #define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api; @@ -57301,6 +60402,8 @@ struct sqlite3_api_routines { /************** End of sqlite3ext.h ******************************************/ /************** Continuing where we left off in loadext.c ********************/ +#ifndef SQLITE_OMIT_LOAD_EXTENSION + /* ** Some API routines are omitted when various features are ** excluded from a build of SQLite. Substitute a NULL pointer @@ -57398,7 +60501,7 @@ struct sqlite3_api_routines { ** also check to make sure that the pointer to the function is ** not NULL before calling it. */ -SQLITE_API const sqlite3_api_routines sqlite3_apis = { +static const sqlite3_api_routines sqlite3Apis = { sqlite3_aggregate_context, sqlite3_aggregate_count, sqlite3_bind_blob, @@ -57571,6 +60674,16 @@ SQLITE_API const sqlite3_api_routines sqlite3_apis = { sqlite3_vfs_find, sqlite3_vfs_register, sqlite3_vfs_unregister, + + /* + ** Added for 3.5.8 + */ + sqlite3_threadsafe, + sqlite3_result_zeroblob, + sqlite3_result_error_code, + sqlite3_test_control, + sqlite3_randomness, + sqlite3_context_db_handle, }; /* @@ -57639,7 +60752,7 @@ static int sqlite3LoadExtension( sqlite3OsDlClose(pVfs, handle); } return SQLITE_ERROR; - }else if( xInit(db, &zErrmsg, &sqlite3_apis) ){ + }else if( xInit(db, &zErrmsg, &sqlite3Apis) ){ if( pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); } @@ -57704,6 +60817,19 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ return SQLITE_OK; } +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ + +/* +** The auto-extension code added regardless of whether or not extension +** loading is supported. We need a dummy sqlite3Apis pointer for that +** code if regular extension loading is not available. This is that +** dummy pointer. +*/ +#ifdef SQLITE_OMIT_LOAD_EXTENSION +static const sqlite3_api_routines sqlite3Apis = { 0 }; +#endif + + /* ** The following object holds the list of automatically loaded ** extensions. @@ -57783,7 +60909,7 @@ SQLITE_PRIVATE int sqlite3AutoLoadExtensions(sqlite3 *db){ autoext.aExt[i]; } sqlite3_mutex_leave(mutex); - if( xInit && xInit(db, &zErrmsg, &sqlite3_apis) ){ + if( xInit && xInit(db, &zErrmsg, &sqlite3Apis) ){ sqlite3Error(db, SQLITE_ERROR, "automatic extension loading failed: %s", zErrmsg); go = 0; @@ -57794,8 +60920,6 @@ SQLITE_PRIVATE int sqlite3AutoLoadExtensions(sqlite3 *db){ return rc; } -#endif /* SQLITE_OMIT_LOAD_EXTENSION */ - /************** End of loadext.c *********************************************/ /************** Begin file pragma.c ******************************************/ /* @@ -57811,7 +60935,7 @@ SQLITE_PRIVATE int sqlite3AutoLoadExtensions(sqlite3 *db){ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.169 2008/01/22 01:48:09 drh Exp $ +** $Id: pragma.c,v 1.174 2008/03/27 22:42:52 drh Exp $ */ /* Ignore this whole file if pragmas are disabled @@ -58148,7 +61272,8 @@ SQLITE_PRIVATE void sqlite3Pragma( /* Malloc may fail when setting the page-size, as there is an internal ** buffer that the pager module resizes using sqlite3_realloc(). */ - if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1) ){ + db->nextPagesize = atoi(zRight); + if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1) ){ db->mallocFailed = 1; } } @@ -58368,7 +61493,7 @@ SQLITE_PRIVATE void sqlite3Pragma( } }else{ if( zRight[0] - && !sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE) + && sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE)==0 ){ sqlite3ErrorMsg(pParse, "not a writable directory"); goto pragma_out; @@ -58692,8 +61817,8 @@ SQLITE_PRIVATE void sqlite3Pragma( if( cnt==0 ) continue; /* Make sure sufficient number of registers have been allocated */ - if( pParse->nMem < cnt+3 ){ - pParse->nMem = cnt+3; + if( pParse->nMem < cnt+4 ){ + pParse->nMem = cnt+4; } /* Do the b-tree integrity checks */ @@ -58703,7 +61828,8 @@ SQLITE_PRIVATE void sqlite3Pragma( sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), P4_DYNAMIC); - sqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 2); + sqlite3VdbeAddOp2(v, OP_Move, 2, 4); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2); sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1); sqlite3VdbeJumpHere(v, addr); @@ -58734,13 +61860,16 @@ SQLITE_PRIVATE void sqlite3Pragma( { OP_Concat, 5, 3, 3}, { OP_Concat, 6, 3, 3}, { OP_ResultRow, 3, 1, 0}, + { OP_IfPos, 1, 0, 0}, /* 9 */ + { OP_Halt, 0, 0, 0}, }; - sqlite3GenerateIndexKey(pParse, pIdx, 1, 3); + sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 1); jmp2 = sqlite3VdbeAddOp3(v, OP_Found, j+2, 0, 3); addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr); sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC); sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC); sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_STATIC); + sqlite3VdbeJumpHere(v, addr+9); sqlite3VdbeJumpHere(v, jmp2); } sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1); @@ -59041,16 +62170,21 @@ pragma_out: ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.75 2008/01/23 03:03:05 drh Exp $ +** $Id: prepare.c,v 1.83 2008/04/03 14:36:26 danielk1977 Exp $ */ /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. */ -static void corruptSchema(InitData *pData, const char *zExtra){ +static void corruptSchema( + InitData *pData, /* Initialization context */ + const char *zObj, /* Object being parsed at the point of error */ + const char *zExtra /* Error information */ +){ if( !pData->db->mallocFailed ){ - sqlite3SetString(pData->pzErrMsg, "malformed database schema", + if( zObj==0 ) zObj = "?"; + sqlite3SetString(pData->pzErrMsg, "malformed database schema (", zObj, ")", zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0); } pData->rc = SQLITE_CORRUPT; @@ -59077,14 +62211,14 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char pData->rc = SQLITE_OK; DbClearProperty(db, iDb, DB_Empty); if( db->mallocFailed ){ - corruptSchema(pData, 0); + corruptSchema(pData, argv[0], 0); return SQLITE_NOMEM; } assert( argc==3 ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[1]==0 ){ - corruptSchema(pData, 0); + corruptSchema(pData, argv[0], 0); return 1; } assert( iDb>=0 && iDbnDb ); @@ -59107,13 +62241,13 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; }else if( rc!=SQLITE_INTERRUPT ){ - corruptSchema(pData, zErr); + corruptSchema(pData, argv[0], zErr); } sqlite3_free(zErr); return 1; } }else if( argv[0]==0 ){ - corruptSchema(pData, 0); + corruptSchema(pData, 0, 0); }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE @@ -59228,12 +62362,16 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ } return SQLITE_OK; } + curMain = sqlite3MallocZero(sqlite3BtreeCursorSize()); + if( !curMain ){ + rc = SQLITE_NOMEM; + goto error_out; + } sqlite3BtreeEnter(pDb->pBt); - rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, 0, &curMain); + rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, curMain); if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); - sqlite3BtreeLeave(pDb->pBt); - goto error_out; + goto leave_error_out; } /* Get the database meta information. @@ -59260,9 +62398,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ } if( rc ){ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); - sqlite3BtreeCloseCursor(curMain); - sqlite3BtreeLeave(pDb->pBt); - goto error_out; + goto leave_error_out; } }else{ memset(meta, 0, sizeof(meta)); @@ -59282,11 +62418,10 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ }else{ /* If opening an attached database, the encoding much match ENC(db) */ if( meta[4]!=ENC(db) ){ - sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "attached databases must use the same" " text encoding as main database", (char*)0); - sqlite3BtreeLeave(pDb->pBt); - return SQLITE_ERROR; + rc = SQLITE_ERROR; + goto leave_error_out; } } }else{ @@ -59311,10 +62446,9 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ pDb->pSchema->file_format = 1; } if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){ - sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0); - sqlite3BtreeLeave(pDb->pBt); - return SQLITE_ERROR; + rc = SQLITE_ERROR; + goto leave_error_out; } /* Ticket #2804: When we open a database in the newer file format, @@ -59357,7 +62491,6 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ sqlite3AnalysisLoad(db, iDb); } #endif - sqlite3BtreeCloseCursor(curMain); } if( db->mallocFailed ){ /* sqlite3SetString(pzErrMsg, "out of memory", (char*)0); */ @@ -59376,6 +62509,14 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ DbSetProperty(db, iDb, DB_SchemaLoaded); rc = SQLITE_OK; } + + /* Jump here for an error that occurs after successfully allocating + ** curMain and calling sqlite3BtreeEnter(). For an error that occurs + ** before that point, jump to error_out. + */ +leave_error_out: + sqlite3BtreeCloseCursor(curMain); + sqlite3_free(curMain); sqlite3BtreeLeave(pDb->pBt); error_out: @@ -59462,23 +62603,32 @@ static int schemaIsValid(sqlite3 *db){ int cookie; int allOk = 1; - assert( sqlite3_mutex_held(db->mutex) ); - for(iDb=0; allOk && iDbnDb; iDb++){ - Btree *pBt; - pBt = db->aDb[iDb].pBt; - if( pBt==0 ) continue; - rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie); - if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){ - allOk = 0; + curTemp = (BtCursor *)sqlite3_malloc(sqlite3BtreeCursorSize()); + if( curTemp ){ + assert( sqlite3_mutex_held(db->mutex) ); + for(iDb=0; allOk && iDbnDb; iDb++){ + Btree *pBt; + pBt = db->aDb[iDb].pBt; + if( pBt==0 ) continue; + memset(curTemp, 0, sqlite3BtreeCursorSize()); + rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, curTemp); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie); + if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){ + allOk = 0; + } + sqlite3BtreeCloseCursor(curTemp); + } + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + db->mallocFailed = 1; } - sqlite3BtreeCloseCursor(curTemp); - } - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - db->mallocFailed = 1; } + sqlite3_free(curTemp); + }else{ + allOk = 0; + db->mallocFailed = 1; } + return allOk; } @@ -59517,7 +62667,7 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ -SQLITE_PRIVATE int sqlite3Prepare( +static int sqlite3Prepare( sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ @@ -59557,9 +62707,10 @@ SQLITE_PRIVATE int sqlite3Prepare( memset(&sParse, 0, sizeof(sParse)); sParse.db = db; - if( nBytes>=0 && zSql[nBytes]!=0 ){ + if( nBytes>=0 && zSql[nBytes-1]!=0 ){ char *zSqlCopy; - if( SQLITE_MAX_SQL_LENGTH>0 && nBytes>SQLITE_MAX_SQL_LENGTH ){ + int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; + if( nBytes>mxLen ){ sqlite3Error(db, SQLITE_TOOBIG, "statement too long"); (void)sqlite3SafetyOff(db); return SQLITE_TOOBIG; @@ -59568,8 +62719,10 @@ SQLITE_PRIVATE int sqlite3Prepare( if( zSqlCopy ){ sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg); sqlite3_free(zSqlCopy); + sParse.zTail = &zSql[sParse.zTail-zSqlCopy]; + }else{ + sParse.zTail = &zSql[nBytes]; } - sParse.zTail = &zSql[nBytes]; }else{ sqlite3RunParser(&sParse, zSql, &zErrMsg); } @@ -59707,7 +62860,10 @@ SQLITE_API int sqlite3_prepare( sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ - return sqlite3LockAndPrepare(db,zSql,nBytes,0,ppStmt,pzTail); + int rc; + rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; } SQLITE_API int sqlite3_prepare_v2( sqlite3 *db, /* Database handle. */ @@ -59716,7 +62872,10 @@ SQLITE_API int sqlite3_prepare_v2( sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ - return sqlite3LockAndPrepare(db,zSql,nBytes,1,ppStmt,pzTail); + int rc; + rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; } @@ -59779,7 +62938,10 @@ SQLITE_API int sqlite3_prepare16( sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const void **pzTail /* OUT: End of parsed string */ ){ - return sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail); + int rc; + rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; } SQLITE_API int sqlite3_prepare16_v2( sqlite3 *db, /* Database handle. */ @@ -59788,7 +62950,10 @@ SQLITE_API int sqlite3_prepare16_v2( sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const void **pzTail /* OUT: End of parsed string */ ){ - return sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail); + int rc; + rc = sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; } #endif /* SQLITE_OMIT_UTF16 */ @@ -59809,7 +62974,7 @@ SQLITE_API int sqlite3_prepare16_v2( ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.411 2008/01/25 15:04:50 drh Exp $ +** $Id: select.c,v 1.427 2008/04/15 12:14:22 drh Exp $ */ @@ -59837,6 +63002,7 @@ SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iPar pDest->iParm = iParm; pDest->affinity = 0; pDest->iMem = 0; + pDest->nMem = 0; } @@ -60000,12 +63166,30 @@ static void setToken(Token *p, const char *z){ ** {a"bc} -> {"a""bc"} */ static void setQuotedToken(Parse *pParse, Token *p, const char *z){ - p->z = (u8 *)sqlite3MPrintf(0, "\"%w\"", z); - p->dyn = 1; - if( p->z ){ - p->n = strlen((char *)p->z); + + /* Check if the string contains any " characters. If it does, then + ** this function will malloc space to create a quoted version of + ** the string in. Otherwise, save a call to sqlite3MPrintf() by + ** just copying the pointer to the string. + */ + const char *z2 = z; + while( *z2 ){ + if( *z2=='"' ) break; + z2++; + } + + if( *z2 ){ + /* String contains " characters - copy and quote the string. */ + p->z = (u8 *)sqlite3MPrintf(pParse->db, "\"%w\"", z); + if( p->z ){ + p->n = strlen((char *)p->z); + p->dyn = 1; + } }else{ - pParse->db->mallocFailed = 1; + /* String contains no " characters - copy the pointer. */ + p->z = (u8*)z; + p->n = (z2 - z); + p->dyn = 0; } } @@ -60018,7 +63202,6 @@ SQLITE_PRIVATE Expr *sqlite3CreateIdExpr(Parse *pParse, const char *zName){ return sqlite3PExpr(pParse, TK_ID, 0, 0, &dummy); } - /* ** Add a term to the WHERE expression in *ppExpr that requires the ** zCol column to be equal in the two tables pTab1 and pTab2. @@ -60031,7 +63214,8 @@ static void addWhereTerm( const Table *pTab2, /* Second table */ const char *zAlias2, /* Alias for second table. May be NULL */ int iRightJoinTable, /* VDBE cursor for the right table */ - Expr **ppExpr /* Add the equality term to this expression */ + Expr **ppExpr, /* Add the equality term to this expression */ + int isOuterJoin /* True if dealing with an OUTER join */ ){ Expr *pE1a, *pE1b, *pE1c; Expr *pE2a, *pE2b, *pE2c; @@ -60050,7 +63234,7 @@ static void addWhereTerm( pE1c = sqlite3PExpr(pParse, TK_DOT, pE1b, pE1a, 0); pE2c = sqlite3PExpr(pParse, TK_DOT, pE2b, pE2a, 0); pE = sqlite3PExpr(pParse, TK_EQ, pE1c, pE2c, 0); - if( pE ){ + if( pE && isOuterJoin ){ ExprSetProperty(pE, EP_FromJoin); pE->iRightJoinTable = iRightJoinTable; } @@ -60118,8 +63302,10 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ for(i=0; inSrc-1; i++, pRight++, pLeft++){ Table *pLeftTab = pLeft->pTab; Table *pRightTab = pRight->pTab; + int isOuter; if( pLeftTab==0 || pRightTab==0 ) continue; + isOuter = (pRight->jointype & JT_OUTER)!=0; /* When the NATURAL keyword is present, add WHERE clause terms for ** every column that the two tables have in common. @@ -60135,7 +63321,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ if( columnIndex(pRightTab, zName)>=0 ){ addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias, pRightTab, pRight->zAlias, - pRight->iCursor, &p->pWhere); + pRight->iCursor, &p->pWhere, isOuter); } } @@ -60153,7 +63339,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ ** an AND operator. */ if( pRight->pOn ){ - setJoinExpr(pRight->pOn, pRight->iCursor); + if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor); p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn); pRight->pOn = 0; } @@ -60176,7 +63362,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ } addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias, pRightTab, pRight->zAlias, - pRight->iCursor, &p->pWhere); + pRight->iCursor, &p->pWhere, isOuter); } } } @@ -60197,9 +63383,9 @@ static void pushOntoSorter( int nExpr = pOrderBy->nExpr; int regBase = sqlite3GetTempRange(pParse, nExpr+2); int regRecord = sqlite3GetTempReg(pParse); - sqlite3ExprCodeExprList(pParse, pOrderBy, regBase); + sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0); sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); - sqlite3VdbeAddOp2(v, OP_Move, regData, regBase+nExpr+1); + sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord); sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord); sqlite3ReleaseTempReg(pParse, regRecord); @@ -60318,7 +63504,6 @@ static void selectInnerLoop( int eDest = pDest->eDest; /* How to dispose of results */ int iParm = pDest->iParm; /* First argument to disposal method */ int nResultCol; /* Number of result columns */ - int nToFree; /* Number of result columns to release */ if( v==0 ) return; assert( pEList!=0 ); @@ -60338,13 +63523,16 @@ static void selectInnerLoop( }else{ nResultCol = pEList->nExpr; } - if( pDest->iMem>0 ){ - regResult = pDest->iMem; - nToFree = 0; - }else{ - pDest->iMem = regResult = sqlite3GetTempRange(pParse, nResultCol); - nToFree = nResultCol; + if( pDest->iMem==0 ){ + pDest->iMem = sqlite3GetTempRange(pParse, nResultCol); + pDest->nMem = nResultCol; + }else if( pDest->nMem!=nResultCol ){ + /* This happens when two SELECTs of a compound SELECT have differing + ** numbers of result columns. The error message will be generated by + ** a higher-level routine. */ + return; } + regResult = pDest->iMem; if( nColumn>0 ){ for(i=0; ia[i].pExpr, regResult+i); - } + sqlite3ExprCodeExprList(pParse, pEList, regResult, eDest==SRT_Callback); } nColumn = nResultCol; @@ -60398,12 +63584,7 @@ static void selectInnerLoop( ** the temporary table iParm. */ case SRT_Except: { - int r1; - r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); - sqlite3VdbeChangeP4(v, -1, aff, P4_STATIC); - sqlite3VdbeAddOp2(v, OP_IdxDelete, iParm, r1); - sqlite3ReleaseTempReg(pParse, r1); + sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nColumn); break; } #endif @@ -60447,6 +63628,7 @@ static void selectInnerLoop( }else{ int r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1); + sqlite3ExprCacheAffinityChange(pParse, regResult, 1); sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); sqlite3ReleaseTempReg(pParse, r1); } @@ -60471,7 +63653,7 @@ static void selectInnerLoop( if( pOrderBy ){ pushOntoSorter(pParse, pOrderBy, p, regResult); }else{ - sqlite3VdbeAddOp2(v, OP_Move, regResult, iParm); + sqlite3ExprCodeMove(pParse, regResult, iParm); /* The LIMIT clause will jump out of the loop for us */ } break; @@ -60490,10 +63672,10 @@ static void selectInnerLoop( pushOntoSorter(pParse, pOrderBy, p, r1); sqlite3ReleaseTempReg(pParse, r1); }else if( eDest==SRT_Subroutine ){ - nToFree = 0; /* Preserve registers. Subroutine will need them. */ sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm); }else{ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn); + sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn); } break; } @@ -60517,7 +63699,6 @@ static void selectInnerLoop( sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak); } - sqlite3ReleaseTempRange(pParse, regResult, nToFree); } /* @@ -60591,8 +63772,8 @@ static void generateSortTail( iTab = pOrderBy->iECursor; if( eDest==SRT_Callback || eDest==SRT_Subroutine ){ pseudoTab = pParse->nTab++; - sqlite3VdbeAddOp2(v, OP_OpenPseudo, pseudoTab, 0); - sqlite3VdbeAddOp2(v, OP_SetNumColumns, pseudoTab, nColumn); + sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, nColumn); + sqlite3VdbeAddOp2(v, OP_OpenPseudo, pseudoTab, eDest==SRT_Callback); } addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, brk); codeOffset(v, p, cont); @@ -60612,14 +63793,15 @@ static void generateSortTail( int j1; assert( nColumn==1 ); j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regRow); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRow, &p->affinity, 1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRow); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1); + sqlite3ExprCacheAffinityChange(pParse, regRow, 1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid); sqlite3VdbeJumpHere(v, j1); break; } case SRT_Mem: { assert( nColumn==1 ); - sqlite3VdbeAddOp2(v, OP_Move, regRow, iParm); + sqlite3ExprCodeMove(pParse, regRow, iParm); /* The LIMIT clause will terminate the loop for us */ break; } @@ -60630,10 +63812,12 @@ static void generateSortTail( sqlite3VdbeAddOp2(v, OP_Integer, 1, regRowid); sqlite3VdbeAddOp3(v, OP_Insert, pseudoTab, regRow, regRowid); for(i=0; iiMem+i ); sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i); } if( eDest==SRT_Callback ){ sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn); + sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn); }else{ sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm); } @@ -60807,6 +63991,7 @@ static void generateColumnTypes( SrcList *pTabList, /* List of tables */ ExprList *pEList /* Expressions defining the result set */ ){ +#ifndef SQLITE_OMIT_DECLTYPE Vdbe *v = pParse->pVdbe; int i; NameContext sNC; @@ -60814,20 +63999,26 @@ static void generateColumnTypes( sNC.pParse = pParse; for(i=0; inExpr; i++){ Expr *p = pEList->a[i].pExpr; + const char *zType; +#ifdef SQLITE_ENABLE_COLUMN_METADATA const char *zOrigDb = 0; const char *zOrigTab = 0; const char *zOrigCol = 0; - const char *zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); + zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); /* The vdbe must make its own copy of the column-type and other ** column specific strings, in case the schema is reset before this ** virtual machine is deleted. */ - sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, P4_TRANSIENT); sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, P4_TRANSIENT); sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, P4_TRANSIENT); sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, P4_TRANSIENT); +#else + zType = columnType(&sNC, p, 0, 0, 0); +#endif + sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, P4_TRANSIENT); } +#endif /* SQLITE_OMIT_DECLTYPE */ } /* @@ -61261,10 +64452,12 @@ static int prepSelectStmt(Parse *pParse, Select *p){ sqlite3ExprListDelete(pEList); p->pEList = pNew; } - if( p->pEList && p->pEList->nExpr>SQLITE_MAX_COLUMN ){ +#if SQLITE_MAX_COLUMN + if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many columns in result set"); rc = SQLITE_ERROR; } +#endif if( db->mallocFailed ){ rc = SQLITE_NOMEM; } @@ -61391,11 +64584,13 @@ static int processOrderGroupBy( ExprList *pEList; if( pOrderBy==0 || pParse->db->mallocFailed ) return 0; - if( pOrderBy->nExpr>SQLITE_MAX_COLUMN ){ +#if SQLITE_MAX_COLUMN + if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ const char *zType = isOrder ? "ORDER" : "GROUP"; sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); return 1; } +#endif pEList = pSelect->pEList; if( pEList==0 ){ return 0; @@ -61458,11 +64653,13 @@ static int processCompoundOrderBy( pOrderBy = pSelect->pOrderBy; if( pOrderBy==0 ) return 0; - if( pOrderBy->nExpr>SQLITE_MAX_COLUMN ){ + db = pParse->db; +#if SQLITE_MAX_COLUMN + if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); return 1; } - db = pParse->db; +#endif for(i=0; inExpr; i++){ pOrderBy->a[i].done = 0; } @@ -62062,6 +65259,7 @@ static int multiSelect( multi_select_end: pDest->iMem = dest.iMem; + pDest->nMem = dest.nMem; return rc; } #endif /* SQLITE_OMIT_COMPOUND_SELECT */ @@ -62219,6 +65417,10 @@ static void substSelect( ** subquery does not have both an ORDER BY and a LIMIT clause. ** (See ticket #2339) ** +** (16) The outer query is not an aggregate or the subquery does +** not contain ORDER BY. (Ticket #2942) This used to not matter +** until we introduced the group_concat() function. +** ** In this routine, the "p" parameter is a pointer to the outer query. ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query ** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates. @@ -62276,6 +65478,7 @@ static int flattenSubquery( if( (p->disallowOrderBy || p->pOrderBy) && pSub->pOrderBy ){ return 0; /* Restriction (11) */ } + if( isAgg && pSub->pOrderBy ) return 0; /* Restriction (16) */ /* Restriction 3: If the subquery is a join, make sure the subquery is ** not used as the right operand of an outer join. Examples of why this @@ -62433,7 +65636,7 @@ static int flattenSubquery( /* ** Analyze the SELECT statement passed as an argument to see if it -** is a min() or max() query. Return ORDERBY_MIN or ORDERBY_MAX if +** is a min() or max() query. Return WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX if ** it is, or 0 otherwise. At present, a query is considered to be ** a min()/max() query if: ** @@ -62446,18 +65649,18 @@ static int minMaxQuery(Parse *pParse, Select *p){ Expr *pExpr; ExprList *pEList = p->pEList; - if( pEList->nExpr!=1 ) return ORDERBY_NORMAL; + if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL; pExpr = pEList->a[0].pExpr; pEList = pExpr->pList; if( pExpr->op!=TK_AGG_FUNCTION || pEList==0 || pEList->nExpr!=1 ) return 0; - if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return ORDERBY_NORMAL; - if( pExpr->token.n!=3 ) return ORDERBY_NORMAL; + 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 ){ - return ORDERBY_MIN; + return WHERE_ORDERBY_MIN; }else if( sqlite3StrNICmp((char*)pExpr->token.z,"max",3)==0 ){ - return ORDERBY_MAX; + return WHERE_ORDERBY_MAX; } - return ORDERBY_NORMAL; + return WHERE_ORDERBY_NORMAL; } /* @@ -62658,7 +65861,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ if( pList ){ nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); - sqlite3ExprCodeExprList(pParse, pList, regAgg); + sqlite3ExprCodeExprList(pParse, pList, regAgg, 0); }else{ nArg = 0; regAgg = 0; @@ -62685,6 +65888,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ (void*)pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, nArg); sqlite3ReleaseTempRange(pParse, regAgg, nArg); + sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg); if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } @@ -62845,12 +66049,14 @@ SQLITE_PRIVATE int sqlite3Select( if( p->pRightmost==0 ){ Select *pLoop, *pRight = 0; int cnt = 0; + int mxSelect; for(pLoop=p; pLoop; pLoop=pLoop->pPrior, cnt++){ pLoop->pRightmost = p; pLoop->pNext = pRight; pRight = pLoop; } - if( SQLITE_MAX_COMPOUND_SELECT>0 && cnt>SQLITE_MAX_COMPOUND_SELECT ){ + mxSelect = db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT]; + if( mxSelect && cnt>mxSelect ){ sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); return 1; } @@ -62913,7 +66119,6 @@ SQLITE_PRIVATE int sqlite3Select( }else{ needRestoreContext = 0; } -#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0 /* Increment Parse.nHeight by the height of the largest expression ** tree refered to by this, the parent select. The child select ** may contain expression trees of at most @@ -62922,15 +66127,12 @@ SQLITE_PRIVATE int sqlite3Select( ** an exact limit. */ pParse->nHeight += sqlite3SelectExprHeight(p); -#endif sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); sqlite3Select(pParse, pItem->pSelect, &dest, p, i, &isAgg, 0); if( db->mallocFailed ){ goto select_end; } -#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0 pParse->nHeight -= sqlite3SelectExprHeight(p); -#endif if( needRestoreContext ){ pParse->zAuthContext = zSavedAuthContext; } @@ -62945,16 +66147,6 @@ SQLITE_PRIVATE int sqlite3Select( } #endif - /* Check for the special case of a min() or max() function by itself - ** in the result set. - */ -#if 0 - if( simpleMinMaxQuery(pParse, p, pDest) ){ - rc = 0; - goto select_end; - } -#endif - /* Check to see if this is a subquery that can be "flattened" into its parent. ** If flattening is a possiblity, do so and return immediately. */ @@ -63112,10 +66304,9 @@ SQLITE_PRIVATE int sqlite3Select( */ sAggInfo.sortingIdx = pParse->nTab++; pKeyInfo = keyInfoFromExprList(pParse, pGroupBy); - addrSortingIdx = - sqlite3VdbeAddOp4(v, OP_OpenEphemeral, sAggInfo.sortingIdx, - sAggInfo.nSortingColumn, 0, - (char*)pKeyInfo, P4_KEYINFO_HANDOFF); + addrSortingIdx = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + sAggInfo.sortingIdx, sAggInfo.nSortingColumn, + 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); /* Initialize memory locations used by GROUP BY aggregate processing */ @@ -63200,14 +66391,18 @@ SQLITE_PRIVATE int sqlite3Select( } } regBase = sqlite3GetTempRange(pParse, nCol); - sqlite3ExprCodeExprList(pParse, pGroupBy, regBase); + sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0); sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy); j = nGroupBy+1; for(i=0; iiSorterColumn>=j ){ - sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn, pCol->iTable, - j + regBase); + int r1 = j + regBase; + int r2 = sqlite3ExprCodeGetColumn(pParse, + pCol->pTab, pCol->iColumn, pCol->iTable, r1, 0); + if( r1!=r2 ){ + sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1); + } j++; } } @@ -63257,7 +66452,7 @@ SQLITE_PRIVATE int sqlite3Select( */ sqlite3VdbeResolveLabel(v, addrGroupByChange); for(j=0; jnExpr; j++){ - sqlite3VdbeAddOp2(v, OP_Move, iBMem+j, iAMem+j); + sqlite3ExprCodeMove(pParse, iBMem+j, iAMem+j); } sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow); VdbeComment((v, "output one row")); @@ -63323,7 +66518,7 @@ SQLITE_PRIVATE int sqlite3Select( if( flag ){ pDel = pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->pList); if( pMinMax && !db->mallocFailed ){ - pMinMax->a[0].sortOrder = ((flag==ORDERBY_MIN)?0:1); + pMinMax->a[0].sortOrder = ((flag==WHERE_ORDERBY_MIN)?0:1); pMinMax->a[0].pExpr->op = TK_COLUMN; } } @@ -63341,7 +66536,7 @@ SQLITE_PRIVATE int sqlite3Select( updateAccumulator(pParse, &sAggInfo); if( !pMinMax && flag ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak); - VdbeComment((v, "%s() by index", (flag==ORDERBY_MIN?"min":"max"))); + VdbeComment((v, "%s() by index", (flag==WHERE_ORDERBY_MIN?"min":"max"))); } sqlite3WhereEnd(pWInfo); finalizeAggFunctions(pParse, &sAggInfo); @@ -63419,7 +66614,7 @@ select_end: ** code base. Then are intended to be called from within the debugger ** or from temporary "printf" statements inserted for debugging. */ -SQLITE_PRIVATE void sqlite3PrintExpr(Expr *p){ +static void sqlite3PrintExpr(Expr *p){ if( p->token.z && p->token.n>0 ){ sqlite3DebugPrintf("(%.*s", p->token.n, p->token.z); }else{ @@ -63435,7 +66630,7 @@ SQLITE_PRIVATE void sqlite3PrintExpr(Expr *p){ } sqlite3DebugPrintf(")"); } -SQLITE_PRIVATE void sqlite3PrintExprList(ExprList *pList){ +static void sqlite3PrintExprList(ExprList *pList){ int i; for(i=0; inExpr; i++){ sqlite3PrintExpr(pList->a[i].pExpr); @@ -63444,7 +66639,7 @@ SQLITE_PRIVATE void sqlite3PrintExprList(ExprList *pList){ } } } -SQLITE_PRIVATE void sqlite3PrintSelect(Select *p, int indent){ +static void sqlite3PrintSelect(Select *p, int indent){ sqlite3DebugPrintf("%*sSELECT(%p) ", indent, "", p); sqlite3PrintExprList(p->pEList); sqlite3DebugPrintf("\n"); @@ -63646,7 +66841,7 @@ SQLITE_API int sqlite3_get_table( res.azResult[0] = 0; rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg); assert( sizeof(res.azResult[0])>= sizeof(res.nData) ); - res.azResult[0] = (char*)res.nData; + res.azResult[0] = (char*)(sqlite3_intptr_t)res.nData; if( (rc&0xff)==SQLITE_ABORT ){ sqlite3_free_table(&res.azResult[1]); if( res.zErrMsg ){ @@ -63688,10 +66883,10 @@ SQLITE_API void sqlite3_free_table( char **azResult /* Result returned from from sqlite3_get_table() */ ){ if( azResult ){ - int i, n; + sqlite3_intptr_t i, n; azResult--; assert( azResult!=0 ); - n = (int)azResult[0]; + n = (sqlite3_intptr_t)azResult[0]; for(i=1; inCol); sqlite3VdbeAddOp2(v, OP_OpenPseudo, oldIdx, 0); - sqlite3VdbeAddOp2(v, OP_SetNumColumns, oldIdx, pTab->nCol); + sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pTab->nCol); sqlite3VdbeAddOp2(v, OP_OpenPseudo, newIdx, 0); - sqlite3VdbeAddOp2(v, OP_SetNumColumns, newIdx, pTab->nCol); iGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); addr = sqlite3VdbeMakeLabel(v); @@ -64890,25 +68079,28 @@ SQLITE_PRIVATE void sqlite3Update( ** a ephemeral table. */ if( isView ){ - Select *pView; - SelectDest dest; + sqlite3MaterializeView(pParse, pTab->pSelect, pWhere, iCur); + } - pView = sqlite3SelectDup(db, pTab->pSelect); - sqlite3SelectMask(pParse, pView, old_col_mask|new_col_mask); - sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); - sqlite3Select(pParse, pView, &dest, 0, 0, 0, 0); - sqlite3SelectDelete(pView); + /* Resolve the column names in all the expressions in the + ** WHERE clause. + */ + if( sqlite3ExprResolveNames(&sNC, pWhere) ){ + goto update_cleanup; } /* Begin the database scan */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0); + sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, + WHERE_ONEPASS_DESIRED); if( pWInfo==0 ) goto update_cleanup; + okOnePass = pWInfo->okOnePass; /* Remember the rowid of every item to be updated. */ - sqlite3VdbeAddOp2(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid,iCur,regOldRowid); - sqlite3VdbeAddOp2(v, OP_FifoWrite, regOldRowid, 0); + sqlite3VdbeAddOp2(v, IsVirtual(pTab)?OP_VRowid:OP_Rowid, iCur, regOldRowid); + if( !okOnePass ) sqlite3VdbeAddOp2(v, OP_FifoWrite, regOldRowid, 0); /* End the database scan loop. */ @@ -64928,7 +68120,7 @@ SQLITE_PRIVATE void sqlite3Update( ** action, then we need to open all indices because we might need ** to be deleting some records. */ - sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); + if( !okOnePass ) sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); if( onError==OE_Replace ){ openAll = 1; }else{ @@ -64956,7 +68148,13 @@ SQLITE_PRIVATE void sqlite3Update( } /* Top of the update loop */ - addr = sqlite3VdbeAddOp2(v, OP_FifoRead, regOldRowid, 0); + if( okOnePass ){ + int a1 = sqlite3VdbeAddOp1(v, OP_NotNull, regOldRowid); + addr = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeJumpHere(v, a1); + }else{ + addr = sqlite3VdbeAddOp2(v, OP_FifoRead, regOldRowid, 0); + } if( triggers_exist ){ int regRowid; @@ -65007,6 +68205,7 @@ SQLITE_PRIVATE void sqlite3Update( sqlite3VdbeAddOp3(v, OP_MakeRecord, regCols, pTab->nCol, regRow); if( !isView ){ sqlite3TableAffinityStr(v, pTab); + sqlite3ExprCacheAffinityChange(pParse, regCols, pTab->nCol); } sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol); if( pParse->nErr ) goto update_cleanup; @@ -65223,6 +68422,11 @@ static void updateVirtualTable( } #endif /* SQLITE_OMIT_VIRTUALTABLE */ +/* Make sure "isView" gets undefined in case this file becomes part of +** the amalgamation - so that subsequent files do not see isView as a +** macro. */ +#undef isView + /************** End of update.c **********************************************/ /************** Begin file vacuum.c ******************************************/ /* @@ -65241,7 +68445,7 @@ static void updateVirtualTable( ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** -** $Id: vacuum.c,v 1.76 2008/01/03 00:01:25 drh Exp $ +** $Id: vacuum.c,v 1.77 2008/03/20 11:04:21 danielk1977 Exp $ */ #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) @@ -65310,6 +68514,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ char *zSql = 0; /* SQL statements */ int saved_flags; /* Saved value of the db->flags */ Db *pDb = 0; /* Database to detach at end of vacuum */ + int nRes; /* Save the current value of the write-schema flag before setting it. */ saved_flags = db->flags; @@ -65337,13 +68542,15 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ pDb = &db->aDb[db->nDb-1]; assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 ); pTemp = db->aDb[db->nDb-1].pBt; - sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), - sqlite3BtreeGetReserve(pMain)); - if( db->mallocFailed ){ + + nRes = sqlite3BtreeGetReserve(pMain); + if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes) + || sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes) + || db->mallocFailed + ){ rc = SQLITE_NOMEM; goto end_of_vacuum; } - assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) ); rc = execSql(db, "PRAGMA vacuum_db.synchronous=OFF"); if( rc!=SQLITE_OK ){ goto end_of_vacuum; @@ -65462,6 +68669,10 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ rc = sqlite3BtreeCommit(pMain); } + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes); + } + end_of_vacuum: /* Restore the original value of db->flags */ db->flags = saved_flags; @@ -65502,7 +68713,7 @@ end_of_vacuum: ************************************************************************* ** This file contains code used to help implement virtual tables. ** -** $Id: vtab.c,v 1.63 2008/01/23 03:03:05 drh Exp $ +** $Id: vtab.c,v 1.66 2008/04/10 18:35:22 drh Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -66086,6 +69297,13 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab } (void)sqlite3SafetyOn(db); if( rc==SQLITE_OK ){ + int i; + for(i=0; inVTrans; i++){ + if( db->aVTrans[i]==pTab->pVtab ){ + db->aVTrans[i] = db->aVTrans[--db->nVTrans]; + break; + } + } pTab->pVtab = 0; } } @@ -66101,7 +69319,7 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab ** ** The array is cleared after invoking the callbacks. */ -static void callFinaliser(sqlite3 *db, int offset){ +static void callFinaliser(sqlite3 *db, sqlite3_intptr_t offset){ int i; if( db->aVTrans ){ for(i=0; inVTrans && db->aVTrans[i]; i++){ @@ -66154,7 +69372,7 @@ SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, int rc2){ ** sqlite3.aVTrans array. Then clear the array itself. */ SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db){ - callFinaliser(db, (int)(&((sqlite3_module *)0)->xRollback)); + callFinaliser(db, (sqlite3_intptr_t)(&((sqlite3_module *)0)->xRollback)); return SQLITE_OK; } @@ -66163,7 +69381,7 @@ SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db){ ** sqlite3.aVTrans array. Then clear the array itself. */ SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db){ - callFinaliser(db, (int)(&((sqlite3_module *)0)->xCommit)); + callFinaliser(db, (sqlite3_intptr_t)(&((sqlite3_module *)0)->xCommit)); return SQLITE_OK; } @@ -66307,7 +69525,7 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( ** 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.286 2008/01/23 12:52:41 drh Exp $ +** $Id: where.c,v 1.298 2008/04/10 13:33:18 drh Exp $ */ /* @@ -66319,8 +69537,8 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( ** Trace output macros */ #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) -SQLITE_API int sqlite3_where_trace = 0; -# define WHERETRACE(X) if(sqlite3_where_trace) sqlite3DebugPrintf X +SQLITE_PRIVATE int sqlite3WhereTrace = 0; +# define WHERETRACE(X) if(sqlite3WhereTrace) sqlite3DebugPrintf X #else # define WHERETRACE(X) #endif @@ -66807,22 +70025,26 @@ static int isLikeOrGlob( sqlite3 *db, /* The database */ Expr *pExpr, /* Test this expression */ int *pnPattern, /* Number of non-wildcard prefix characters */ - int *pisComplete /* True if the only wildcard is % in the last character */ + int *pisComplete, /* True if the only wildcard is % in the last character */ + int *pnoCase /* True if uppercase is equivalent to lowercase */ ){ const char *z; Expr *pRight, *pLeft; ExprList *pList; int c, cnt; - int noCase; char wc[3]; CollSeq *pColl; - if( !sqlite3IsLikeFunction(db, pExpr, &noCase, wc) ){ + if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){ return 0; } +#ifdef SQLITE_EBCDIC + if( *pnoCase ) return 0; +#endif pList = pExpr->pList; pRight = pList->a[0].pExpr; - if( pRight->op!=TK_STRING ){ + if( pRight->op!=TK_STRING + && (pRight->op!=TK_REGISTER || pRight->iColumn!=TK_STRING) ){ return 0; } pLeft = pList->a[1].pExpr; @@ -66835,8 +70057,8 @@ static int isLikeOrGlob( /* No collation is defined for the ROWID. Use the default. */ pColl = db->pDfltColl; } - if( (pColl->type!=SQLITE_COLL_BINARY || noCase) && - (pColl->type!=SQLITE_COLL_NOCASE || !noCase) ){ + if( (pColl->type!=SQLITE_COLL_BINARY || *pnoCase) && + (pColl->type!=SQLITE_COLL_NOCASE || !*pnoCase) ){ return 0; } sqlite3DequoteExpr(db, pRight); @@ -67006,6 +70228,7 @@ static void exprAnalyze( Bitmask prereqAll; int nPattern; int isComplete; + int noCase; int op; Parse *pParse = pWC->pParse; sqlite3 *db = pParse->db; @@ -67029,7 +70252,10 @@ static void exprAnalyze( } prereqAll = exprTableUsage(pMaskSet, pExpr); if( ExprHasProperty(pExpr, EP_FromJoin) ){ - prereqAll |= getMask(pMaskSet, pExpr->iRightJoinTable); + Bitmask x = getMask(pMaskSet, pExpr->iRightJoinTable); + prereqAll |= x; + pTerm->prereqRight |= x-1; /* ON clause terms may not be used with an index + ** on left table of a LEFT JOIN. Ticket #3015 */ } pTerm->prereqAll = prereqAll; pTerm->leftCursor = -1; @@ -67124,6 +70350,7 @@ static void exprAnalyze( exprAnalyzeAll(pSrc, &sOr); assert( sOr.nTerm>=2 ); j = 0; + if( db->mallocFailed ) goto or_not_possible; do{ assert( j='abc' AND x<'abd' AND x LIKE 'abc%' + ** + ** The last character of the prefix "abc" is incremented to form the + ** termination condidtion "abd". This trick of incrementing the last + ** is not 255 and if the character set is not EBCDIC. */ - if( isLikeOrGlob(db, pExpr, &nPattern, &isComplete) ){ + if( isLikeOrGlob(db, pExpr, &nPattern, &isComplete, &noCase) ){ Expr *pLeft, *pRight; Expr *pStr1, *pStr2; Expr *pNewExpr1, *pNewExpr2; @@ -67193,8 +70428,12 @@ or_not_possible: } pStr2 = sqlite3ExprDup(db, pStr1); if( !db->mallocFailed ){ + u8 c, *pC; assert( pStr2->token.dyn ); - ++*(u8*)&pStr2->token.z[nPattern-1]; + pC = (u8*)&pStr2->token.z[nPattern-1]; + c = *pC; + if( noCase ) c = sqlite3UpperToLower[c]; + *pC = c + 1; } pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprDup(db,pLeft), pStr1, 0); idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); @@ -67450,7 +70689,7 @@ static double estLog(double N){ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_DEBUG) static void TRACE_IDX_INPUTS(sqlite3_index_info *p){ int i; - if( !sqlite3_where_trace ) return; + if( !sqlite3WhereTrace ) return; for(i=0; inConstraint; i++){ sqlite3DebugPrintf(" constraint[%d]: col=%d termid=%d op=%d usabled=%d\n", i, @@ -67468,7 +70707,7 @@ static void TRACE_IDX_INPUTS(sqlite3_index_info *p){ } static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){ int i; - if( !sqlite3_where_trace ) return; + if( !sqlite3WhereTrace ) return; for(i=0; inConstraint; i++){ sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", i, @@ -67674,6 +70913,16 @@ static double bestVirtualIndex( TRACE_IDX_INPUTS(pIdxInfo); rc = pTab->pVtab->pModule->xBestIndex(pTab->pVtab, pIdxInfo); TRACE_IDX_OUTPUTS(pIdxInfo); + (void)sqlite3SafetyOn(pParse->db); + + for(i=0; inConstraint; i++){ + if( !pIdxInfo->aConstraint[i].usable && pUsage[i].argvIndex>0 ){ + sqlite3ErrorMsg(pParse, + "table %s: xBestIndex returned an invalid plan", pTab->zName); + return 0.0; + } + } + if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ){ pParse->db->mallocFailed = 1; @@ -67681,7 +70930,6 @@ static double bestVirtualIndex( sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc)); } } - (void)sqlite3SafetyOn(pParse->db); *(int*)&pIdxInfo->nOrderBy = nOrderBy; return pIdxInfo->estimatedCost; @@ -67989,16 +71237,19 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ ** problem. */ static void buildIndexProbe( - Vdbe *v, /* Generate code into this VM */ + Parse *pParse, /* Parsing and code generation context */ int nColumn, /* The number of columns to check for NULL */ Index *pIdx, /* Index that we will be searching */ int regSrc, /* Take values from this register */ int regDest /* Write the result into this register */ ){ + Vdbe *v = pParse->pVdbe; assert( regSrc>0 ); assert( regDest>0 ); + assert( v!=0 ); sqlite3VdbeAddOp3(v, OP_MakeRecord, regSrc, nColumn, regDest); sqlite3IndexAffinityStr(v, pIdx); + sqlite3ExprCacheAffinityChange(pParse, regSrc, nColumn); } @@ -68013,19 +71264,23 @@ static void buildIndexProbe( ** result is left on the stack. For constraints of the form X IN (...) ** this routine sets up a loop that will iterate over all values of X. */ -static void codeEqualityTerm( +static int codeEqualityTerm( Parse *pParse, /* The parsing context */ WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ WhereLevel *pLevel, /* When level of the FROM clause we are working on */ - int iReg /* Leave results in this register */ + int iTarget /* Attempt to leave results in this register */ ){ Expr *pX = pTerm->pExpr; Vdbe *v = pParse->pVdbe; + int iReg; /* Register holding results */ - assert( iReg>0 && iReg<=pParse->nMem ); + if( iTarget<=0 ){ + iReg = iTarget = sqlite3GetTempReg(pParse); + } if( pX->op==TK_EQ ){ - sqlite3ExprCode(pParse, pX->pRight, iReg); + iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); }else if( pX->op==TK_ISNULL ){ + iReg = iTarget; sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); #ifndef SQLITE_OMIT_SUBQUERY }else{ @@ -68034,6 +71289,7 @@ static void codeEqualityTerm( struct InLoop *pIn; assert( pX->op==TK_IN ); + iReg = iTarget; eType = sqlite3FindInIndex(pParse, pX, 1); iTab = pX->iTable; sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); @@ -68060,6 +71316,7 @@ static void codeEqualityTerm( #endif } disableTerm(pLevel, pTerm); + return iReg; } /* @@ -68113,11 +71370,15 @@ static int codeAllEqualityTerms( */ assert( pIdx->nColumn>=nEq ); for(j=0; jaiColumn[j]; pTerm = findTerm(pWC, iCur, k, notReady, pLevel->flags, pIdx); if( pTerm==0 ) break; assert( (pTerm->flags & TERM_CODED)==0 ); - codeEqualityTerm(pParse, pTerm, pLevel, regBase+j); + r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j); + if( r1!=regBase+j ){ + sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j); + } if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){ sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->brk); } @@ -68249,7 +71510,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( SrcList *pTabList, /* A list of all tables to be scanned */ Expr *pWhere, /* The WHERE clause */ ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */ - u8 obflag /* One of ORDERBY_MIN, ORDERBY_MAX or ORDERBY_NORMAL */ + u8 wflags /* One of the WHERE_* flags defined in sqliteInt.h */ ){ int i; /* Loop counter */ WhereInfo *pWInfo; /* Will become the return value of this function */ @@ -68283,6 +71544,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( */ initMaskSet(&maskSet); whereClauseInit(&wc, pParse, &maskSet); + sqlite3ExprCodeConstants(pParse, pWhere); whereSplit(&wc, pWhere, TK_AND); /* Allocate and initialize the WhereInfo structure that will become the @@ -68307,14 +71569,36 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( pWhere = 0; } + /* Assign a bit from the bitmask to every term in the FROM clause. + ** + ** When assigning bitmask values to FROM clause cursors, it must be + ** the case that if X is the bitmask for the N-th FROM clause term then + ** the bitmask for all FROM clause terms to the left of the N-th term + ** is (X-1). An expression from the ON clause of a LEFT JOIN can use + ** its Expr.iRightJoinTable value to find the bitmask of the right table + ** of the join. Subtracting one from the right table bitmask gives a + ** bitmask for all tables to the left of the join. Knowing the bitmask + ** for all tables to the left of a left join is important. Ticket #3015. + */ + for(i=0; inSrc; i++){ + createMask(&maskSet, pTabList->a[i].iCursor); + } +#ifndef NDEBUG + { + Bitmask toTheLeft = 0; + for(i=0; inSrc; i++){ + Bitmask m = getMask(&maskSet, pTabList->a[i].iCursor); + assert( (m-1)==toTheLeft ); + toTheLeft |= m; + } + } +#endif + /* Analyze all of the subexpressions. Note that exprAnalyze() might ** add new virtual terms onto the end of the WHERE clause. We do not ** want to analyze these virtual terms, so start analyzing at the end ** and work forward so that the added virtual terms are never processed. */ - for(i=0; inSrc; i++){ - createMask(&maskSet, pTabList->a[i].iCursor); - } exprAnalyzeAll(pTabList, &wc); if( db->mallocFailed ){ goto whereBeginNoMem; @@ -68434,6 +71718,17 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( *ppOrderBy = 0; } + /* If the caller is an UPDATE or DELETE statement that is requesting + ** to use a one-pass algorithm, determine if this is appropriate. + ** The one-pass algorithm only works if the WHERE clause constraints + ** the statement to update a single row. + */ + assert( (wflags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 ); + if( (wflags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_UNIQUE)!=0 ){ + pWInfo->okOnePass = 1; + pWInfo->a[0].flags &= ~WHERE_IDX_ONLY; + } + /* Open all tables in the pTabList and any indices selected for ** searching those tables. */ @@ -68482,12 +71777,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( }else #endif if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){ - sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, OP_OpenRead); - if( pTab->nCol<(sizeof(Bitmask)*8) ){ + int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead; + sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op); + if( !pWInfo->okOnePass && pTab->nCol<(sizeof(Bitmask)*8) ){ Bitmask b = pTabItem->colUsed; int n = 0; for(; b; b=b>>1, n++){} - sqlite3VdbeChangeP2(v, sqlite3VdbeCurrentAddr(v)-1, n); + sqlite3VdbeChangeP2(v, sqlite3VdbeCurrentAddr(v)-2, n); assert( n<=pTab->nCol ); } }else{ @@ -68497,10 +71793,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( (pIx = pLevel->pIdx)!=0 ){ KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx); assert( pIx->pSchema==pTab->pSchema ); + 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)); - sqlite3VdbeAddOp2(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1); } sqlite3CodeVerifySchema(pParse, iDb); } @@ -68606,13 +71902,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( assert( pTerm->pExpr!=0 ); assert( pTerm->leftCursor==iCur ); assert( omitTable==0 ); - r1 = sqlite3GetTempReg(pParse); - codeEqualityTerm(pParse, pTerm, pLevel, r1); + r1 = codeEqualityTerm(pParse, pTerm, pLevel, 0); nxt = pLevel->nxt; - sqlite3VdbeAddOp3(v, OP_MustBeInt, r1, nxt, 1); + sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, nxt); sqlite3VdbeAddOp3(v, OP_NotExists, iCur, nxt, r1); VdbeComment((v, "pk")); - sqlite3ReleaseTempReg(pParse, r1); pLevel->op = OP_Noop; }else if( pLevel->flags & WHERE_ROWID_RANGE ){ /* Case 2: We have an inequality comparison against the ROWID field. @@ -68722,7 +72016,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** the first one after the nEq equality constraints in the index, ** this requires some special handling. */ - if( (obflag==ORDERBY_MIN) + if( (wflags&WHERE_ORDERBY_MIN)!=0 && (pLevel->flags&WHERE_ORDERBY) && (pIdx->nColumn>nEq) && (pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq]) @@ -68756,12 +72050,12 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( } if( testOp!=OP_Noop || (isMinQuery&&bRev) ){ int nCol = nEq + topLimit; - if( isMinQuery && !topLimit ){ + if( isMinQuery && bRev && !topLimit ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nCol); nCol++; topEq = 0; } - buildIndexProbe(v, nCol, pIdx, regBase, pLevel->iMem); + buildIndexProbe(pParse, nCol, pIdx, regBase, pLevel->iMem); if( bRev ){ int op = topEq ? OP_MoveLe : OP_MoveLt; sqlite3VdbeAddOp3(v, op, iIdxCur, nxt, pLevel->iMem); @@ -68795,7 +72089,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( } if( nEq>0 || btmLimit || (isMinQuery&&!bRev) ){ int nCol = nEq + btmLimit; - if( isMinQuery && !btmLimit ){ + if( isMinQuery && !bRev && !btmLimit ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nCol); nCol++; btmEq = 0; @@ -68806,7 +72100,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( }else{ r1 = sqlite3GetTempReg(pParse); } - buildIndexProbe(v, nCol, pIdx, regBase, r1); + buildIndexProbe(pParse, nCol, pIdx, regBase, r1); if( !bRev ){ int op = btmEq ? OP_MoveGe : OP_MoveGt; sqlite3VdbeAddOp3(v, op, iIdxCur, nxt, r1); @@ -68861,22 +72155,22 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( regBase = codeAllEqualityTerms(pParse, pLevel, &wc, notReady, 1); nxt = pLevel->nxt; - if( (obflag==ORDERBY_MIN) + if( (wflags&WHERE_ORDERBY_MIN)!=0 && (pLevel->flags&WHERE_ORDERBY) && (pIdx->nColumn>nEq) && (pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq]) ){ isMinQuery = 1; - buildIndexProbe(v, nEq, pIdx, regBase, pLevel->iMem); + buildIndexProbe(pParse, nEq, pIdx, regBase, pLevel->iMem); sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); r1 = ++pParse->nMem; - buildIndexProbe(v, nEq+1, pIdx, regBase, r1); + buildIndexProbe(pParse, nEq+1, pIdx, regBase, r1); }else{ /* Generate a single key that will be used to both start and ** terminate the search */ r1 = pLevel->iMem; - buildIndexProbe(v, nEq, pIdx, regBase, r1); + buildIndexProbe(pParse, nEq, pIdx, regBase, r1); } /* Generate code (1) to move to the first matching element of the table. @@ -68951,6 +72245,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( pLevel->top = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); VdbeComment((v, "record LEFT JOIN hit")); + sqlite3ExprClearColumnCache(pParse, pLevel->iTabCur); + sqlite3ExprClearColumnCache(pParse, pLevel->iIdxCur); for(pTerm=wc.a, j=0; jflags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( (pTerm->prereqAll & notReady)!=0 ) continue; @@ -69034,6 +72330,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ /* Generate loop termination code. */ + sqlite3ExprClearColumnCache(pWInfo->pParse, -1); for(i=pTabList->nSrc-1; i>=0; i--){ pLevel = &pWInfo->a[i]; sqlite3VdbeResolveLabel(v, pLevel->cont); @@ -69076,7 +72373,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ Table *pTab = pTabItem->pTab; assert( pTab!=0 ); if( pTab->isEphem || pTab->pSelect ) continue; - if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){ + if( !pWInfo->okOnePass && (pLevel->flags & WHERE_IDX_ONLY)==0 ){ sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); } if( pLevel->pIdx!=0 ){ @@ -69258,6 +72555,10 @@ typedef union { #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) #define YY_ERROR_ACTION (YYNSTATE+YYNRULE) +/* The yyzerominor constant is used to initialize instances of +** YYMINORTYPE objects to zero. */ +static const YYMINORTYPE yyzerominor; + /* Next are that tables used to determine what action to take based on the ** current state and lookahead token. These tables are used to implement ** functions that take a state number and lookahead value and return an @@ -70997,7 +74298,8 @@ static void yy_reduce( ** from wireshark this week. Clearly they are stressing Lemon in ways ** that it has not been previously stressed... (SQLite ticket #2172) */ - memset(&yygotominor, 0, sizeof(yygotominor)); + /*memset(&yygotominor, 0, sizeof(yygotominor));*/ + yygotominor = yyzerominor; switch( yyruleno ){ @@ -71297,7 +74599,7 @@ static void yy_reduce( break; case 104: /* cmd ::= select */ { - SelectDest dest = {SRT_Callback, 0, 0}; + SelectDest dest = {SRT_Callback, 0, 0, 0, 0}; sqlite3Select(pParse, yymsp[0].minor.yy219, &dest, 0, 0, 0, 0); sqlite3SelectDelete(yymsp[0].minor.yy219); } @@ -71477,7 +74779,7 @@ static void yy_reduce( break; case 160: /* cmd ::= UPDATE orconf fullname SET setlist where_opt */ { - sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy174,SQLITE_MAX_COLUMN,"set list"); + sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy174,"set list"); sqlite3Update(pParse,yymsp[-3].minor.yy373,yymsp[-1].minor.yy174,yymsp[0].minor.yy172,yymsp[-4].minor.yy46); } break; @@ -71787,7 +75089,7 @@ static void yy_reduce( sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy410); } yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy174, p, &yymsp[-2].minor.yy410); - sqlite3ExprListCheckLength(pParse, yygotominor.yy174, SQLITE_MAX_COLUMN, "index"); + sqlite3ExprListCheckLength(pParse, yygotominor.yy174, "index"); if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46; } break; @@ -71799,7 +75101,7 @@ static void yy_reduce( sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy410); } yygotominor.yy174 = sqlite3ExprListAppend(pParse,0, p, &yymsp[-2].minor.yy410); - sqlite3ExprListCheckLength(pParse, yygotominor.yy174, SQLITE_MAX_COLUMN, "index"); + sqlite3ExprListCheckLength(pParse, yygotominor.yy174, "index"); if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46; } break; @@ -72103,7 +75405,8 @@ SQLITE_PRIVATE void sqlite3Parser( if( yypParser->yyidx<0 ){ #if YYSTACKDEPTH<=0 if( yypParser->yystksz <=0 ){ - memset(&yyminorunion, 0, sizeof(yyminorunion)); + /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/ + yyminorunion = yyzerominor; yyStackOverflow(yypParser, &yyminorunion); return; } @@ -72241,7 +75544,7 @@ SQLITE_PRIVATE void sqlite3Parser( ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.138 2008/01/22 23:37:10 drh Exp $ +** $Id: tokenize.c,v 1.141 2008/04/05 18:41:43 drh Exp $ */ /* @@ -72459,7 +75762,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[] = { ** Return the length of the token that begins at z[0]. ** Store the token type in *tokenType before returning. */ -static int getToken(const unsigned char *z, int *tokenType){ +SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ int i, c; switch( *z ){ case ' ': case '\t': case '\n': case '\f': case '\r': { @@ -72709,9 +76012,6 @@ static int getToken(const unsigned char *z, int *tokenType){ *tokenType = TK_ILLEGAL; return 1; } -SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ - return getToken(z, tokenType); -} /* ** Run the parser on the given SQL string. The parser structure is @@ -72727,11 +76027,13 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr int tokenType; int lastTokenParsed = -1; sqlite3 *db = pParse->db; + int mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; if( db->activeVdbeCnt==0 ){ db->u1.isInterrupted = 0; } pParse->rc = SQLITE_OK; + pParse->zTail = pParse->zSql = zSql; i = 0; pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3_malloc); if( pEngine==0 ){ @@ -72745,14 +76047,13 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr assert( pParse->nVarExpr==0 ); assert( pParse->nVarExprAlloc==0 ); assert( pParse->apVarExpr==0 ); - pParse->zTail = pParse->zSql = zSql; while( !db->mallocFailed && zSql[i]!=0 ){ assert( i>=0 ); pParse->sLastToken.z = (u8*)&zSql[i]; assert( pParse->sLastToken.dyn==0 ); - pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType); + pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType); i += pParse->sLastToken.n; - if( SQLITE_MAX_SQL_LENGTH>0 && i>SQLITE_MAX_SQL_LENGTH ){ + if( i>mxSqlLen ){ pParse->rc = SQLITE_TOOBIG; break; } @@ -73132,7 +76433,7 @@ SQLITE_API int sqlite3_complete16(const void *zSql){ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.417 2008/01/31 15:31:02 danielk1977 Exp $ +** $Id: main.c,v 1.434 2008/04/16 00:49:12 drh Exp $ */ #ifdef SQLITE_ENABLE_FTS3 /************** Include fts3.h in the middle of main.c ***********************/ @@ -73181,7 +76482,7 @@ SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } ** I/O active are written using this function. These messages ** are intended for debugging activity only. */ -SQLITE_API void (*sqlite3_io_trace)(const char*, ...) = 0; +SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*, ...) = 0; /* ** If the following global variable points to a string which is the @@ -73192,12 +76493,22 @@ SQLITE_API void (*sqlite3_io_trace)(const char*, ...) = 0; */ SQLITE_API char *sqlite3_temp_directory = 0; +/* +** Routine needed to support the testcase() macro. +*/ +#ifdef SQLITE_COVERAGE_TEST +SQLITE_PRIVATE void sqlite3Coverage(int x){ + static int dummy = 0; + dummy += x; +} +#endif + /* ** Return true if the buffer z[0..n-1] contains all spaces. */ static int allSpaces(const char *z, int n){ - while( n>0 && z[--n]==' ' ){} + while( n>0 && z[n-1]==' ' ){ n--; } return n==0; } @@ -73686,7 +76997,6 @@ SQLITE_API int sqlite3_create_function( ){ int rc; sqlite3_mutex_enter(db->mutex); - assert( !db->mallocFailed ); rc = sqlite3CreateFunc(db, zFunctionName, nArg, enc, p, xFunc, xStep, xFinal); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); @@ -74074,6 +77384,87 @@ static int createCollation( } +/* +** This array defines hard upper bounds on limit values. The +** initializer must be kept in sync with the SQLITE_LIMIT_* +** #defines in sqlite3.h. +*/ +static const int aHardLimit[] = { + SQLITE_MAX_LENGTH, + SQLITE_MAX_SQL_LENGTH, + SQLITE_MAX_COLUMN, + SQLITE_MAX_EXPR_DEPTH, + SQLITE_MAX_COMPOUND_SELECT, + SQLITE_MAX_VDBE_OP, + SQLITE_MAX_FUNCTION_ARG, + SQLITE_MAX_ATTACHED, + SQLITE_MAX_LIKE_PATTERN_LENGTH, + SQLITE_MAX_VARIABLE_NUMBER, +}; + +/* +** Make sure the hard limits are set to reasonable values +*/ +#if SQLITE_MAX_LENGTH<100 +# error SQLITE_MAX_LENGTH must be at least 100 +#endif +#if SQLITE_MAX_SQL_LENGTH<100 +# error SQLITE_MAX_SQL_LENGTH must be at least 100 +#endif +#if SQLITE_MAX_SQL_LENGTH>SQLITE_MAX_LENGTH +# error SQLITE_MAX_SQL_LENGTH must not be greater than SQLITE_MAX_LENGTH +#endif +#if SQLITE_MAX_COLUMN<1 +# error SQLITE_MAX_COLUMN must be at least 1 +#endif +#if SQLITE_MAX_EXPR_DEPTH<1 +# error SQLITE_MAX_EXPR_DEPTH must be at least 1 +#endif +#if SQLITE_MAX_COMPOUND_SELECT<2 +# error SQLITE_MAX_COMPOUND_SELECT must be at least 2 +#endif +#if SQLITE_MAX_VDBE_OP<40 +# error SQLITE_MAX_VDBE_OP must be at least 40 +#endif +#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>255 +# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 255 +#endif +#if SQLITE_MAX_ATTACH<0 || SQLITE_MAX_ATTACH>30 +# error SQLITE_MAX_ATTACH must be between 0 and 30 +#endif +#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 +# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 +#endif +#if SQLITE_MAX_VARIABLE_NUMBER<1 +# error SQLITE_MAX_VARIABLE_NUMBER must be at least 1 +#endif + + +/* +** Change the value of a limit. Report the old value. +** If an invalid limit index is supplied, report -1. +** Make no changes but still report the old value if the +** new limit is negative. +** +** A new lower limit does not shrink existing constructs. +** It merely prevents new constructs that exceed the limit +** from forming. +*/ +SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ + int oldLimit; + if( limitId<0 || limitId>=SQLITE_N_LIMIT ){ + return -1; + } + oldLimit = db->aLimit[limitId]; + if( newLimit>=0 ){ + if( newLimit>aHardLimit[limitId] ){ + newLimit = aHardLimit[limitId]; + } + db->aLimit[limitId] = newLimit; + } + return oldLimit; +} + /* ** This routine does the work of opening a database on behalf of ** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" @@ -74089,6 +77480,17 @@ static int openDatabase( int rc; CollSeq *pColl; + /* Remove harmful bits from the flags parameter */ + flags &= ~( SQLITE_OPEN_DELETEONCLOSE | + SQLITE_OPEN_MAIN_DB | + SQLITE_OPEN_TEMP_DB | + SQLITE_OPEN_TRANSIENT_DB | + SQLITE_OPEN_MAIN_JOURNAL | + SQLITE_OPEN_TEMP_JOURNAL | + SQLITE_OPEN_SUBJOURNAL | + SQLITE_OPEN_MASTER_JOURNAL + ); + /* Allocate the sqlite data structure */ db = sqlite3MallocZero( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; @@ -74104,8 +77506,11 @@ static int openDatabase( db->nDb = 2; db->magic = SQLITE_MAGIC_BUSY; db->aDb = db->aDbStatic; + assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); + memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); db->autoCommit = 1; db->nextAutovac = -1; + db->nextPagesize = 0; db->flags |= SQLITE_ShortColNames #if SQLITE_DEFAULT_FILE_FORMAT<4 | SQLITE_LegacyFileFmt @@ -74124,7 +77529,7 @@ static int openDatabase( if( !db->pVfs ){ rc = SQLITE_ERROR; db->magic = SQLITE_MAGIC_SICK; - sqlite3Error(db, rc, "no such vfs: %s", (zVfs?zVfs:"(null)")); + sqlite3Error(db, rc, "no such vfs: %s", zVfs); goto opendb_out; } @@ -74132,16 +77537,16 @@ static int openDatabase( ** and UTF-16, so add a version for each to avoid any unnecessary ** conversions. The only error that can occur here is a malloc() failure. */ - if( createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0) || - createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0) || - createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0) || - createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0) || - (db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0))==0 - ){ - assert( db->mallocFailed ); + createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0); + createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0); + if( db->mallocFailed ){ db->magic = SQLITE_MAGIC_SICK; goto opendb_out; } + db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0); + assert( db->pDfltColl!=0 ); /* Also add a UTF-8 case-insensitive collation sequence. */ createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); @@ -74236,7 +77641,8 @@ static int openDatabase( #endif opendb_out: - if( db && db->mutex ){ + if( db ){ + assert( db->mutex!=0 ); sqlite3_mutex_leave(db->mutex); } if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){ @@ -74287,8 +77693,9 @@ SQLITE_API int sqlite3_open16( if( zFilename8 ){ rc = openDatabase(zFilename8, ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); - if( rc==SQLITE_OK && *ppDb ){ - rc = sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0); + assert( *ppDb || rc==SQLITE_NOMEM ); + if( rc==SQLITE_OK ){ + ENC(*ppDb) = SQLITE_UTF16NATIVE; if( rc!=SQLITE_OK ){ sqlite3_close(*ppDb); *ppDb = 0; @@ -74474,9 +77881,11 @@ SQLITE_API int sqlite3_table_column_metadata( int autoinc = 0; /* Ensure the database schema has been loaded */ - (void)sqlite3SafetyOn(db); sqlite3_mutex_enter(db->mutex); + (void)sqlite3SafetyOn(db); + sqlite3BtreeEnterAll(db); rc = sqlite3Init(db, &zErrMsg); + sqlite3BtreeLeaveAll(db); if( SQLITE_OK!=rc ){ goto error_out; } @@ -74620,11 +78029,19 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo ** Interface to the testing logic. */ SQLITE_API int sqlite3_test_control(int op, ...){ - va_list ap; int rc = 0; +#ifndef SQLITE_OMIT_BUILTIN_TEST + va_list ap; va_start(ap, op); switch( op ){ -#ifndef SQLITE_OMIT_FAULTINJECTOR + /* + ** sqlite3_test_control(FAULT_CONFIG, fault_id, nDelay, nRepeat) + ** + ** Configure a fault injector. The specific fault injector is + ** identified by the fault_id argument. (ex: SQLITE_FAULTINJECTOR_MALLOC) + ** The fault will occur after a delay of nDelay calls. The fault + ** will repeat nRepeat times. + */ case SQLITE_TESTCTRL_FAULT_CONFIG: { int id = va_arg(ap, int); int nDelay = va_arg(ap, int); @@ -74632,24 +78049,89 @@ SQLITE_API int sqlite3_test_control(int op, ...){ sqlite3FaultConfig(id, nDelay, nRepeat); break; } + + /* + ** sqlite3_test_control(FAULT_FAILURES, fault_id) + ** + ** Return the number of faults (both hard and benign faults) that have + ** occurred since the injector identified by fault_id) was last configured. + */ case SQLITE_TESTCTRL_FAULT_FAILURES: { int id = va_arg(ap, int); rc = sqlite3FaultFailures(id); break; } + + /* + ** sqlite3_test_control(FAULT_BENIGN_FAILURES, fault_id) + ** + ** Return the number of benign faults that have occurred since the + ** injector identified by fault_id was last configured. + */ case SQLITE_TESTCTRL_FAULT_BENIGN_FAILURES: { int id = va_arg(ap, int); rc = sqlite3FaultBenignFailures(id); break; } + + /* + ** sqlite3_test_control(FAULT_PENDING, fault_id) + ** + ** Return the number of successes that will occur before the next + ** scheduled failure on fault injector fault_id. + ** If no failures are scheduled, return -1. + */ case SQLITE_TESTCTRL_FAULT_PENDING: { int id = va_arg(ap, int); rc = sqlite3FaultPending(id); break; } -#endif /* SQLITE_OMIT_FAULTINJECTOR */ + + /* + ** Save the current state of the PRNG. + */ + case SQLITE_TESTCTRL_PRNG_SAVE: { + sqlite3PrngSaveState(); + break; + } + + /* + ** Restore the state of the PRNG to the last state saved using + ** PRNG_SAVE. If PRNG_SAVE has never before been called, then + ** this verb acts like PRNG_RESET. + */ + case SQLITE_TESTCTRL_PRNG_RESTORE: { + sqlite3PrngRestoreState(); + break; + } + + /* + ** Reset the PRNG back to its uninitialized state. The next call + ** to sqlite3_randomness() will reseed the PRNG using a single call + ** to the xRandomness method of the default VFS. + */ + case SQLITE_TESTCTRL_PRNG_RESET: { + sqlite3PrngResetState(); + break; + } + + /* + ** sqlite3_test_control(BITVEC_TEST, size, program) + ** + ** Run a test against a Bitvec object of size. The program argument + ** is an array of integers that defines the test. Return -1 on a + ** memory allocation error, 0 on success, or non-zero for an error. + ** See the sqlite3BitvecBuiltinTest() for additional information. + */ + case SQLITE_TESTCTRL_BITVEC_TEST: { + int sz = va_arg(ap, int); + int *aProg = va_arg(ap, int*); + rc = sqlite3BitvecBuiltinTest(sz, aProg); + break; + } } va_end(ap); +#endif /* SQLITE_OMIT_BUILTIN_TEST */ return rc; } @@ -75201,7 +78683,6 @@ struct sqlite3_tokenizer_cursor { /************** End of fts3_tokenizer.h **************************************/ /************** Continuing where we left off in fts3.c ***********************/ #ifndef SQLITE_CORE - #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #endif @@ -78285,8 +81766,8 @@ static void snippetOffsetText(Snippet *p){ ** it in this case */ zBuf[0] = ' '; - sprintf(&zBuf[cnt>0], "%d %d %d %d", pMatch->iCol, - pMatch->iTerm, pMatch->iStart, pMatch->nByte); + sqlite3_snprintf(sizeof(zBuf)-1, &zBuf[cnt>0], "%d %d %d %d", + pMatch->iCol, pMatch->iTerm, pMatch->iStart, pMatch->nByte); append(&sb, zBuf); cnt++; } @@ -82355,7 +85836,9 @@ SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule( */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) -SQLITE_EXTENSION_INIT1 +#ifndef SQLITE_CORE + SQLITE_EXTENSION_INIT1 +#endif /* diff --git a/src/contrib/taglib_plugin/TagReaderTaglib.cpp b/src/contrib/taglib_plugin/TagReaderTaglib.cpp index 08144756e..b5e716001 100644 --- a/src/contrib/taglib_plugin/TagReaderTaglib.cpp +++ b/src/contrib/taglib_plugin/TagReaderTaglib.cpp @@ -143,7 +143,7 @@ bool TagReaderTaglib::GetGenericTag(musik::core::Track *track){ // ALBUM this->SetTagValue("album",tag->album(),track); // ARTISTS - this->SetSlashSeparatedValues("artist",tag->album(),track); + this->SetSlashSeparatedValues("artist",tag->artist(),track); // GENRES this->SetTagValue("genre",tag->genre(),track); // COMMENT @@ -422,3 +422,4 @@ void TagReaderTaglib::SetAudioProperties(TagLib::AudioProperties *audioPropertie } } + diff --git a/src/core/Library/Base.cpp b/src/core/Library/Base.cpp index f238d53dd..75fa82fcf 100644 --- a/src/core/Library/Base.cpp +++ b/src/core/Library/Base.cpp @@ -245,15 +245,12 @@ bool Library::Base::AddQuery( const Query::Base &query,unsigned int options ){ boost::mutex::scoped_lock lock(this->libraryMutex); // wait for the query to be finished or canceled - while( !(queryCopy->status&Query::Base::Status::Ended) ){ + while( !(queryCopy->status&Query::Base::Status::Ended) && !(queryCopy->status&Query::Base::Status::Canceled) ){ this->waitCondition.wait(lock); } if( options & Query::Options::AutoCallback ){ // Should the callbacks be involved? - if( !(queryCopy->status&Query::Base::Status::Canceled) ){ // If not canceled - queryCopy->RunCallbacks(this); // Run the callbacks. - queryCopy->status |= Query::Base::Status::Finished; // Set to finished for removal. - } + queryCopy->status |= Query::Base::Status::Finished; // Set to finished for removal. } } @@ -261,6 +258,13 @@ bool Library::Base::AddQuery( const Query::Base &query,unsigned int options ){ // Finaly, remove old, finished queries this->ClearFinishedQueries(); + if( options & Query::Options::AutoCallback ){ // Should the callbacks be involved? + if( !(queryCopy->status&Query::Base::Status::Canceled) ){ // If not canceled + queryCopy->RunCallbacks(this); // Run the callbacks. + } + } + + } return true; diff --git a/src/core/PlaybackQueue.cpp b/src/core/PlaybackQueue.cpp index b234439a8..3e90c84ff 100644 --- a/src/core/PlaybackQueue.cpp +++ b/src/core/PlaybackQueue.cpp @@ -31,7 +31,11 @@ // ////////////////////////////////////////////////////////////////////////////// #include "pch.hpp" -#include "PlaybackQueue.h" +#include "core/PlaybackQueue.h" +#include "core/LibraryFactory.h" + +#include + using namespace musik::core; @@ -41,12 +45,24 @@ PlaybackQueue PlaybackQueue::sInstance; PlaybackQueue::PlaybackQueue(void) : - nowPlaying( new musik::core::tracklist::Standard() ) + nowPlaying( new musik::core::tracklist::Standard() ), + signalDisabled(false), + playing(false) { + this->transport.MixpointReached.connect(this,&PlaybackQueue::OnPlaybackEndOrFail); +// this->transport.PlaybackStoppedFail.connect(this,&PlaybackQueue::OnPlaybackEndOrFail); } PlaybackQueue::~PlaybackQueue(void) { + this->transport.Stop(0); +} + +void PlaybackQueue::OnPlaybackEndOrFail(){ + this->playing = false; + if(!this->signalDisabled){ + this->Next(); + } } tracklist::IRandomAccessPtr PlaybackQueue::NowPlayingTracklist(){ @@ -59,15 +75,46 @@ void PlaybackQueue::Play(){ if(track){ // If current track exists - this->transport.Start(track->GetValue("path")); + utfstring path(track->GetValue("path")); + + this->Stop(); + + this->playing = true; + this->transport.Start(path); } } +void PlaybackQueue::Next(){ + musik::core::TrackPtr track( this->nowPlaying->NextTrack() ); + if(track){ + this->SetCurrentTrack(track->Copy()); + this->Play(); + } +} + +void PlaybackQueue::Previous(){ + musik::core::TrackPtr track( this->nowPlaying->PreviousTrack() ); + if(track){ + this->SetCurrentTrack(track->Copy()); + this->Play(); + } +} + +void PlaybackQueue::Stop(){ + this->signalDisabled = true; + if( this->playing ){ + this->transport.Stop(0); + } + this->signalDisabled = false; +} + + TrackPtr PlaybackQueue::CurrentTrack(){ if(!this->currentTrack){ // If the current track is empty, get a track from the nowPlaying tracklist - this->SetCurrentTrack( this->nowPlaying->CurrentTrack() ); + this->SetCurrentTrack( this->nowPlaying->CurrentTrack()->Copy() ); + } return this->currentTrack; } @@ -76,8 +123,23 @@ void PlaybackQueue::SetCurrentTrack(TrackPtr track){ if(this->currentTrack!=track){ this->currentTrack = track; + // Get all metadata to the track + if(this->currentTrack){ + this->metadataQuery.Clear(); + this->metadataQuery.RequestAllMetakeys(); + this->metadataQuery.RequestTrack(this->currentTrack); + this->nowPlaying->Library()->AddQuery(this->metadataQuery,musik::core::Query::Wait|musik::core::Query::AutoCallback|musik::core::Query::UnCanceable|musik::core::Query::Prioritize); + } + // Call the signal if track updates this->CurrentTrackChanged(track); } } +void PlaybackQueue::Play(tracklist::IRandomAccess &tracklist){ + this->currentTrack.reset(); + this->nowPlaying->CopyTracks(tracklist); + this->Play(); +} + + diff --git a/src/core/PlaybackQueue.h b/src/core/PlaybackQueue.h index f73db5631..fa55af649 100644 --- a/src/core/PlaybackQueue.h +++ b/src/core/PlaybackQueue.h @@ -46,7 +46,7 @@ namespace musik { namespace core { ////////////////////////////////////////////////////////////////////////////// -class PlaybackQueue{ +class PlaybackQueue : public sigslot::has_slots<>{ private: PlaybackQueue(void); static PlaybackQueue sInstance; @@ -54,6 +54,8 @@ class PlaybackQueue{ audio::Transport transport; tracklist::IRandomAccessPtr nowPlaying; + bool playing; + public: ~PlaybackQueue(void); static PlaybackQueue& Instance(){ return sInstance; }; @@ -66,7 +68,7 @@ class PlaybackQueue{ // Playback Control void Play(); void Next(); - void Previos(); + void Previous(); void Stop(); musik::core::TrackPtr CurrentTrack(); @@ -77,6 +79,11 @@ class PlaybackQueue{ private: TrackPtr currentTrack; void SetCurrentTrack(TrackPtr track); + musik::core::Query::Tracks metadataQuery; + + void OnPlaybackEndOrFail(); + + bool signalDisabled; }; diff --git a/src/core/Query/Tracks.cpp b/src/core/Query/Tracks.cpp index 85311af56..ab60c8f02 100644 --- a/src/core/Query/Tracks.cpp +++ b/src/core/Query/Tracks.cpp @@ -141,6 +141,11 @@ bool Tracks::ParseQuery(Library::Base *oLibrary,db::Connection &db){ std::string sql=this->sSQL+this->sSQLTables+this->sSQLWhere; + if(sql.empty()){ + // ERROR.. SOMETHING IS WRONG HERE + return true; + } + db::CachedStatement trackData(sql.c_str(),db); bool bCancel(false); diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 7877e220f..81310e1f4 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -531,3 +531,7 @@ void Track::SetThumbnail(const char *data,unsigned int size){ this->meta->SetThumbnail(data,size); } } + +TrackPtr Track::Copy(){ + return TrackPtr(new Track(this->id)); +} diff --git a/src/core/Track.h b/src/core/Track.h index 48d840f98..61aee9877 100644 --- a/src/core/Track.h +++ b/src/core/Track.h @@ -50,6 +50,22 @@ namespace musik{ namespace core{ // Forward declare + class Track; + + /*! + * \brief + * shared pointer to a track. + * + * The TrackPtr is used almost everywhere since the Tracks can be + * shared between different threads. + * + * \remarks + * For the Tracks to be thread-safe, you need to pass the ThreadHelper object when required. + * + * \see + * Track|TrackVector + */ + typedef boost::shared_ptr TrackPtr; /*! * \brief @@ -82,6 +98,8 @@ namespace musik{ namespace core{ DBINT id; void ClearMeta(); + TrackPtr Copy(); + private: // const TrackMeta::Value& GetValue(const TrackMeta::Key &key) const; @@ -109,20 +127,6 @@ namespace musik{ namespace core{ DBINT _GetArtist(db::Connection &dbConnection,utfstring artist,bool addRelation,bool aggregated=false); }; - /*! - * \brief - * shared pointer to a track. - * - * The TrackPtr is used almost everywhere since the Tracks can be - * shared between different threads. - * - * \remarks - * For the Tracks to be thread-safe, you need to pass the ThreadHelper object when required. - * - * \see - * Track|TrackVector - */ - typedef boost::shared_ptr TrackPtr; /*! * \brief diff --git a/src/core/tracklist/IRandomAccess.h b/src/core/tracklist/IRandomAccess.h index d27815eda..d52c69d9a 100644 --- a/src/core/tracklist/IRandomAccess.h +++ b/src/core/tracklist/IRandomAccess.h @@ -37,6 +37,7 @@ #pragma once #include "core/tracklist/IBase.h" +#include #include namespace musik{ namespace core{ @@ -49,6 +50,13 @@ namespace musik{ namespace core{ virtual int Size() = 0; virtual void SetCurrentPosition(int position) = 0; virtual int CurrentPosition() = 0; + virtual void SetLibrary(musik::core::LibraryPtr setLibrary) = 0; + virtual musik::core::LibraryPtr Library() = 0; + + virtual void CopyTracks(musik::core::tracklist::IRandomAccess &tracklist) = 0; + virtual void AppendTracks(musik::core::tracklist::IRandomAccess &tracklist) = 0; + + virtual musik::core::TrackPtr Track(int position)=0; }; typedef boost::shared_ptr IRandomAccessPtr; @@ -56,3 +64,4 @@ namespace musik{ namespace core{ } } } + diff --git a/src/core/tracklist/Standard.cpp b/src/core/tracklist/Standard.cpp index 6b04fbf1d..b01254449 100644 --- a/src/core/tracklist/Standard.cpp +++ b/src/core/tracklist/Standard.cpp @@ -50,7 +50,7 @@ Standard::~Standard(void){ } musik::core::TrackPtr Standard::CurrentTrack(){ - return (*this)[this->currentPosition]; + return this->Track(this->currentPosition); } @@ -79,7 +79,7 @@ musik::core::TrackPtr Standard::operator [](int position){ return musik::core::TrackPtr(); } -musik::core::TrackPtr Standard::at(int position){ +musik::core::TrackPtr Standard::Track(int position){ if(position>=0 && positiontracks.size()) return this->tracks[position]; @@ -100,7 +100,7 @@ void Standard::SetCurrentPosition(int position){ if(position<-1){ this->currentPosition = -1; }else{ - if(position>=this->tracks.size()){ + if(position >= (int)this->tracks.size()){ this->currentPosition = this->tracks.size()-1; }else{ this->currentPosition = position; @@ -113,7 +113,7 @@ int Standard::CurrentPosition(){ if(this->currentPosition<0) return -1; - if(this->currentPosition>=this->tracks.size()) + if(this->currentPosition >= (int)this->tracks.size()) return this->tracks.size()-1; return this->currentPosition; @@ -124,10 +124,14 @@ void Standard::ConnectToQuery(musik::core::Query::ListBase &listQuery){ } -void Standard::ConnectToLibrary(musik::core::LibraryPtr setLibrary){ +void Standard::SetLibrary(musik::core::LibraryPtr setLibrary){ this->library = setLibrary; } +musik::core::LibraryPtr Standard::Library(){ + return this->library; +} + void Standard::OnTracksFromQuery(musik::core::TrackVector *newTracks,bool clear){ @@ -152,7 +156,7 @@ void Standard::LoadTrack(int position){ for(int i(position);ihintedRows;++i){ if(!this->InCache(i)){ // Not in cache, load the track and add to Cache - musik::core::TrackPtr track = this->at(i); + musik::core::TrackPtr track = this->Track(i); if(track){ this->trackCache.insert(CacheTrack(track,i)); ++trackCount; @@ -161,7 +165,7 @@ void Standard::LoadTrack(int position){ } } - if(trackCount){ + if(trackCount && this->library){ this->library->AddQuery(this->trackQuery,musik::core::Query::Prioritize); this->trackQuery.Clear(); } @@ -218,5 +222,26 @@ void Standard::RemoveRequestedMetakey(const char* metakey){ this->trackQuery.RequestMetakeys(this->requestedMetaKeys); } +void Standard::CopyTracks(musik::core::tracklist::IRandomAccess &tracklist){ + this->SetLibrary(tracklist.Library()); + this->tracks.clear(); + this->tracks.reserve(tracklist.Size()); + for(int i(0);itracks.push_back(tracklist.Track(i)->Copy()); + } + this->SetCurrentPosition(tracklist.CurrentPosition()); +} + +void Standard::AppendTracks(musik::core::tracklist::IRandomAccess &tracklist){ + if(!this->library){ + this->SetLibrary(tracklist.Library()); + } + + this->tracks.reserve(this->tracks.size()+tracklist.Size()); + + for(int i(0);itracks.push_back(tracklist.Track(i)->Copy()); + } +} diff --git a/src/core/tracklist/Standard.h b/src/core/tracklist/Standard.h index 4b3588084..6e86ece8a 100644 --- a/src/core/tracklist/Standard.h +++ b/src/core/tracklist/Standard.h @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -59,6 +60,9 @@ namespace musik{ namespace core{ class Standard : public IRandomAccess, public sigslot::has_slots<> { public: + + typedef boost::shared_ptr Ptr; + Standard(void); ~Standard(void); @@ -72,7 +76,8 @@ namespace musik{ namespace core{ int CurrentPosition(); void ConnectToQuery(musik::core::Query::ListBase &listQuery); - void ConnectToLibrary(musik::core::LibraryPtr setLibrary); + void SetLibrary(musik::core::LibraryPtr setLibrary); + musik::core::LibraryPtr Library(); typedef sigslot::signal1 TracksEvent; @@ -87,9 +92,11 @@ namespace musik{ namespace core{ void AddRequestedMetakey(const char* metakey); void RemoveRequestedMetakey(const char* metakey); + void CopyTracks(musik::core::tracklist::IRandomAccess &tracklist); + void AppendTracks(musik::core::tracklist::IRandomAccess &tracklist); protected: - musik::core::TrackPtr at(int position); + musik::core::TrackPtr Track(int position); std::set requestedMetaKeys; diff --git a/src/cube/MainWindowController.cpp b/src/cube/MainWindowController.cpp index 5b4c8d81f..9783782fd 100644 --- a/src/cube/MainWindowController.cpp +++ b/src/cube/MainWindowController.cpp @@ -68,8 +68,6 @@ using namespace musik::cube; musik::core::LibraryFactory::GetCurrentLibrary()->OnQueryQueueStart.connect(this,&MainWindowController::QueryQueueStart); musik::core::LibraryFactory::GetCurrentLibrary()->OnQueryQueueEnd.connect(this,&MainWindowController::QueryQueueEnd); - musik::core::LibraryPtr lib = musik::core::LibraryFactory::GetCurrentLibrary(); - ((musik::core::Library::LocalDB*)lib.get())->indexer.AddPath(_T("X:/musik/")); } MainWindowController::~MainWindowController() diff --git a/src/cube/TracklistController.cpp b/src/cube/TracklistController.cpp index bf45f3078..9a336efd9 100644 --- a/src/cube/TracklistController.cpp +++ b/src/cube/TracklistController.cpp @@ -73,15 +73,22 @@ void TracklistController::OnViewCreated() // listView->EnableStripedBackground(true); listView->SetModel(this->model); + listView->RowDoubleClick.connect(this,&TracklistController::OnRowDoubleClick); } void TracklistController::OnResized(Size size) { } +void TracklistController::OnRowDoubleClick(int row) +{ + ((TracklistModel*)this->model.get())->OnRowDoubleClick(row); +} + + void TracklistController::AddColumn(const utfchar *name,const char *metakey,int size){ this->view.listView->AddColumn(ListView::ColumnRef(new TracklistColumn(metakey,name, size))); - ((TracklistModel*)this->model.get())->tracklist.AddRequestedMetakey(metakey); + ((TracklistModel*)this->model.get())->tracklist->AddRequestedMetakey(metakey); } diff --git a/src/cube/TracklistController.hpp b/src/cube/TracklistController.hpp index 0cb680698..e41e07f88 100644 --- a/src/cube/TracklistController.hpp +++ b/src/cube/TracklistController.hpp @@ -66,6 +66,7 @@ public: /*ctor*/ TracklistController(TracklistView& listView,musik::core: protected: void OnViewCreated(); protected: void OnResized(Size size); +protected: void OnRowDoubleClick(int row); protected: void AddColumn(const utfchar *name,const char *metakey,int size); protected: ModelRef model; diff --git a/src/cube/TracklistModel.cpp b/src/cube/TracklistModel.cpp index fc616d688..41ad4b98d 100644 --- a/src/cube/TracklistModel.cpp +++ b/src/cube/TracklistModel.cpp @@ -43,6 +43,8 @@ #include #include +#include + #include #include @@ -50,16 +52,17 @@ using namespace musik::cube; ////////////////////////////////////////////////////////////////////////////// -/*ctor*/ TracklistModel::TracklistModel(musik::core::Query::ListBase *connectedQuery) +/*ctor*/ TracklistModel::TracklistModel(musik::core::Query::ListBase *connectedQuery) : + tracklist(new musik::core::tracklist::Standard()) { this->SetRowCount(0); - this->tracklist.OnTracks.connect(this,&TracklistModel::OnTracks); - this->tracklist.OnTrackMeta.connect(this,&TracklistModel::OnTrackMeta); - this->tracklist.ConnectToLibrary(musik::core::LibraryFactory::GetCurrentLibrary()); + this->tracklist->OnTracks.connect(this,&TracklistModel::OnTracks); + this->tracklist->OnTrackMeta.connect(this,&TracklistModel::OnTrackMeta); + this->tracklist->SetLibrary(musik::core::LibraryFactory::GetCurrentLibrary()); if(connectedQuery){ - this->tracklist.ConnectToQuery(*connectedQuery); + this->tracklist->ConnectToQuery(*connectedQuery); } } @@ -71,7 +74,7 @@ uistring TracklistModel::CellValueToString(int rowIndex, ColumnRef co typedef boost::basic_format format; // return (format(_T("%1% %2%")) % column->Name() % (rowIndex + 1)).str(); - musik::core::TrackPtr track = this->tracklist[rowIndex]; + musik::core::TrackPtr track = (*this->tracklist)[rowIndex]; if(!track){ return _T(""); }else{ @@ -92,7 +95,11 @@ void TracklistModel::OnTracks(bool cleared){ if(cleared){ this->SetRowCount(0); } - this->SetRowCount(this->tracklist.Size()); + this->SetRowCount(this->tracklist->Size()); } +void TracklistModel::OnRowDoubleClick(int row){ + this->tracklist->SetCurrentPosition(row); + musik::core::PlaybackQueue::Instance().Play(*this->tracklist); +} diff --git a/src/cube/TracklistModel.hpp b/src/cube/TracklistModel.hpp index f458c0164..98c3bf2a3 100644 --- a/src/cube/TracklistModel.hpp +++ b/src/cube/TracklistModel.hpp @@ -67,7 +67,8 @@ public: virtual uistring CellValueToString(int rowIndex, ColumnRef column); // instance data protected: void OnTrackMeta(std::vector &trackPositions); protected: void OnTracks(bool cleared); -public: musik::core::tracklist::Standard tracklist; +public: musik::core::tracklist::Standard::Ptr tracklist; +public: void OnRowDoubleClick(int row); }; ////////////////////////////////////////////////////////////////////////////// diff --git a/src/cube/TransportController.cpp b/src/cube/TransportController.cpp index fc3d1e8fe..fb99111d0 100644 --- a/src/cube/TransportController.cpp +++ b/src/cube/TransportController.cpp @@ -63,9 +63,15 @@ void TransportController::OnViewCreated() this->transportView.stopButton->Pressed.connect( this, &TransportController::OnStopPressed); - this->transportView.volumeSlider->Repositioned.connect( + this->transportView.nextButton->Pressed.connect( + this, &TransportController::OnNextPressed); + + this->transportView.prevButton->Pressed.connect( + this, &TransportController::OnPreviousPressed); + +/* this->transportView.volumeSlider->Repositioned.connect( this, &TransportController::OnVolumeSliderChange); - this->transportView.volumeSlider->SetPosition(transport.Volume()); + this->transportView.volumeSlider->SetPosition(transport.Volume());*/ } void TransportController::OnViewResized(Size size) @@ -74,15 +80,25 @@ void TransportController::OnViewResized(Size size) void TransportController::OnPlayPressed() { - transport.Start(_T("d:\\musik\\test.mp3")); + musik::core::PlaybackQueue::Instance().Play(); } void TransportController::OnStopPressed() { - transport.Stop(0); + musik::core::PlaybackQueue::Instance().Stop(); +} + +void TransportController::OnNextPressed() +{ + musik::core::PlaybackQueue::Instance().Next(); +} + +void TransportController::OnPreviousPressed() +{ + musik::core::PlaybackQueue::Instance().Previous(); } void TransportController::OnVolumeSliderChange() { - transport.ChangeVolume(transportView.volumeSlider->Position()/100.0f); +// transport.ChangeVolume(transportView.volumeSlider->Position()/100.0f); } diff --git a/src/cube/TransportController.hpp b/src/cube/TransportController.hpp index 0cc478ec0..56cf26eb4 100644 --- a/src/cube/TransportController.hpp +++ b/src/cube/TransportController.hpp @@ -40,7 +40,7 @@ ////////////////////////////////////////////////////////////////////////////// -#include +#include #include ////////////////////////////////////////////////////////////////////////////// @@ -63,9 +63,11 @@ protected: musik::core::audio::Transport transport; protected: void OnPlayPressed(); protected: void OnStopPressed(); +protected: void OnNextPressed(); +protected: void OnPreviousPressed(); protected: void OnVolumeSliderChange(); }; ////////////////////////////////////////////////////////////////////////////// -} } // musik::cube \ No newline at end of file +} } // musik::cube diff --git a/src/win32cpp/ListView.cpp b/src/win32cpp/ListView.cpp index 82335fdce..3fa38971b 100644 --- a/src/win32cpp/ListView.cpp +++ b/src/win32cpp/ListView.cpp @@ -449,6 +449,22 @@ void ListView::OnMouseMoved(MouseEventFlags flags, const Point& location) this->SetHotCell(rowIndex, column); } +void ListView::OnMouseButtonDoubleClicked(MouseEventFlags flags, const Point& location) +{ + int rowIndex(0); + ColumnRef column = ColumnRef(); + // + if ( ! this->CellAtPoint(location, rowIndex, column)) + { + rowIndex = -1; + column = ColumnRef(); + }else{ + this->RowDoubleClick(rowIndex); + } + // + +} + void ListView::OnMouseExit() { this->SetHotCell(-1, ColumnRef()); diff --git a/src/win32cpp/ListView.hpp b/src/win32cpp/ListView.hpp index 094c9902a..271fda66e 100644 --- a/src/win32cpp/ListView.hpp +++ b/src/win32cpp/ListView.hpp @@ -123,11 +123,14 @@ public: typedef boost::shared_ptr ModelRef; public: /*! */ typedef sigslot::signal1 HotRowChangedEvent; +public: /*! */ typedef sigslot::signal1 RowDoubleClickEvent; public: /*! */ typedef sigslot::signal2 HotCellChangedEvent; public: /*! */ typedef sigslot::signal0<> SelectionChangedEvent; ///\brief Emitted when the the mouse cursor has entered a new row public: HotRowChangedEvent HotRowChanged; + ///\brief Emitted when the the mousebutton doubleclicks on a row +public: RowDoubleClickEvent RowDoubleClick; ///\brief Emitted when the the mouse cursor has entered a new cell public: HotCellChangedEvent HotCellChanged; ///\brief Emitted when the selection has changed @@ -184,6 +187,7 @@ protected: virtual void OnRowCountChanged(); protected: virtual void OnDataChanged(int rowIndex); protected: virtual void OnMeasureItem(MEASUREITEMSTRUCT* measureItemStruct); protected: virtual void OnMouseMoved(MouseEventFlags flags, const Point& location); +protected: virtual void OnMouseButtonDoubleClicked(MouseEventFlags flags, const Point& location); protected: virtual void OnMouseExit(); private: typedef Window base;